source: libcaca/trunk/src/weapons.c @ 25

Last change on this file since 25 was 25, checked in by Sam Hocevar, 20 years ago
  • the bomb's head is now white
File size: 16.5 KB
Line 
1
2#include <stdlib.h>
3#include <math.h>
4
5#include "common.h"
6
7static void draw_bomb( int x, int y, int vx, int vy );
8static void draw_nuke( int x, int y, int frame );
9static void draw_beam( int x, int y, int frame );
10static void draw_circle( int x, int y, int r, char c );
11
12void init_weapons( game *g, weapons *wp )
13{
14    int i;
15
16    for( i = 0; i < WEAPONS; i++ )
17    {
18        wp->type[i] = WEAPON_NONE;
19    }
20}
21
22void draw_weapons( game *g, weapons *wp )
23{
24    int i;
25
26    for( i = 0; i < WEAPONS; i++ )
27    {
28        switch( wp->type[i] )
29        {
30            case WEAPON_LASER:
31                gfx_color( WHITE );
32                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
33                gfx_putchar( '|' );
34                gfx_color( CYAN );
35                gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
36                gfx_putchar( '|' );
37                break;
38            case WEAPON_SEEKER:
39                gfx_color( CYAN );
40                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
41                gfx_putchar( '.' );
42                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
43                gfx_putchar( 'o' );
44                gfx_color( WHITE );
45                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
46                gfx_putchar( '@' );
47                break;
48            case WEAPON_BOMB:
49                gfx_color( GRAY );
50                gfx_goto( (wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4 );
51                gfx_putchar( '.' );
52                gfx_goto( (wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4 );
53                gfx_putchar( '.' );
54                gfx_goto( (wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4 );
55                gfx_putchar( '.' );
56                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
57                gfx_putchar( '.' );
58                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
59                gfx_putchar( '.' );
60                draw_bomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->vx[i], wp->vy[i] );
61                break;
62            case WEAPON_BEAM:
63                draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
64                break;
65            case WEAPON_NUKE:
66                draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
67                break;
68            case WEAPON_NONE:
69                break;
70        }
71    }
72}
73
74void update_weapons( game *g, weapons *wp )
75{
76    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
77
78    for( i = 0; i < WEAPONS; i++ )
79    {
80        switch( wp->type[i] )
81        {
82            case WEAPON_LASER:
83                wp->x[i] += wp->vx[i];
84                wp->y[i] += wp->vy[i];
85                if( wp->y[i] < 0 )
86                {
87                    wp->type[i] = WEAPON_NONE;
88                }
89                break;
90            case WEAPON_BOMB:
91            case WEAPON_SEEKER:
92                /* Update tail */
93                wp->x3[i] = wp->x2[i];
94                wp->y3[i] = wp->y2[i];
95
96                wp->x2[i] = wp->x[i];
97                wp->y2[i] = wp->y[i];
98
99                wp->x[i] += wp->vx[i];
100                wp->y[i] += wp->vy[i];
101
102                if( wp->y[i] < 0 )
103                {
104                    wp->type[i] = WEAPON_NONE;
105                    break;
106                }
107
108                if( wp->n[i] < 0 )
109                {
110                    /* Stop updating direction */
111                    break;
112                }
113
114                wp->n[i]--;
115
116                /* Estimate our position in 2 frames */
117                xnew = wp->x[i] + 4 * wp->vx[i];
118                ynew = wp->y[i] + 4 * wp->vy[i];
119
120                xmin = xnew;
121                ymin = - (g->h << 4);
122                dist = (xnew - xmin) * (xnew - xmin)
123                        + 4 * (ynew - ymin) * (ynew - ymin);
124
125                /* Find the nearest alien */
126                for( j = 0; j < ALIENS; j++ )
127                {
128                    if( g->al->type[j] != ALIEN_NONE )
129                    {
130                        int alx = g->al->x[j] << 4;
131                        int aly = g->al->y[j] << 4;
132                        int new = (xnew - alx) * (xnew - alx)
133                                   + 4 * (ynew - aly) * (ynew - aly);
134                        if( new <= dist )
135                        {
136                            dist = new;
137                            xmin = alx;
138                            ymin = aly;
139                        }
140                    }
141                }
142
143                /* Find our new direction */
144                dx = xmin - wp->x[i];
145                dy = ymin - wp->y[i];
146
147                /* Normalize and update speed */
148                wp->vx[i] = (7 * wp->vx[i]
149                              + (dx * 48) / sqrt(dx*dx+dy*dy) ) / 8;
150                wp->vy[i] = (7 * wp->vy[i]
151                              + (dy * 24) / sqrt(dx*dx+dy*dy) ) / 8;
152
153                break;
154            case WEAPON_BEAM:
155                wp->x[i] = (g->p->x + 2) << 4;
156                wp->y[i] = g->p->y << 4;
157                wp->n[i]--;
158                if( wp->n[i] < 0 )
159                {
160                    wp->type[i] = WEAPON_NONE;
161                }
162                break;
163            case WEAPON_NUKE:
164                wp->n[i]--;
165                if( wp->n[i] < 0 )
166                {
167                    wp->type[i] = WEAPON_NONE;
168                }
169                break;
170            case WEAPON_NONE:
171                break;
172        }
173    }
174}
175
176void add_weapon( game *g, weapons *wp, int x, int y, int vx, int vy, int type )
177{
178    int i;
179
180    for( i = 0; i < WEAPONS; i++ )
181    {
182        if( wp->type[i] == WEAPON_NONE )
183        {
184            wp->x[i] = x;
185            wp->y[i] = y;
186            wp->vx[i] = vx;
187            wp->vy[i] = vy;
188            wp->type[i] = type;
189            switch( type )
190            {
191                case WEAPON_LASER:
192                    break;
193                case WEAPON_SEEKER:
194                case WEAPON_BOMB:
195                    wp->x2[i] = x;
196                    wp->y2[i] = y;
197                    wp->x3[i] = x;
198                    wp->y3[i] = y;
199                    wp->n[i] = 20;
200                    break;
201                case WEAPON_BEAM:
202                    wp->n[i] = 25;
203                    break;
204                case WEAPON_NUKE:
205                    wp->n[i] = 25;
206                    break;
207                case WEAPON_NONE:
208                    break;
209            }
210            break;
211        }
212    }
213}
214
215static void draw_bomb( int x, int y, int vx, int vy )
216{
217    vy *= 2;
218    gfx_color( CYAN );
219
220    if( vx > vy )
221    {
222        if( vx > -vy ) /* right quarter */
223        {
224            if( vy > vx/4 )
225            {
226                /* -1pi/6 */
227                gfx_goto( x-4, y-1 );
228                gfx_putstr( "/`-." );
229                gfx_goto( x-4, y );
230                gfx_putstr( "`-._\\" );
231                gfx_color( WHITE );
232                gfx_goto( x-1, y );
233                gfx_putstr( "_\\" );
234                gfx_goto( x, y+1 );
235                gfx_putchar( '`' );
236            }
237            else if( vy < -vx/4 )
238            {
239                /* 1pi/6 */
240                gfx_goto( x-4, y );
241                gfx_putstr( ",-' " );
242                gfx_goto( x-4, y+1 );
243                gfx_putstr( "\\,-'" );
244                gfx_color( WHITE );
245                gfx_goto( x-1, y-1 );
246                gfx_putstr( "_," );
247                gfx_goto( x, y );
248                gfx_putchar( '/' );
249            }
250            else
251            {
252                /* 0pi/6 */
253                gfx_goto( x-4, y-1 );
254                gfx_putstr( "____" );
255                gfx_goto( x-5, y );
256                gfx_putstr( "|____" );
257                gfx_color( WHITE );
258                gfx_goto( x, y );
259                gfx_putchar( '>' );
260            }
261        }
262        else /* top quarter */
263        {
264            if( vx > -vy/4 )
265            {
266                /* 2pi/6 */
267                gfx_goto( x-2, y );
268                gfx_putstr( "/ " );
269                gfx_goto( x-3, y+1 );
270                gfx_putstr( "/ /" );
271                gfx_goto( x-3, y+2 );
272                gfx_putstr( "`'" );
273                gfx_color( WHITE );
274                gfx_goto( x-1, y-1 );
275                gfx_putstr( "_," );
276                gfx_goto( x, y );
277                gfx_putchar( '|' );
278            }
279            else if( vx < vy/4 )
280            {
281                /* 4pi/6 */
282                gfx_goto( x+1, y );
283                gfx_putstr( " \\" );
284                gfx_goto( x+1, y+1 );
285                gfx_putstr( "\\ \\" );
286                gfx_goto( x+2, y+2 );
287                gfx_putstr( "`'" );
288                gfx_color( WHITE );
289                gfx_goto( x, y-1 );
290                gfx_putstr( "._" );
291                gfx_goto( x, y );
292                gfx_putchar( '|' );
293            }
294            else
295            {
296                /* 3pi/6 */
297                gfx_goto( x-1, y+1 );
298                gfx_putstr( "| |" );
299                gfx_goto( x-1, y+2 );
300                gfx_putstr( "|_|" );
301                gfx_color( WHITE );
302                gfx_goto( x-1, y );
303                gfx_putstr( ",^." );
304            }
305        }
306    }
307    else
308    {
309        if( vx > -vy ) /* bottom quarter */
310        {
311            if( vx > vy/4 )
312            {
313                /* -2pi/6 */
314                gfx_goto( x-2, y-2 );
315                gfx_putstr( ",." );
316                gfx_goto( x-2, y-1 );
317                gfx_putstr( "\\ \\" );
318                gfx_goto( x-1, y );
319                gfx_putchar( '\\' );
320                gfx_color( WHITE );
321                gfx_goto( x, y );
322                gfx_putstr( "_|" );
323            }
324            else if( vx < -vy/4 )
325            {
326                /* -4pi/6 */
327                gfx_goto( x+1, y-2 );
328                gfx_putstr( ",." );
329                gfx_goto( x, y-1 );
330                gfx_putstr( "/ /" );
331                gfx_goto( x+1, y );
332                gfx_putchar( '/' );
333                gfx_color( WHITE );
334                gfx_goto( x-1, y );
335                gfx_putstr( "|_/" );
336            }
337            else
338            {
339                /* -3pi/6 */
340                gfx_goto( x, y-3 );
341                gfx_putchar( '_' );
342                gfx_goto( x-1, y-2 );
343                gfx_putstr( "| |" );
344                gfx_goto( x-1, y-1 );
345                gfx_putstr( "| |" );
346                gfx_color( WHITE );
347                gfx_goto( x-1, y );
348                gfx_putstr( "`v'" );
349            }
350        }
351        else /* left quarter */
352        {
353            if( vy > -vx/4 )
354            {
355                /* -5pi/6 */
356                gfx_goto( x+1, y-1 );
357                gfx_putstr( ",-'\\" );
358                gfx_goto( x+2, y );
359                gfx_putstr( ",-'" );
360                gfx_goto( x, y+1 );
361                gfx_putchar( '\'' );
362                gfx_color( WHITE );
363                gfx_goto( x, y );
364                gfx_putstr( "/_" );
365            }
366            else if( vy < vx/4 )
367            {
368                /* 5pi/6 */
369                gfx_goto( x+1, y );
370                gfx_putstr( " `-." );
371                gfx_goto( x+1, y+1 );
372                gfx_putstr( "`-./" );
373                gfx_color( WHITE );
374                gfx_goto( x, y-1 );
375                gfx_putstr( "._" );
376                gfx_goto( x, y );
377                gfx_putchar( '\\' );
378            }
379            else
380            {
381                /* 6pi/6 */
382                gfx_goto( x+1, y-1 );
383                gfx_putstr( "____" );
384                gfx_goto( x+1, y );
385                gfx_putstr( "____|" );
386                gfx_color( WHITE );
387                gfx_goto( x, y );
388                gfx_putchar( '<' );
389            }
390        }
391    }
392}
393
394static void draw_beam( int x, int y, int frame )
395{
396    int r = (29 - frame) * (29 - frame) / 8;
397    int i;
398
399    switch( frame )
400    {
401        case 24:
402            gfx_color( WHITE );
403            gfx_goto( x, y-3 );
404            gfx_putstr( "__" );
405            gfx_goto( x-1, y-2 );
406            gfx_putchar( '\'' );
407            gfx_goto( x+2, y-2 );
408            gfx_putchar( '`' );
409            break;
410        case 23:
411            gfx_color( CYAN );
412            gfx_goto( x, y-3 );
413            gfx_putstr( "__" );
414            gfx_color( WHITE );
415            gfx_goto( x-2, y-2 );
416            gfx_putstr( "-'" );
417            gfx_goto( x+2, y-2 );
418            gfx_putstr( "`-" );
419            break;
420        case 22:
421            gfx_color( CYAN );
422            gfx_goto( x, y-3 );
423            gfx_putstr( "__" );
424            gfx_goto( x-1, y-2 );
425            gfx_putchar( '\'' );
426            gfx_goto( x+2, y-2 );
427            gfx_putchar( '`' );
428            gfx_color( WHITE );
429            gfx_goto( x-3, y-2 );
430            gfx_putstr( ",-" );
431            gfx_goto( x+3, y-2 );
432            gfx_putstr( "-." );
433            break;
434        case 21:
435            gfx_color( CYAN );
436            gfx_goto( x-1, y-3 );
437            gfx_putstr( "____" );
438            gfx_goto( x-2, y-2 );
439            gfx_putchar( '\'' );
440            gfx_goto( x+3, y-2 );
441            gfx_putchar( '`' );
442            gfx_color( WHITE );
443            gfx_goto( x-4, y-2 );
444            gfx_putstr( ",-" );
445            gfx_goto( x+4, y-2 );
446            gfx_putstr( "-." );
447            break;
448        case 20:
449            gfx_color( WHITE );
450            gfx_goto( x, y-3 );
451            gfx_putstr( "%%" );
452            gfx_goto( x-4, y-2 );
453            gfx_putchar( ',' );
454            gfx_goto( x+5, y-2 );
455            gfx_putchar( '.' );
456            gfx_color( CYAN );
457            gfx_goto( x-1, y-3 );
458            gfx_putchar( ':' );
459            gfx_goto( x+2, y-3 );
460            gfx_putchar( ':' );
461            gfx_goto( x-3, y-2 );
462            gfx_putstr( "-'" );
463            gfx_goto( x+3, y-2 );
464            gfx_putstr( "`-" );
465            break;
466        case 19:
467            gfx_color( WHITE );
468            gfx_goto( x, y-4 );
469            gfx_putstr( "%%" );
470            gfx_goto( x, y-3 );
471            gfx_putstr( "##" );
472            gfx_color( CYAN );
473            gfx_goto( x-1, y-4 );
474            gfx_putchar( ':' );
475            gfx_goto( x+2, y-4 );
476            gfx_putchar( ':' );
477            gfx_goto( x-1, y-3 );
478            gfx_putchar( '%' );
479            gfx_goto( x+2, y-3 );
480            gfx_putchar( '%' );
481            gfx_goto( x-4, y-2 );
482            gfx_putstr( ",-'" );
483            gfx_goto( x+3, y-2 );
484            gfx_putstr( "`-." );
485            gfx_color( BLUE );
486            gfx_goto( x-2, y-3 );
487            gfx_putchar( ':' );
488            gfx_goto( x+3, y-3 );
489            gfx_putchar( ':' );
490            break;
491        case 18:
492        default:
493            r = (18 - frame) * (18 - frame);
494            gfx_color( WHITE );
495            gfx_goto( x-1, y-5-r );
496            gfx_putstr( ":%%:" );
497            gfx_goto( x-1, y-4-r );
498            gfx_putstr( "%##%" );
499            gfx_color( CYAN );
500            gfx_goto( x-2, y-4-r );
501            gfx_putchar( ':' );
502            gfx_goto( x+3, y-4-r );
503            gfx_putchar( ':' );
504            gfx_goto( x-2, y-2 );
505            gfx_putchar( '\'' );
506            gfx_goto( x+3, y-2 );
507            gfx_putchar( '`' );
508            gfx_color( BLUE );
509            gfx_goto( x-3, y-2 );
510            gfx_putchar( ':' );
511            gfx_goto( x+4, y-2 );
512            gfx_putchar( ':' );
513            for( i = 0; i <= r; i++ )
514            {
515                gfx_color( WHITE );
516                gfx_goto( x-1, y-3-i );
517                gfx_putstr( (i+frame) % 5 ? "####" : "%%%%" );
518                gfx_color( CYAN );
519                gfx_goto( x-2, y-3-i );
520                gfx_putchar( '%' );
521                gfx_goto( x+3, y-3-i );
522                gfx_putchar( '%' );
523                gfx_color( BLUE );
524                gfx_goto( x-3, y-3-i );
525                gfx_putchar( ':' );
526                gfx_goto( x+4, y-3-i );
527                gfx_putchar( ':' );
528            }
529            break;
530    }
531}
532
533static void draw_nuke( int x, int y, int frame )
534{
535    int r = (29 - frame) * (29 - frame) / 8;
536
537    /* Lots of duplicate pixels, but we don't care */
538    gfx_color( BLUE );
539    draw_circle( x, y, r++, ':' );
540    gfx_color( CYAN );
541    draw_circle( x, y, r++, '%' );
542    gfx_color( WHITE );
543    draw_circle( x, y, r++, '#' );
544    draw_circle( x, y, r++, '#' );
545}
546
547static void draw_circle( int x, int y, int r, char c )
548{
549    int test, dx, dy;
550
551    /* Optimized Bresenham. Kick ass. */
552    for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
553    {
554        gfx_putcharTO( x + dx, y + dy / 2, c );
555        gfx_putcharTO( x - dx, y + dy / 2, c );
556        gfx_putcharTO( x + dx, y - dy / 2, c );
557        gfx_putcharTO( x - dx, y - dy / 2, c );
558
559        gfx_putcharTO( x + dy, y + dx / 2, c );
560        gfx_putcharTO( x - dy, y + dx / 2, c );
561        gfx_putcharTO( x + dy, y - dx / 2, c );
562        gfx_putcharTO( x - dy, y - dx / 2, c );
563
564        test += test > 0 ? dx - dy-- : dx;
565    }
566}
567
Note: See TracBrowser for help on using the repository browser.