source: ttyvaders/trunk/src/collide.c @ 2990

Last change on this file since 2990 was 2990, checked in by Sam Hocevar, 11 years ago

Port ttyvaders to the unified libcaca 0.99.beta15 API.

  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/*
2 *  ttyvaders     Textmode shoot'em up
3 *  Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: collide.c 2990 2008-10-18 21:42:24Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#include <stdlib.h>
18
19#include "common.h"
20
21void collide_weapons_tunnel(game *g, weapons *wp, tunnel *t, explosions *ex)
22{
23    int i, j, x, y;
24
25    for(i = 0; i < WEAPONS; i++)
26    {
27        x = wp->x[i] >> 4;
28        y = wp->y[i] >> 4;
29
30        switch(wp->type[i])
31        {
32        case WEAPON_LIGHTNING:
33        case WEAPON_NONE:
34            break;
35        case WEAPON_SEEKER:
36        case WEAPON_BOMB:
37        case WEAPON_FRAGBOMB:
38            if(y < 0 || y >= g->h)
39            {
40                break;
41            }
42
43            if(x <= t->left[y]
44                 || x >= t->right[y])
45            {
46                int damage = wp->type[i] == WEAPON_SEEKER ? 1 : 2;
47
48                add_explosion(g, ex, x, y, 0, 1, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM);
49
50                if(x <= t->left[y])
51                {
52                    if(y-2 >= 0) t->left[y-2] -= damage - 1;
53                    if(y-1 >= 0) t->left[y-1] -= damage;
54                    t->left[y] -= damage + 1;
55                    if(y+1 < g->h) t->left[y+1] -= damage;
56                    if(y+2 < g->h) t->left[y+2] -= damage - 1;
57                }
58                else
59                {
60                    if(y-2 >= 0) t->right[y-2] += damage - 1;
61                    if(y-1 >= 0) t->right[y-1] += damage;
62                    t->right[y] += damage + 1;
63                    if(y+1 < g->h) t->right[y+1] += damage;
64                    if(y+2 < g->h) t->right[y+2] += damage - 1;
65                }
66
67                if(wp->type[i] == WEAPON_FRAGBOMB)
68                {
69                    wp->n[i] = -1;
70                }
71                else
72                {
73                    wp->type[i] = WEAPON_NONE;
74                }
75            }
76            break;
77        case WEAPON_LASER:
78            for(j = GET_MIN(0, wp->vy[i] >> 4);
79                 j < GET_MAX(0, wp->vy[i] >> 4);
80                 j++)
81            {
82                if(y+j >= g->h || y+j < 0)
83                {
84                    continue;
85                }
86
87                if(x <= t->left[y+j] || x >= t->right[y+j])
88                {
89                    add_explosion(g, ex, x, y+j, 0, 1, EXPLOSION_SMALL);
90                    wp->type[i] = WEAPON_NONE;
91
92                    if(x <= t->left[y+j])
93                    {
94                        if(y+j-1 >= 0) t->left[y+j-1]--;
95                        t->left[y+j] -= 2;
96                        if(y+j+1 < g->h) t->left[y+j+1]--;
97                    }
98                    else
99                    {
100                        if(y+j-1 >= 0) t->right[y+j-1]++;
101                        t->right[y+j] += 2;
102                        if(y+j+1 < g->h) t->right[y+j+1]++;
103                    }
104                    break;
105                }
106            }
107            break;
108        case WEAPON_BEAM:
109            if(wp->n[i] > 19)
110            {
111                break;
112            }
113
114            j = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
115            j = GET_MIN(y, j);
116
117            for(; j > 0; j--)
118            {
119                if(x - 2 <= t->left[y-j])
120                {
121                    add_explosion(g, ex, GET_MIN(t->left[y-j], x+3), y-j, 0, 1, EXPLOSION_SMALL);
122                    t->left[y-j] -= caca_rand(0,2);
123                }
124                else if(x + 3 >= t->right[y-j])
125                {
126                    add_explosion(g, ex, GET_MAX(t->right[y-j], x-2), y-j, 0, 1, EXPLOSION_SMALL);
127                    t->right[y-j] += caca_rand(0,2);
128                }
129            }
130            break;
131
132        case WEAPON_NUKE:
133            /* The nuke does not break the tunnel */
134            break;
135        }
136    }
137}
138
139void collide_weapons_aliens(game *g, weapons *wp, aliens *al, explosions *ex)
140{
141    int i, j, k, x, y;
142
143    for(i = 0; i < WEAPONS; i++)
144    {
145        int ok = 0;
146        int r;
147
148        x = wp->x[i] >> 4;
149        y = wp->y[i] >> 4;
150
151        switch(wp->type[i])
152        {
153        case WEAPON_LIGHTNING:
154        case WEAPON_NONE:
155            break;
156        case WEAPON_NUKE:
157            /* Big nuke */
158            r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
159
160            for(j = 0; j < ALIENS; j++)
161            {
162                if(al->type[j] == ALIEN_NONE || al->life[j] < 0)
163                {
164                    continue;
165                }
166
167                if(wp->n[i] == 0 /* Nuke destroys _everything_ */ ||
168                    (al->x[j] - x) * (al->x[j] - x)
169                      + 4 * (al->y[j] - y) * (al->y[j] - y)
170                    <= r * r)
171                {
172                    /* Kill alien, not nuke */
173                    al->life[j] -= 10;
174                }
175            }
176            break;
177
178        case WEAPON_BEAM:
179            if(wp->n[i] > 19)
180            {
181                break;
182            }
183
184            r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
185
186            for(j = 0; j < ALIENS; j++)
187            {
188                if(al->type[j] == ALIEN_NONE || al->life[j] < 0)
189                {
190                    continue;
191                }
192
193                if(x >= al->x[j] && x <= al->x[j] + 4
194                     && y >= al->y[j] + 2 && y-5-r <= al->y[j])
195                {
196                    al->life[j] -= 4;
197                }
198            }
199            break;
200
201        case WEAPON_LASER:
202            for(j = 0; j < ALIENS; j++)
203            {
204                if(al->type[j] == ALIEN_NONE || al->life[j] < 0)
205                {
206                    continue;
207                }
208
209                for(k = GET_MIN(0, wp->vy[i] >> 4);
210                     k < GET_MAX(0, wp->vy[i] >> 4);
211                     k++)
212                {
213                    if(x >= al->x[j] && x <= al->x[j] + 4
214                         && y+k >= al->y[j] && y+k <= al->y[j] + 2)
215                    {
216                        al->life[j]--;
217                        ok = 1;
218                        break;
219                    }
220                }
221            }
222
223            if(ok)
224            {
225                add_explosion(g, ex, x, y+1, 0, 0, EXPLOSION_SMALL);
226                wp->type[i] = WEAPON_NONE;
227            }
228            break;
229
230        case WEAPON_SEEKER:
231        case WEAPON_BOMB:
232        case WEAPON_FRAGBOMB:
233            for(j = 0; j < ALIENS; j++)
234            {
235                if(al->type[j] == ALIEN_NONE || al->life[j] < 0)
236                {
237                    continue;
238                }
239
240                if(x >= al->x[j] && x <= al->x[j] + 4
241                     && y >= al->y[j] && y <= al->y[j] + 2)
242                {
243                    al->life[j] -= wp->type[i] == WEAPON_SEEKER ? 1 : 5;
244                    ok = 1;
245                }
246            }
247
248            if(ok)
249            {
250                add_explosion(g, ex, x, y+1, 0, 0, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM);
251
252                if(wp->type[i] == WEAPON_FRAGBOMB)
253                {
254                    wp->n[i] = -1;
255                }
256                else
257                {
258                    wp->type[i] = WEAPON_NONE;
259                }
260            }
261            break;
262        }
263    }
264}
265
266void collide_player_tunnel(game *g, player *p, tunnel *t, explosions *ex)
267{
268    if(p->dead)
269    {
270        return;
271    }
272
273    if(p->x - 2 <= t->left[p->y])
274    {
275        p->x += 3;
276        p->vx = 2;
277        add_explosion(g, ex, p->x-1, p->y, 0, 0, EXPLOSION_SMALL);
278        p->life -= 180;
279    }
280    else if(p->x + 3 >= t->right[p->y])
281    {
282        p->x -= 3;
283        p->vx = -2;
284        add_explosion(g, ex, p->x+2, p->y, 0, 0, EXPLOSION_SMALL);
285        p->life -= 180;
286    }
287}
288
Note: See TracBrowser for help on using the repository browser.