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

Last change on this file since 64 was 64, checked in by Sam Hocevar, 19 years ago
  • new timestamp for a new snapshot.
  • lots of sanity checks in collide.c.
  • moved usleep() to graphics.c.
  • added random key generator in the dummy driver.
  • cosmetic changes in the energy bars.
File size: 8.7 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,v 1.10 2002/12/23 16:21:38 sam Exp $
7 *
8 *   This program is free software; you can redistribute it and/or modify
9 *   it under the terms of the GNU General Public License as published by
10 *   the Free Software Foundation; either version 2 of the License, or
11 *   (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <stdlib.h>
24
25#include "common.h"
26
27void collide_weapons_tunnel( game *g, weapons *wp, tunnel *t, explosions *ex )
28{
29    int i, j, x, y;
30
31    for( i = 0; i < WEAPONS; i++ )
32    {
33        x = wp->x[i] >> 4;
34        y = wp->y[i] >> 4;
35
36        switch( wp->type[i] )
37        {
38        case WEAPON_LIGHTNING:
39        case WEAPON_NONE:
40            break;
41        case WEAPON_SEEKER:
42        case WEAPON_BOMB:
43        case WEAPON_FRAGBOMB:
44            if( y < 0 || y >= g->h )
45            {
46                break;
47            }
48
49            if( x <= t->left[y]
50                 || x >= t->right[y] )
51            {
52                int damage = wp->type[i] == WEAPON_SEEKER ? 1 : 2;
53
54                add_explosion( g, ex, x, y, 0, 1, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM );
55
56                if( x <= t->left[y] )
57                {
58                    if( y-2 >= 0 ) t->right[y-2] -= damage - 1;
59                    if( y-1 >= 0 ) t->left[y-1] -= damage;
60                    t->left[y] -= damage + 1;
61                    if( y+1 < g->h ) t->left[y+1] -= damage;
62                    if( y+2 < g->h ) t->right[y+2] -= damage - 1;
63                }
64                else
65                {
66                    if( y-2 >= 0 ) t->right[y-2] += damage - 1;
67                    if( y-1 >= 0 ) t->right[y-1] += damage;
68                    t->right[y] += damage + 1;
69                    if( y+1 < g->h ) t->right[y+1] += damage;
70                    if( y+2 < g->h ) t->right[y+2] += damage - 1;
71                }
72
73                if( wp->type[i] == WEAPON_FRAGBOMB )
74                {
75                    wp->n[i] = -1;
76                }
77                else
78                {
79                    wp->type[i] = WEAPON_NONE;
80                }
81            }
82            break;
83        case WEAPON_LASER:
84            for( j = GET_MIN( 0, wp->vy[i] >> 4 ) ;
85                 j < GET_MAX( 0, wp->vy[i] >> 4 ) ;
86                 j++ )
87            {
88                if( y+j >= g->h || y+j < 0 )
89                {
90                    continue;
91                }
92
93                if( x <= t->left[y+j] || x >= t->right[y+j] )
94                {
95                    add_explosion( g, ex, x, y+j, 0, 1, EXPLOSION_SMALL );
96                    wp->type[i] = WEAPON_NONE;
97
98                    if( x <= t->left[y+j] )
99                    {
100                        if( y+j-1 >= 0 )
101                        {
102                            t->left[y+j-1]--;
103                        }
104                        t->left[y+j] -= 2;
105                        if( y+j+1 < g->h )
106                        {
107                            t->left[y+j+1]--;
108                        }
109                    }
110                    else
111                    {
112                        if( y+j-1 >= 0 )
113                        {
114                            t->right[y+j-1]++;
115                        }
116                        t->right[y+j] += 2;
117                        if( y+j+1 < g->h )
118                        {
119                            t->right[y+j+1]++;
120                        }
121                    }
122                    break;
123                }
124            }
125            break;
126        case WEAPON_BEAM:
127            if( wp->n[i] > 19 )
128            {
129                break;
130            }
131
132            j = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
133            j = GET_MIN( y, j );
134
135            for( ; j > 0 ; j-- )
136            {
137                if( x - 2 <= t->left[y-j] )
138                {
139                    add_explosion( g, ex, GET_MIN(t->left[y-j], x+3), y-j, 0, 1, EXPLOSION_SMALL );
140                    t->left[y-j] -= GET_RAND(0,3);
141                }
142                else if( x + 3 >= t->right[y-j] )
143                {
144                    add_explosion( g, ex, GET_MAX(t->right[y-j], x-2), y-j, 0, 1, EXPLOSION_SMALL );
145                    t->right[y-j] += GET_RAND(0,3);
146                }
147            }
148            break;
149
150        case WEAPON_NUKE:
151            /* The nuke does not break the tunnel */
152            break;
153        }
154    }
155}
156
157void collide_weapons_aliens( game *g, weapons *wp, aliens *al, explosions *ex )
158{
159    int i, j, k, x, y;
160
161    for( i = 0; i < WEAPONS; i++ )
162    {
163        int ok = 0;
164        int r;
165
166        x = wp->x[i] >> 4;
167        y = wp->y[i] >> 4;
168
169        switch( wp->type[i] )
170        {
171        case WEAPON_LIGHTNING:
172        case WEAPON_NONE:
173            break;
174        case WEAPON_NUKE:
175            /* Big nuke */
176            r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
177
178            for( j = 0; j < ALIENS; j++ )
179            {
180                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
181                {
182                    continue;
183                }
184
185                if( wp->n[i] == 0 /* Nuke destroys _everything_ */ ||
186                    (al->x[j] - x) * (al->x[j] - x)
187                      + 4 * (al->y[j] - y) * (al->y[j] - y)
188                    <= r * r )
189                {
190                    /* Kill alien, not nuke */
191                    al->life[j] -= 10;
192                }
193            }
194            break;
195
196        case WEAPON_BEAM:
197            if( wp->n[i] > 19 )
198            {
199                break;
200            }
201
202            r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
203
204            for( j = 0; j < ALIENS; j++ )
205            {
206                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
207                {
208                    continue;
209                }
210
211                if( x >= al->x[j] && x <= al->x[j] + 4
212                     && y >= al->y[j] + 2 && y-5-r <= al->y[j] )
213                {
214                    al->life[j] -= 4;
215                }
216            }
217            break;
218
219        case WEAPON_LASER:
220            for( j = 0; j < ALIENS; j++ )
221            {
222                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
223                {
224                    continue;
225                }
226
227                for( k = GET_MIN( 0, wp->vy[i] >> 4 ) ;
228                     k < GET_MAX( 0, wp->vy[i] >> 4 ) ;
229                     k++ )
230                {
231                    if( x >= al->x[j] && x <= al->x[j] + 4
232                         && y+k >= al->y[j] && y+k <= al->y[j] + 2 )
233                    {
234                        al->life[j]--;
235                        ok = 1;
236                        break;
237                    }
238                }
239            }
240
241            if( ok )
242            {
243                add_explosion( g, ex, x, y+1, 0, 0, EXPLOSION_SMALL );
244                wp->type[i] = WEAPON_NONE;
245            }
246            break;
247
248        case WEAPON_SEEKER:
249        case WEAPON_BOMB:
250        case WEAPON_FRAGBOMB:
251            for( j = 0; j < ALIENS; j++ )
252            {
253                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
254                {
255                    continue;
256                }
257
258                if( x >= al->x[j] && x <= al->x[j] + 4
259                     && y >= al->y[j] && y <= al->y[j] + 2 )
260                {
261                    al->life[j] -= wp->type[i] == WEAPON_SEEKER ? 1 : 5;
262                    ok = 1;
263                }
264            }
265
266            if( ok )
267            {
268                add_explosion( g, ex, x, y+1, 0, 0, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM );
269
270                if( wp->type[i] == WEAPON_FRAGBOMB )
271                {
272                    wp->n[i] = -1;
273                }
274                else
275                {
276                    wp->type[i] = WEAPON_NONE;
277                }
278            }
279            break;
280        }
281    }
282}
283
284void collide_player_tunnel( game *g, player *p, tunnel *t, explosions *ex )
285{
286    if( p->dead )
287    {
288        return;
289    }
290
291    if( p->x <= t->left[p->y] )
292    {
293        p->x += 3;
294        p->vx = 2;
295        add_explosion( g, ex, p->x+1, p->y-1, 0, 0, EXPLOSION_SMALL );
296        p->life -= 80;
297    }
298    else if( p->x + 5 >= t->right[p->y] )
299    {
300        p->x -= 3;
301        p->vx = -2;
302        add_explosion( g, ex, p->x+4, p->y-1, 0, 0, EXPLOSION_SMALL );
303        p->life -= 80;
304    }
305}
306
Note: See TracBrowser for help on using the repository browser.