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

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