コード例 #1
0
void aftermove_blade_l12_shot(Object *o)
{
    int level = (o->shot.btype - B_BLADE_L1);
    ANIMATE(1, 0, 3);

    if (--o->shot.ttl < 0)
    {
        shot_dissipate(o);
        return;
    }

    // only start damaging enemies after we've passed the player
    // as it starts slightly behind him
    if (++o->timer >= 4)
    {
        Object *enemy;
        if ((enemy = damage_enemies(o)))
        {
            // on level 2 we can deal damage up to 3 times (18 max)
            if (level == 0 || \
                    ++o->timer2 >= 3 || (enemy->flags & FLAG_INVULNERABLE))
            {
                o->Delete();
                return;
            }
        }
        else if (IsBlockedInShotDir(o))
        {
            if (!shot_destroy_blocks(o))
                sound(SND_SHOT_HIT);

            shot_dissipate(o, EFFECT_STARSOLID);
            return;
        }
    }

    switch(level)
    {
    case 0:
        if ((o->timer % 5) == 1)
            sound(SND_FIREBALL);
        break;

    case 1:
        if ((o->timer % 7) == 1)
            sound(SND_SLASH);
        break;
    }
}
コード例 #2
0
ファイル: missile.cpp プロジェクト: lluixhi/nxengine-evo
void ai_missile_shot(Object *o)
{
        int index = o->shot.level + ((o->type == OBJ_SUPERMISSILE_SHOT) ? 3 : 0);
        MissileSettings *settings = &missile_settings[index];

        if (o->state == 0) {
                o->shot.damage = settings->damage;

                if (o->shot.level == 2) {
                        // initilize wavey effect
                        if (o->shot.dir == LEFT || o->shot.dir == RIGHT)
                                o->ymark = -0x20;
                        else
                                o->xmark = -0x20;

                        // don't let it explode until the "recoil" effect is over.
                        o->state = STATE_WAIT_RECOIL_OVER;
                        // record position we were fired at (we won't explode until we pass it)
                        o->xmark2 = player->x;
                        o->ymark2 = player->y;
                } else {
                        o->state = STATE_MISSILE_CAN_EXPLODE;
                }
        }

        // accelerate according to current type and level of missile
        // don't use LIMITX here as it can mess up recoil of level 3 super missiles
        switch(o->shot.dir) {
        case RIGHT:
                o->xinertia += settings->accel;
                if (o->xinertia > settings->maxspeed) o->xinertia = settings->maxspeed;
                break;

        case LEFT:
                o->xinertia -= settings->accel;
                if (o->xinertia < -settings->maxspeed) o->xinertia = -settings->maxspeed;
                break;

        case UP:
                o->yinertia -= settings->accel;
                if (o->yinertia < -settings->maxspeed) o->yinertia = -settings->maxspeed;
                break;

        case DOWN:
                o->yinertia += settings->accel;
                if (o->yinertia > settings->maxspeed) o->yinertia = settings->maxspeed;
                break;
        }

        // wavey effect for level 3
        // (markx/y is used as a "speed" value here)
        if (o->shot.level == 2) {
                if (o->shot.dir == LEFT || o->shot.dir == RIGHT) {
                        o->yinertia += o->ymark;

                        if (o->ymark > 0 && o->yinertia > 0x100)  o->ymark = -o->ymark;
                        if (o->ymark < 0 && o->yinertia < -0x100) o->ymark = -o->ymark;
                } else {
                        o->xinertia += o->xmark;

                        if (o->xmark > 0 && o->xinertia > 0x100)  o->xmark = -o->xmark;
                        if (o->xmark < 0 && o->xinertia < -0x100) o->xmark = -o->xmark;
                }
        }

        // check if we hit an enemy
        // level 3 missiles can not blow up while they are "recoiling"
        // what we do is first wait until they're traveling in the direction
        // they're pointing, then wait till they pass the player's original position.
        switch(o->state) {
        case STATE_WAIT_RECOIL_OVER:
                switch(o->shot.dir) {
                case LEFT:
                        if (o->xinertia <= 0) o->state = STATE_RECOIL_OVER;
                        break;
                case RIGHT:
                        if (o->xinertia >= 0) o->state = STATE_RECOIL_OVER;
                        break;
                case UP:
                        if (o->yinertia <= 0) o->state = STATE_RECOIL_OVER;
                        break;
                case DOWN:
                        if (o->yinertia >= 0) o->state = STATE_RECOIL_OVER;
                        break;
                }
                if (o->state != STATE_RECOIL_OVER)
                        break;

        case STATE_RECOIL_OVER:
                switch(o->shot.dir) {
                case LEFT:
                        if (o->x <= o->xmark2-(2<<CSF)) o->state = STATE_MISSILE_CAN_EXPLODE;
                        break;
                case RIGHT:
                        if (o->x >= o->xmark2+(2<<CSF)) o->state = STATE_MISSILE_CAN_EXPLODE;
                        break;
                case UP:
                        if (o->y <= o->ymark2-(2<<CSF)) o->state = STATE_MISSILE_CAN_EXPLODE;
                        break;
                case DOWN:
                        if (o->y >= o->ymark2+(2<<CSF)) o->state = STATE_MISSILE_CAN_EXPLODE;
                        break;
                }
                if (o->state != STATE_MISSILE_CAN_EXPLODE)
                        break;

        case STATE_MISSILE_CAN_EXPLODE: {
                bool blow_up = false;

                if (damage_enemies(o)) {
                        blow_up = true;
                } else {
                        // check if we hit a wall
                        if (o->shot.dir==LEFT && o->blockl) 	  blow_up = true;
                        else if (o->shot.dir==RIGHT && o->blockr) blow_up = true;
                        else if (o->shot.dir==UP && o->blocku)	  blow_up = true;
                        else if (o->shot.dir==DOWN && o->blockd)  blow_up = true;
                }

                if (blow_up) {
                        sound(SND_MISSILE_HIT);

                        // create the boom-spawner object for the flashes, smoke, and AoE damage
                        Object *sp = CreateObject(o->CenterX(), o->CenterY(), OBJ_MISSILE_BOOM_SPAWNER);

                        sp->shot.boomspawner.range = settings->boomrange;
                        sp->shot.boomspawner.booms_left = settings->num_booms;
                        sp->shot.damage = settings->boomdamage;

                        o->Delete();
                        return;
                }
        }
        break;
        }

        if (--o->shot.ttl < 0)
                shot_dissipate(o, EFFECT_STARPOOF);

        // smoke trails
        if (++o->timer > 2) {
                o->timer = 0;
                Caret *trail = effect(o->CenterX() - o->xinertia, \
                                      o->CenterY() - o->yinertia, EFFECT_SMOKETRAIL);

                const int trailspd = 0x400;
                switch(o->shot.dir) {
                case LEFT:
                        trail->xinertia = trailspd;
                        trail->y -= (2<<CSF);
                        break;
                case RIGHT:
                        trail->xinertia = -trailspd;
                        trail->y -= (2<<CSF);
                        break;
                case UP:
                        trail->yinertia = trailspd;
                        trail->x -= (1<<CSF);
                        break;
                case DOWN:
                        trail->yinertia = -trailspd;
                        trail->x -= (1<<CSF);
                        break;
                }
        }

}
コード例 #3
0
void ai_blade_l3_shot(Object *o)
{

    switch(o->state)
    {
    case STATE_FLYING:
    {
        if ((++o->timer % 4) == 1)
        {
            Object *slash = CreateObject(o->x, o->y - (12 << CSF), OBJ_BLADE_SLASH);

            if (++o->timer2 & 1)
            {
                slash->dir = LEFT;
                slash->x += (10 << CSF);
            }
            else
            {
                slash->dir = RIGHT;
                slash->x -= (10 << CSF);
            }

            sound(SND_SLASH);
        }

        if (++o->timer2 > o->shot.ttl)
        {
            shot_dissipate(o);
            return;
        }

        // damage enemies and hit walls
        if (o->timer2 >= 5)
        {
            Object *enemy;
            if ((enemy = damage_enemies(o)))
            {
                if (enemy->flags & FLAG_INVULNERABLE)
                {
                    shot_spawn_effect(o, EFFECT_STARSOLID);
                    sound(SND_SHOT_HIT);
                    o->Delete();
                }
                else
                {
                    o->x += o->xinertia;
                    o->y += o->yinertia;
                    o->xinertia = 0;
                    o->yinertia = 0;

                    o->state = STATE_AOE;
                    o->frame = 1;
                    o->timer = 0;
                }
            }
            else if (IsBlockedInShotDir(o))
            {
                if (!shot_destroy_blocks(o))
                    sound(SND_SHOT_HIT);

                shot_spawn_effect(o, EFFECT_STARSOLID);
                o->Delete();
            }
        }
    }
    break;

    case STATE_AOE:
    {
        if (!random(0, 2))
        {
            Object *slash = CreateObject(o->x + random(-BLADE_AOE, BLADE_AOE),
                                         o->y + random(-BLADE_AOE, BLADE_AOE),
                                         OBJ_BLADE_SLASH);

            slash->dir = random(0, 1) ? LEFT : RIGHT;
            sound(SND_SLASH);
        }

        if (++o->timer > 50)
            o->Delete();
    }
    break;
    }

    o->invisible = (o->timer & 1);
}