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

Last change on this file since 186 was 186, checked in by Sam Hocevar, 17 years ago
  • Renamed libee to libcaca. Far less collisions.
  • Property svn:keywords set to Id
File size: 13.9 KB
RevLine 
[36]1/*
2 *   ttyvaders     Textmode shoot'em up
3 *   Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
4 *                 All Rights Reserved
5 *
[80]6 *   $Id: weapons.c 186 2003-11-16 00:33:35Z sam $
[36]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 */
[18]22
[110]23#include "config.h"
24
[18]25#include <stdlib.h>
26
27#include "common.h"
28
[88]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);
[18]33
[186]34struct caca_sprite *bomb_sprite;
35struct caca_sprite *fragbomb_sprite;
[142]36
[88]37void init_weapons(game *g, weapons *wp)
[18]38{
39    int i;
40
[88]41    for(i = 0; i < WEAPONS; i++)
[18]42    {
[20]43        wp->type[i] = WEAPON_NONE;
[18]44    }
[142]45
[186]46    bomb_sprite = caca_load_sprite("data/wpnbomb.txt");
47    fragbomb_sprite = caca_load_sprite("data/wpnfrag.txt");
[18]48}
49
[88]50void draw_weapons(game *g, weapons *wp)
[18]51{
52    int i;
53
[88]54    for(i = 0; i < WEAPONS; i++)
[18]55    {
[88]56        switch(wp->type[i])
[18]57        {
[20]58            case WEAPON_LASER:
[186]59                caca_set_color(EE_WHITE);
60                caca_putchar(wp->x[i] >> 4, wp->y[i] >> 4, '|');
61                caca_set_color(EE_CYAN);
62                caca_putchar(wp->x[i] >> 4, (wp->y[i] >> 4) + 1, '|');
[20]63                break;
64            case WEAPON_SEEKER:
[186]65                caca_set_color(EE_CYAN);
66                caca_putchar(wp->x3[i] >> 4, wp->y3[i] >> 4, '.');
67                caca_putchar(wp->x2[i] >> 4, wp->y2[i] >> 4, 'o');
68                caca_set_color(EE_WHITE);
69                caca_putchar(wp->x[i] >> 4, wp->y[i] >> 4, '@');
[20]70                break;
[24]71            case WEAPON_BOMB:
[186]72                caca_set_color(EE_DARKGRAY);
73                caca_putchar((wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4, '.');
74                caca_putchar((wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4, '.');
75                caca_putchar((wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4, '.');
76                caca_putchar(wp->x3[i] >> 4, wp->y3[i] >> 4, '.');
77                caca_putchar(wp->x2[i] >> 4, wp->y2[i] >> 4, '.');
[88]78                draw_bomb(wp->x[i] >> 4, wp->y[i] >> 4, wp->vx[i], wp->vy[i]);
[24]79                break;
[42]80            case WEAPON_FRAGBOMB:
[88]81                draw_fragbomb(wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i]);
[42]82                break;
[22]83            case WEAPON_BEAM:
[88]84                draw_beam(wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i]);
[22]85                break;
[20]86            case WEAPON_NUKE:
[88]87                draw_nuke(wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i]);
[20]88                break;
[42]89            case WEAPON_LIGHTNING:
[20]90            case WEAPON_NONE:
91                break;
[18]92        }
93    }
94}
95
[88]96void update_weapons(game *g, weapons *wp)
[18]97{
[20]98    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;
[18]99
[88]100    for(i = 0; i < WEAPONS; i++)
[18]101    {
[88]102        switch(wp->type[i])
[18]103        {
[20]104            case WEAPON_LASER:
105                wp->x[i] += wp->vx[i];
106                wp->y[i] += wp->vy[i];
[88]107                if(wp->y[i] < 0)
[20]108                {
109                    wp->type[i] = WEAPON_NONE;
110                }
111                break;
[24]112            case WEAPON_BOMB:
[20]113            case WEAPON_SEEKER:
114                /* Update tail */
115                wp->x3[i] = wp->x2[i];
116                wp->y3[i] = wp->y2[i];
117
118                wp->x2[i] = wp->x[i];
119                wp->y2[i] = wp->y[i];
120
121                wp->x[i] += wp->vx[i];
122                wp->y[i] += wp->vy[i];
123
[88]124                if(wp->y[i] < 0)
[20]125                {
126                    wp->type[i] = WEAPON_NONE;
127                    break;
128                }
129
[88]130                if(wp->n[i] < 0)
[20]131                {
132                    /* Stop updating direction */
133                    break;
134                }
135
[18]136                wp->n[i]--;
[20]137
[48]138                /* Estimate our position next frames */
139                xnew = wp->x[i] + wp->vx[i];
140                ynew = wp->y[i] + wp->vy[i];
[20]141
142                xmin = xnew;
143                ymin = - (g->h << 4);
144                dist = (xnew - xmin) * (xnew - xmin)
145                        + 4 * (ynew - ymin) * (ynew - ymin);
146
147                /* Find the nearest alien */
[88]148                for(j = 0; j < ALIENS; j++)
[18]149                {
[88]150                    if(g->al->type[j] != ALIEN_NONE)
[20]151                    {
152                        int alx = g->al->x[j] << 4;
153                        int aly = g->al->y[j] << 4;
154                        int new = (xnew - alx) * (xnew - alx)
155                                   + 4 * (ynew - aly) * (ynew - aly);
[88]156                        if(new <= dist)
[20]157                        {
158                            dist = new;
159                            xmin = alx;
160                            ymin = aly;
161                        }
162                    }
[18]163                }
[20]164
165                /* Find our new direction */
166                dx = xmin - wp->x[i];
167                dy = ymin - wp->y[i];
168
[48]169                /* Normalize direction */
[88]170                if(dx | dy)
[46]171                {
[186]172                    unsigned int norm = caca_sqrt(dx * dx + 4 * dy * dy);
[48]173                    dx = dx * 32 / norm;
174                    dy = dy * 32 / norm;
175                }
[20]176
[48]177                /* Find our new speed */
178                dx = (dx + 3 * wp->vx[i]) / 4;
179                dy = (dy + 3 * wp->vy[i]) / 4;
180
181                /* Normalize speed */
[88]182                if(dx | dy)
[48]183                {
[186]184                    unsigned int norm = caca_sqrt(dx * dx + 4 * dy * dy);
[48]185                    wp->vx[i] = dx * 32 / norm;
186                    wp->vy[i] = dy * 32 / norm;
[46]187                }
[48]188
[18]189                break;
[46]190
[42]191            case WEAPON_FRAGBOMB:
[46]192                /* If n was set to -1, the fragbomb just exploded */
[88]193                if(wp->n[i] == -1)
[42]194                {
[46]195                    int coords[] =
196                    {
[48]197                        32,  0,   -32,  0,    0,  16,     0, -16,
[50]198                        28,  8,   -28,  8,   28,  -8,   -28,  -8,
[48]199                        24, 12,   -24, 12,   24, -12,   -24, -12,
200                        16, 14,   -16, 14,   16, -14,   -16, -14
[46]201                    };
202
[88]203                    for(j = 0 ; j < sizeof(coords) / sizeof(int) ; j += 2)
[46]204                    {
[88]205                        add_weapon(g, g->wp, wp->x[i] + coords[j], wp->y[i] + coords[j+1] / 2, coords[j], coords[j+1], WEAPON_SEEKER);
206                        add_weapon(g, g->wp, wp->x[i] + coords[j] / 2, wp->y[i] + coords[j+1], coords[j], coords[j+1], WEAPON_SEEKER);
[46]207                    }
208
[42]209                    wp->type[i] = WEAPON_NONE;
210                }
211
212                wp->x[i] += wp->vx[i];
213                wp->y[i] += wp->vy[i];
214                wp->n[i]++;
[88]215                if(wp->y[i] < 0)
[42]216                {
217                    wp->type[i] = WEAPON_NONE;
218                }
219                break;
[46]220
[22]221            case WEAPON_BEAM:
[150]222                wp->x[i] = g->p->x << 4;
[22]223                wp->y[i] = g->p->y << 4;
224                wp->n[i]--;
[88]225                if(wp->n[i] < 0)
[22]226                {
227                    wp->type[i] = WEAPON_NONE;
228                }
229                break;
[20]230            case WEAPON_NUKE:
231                wp->n[i]--;
[88]232                if(wp->n[i] < 0)
[20]233                {
234                    wp->type[i] = WEAPON_NONE;
235                }
[18]236                break;
[42]237            case WEAPON_LIGHTNING:
[20]238            case WEAPON_NONE:
239                break;
[18]240        }
241    }
242}
243
[88]244void add_weapon(game *g, weapons *wp, int x, int y, int vx, int vy, int type)
[18]245{
246    int i;
247
[88]248    for(i = 0; i < WEAPONS; i++)
[18]249    {
[88]250        if(wp->type[i] == WEAPON_NONE)
[18]251        {
252            wp->x[i] = x;
253            wp->y[i] = y;
[20]254            wp->vx[i] = vx;
255            wp->vy[i] = vy;
[18]256            wp->type[i] = type;
[42]257            wp->n[i] = 0;
[88]258            switch(type)
[20]259            {
260                case WEAPON_LASER:
261                    break;
[42]262                case WEAPON_FRAGBOMB:
263                    break;
[20]264                case WEAPON_SEEKER:
[24]265                case WEAPON_BOMB:
[20]266                    wp->x2[i] = x;
267                    wp->y2[i] = y;
268                    wp->x3[i] = x;
269                    wp->y3[i] = y;
[26]270                    wp->n[i] = 20;
[20]271                    break;
[22]272                case WEAPON_BEAM:
273                    wp->n[i] = 25;
274                    break;
[20]275                case WEAPON_NUKE:
276                    wp->n[i] = 25;
277                    break;
278                case WEAPON_NONE:
279                    break;
280            }
[18]281            break;
282        }
283    }
284}
285
[88]286static void draw_bomb(int x, int y, int vx, int vy)
[24]287{
[142]288    int frame;
289
290    /* We have 1x2 pixels */
[24]291    vy *= 2;
292
[88]293    if(vx > vy)
[24]294    {
[88]295        if(vx > -vy) /* right quarter */
[24]296        {
[88]297            if(vy > vx/4)
[142]298                frame = 0; /* -pi/6 */
[88]299            else if(vy < -vx/4)
[142]300                frame = 1; /* pi/6 */
[24]301            else
[142]302                frame = 2; /* 0pi/6 */
[24]303        }
304        else /* top quarter */
305        {
[88]306            if(vx > -vy/4)
[142]307                frame = 3; /* 2pi/6 */
[88]308            else if(vx < vy/4)
[142]309                frame = 4; /* 4pi/6 */
[24]310            else
[142]311                frame = 5; /* 3pi/6 */
[24]312        }
313    }
314    else
315    {
[88]316        if(vx > -vy) /* bottom quarter */
[24]317        {
[88]318            if(vx > vy/4)
[142]319                frame = 6; /* -2pi/6 */
[88]320            else if(vx < -vy/4)
[142]321                frame = 7; /* -4pi/6 */
[24]322            else
[142]323                frame = 8; /* -3pi/6 */
[24]324        }
325        else /* left quarter */
326        {
[88]327            if(vy > -vx/4)
[142]328                frame = 9; /* -5pi/6 */
[88]329            else if(vy < vx/4)
[142]330                frame = 10; /* 5pi/6 */
[24]331            else
[142]332                frame = 11; /* 6pi/6 */
[24]333        }
334    }
[142]335
[186]336    caca_draw_sprite(x, y, bomb_sprite, frame);
[24]337}
338
[88]339static void draw_fragbomb(int x, int y, int frame)
[42]340{
[144]341    /* Draw the head */
[186]342    caca_draw_sprite(x, y, fragbomb_sprite, frame & 1);
[42]343
[144]344    /* Draw the tail */
[186]345    caca_draw_sprite(x, y, fragbomb_sprite, 2 + (frame % 4));
[42]346}
347
[88]348static void draw_beam(int x, int y, int frame)
[22]349{
350    int r = (29 - frame) * (29 - frame) / 8;
351    int i;
352
[88]353    switch(frame)
[22]354    {
355        case 24:
[186]356            caca_set_color(EE_WHITE);
357            caca_putstr(x, y-3, "__");
358            caca_putchar(x-1, y-2, '\'');
359            caca_putchar(x+2, y-2, '`');
[22]360            break;
361        case 23:
[186]362            caca_set_color(EE_CYAN);
363            caca_putstr(x, y-3, "__");
364            caca_set_color(EE_WHITE);
365            caca_putstr(x-2, y-2, "-'");
366            caca_putstr(x+2, y-2, "`-");
[22]367            break;
368        case 22:
[186]369            caca_set_color(EE_CYAN);
370            caca_putstr(x, y-3, "__");
371            caca_putchar(x-1, y-2, '\'');
372            caca_putchar(x+2, y-2, '`');
373            caca_set_color(EE_WHITE);
374            caca_putstr(x-3, y-2, ",-");
375            caca_putstr(x+3, y-2, "-.");
[22]376            break;
377        case 21:
[186]378            caca_set_color(EE_CYAN);
379            caca_putstr(x-1, y-3, "____");
380            caca_putchar(x-2, y-2, '\'');
381            caca_putchar(x+3, y-2, '`');
382            caca_set_color(EE_WHITE);
383            caca_putstr(x-4, y-2, ",-");
384            caca_putstr(x+4, y-2, "-.");
[22]385            break;
386        case 20:
[186]387            caca_set_color(EE_WHITE);
388            caca_putstr(x, y-3, "%%");
389            caca_putchar(x-4, y-2, ',');
390            caca_putchar(x+5, y-2, '.');
391            caca_set_color(EE_CYAN);
392            caca_putchar(x-1, y-3, ':');
393            caca_putchar(x+2, y-3, ':');
394            caca_putstr(x-3, y-2, "-'");
395            caca_putstr(x+3, y-2, "`-");
[22]396            break;
397        case 19:
[186]398            caca_set_color(EE_WHITE);
399            caca_putstr(x, y-4, "%%");
400            caca_putstr(x, y-3, "##");
401            caca_set_color(EE_CYAN);
402            caca_putchar(x-1, y-4, ':');
403            caca_putchar(x+2, y-4, ':');
404            caca_putchar(x-1, y-3, '%');
405            caca_putchar(x+2, y-3, '%');
406            caca_putstr(x-4, y-2, ",-'");
407            caca_putstr(x+3, y-2, "`-.");
408            caca_set_color(EE_BLUE);
409            caca_putchar(x-2, y-3, ':');
410            caca_putchar(x+3, y-3, ':');
[22]411            break;
412        case 18:
413        default:
414            r = (18 - frame) * (18 - frame);
[186]415            caca_set_color(EE_WHITE);
416            caca_putstr(x-1, y-5-r, ":%%:");
417            caca_putstr(x-1, y-4-r, "%##%");
418            caca_set_color(EE_CYAN);
419            caca_putchar(x-2, y-4-r, ':');
420            caca_putchar(x+3, y-4-r, ':');
421            caca_putchar(x-2, y-2, '\'');
422            caca_putchar(x+3, y-2, '`');
423            caca_set_color(EE_BLUE);
424            caca_putchar(x-3, y-2, ':');
425            caca_putchar(x+4, y-2, ':');
[88]426            for(i = 0; i <= r; i++)
[22]427            {
[186]428                caca_set_color(EE_WHITE);
429                caca_putstr(x-1, y-3-i, ((i+frame) % 5) ? "####" : "%%%%");
430                caca_set_color(EE_CYAN);
431                caca_putchar(x-2, y-3-i, '%');
432                caca_putchar(x+3, y-3-i, '%');
433                caca_set_color(EE_BLUE);
434                caca_putchar(x-3, y-3-i, ':');
435                caca_putchar(x+4, y-3-i, ':');
[22]436            }
437            break;
438    }
439}
440
[88]441static void draw_nuke(int x, int y, int frame)
[18]442{
[20]443    int r = (29 - frame) * (29 - frame) / 8;
[18]444
445    /* Lots of duplicate pixels, but we don't care */
[186]446    caca_set_color(EE_BLUE);
447    caca_draw_ellipse(x, y, r, r / 2, ':');
448    caca_draw_ellipse(x, y, r + 1, r / 2, ':');
449    caca_draw_ellipse(x, y, r + 2, r / 2, ':');
450    caca_set_color(EE_CYAN);
451    caca_draw_ellipse(x, y, r + 2, r / 2 + 1, '%');
452    caca_draw_ellipse(x, y, r + 3, r / 2 + 1, '%');
453    caca_set_color(EE_WHITE);
454    caca_draw_ellipse(x, y, r + 3, r / 2 + 2, '#');
455    caca_draw_ellipse(x, y, r + 4, r / 2 + 2, '#');
456    caca_draw_ellipse(x, y, r + 4, r / 2 + 3, '#');
[18]457}
458
Note: See TracBrowser for help on using the repository browser.