source: ttyvaders/trunk/src/weapons.c @ 22

Last change on this file since 22 was 22, checked in by Sam Hocevar, 17 years ago
  • 'beam' weapon.
File size: 10.5 KB
Line 
1
2#include <stdlib.h>
3#include <math.h>
4
5#include "common.h"
6
7static void draw_nuke( int x, int y, int frame );
8static void draw_beam( int x, int y, int frame );
9static void draw_circle( int x, int y, int r, char c );
10
11void init_weapons( game *g, weapons *wp )
12{
13    int i;
14
15    for( i = 0; i < WEAPONS; i++ )
16    {
17        wp->type[i] = WEAPON_NONE;
18    }
19}
20
21void draw_weapons( game *g, weapons *wp )
22{
23    int i;
24
25    for( i = 0; i < WEAPONS; i++ )
26    {
27        switch( wp->type[i] )
28        {
29            case WEAPON_LASER:
30                gfx_color( WHITE );
31                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
32                gfx_putchar( '|' );
33                gfx_color( CYAN );
34                gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
35                gfx_putchar( '|' );
36                break;
37            case WEAPON_SEEKER:
38                gfx_color( CYAN );
39                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
40                gfx_putchar( '.' );
41                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
42                gfx_putchar( 'o' );
43                gfx_color( WHITE );
44                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
45                gfx_putchar( '@' );
46                break;
47            case WEAPON_BEAM:
48                draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
49                break;
50            case WEAPON_NUKE:
51                draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
52                break;
53            case WEAPON_NONE:
54                break;
55        }
56    }
57}
58
59void update_weapons( game *g, weapons *wp )
60{
61    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
62
63    for( i = 0; i < WEAPONS; i++ )
64    {
65        switch( wp->type[i] )
66        {
67            case WEAPON_LASER:
68                wp->x[i] += wp->vx[i];
69                wp->y[i] += wp->vy[i];
70                if( wp->y[i] < 0 )
71                {
72                    wp->type[i] = WEAPON_NONE;
73                }
74                break;
75            case WEAPON_SEEKER:
76                /* Update tail */
77                wp->x3[i] = wp->x2[i];
78                wp->y3[i] = wp->y2[i];
79
80                wp->x2[i] = wp->x[i];
81                wp->y2[i] = wp->y[i];
82
83                wp->x[i] += wp->vx[i];
84                wp->y[i] += wp->vy[i];
85
86                if( wp->y[i] < 0 )
87                {
88                    wp->type[i] = WEAPON_NONE;
89                    break;
90                }
91
92                if( wp->n[i] < 0 )
93                {
94                    /* Stop updating direction */
95                    break;
96                }
97
98                wp->n[i]--;
99
100                /* Estimate our position in 2 frames */
101                xnew = wp->x[i] + 4 * wp->vx[i];
102                ynew = wp->y[i] + 4 * wp->vy[i];
103
104                xmin = xnew;
105                ymin = - (g->h << 4);
106                dist = (xnew - xmin) * (xnew - xmin)
107                        + 4 * (ynew - ymin) * (ynew - ymin);
108
109                /* Find the nearest alien */
110                for( j = 0; j < ALIENS; j++ )
111                {
112                    if( g->al->type[j] != ALIEN_NONE )
113                    {
114                        int alx = g->al->x[j] << 4;
115                        int aly = g->al->y[j] << 4;
116                        int new = (xnew - alx) * (xnew - alx)
117                                   + 4 * (ynew - aly) * (ynew - aly);
118                        if( new <= dist )
119                        {
120                            dist = new;
121                            xmin = alx;
122                            ymin = aly;
123                        }
124                    }
125                }
126
127                /* Find our new direction */
128                dx = xmin - wp->x[i];
129                dy = ymin - wp->y[i];
130
131                /* Normalize and update speed */
132                wp->vx[i] = (7 * wp->vx[i]
133                              + (dx * 48) / sqrt(dx*dx+dy*dy) ) / 8;
134                wp->vy[i] = (7 * wp->vy[i]
135                              + (dy * 24) / sqrt(dx*dx+dy*dy) ) / 8;
136
137                break;
138            case WEAPON_BEAM:
139                wp->x[i] = (g->p->x + 2) << 4;
140                wp->y[i] = g->p->y << 4;
141                wp->n[i]--;
142                if( wp->n[i] < 0 )
143                {
144                    wp->type[i] = WEAPON_NONE;
145                }
146                break;
147            case WEAPON_NUKE:
148                wp->n[i]--;
149                if( wp->n[i] < 0 )
150                {
151                    wp->type[i] = WEAPON_NONE;
152                }
153                break;
154            case WEAPON_NONE:
155                break;
156        }
157    }
158}
159
160void add_weapon( game *g, weapons *wp, int x, int y, int vx, int vy, int type )
161{
162    int i;
163
164    for( i = 0; i < WEAPONS; i++ )
165    {
166        if( wp->type[i] == WEAPON_NONE )
167        {
168            wp->x[i] = x;
169            wp->y[i] = y;
170            wp->vx[i] = vx;
171            wp->vy[i] = vy;
172            wp->type[i] = type;
173            switch( type )
174            {
175                case WEAPON_LASER:
176                    break;
177                case WEAPON_SEEKER:
178                    wp->x2[i] = x;
179                    wp->y2[i] = y;
180                    wp->x3[i] = x;
181                    wp->y3[i] = y;
182                    wp->n[i] = 10;
183                    break;
184                case WEAPON_BEAM:
185                    wp->n[i] = 25;
186                    break;
187                case WEAPON_NUKE:
188                    wp->n[i] = 25;
189                    break;
190                case WEAPON_NONE:
191                    break;
192            }
193            break;
194        }
195    }
196}
197
198static void draw_beam( int x, int y, int frame )
199{
200    int r = (29 - frame) * (29 - frame) / 8;
201    int i;
202
203    switch( frame )
204    {
205        case 24:
206            gfx_color( WHITE );
207            gfx_goto( x, y-3 );
208            gfx_putstr( "__" );
209            gfx_goto( x-1, y-2 );
210            gfx_putchar( '\'' );
211            gfx_goto( x+2, y-2 );
212            gfx_putchar( '`' );
213            break;
214        case 23:
215            gfx_color( CYAN );
216            gfx_goto( x, y-3 );
217            gfx_putstr( "__" );
218            gfx_color( WHITE );
219            gfx_goto( x-2, y-2 );
220            gfx_putstr( "-'" );
221            gfx_goto( x+2, y-2 );
222            gfx_putstr( "`-" );
223            break;
224        case 22:
225            gfx_color( CYAN );
226            gfx_goto( x, y-3 );
227            gfx_putstr( "__" );
228            gfx_goto( x-1, y-2 );
229            gfx_putchar( '\'' );
230            gfx_goto( x+2, y-2 );
231            gfx_putchar( '`' );
232            gfx_color( WHITE );
233            gfx_goto( x-3, y-2 );
234            gfx_putstr( ",-" );
235            gfx_goto( x+3, y-2 );
236            gfx_putstr( "-." );
237            break;
238        case 21:
239            gfx_color( CYAN );
240            gfx_goto( x-1, y-3 );
241            gfx_putstr( "____" );
242            gfx_goto( x-2, y-2 );
243            gfx_putchar( '\'' );
244            gfx_goto( x+3, y-2 );
245            gfx_putchar( '`' );
246            gfx_color( WHITE );
247            gfx_goto( x-4, y-2 );
248            gfx_putstr( ",-" );
249            gfx_goto( x+4, y-2 );
250            gfx_putstr( "-." );
251            break;
252        case 20:
253            gfx_color( WHITE );
254            gfx_goto( x, y-3 );
255            gfx_putstr( "%%" );
256            gfx_goto( x-4, y-2 );
257            gfx_putchar( ',' );
258            gfx_goto( x+5, y-2 );
259            gfx_putchar( '.' );
260            gfx_color( CYAN );
261            gfx_goto( x-1, y-3 );
262            gfx_putchar( ':' );
263            gfx_goto( x+2, y-3 );
264            gfx_putchar( ':' );
265            gfx_goto( x-3, y-2 );
266            gfx_putstr( "-'" );
267            gfx_goto( x+3, y-2 );
268            gfx_putstr( "`-" );
269            break;
270        case 19:
271            gfx_color( WHITE );
272            gfx_goto( x, y-4 );
273            gfx_putstr( "%%" );
274            gfx_goto( x, y-3 );
275            gfx_putstr( "##" );
276            gfx_color( CYAN );
277            gfx_goto( x-1, y-4 );
278            gfx_putchar( ':' );
279            gfx_goto( x+2, y-4 );
280            gfx_putchar( ':' );
281            gfx_goto( x-1, y-3 );
282            gfx_putchar( '%' );
283            gfx_goto( x+2, y-3 );
284            gfx_putchar( '%' );
285            gfx_goto( x-4, y-2 );
286            gfx_putstr( ",-'" );
287            gfx_goto( x+3, y-2 );
288            gfx_putstr( "`-." );
289            gfx_color( BLUE );
290            gfx_goto( x-2, y-3 );
291            gfx_putchar( ':' );
292            gfx_goto( x+3, y-3 );
293            gfx_putchar( ':' );
294            break;
295        case 18:
296        default:
297            r = (18 - frame) * (18 - frame);
298            gfx_color( WHITE );
299            gfx_goto( x-1, y-5-r );
300            gfx_putstr( ":%%:" );
301            gfx_goto( x-1, y-4-r );
302            gfx_putstr( "%##%" );
303            gfx_color( CYAN );
304            gfx_goto( x-2, y-4-r );
305            gfx_putchar( ':' );
306            gfx_goto( x+3, y-4-r );
307            gfx_putchar( ':' );
308            gfx_goto( x-2, y-2 );
309            gfx_putchar( '\'' );
310            gfx_goto( x+3, y-2 );
311            gfx_putchar( '`' );
312            gfx_color( BLUE );
313            gfx_goto( x-3, y-2 );
314            gfx_putchar( ':' );
315            gfx_goto( x+4, y-2 );
316            gfx_putchar( ':' );
317            for( i = 0; i <= r; i++ )
318            {
319                gfx_color( WHITE );
320                gfx_goto( x-1, y-3-i );
321                gfx_putstr( "####" );
322                gfx_color( CYAN );
323                gfx_goto( x-2, y-3-i );
324                gfx_putchar( '%' );
325                gfx_goto( x+3, y-3-i );
326                gfx_putchar( '%' );
327                gfx_color( BLUE );
328                gfx_goto( x-3, y-3-i );
329                gfx_putchar( ':' );
330                gfx_goto( x+4, y-3-i );
331                gfx_putchar( ':' );
332            }
333            break;
334    }
335}
336
337static void draw_nuke( int x, int y, int frame )
338{
339    int r = (29 - frame) * (29 - frame) / 8;
340
341    /* Lots of duplicate pixels, but we don't care */
342    gfx_color( BLUE );
343    draw_circle( x, y, r++, ':' );
344    gfx_color( CYAN );
345    draw_circle( x, y, r++, '%' );
346    gfx_color( WHITE );
347    draw_circle( x, y, r++, '#' );
348    draw_circle( x, y, r++, '#' );
349}
350
351static void draw_circle( int x, int y, int r, char c )
352{
353    int test, dx, dy;
354
355    /* Optimized Bresenham. Kick ass. */
356    for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
357    {
358        gfx_putcharTO( x + dx, y + dy / 2, c );
359        gfx_putcharTO( x - dx, y + dy / 2, c );
360        gfx_putcharTO( x + dx, y - dy / 2, c );
361        gfx_putcharTO( x - dx, y - dy / 2, c );
362
363        gfx_putcharTO( x + dy, y + dx / 2, c );
364        gfx_putcharTO( x - dy, y + dx / 2, c );
365        gfx_putcharTO( x + dy, y - dx / 2, c );
366        gfx_putcharTO( x - dy, y - dx / 2, c );
367
368        test += test > 0 ? dx - dy-- : dx;
369    }
370}
371
Note: See TracBrowser for help on using the repository browser.