<commit_before>/*
 *   ttyvaders     Textmode shoot'em up
 *   Copyright (c) 2002 <NAME> <<EMAIL>>
 *                 All Rights Reserved
 *
 *   $Id: weapons.c,v 1.10 2002/12/22 23:01:35 sam Exp $
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdlib.h>

#include "common.h"

static void draw_bomb( int x, int y, int vx, int vy );
static void draw_nuke( int x, int y, int frame );
static void draw_beam( int x, int y, int frame );
static void draw_circle( int x, int y, int r, char c );
static void draw_fragbomb( int x, int y, int frame );

void init_weapons( game *g, weapons *wp )
{
    int i;

    for( i = 0; i < WEAPONS; i++ )
    {
        wp->type[i] = WEAPON_NONE;
    }
}

void draw_weapons( game *g, weapons *wp )
{
    int i;

    for( i = 0; i < WEAPONS; i++ )
    {
        switch( wp->type[i] )
        {
            case WEAPON_LASER:
                gfx_color( WHITE );
                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
                gfx_putchar( '|' );
                gfx_color( CYAN );
                gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
                gfx_putchar( '|' );
                break;
            case WEAPON_SEEKER:
                gfx_color( CYAN );
                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
                gfx_putchar( '.' );
                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
                gfx_putchar( 'o' );
                gfx_color( WHITE );
                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
                gfx_putchar( '@' );
                break;
            case WEAPON_BOMB:
                gfx_color( GRAY );
                gfx_goto( (wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4 );
                gfx_putchar( '.' );
                gfx_goto( (wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4 );
                gfx_putchar( '.' );
                gfx_goto( (wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4 );
                gfx_putchar( '.' );
                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
                gfx_putchar( '.' );
                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
                gfx_putchar( '.' );
                draw_bomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->vx[i], wp->vy[i] );
                break;
            case WEAPON_FRAGBOMB:
                draw_fragbomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
                break;
            case WEAPON_BEAM:
                draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
                break;
            case WEAPON_NUKE:
                draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
                break;
            case WEAPON_LIGHTNING:
            case WEAPON_NONE:
                break;
        }
    }
}

void update_weapons( game *g, weapons *wp )
{
    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;

    for( i = 0; i < WEAPONS; i++ )
    {
        switch( wp->type[i] )
        {
            case WEAPON_LASER:
                wp->x[i] += wp->vx[i];
                wp->y[i] += wp->vy[i];
                if( wp->y[i] < 0 )
                {
                    wp->type[i] = WEAPON_NONE;
                }
                break;
            case WEAPON_BOMB:
            case WEAPON_SEEKER:
                /* Update tail */
                wp->x3[i] = wp->x2[i];
                wp->y3[i] = wp->y2[i];

                wp->x2[i] = wp->x[i];
                wp->y2[i] = wp->y[i];

                wp->x[i] += wp->vx[i];
                wp->y[i] += wp->vy[i];

                if( wp->y[i] < 0 )
                {
                    wp->type[i] = WEAPON_NONE;
                    break;
                }

                if( wp->n[i] < 0 )
                {
                    /* Stop updating direction */
                    break;
                }

                wp->n[i]--;

                /* Estimate our position in 2 frames */
                xnew = wp->x[i] + 4 * wp->vx[i];
                ynew = wp->y[i] + 4 * wp->vy[i];

                xmin = xnew;
                ymin = - (g->h << 4);
                dist = (xnew - xmin) * (xnew - xmin)
                        + 4 * (ynew - ymin) * (ynew - ymin);

                /* Find the nearest alien */
                for( j = 0; j < ALIENS; j++ )
                {
                    if( g->al->type[j] != ALIEN_NONE )
                    {
                        int alx = g->al->x[j] << 4;
                        int aly = g->al->y[j] << 4;
                        int new = (xnew - alx) * (xnew - alx)
                                   + 4 * (ynew - aly) * (ynew - aly);
                        if( new <= dist )
                        {
                            dist = new;
                            xmin = alx;
                            ymin = aly;
                        }
                    }
                }

                /* Find our new direction */
                dx = xmin - wp->x[i];
                dy = ymin - wp->y[i];

                /* Normalize and update speed */
                if( dx | dy )
                {
                    int norm = r00t( dx * dx + dy * dy );

                    wp->vx[i] = (7 * wp->vx[i] + (dx * 48) / norm ) / 8;
                    wp->vy[i] = (7 * wp->vy[i] + (dy * 24) / norm ) / 8;
                }
                break;

            case WEAPON_FRAGBOMB:
                /* If n was set to -1, the fragbomb just exploded */
                if( wp->n[i] == -1 )
                {
                    int coords[] =
                    {
                        24,  0,   -24,  0,    0,  24,     0, -24,
                        24,  8,   -24,  8,   24,  -8,   -24,  -8,
                        16, 16,   -16, 16,   16, -16,   -16, -16
                    };

                    for( j = 0; j < 12; j++ )
                    {
                        add_weapon( g, g->wp, wp->x[i] + coords[2*j], wp->y[i] + coords[2*j+1], coords[2*j], coords[2*j+1], WEAPON_SEEKER );
                    }

                    wp->type[i] = WEAPON_NONE;<commit_msg>  * seekers and homing bombs react more quickly.   * 16 seekers on fragbomb explosion instead of 12.<commit_after>/*
 *   ttyvaders     Textmode shoot'em up
 *   Copyright (c) 2002 <NAME> <<EMAIL>>
 *                 All Rights Reserved
 *
 *   $Id: weapons.c,v 1.11 2002/12/22 23:39:15 sam Exp $
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdlib.h>

#include "common.h"

static void draw_bomb( int x, int y, int vx, int vy );
static void draw_nuke( int x, int y, int frame );
static void draw_beam( int x, int y, int frame );
static void draw_circle( int x, int y, int r, char c );
static void draw_fragbomb( int x, int y, int frame );

void init_weapons( game *g, weapons *wp )
{
    int i;

    for( i = 0; i < WEAPONS; i++ )
    {
        wp->type[i] = WEAPON_NONE;
    }
}

void draw_weapons( game *g, weapons *wp )
{
    int i;

    for( i = 0; i < WEAPONS; i++ )
    {
        switch( wp->type[i] )
        {
            case WEAPON_LASER:
                gfx_color( WHITE );
                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
                gfx_putchar( '|' );
                gfx_color( CYAN );
                gfx_goto( wp->x[i] >> 4, (wp->y[i] >> 4) + 1 );
                gfx_putchar( '|' );
                break;
            case WEAPON_SEEKER:
                gfx_color( CYAN );
                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
                gfx_putchar( '.' );
                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
                gfx_putchar( 'o' );
                gfx_color( WHITE );
                gfx_goto( wp->x[i] >> 4, wp->y[i] >> 4 );
                gfx_putchar( '@' );
                break;
            case WEAPON_BOMB:
                gfx_color( GRAY );
                gfx_goto( (wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4 );
                gfx_putchar( '.' );
                gfx_goto( (wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4 );
                gfx_putchar( '.' );
                gfx_goto( (wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4 );
                gfx_putchar( '.' );
                gfx_goto( wp->x3[i] >> 4, wp->y3[i] >> 4 );
                gfx_putchar( '.' );
                gfx_goto( wp->x2[i] >> 4, wp->y2[i] >> 4 );
                gfx_putchar( '.' );
                draw_bomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->vx[i], wp->vy[i] );
                break;
            case WEAPON_FRAGBOMB:
                draw_fragbomb( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
                break;
            case WEAPON_BEAM:
                draw_beam( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
                break;
            case WEAPON_NUKE:
                draw_nuke( wp->x[i] >> 4, wp->y[i] >> 4, wp->n[i] );
                break;
            case WEAPON_LIGHTNING:
            case WEAPON_NONE:
                break;
        }
    }
}

void update_weapons( game *g, weapons *wp )
{
    int i, j, dist, xmin, ymin, dx, dy, xnew, ynew;

    for( i = 0; i < WEAPONS; i++ )
    {
        switch( wp->type[i] )
        {
            case WEAPON_LASER:
                wp->x[i] += wp->vx[i];
                wp->y[i] += wp->vy[i];
                if( wp->y[i] < 0 )
                {
                    wp->type[i] = WEAPON_NONE;
                }
                break;
            case WEAPON_BOMB:
            case WEAPON_SEEKER:
                /* Update tail */
                wp->x3[i] = wp->x2[i];
                wp->y3[i] = wp->y2[i];

                wp->x2[i] = wp->x[i];
                wp->y2[i] = wp->y[i];

                wp->x[i] += wp->vx[i];
                wp->y[i] += wp->vy[i];

                if( wp->y[i] < 0 )
                {
                    wp->type[i] = WEAPON_NONE;
                    break;
                }

                if( wp->n[i] < 0 )
                {
                    /* Stop updating direction */
                    break;
                }

                wp->n[i]--;

                /* Estimate our position next frames */
                xnew = wp->x[i] + wp->vx[i];
                ynew = wp->y[i] + wp->vy[i];

                xmin = xnew;
                ymin = - (g->h << 4);
                dist = (xnew - xmin) * (xnew - xmin)
                        + 4 * (ynew - ymin) * (ynew - ymin);

                /* Find the nearest alien */
                for( j = 0; j < ALIENS; j++ )
                {
                    if( g->al->type[j] != ALIEN_NONE )
                    {
                        int alx = g->al->x[j] << 4;
                        int aly = g->al->y[j] << 4;
                        int new = (xnew - alx) * (xnew - alx)
                                   + 4 * (ynew - aly) * (ynew - aly);
                        if( new <= dist )
                        {
                            dist = new;
                            xmin = alx;
                            ymin = aly;
                        }
                    }
                }

                /* Find our new direction */
                dx = xmin - wp->x[i];
                dy = ymin - wp->y[i];

                /* Normalize direction */
                if( dx | dy )
                {
                    int norm = r00t( dx * dx + 4 * dy * dy );
                    dx = dx * 32 / norm;
                    dy = dy * 32 / norm;
                }

                /* Find our new speed */
                dx = (dx + 3 * wp->vx[i]) / 4;
                dy = (dy + 3 * wp->vy[i]) / 4;

                /* Normalize speed */
                if( dx | dy )
                {
                    int norm = r00t( dx * dx + 4 * dy * dy );
                    wp->vx[i] = dx * 32 / norm;
                    wp->vy[i] = dy * 32 / norm;
                }

                break;

            case WEAPON_FRAGBOMB:
                /* If n was set to -1, the fragbomb just exploded */
                if( wp->n[i] == -1 )
                {
                    int coords[] =
                    {
                        32,  0,   -32,  0,    0,  16,     0, -16,
                        24, 12,   -24, 12,   24, -12,   -24, -12,
                        28,  8,   -28,  8,   28,  -8,   -28,  -8,
                        16, 14,   -16, 14,   16, -14,   -16, -14
                    };

                    for( j = 0 ; j < sizeof(coords) / sizeof(int) ; j += 2 )
                    {
                        add_weapon( g, g->wp, wp->x[i] + coords[j], wp->y[i] + coords[j+1], coords[j], coords[j+1], WEAPON_SEEKER );
                    }

                    wp->type[i] = WEAPON_NONE;
{'fraction_non_alphanumeric': 0.14917798427448178, 'fraction_numerical': 0.023302358827734095, 'mean_word_length': 1.019486143187067, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 295, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7006348', 'n_tokens_mistral': 5093, 'n_tokens_neox': 4573, 'n_words': 1205}