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

Last change on this file since 42 was 42, checked in by Sam Hocevar, 17 years ago
  • dead aliens don't explode in the collision loop but in their update loop.
  • new super weapon, the fragmentation bomb.
File size: 7.4 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.7 2002/12/22 22:17:41 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, 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( x <= t->left[y]
45                 || x >= t->right[y] )
46            {
47                int damage = wp->type[i] == WEAPON_SEEKER ? 1 : 2;
48
49                add_explosion( g, ex, x, y, 0, 1, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM );
50
51                if( x <= t->left[y] )
52                {
53                    t->right[y-2] -= damage - 1;
54                    t->left[y-1] -= damage;
55                    t->left[y] -= damage + 1;
56                    t->left[y+1] -= damage;
57                    t->right[y+2] -= damage - 1;
58                }
59                else
60                {
61                    t->right[y-2] += damage - 1;
62                    t->right[y-1] += damage;
63                    t->right[y] += damage + 1;
64                    t->right[y+1] += damage;
65                    t->right[y+2] += damage - 1;
66                }
67
68                if( wp->type[i] == WEAPON_FRAGBOMB )
69                {
70                    wp->n[i] = -1;
71                }
72                else
73                {
74                    wp->type[i] = WEAPON_NONE;
75                }
76            }
77            break;
78        case WEAPON_LASER:
79            if( x <= t->left[y+1]
80                 || x >= t->right[y+1] )
81            {
82                add_explosion( g, ex, x, y+1, 0, 1, EXPLOSION_SMALL );
83
84                if( x <= t->left[y+1] )
85                {
86                    t->left[y]--;
87                    t->left[y+1]-=2;
88                    t->left[y+2]--;
89                }
90                else
91                {
92                    t->right[y]++;
93                    t->right[y+1]+=2;
94                    t->right[y+2]++;
95                }
96
97                wp->type[i] = WEAPON_NONE;
98            }
99            else if( x <= t->left[y]
100                      || x >= t->right[y] )
101            {
102                add_explosion( g, ex, x, y, 0, 1, EXPLOSION_SMALL );
103
104                if( x <= t->left[y] )
105                {
106                    t->left[y-1]--;
107                    t->left[y]-=2;
108                    t->left[y+1]--;
109                }
110                else
111                {
112                    t->right[y-1]++;
113                    t->right[y]+=2;
114                    t->right[y+1]++;
115                }
116
117                wp->type[i] = WEAPON_NONE;
118            }
119            break;
120        case WEAPON_NUKE:
121        case WEAPON_BEAM:
122            /* The nuke and the laser do not break the tunnel */
123            break;
124        }
125    }
126}
127
128void collide_weapons_aliens( game *g, weapons *wp, aliens *al, explosions *ex )
129{
130    int i, j, x, y;
131
132    for( i = 0; i < WEAPONS; i++ )
133    {
134        int ok = 0;
135        int r;
136
137        x = wp->x[i] >> 4;
138        y = wp->y[i] >> 4;
139
140        switch( wp->type[i] )
141        {
142        case WEAPON_LIGHTNING:
143        case WEAPON_NONE:
144            break;
145        case WEAPON_NUKE:
146            /* Big nuke */
147            r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
148
149            for( j = 0; j < ALIENS; j++ )
150            {
151                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
152                {
153                    continue;
154                }
155
156                if( wp->n[i] == 0 /* Nuke destroys _everything_ */ ||
157                    (al->x[j] - x) * (al->x[j] - x)
158                      + 4 * (al->y[j] - y) * (al->y[j] - y)
159                    <= r * r )
160                {
161                    /* Kill alien, not nuke */
162                    al->life[j] -= 10;
163                }
164            }
165            break;
166
167        case WEAPON_BEAM:
168            r = (29 - wp->n[i]) * (29 - wp->n[i]) / 8;
169
170            for( j = 0; j < ALIENS; j++ )
171            {
172                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
173                {
174                    continue;
175                }
176
177                if( x >= al->x[j] && x <= al->x[j] + 4
178                     && y >= al->y[j] + 2 && y-5-r <= al->y[j] )
179                {
180                    al->life[j] -= 4;
181                }
182            }
183            break;
184
185        case WEAPON_LASER:
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] && y <= al->y[j] + 2 )
195                {
196                    al->life[j]--;
197                    ok = 1;
198                }
199                else if( x >= al->x[j] && x <= al->x[j] + 4
200                          && y+1 >= al->y[j] && y+1 <= al->y[j] + 2 )
201                {
202                    al->life[j]--;
203                    ok = 1;
204                }
205            }
206
207            if( ok )
208            {
209                add_explosion( g, ex, x, y+1, 0, 0, EXPLOSION_SMALL );
210                wp->type[i] = WEAPON_NONE;
211            }
212            break;
213
214        case WEAPON_SEEKER:
215        case WEAPON_BOMB:
216        case WEAPON_FRAGBOMB:
217            for( j = 0; j < ALIENS; j++ )
218            {
219                if( al->type[j] == ALIEN_NONE || al->life[j] < 0 )
220                {
221                    continue;
222                }
223
224                if( x >= al->x[j] && x <= al->x[j] + 4
225                     && y >= al->y[j] && y <= al->y[j] + 2 )
226                {
227                    al->life[j] -= wp->type[i] == WEAPON_SEEKER ? 1 : 5;
228                    ok = 1;
229                }
230            }
231
232            if( ok )
233            {
234                add_explosion( g, ex, x, y+1, 0, 0, wp->type[i] == WEAPON_SEEKER ? EXPLOSION_SMALL : EXPLOSION_MEDIUM );
235
236                if( wp->type[i] == WEAPON_FRAGBOMB )
237                {
238                    wp->n[i] = -1;
239                }
240                else
241                {
242                    wp->type[i] = WEAPON_NONE;
243                }
244            }
245            break;
246        }
247    }
248}
249
250void collide_player_tunnel( game *g, player *p, tunnel *t, explosions *ex )
251{
252    if( p->x <= t->left[p->y] )
253    {
254        p->x += 2;
255        add_explosion( g, ex, p->x+1, p->y-2, 0, 0, EXPLOSION_SMALL );
256    }
257    else if( p->x + 5 >= t->right[p->y] )
258    {
259        p->x -= 2;
260        add_explosion( g, ex, p->x+4, p->y-2, 0, 0, EXPLOSION_SMALL );
261    }
262}
263
Note: See TracBrowser for help on using the repository browser.