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

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