void ai_proximity_press_vert(Object *o) { switch(o->state) { case 0: { if (pdistlx(8<<CSF) && pdistly2(8<<CSF, 128<<CSF) && \ !o->blockd) { o->state = 10; o->animtimer = 0; o->frame = 1; } } break; case 10: { if (o->frame < 2) ANIMATE_FWD(2); if (o->blockd) { if (o->frame >= 2) // make sure eye fully open { SmokeSide(o, 4, DOWN); quake(10); } o->flags |= FLAG_SOLID_BRICK; o->damage = 0; o->state = 11; o->frame = 0; } else { if (player->Top() > o->CenterY()) { o->flags &= ~FLAG_SOLID_BRICK; o->damage = 127; } else { o->flags |= FLAG_SOLID_BRICK; o->damage = 0; } } } break; } if (o->state >= 5) { o->yinertia += 0x80; LIMITY(0x5ff); } }
void aftermove_blade_slash(Object *o) { ANIMATE_FWD(2); if (o->frame >= 4) { o->Delete(); return; } o->x += (o->dir == LEFT) ? -0x400 : 0x400; o->y += 0x400; static const int damage_for_frames[] = { 0, 1, 2, 2, 2 }; o->shot.damage = damage_for_frames[o->frame]; // deal damage to anything we touch. Object *enemy = damage_enemies(o); if (enemy && (enemy->flags & FLAG_INVULNERABLE)) o->Delete(); }
void ai_press_vert(Object *o) { switch(o->state) { case 0: { o->state = 1; o->y -= (4 << CSF); if (pdistlx((8<<CSF)) && pdistly2((8<<CSF), (128<<CSF))) { o->state = 5; } } break; case 5: { if (o->blockd) { o->state = 10; o->animtimer = 0; o->frame = 1; } } break; case 10: { ANIMATE_FWD(2); if (o->frame > 2) o->frame = 2; if (player->y > o->y) o->flags |= FLAG_SOLID_BRICK; } break; } }
// lava drip spawner in Last Cave (hidden) and used extensively in Final Cave. // the id1 tag sets the frequency of the drip, the id2 tag sets an amount to // delay the first drip in order to desync a group of drips. void ai_lava_drip_spawner(Object *o) { switch(o->state) { case 0: { o->sprite = SPR_LAVA_DRIP; o->x += (4 << CSF); o->timer = (o->id2 - o->id1); o->state = 1; } case 1: { if (--o->timer < 0) { o->state = 2; o->animtimer = 0; o->timer2 = 0; } } break; case 2: { o->display_xoff = (++o->timer2 & 2) ? 0 : 1; ANIMATE_FWD(10); if (o->frame > 3) { o->frame = 0; o->state = 1; o->timer = o->id1; ai_lava_drip(CreateObject(o->x, o->y, OBJ_LAVA_DRIP)); } } break; } }
void ai_intro_doctor(Object *o) { switch(o->state) { case 0: { o->y -= (8 << CSF); o->state = 1; } case 1: { o->frame = 0; } break; case 10: // chuckle; facing screen { o->state = 11; o->frame = 0; o->animtimer = 0; o->timer2 = 0; } case 11: { ANIMATE_FWD(6); if (o->frame > 1) { o->frame = 0; if (++o->timer2 > 7) o->state = 1; } } break; case 20: // walk { o->state = 21; o->frame = 2; o->animtimer = 0; } case 21: { ANIMATE(10, 2, 5); o->x += 0x100; } break; case 30: // face away { o->frame = 6; o->state = 31; } break; case 40: // chuckle; facing away { o->state = 41; o->frame = 6; o->animtimer = 0; o->timer2 = 0; } case 41: { ANIMATE_FWD(6); if (o->frame > 7) { o->frame = 6; if (++o->timer2 > 7) o->state = 30; } } break; } }
void ai_bute_arrow(Object *o) { // check for hit wall/floor etc if (o->state < 20) { if ((o->blockl && o->xinertia < 0) || \ (o->blockr && o->xinertia > 0) || \ (o->blocku && o->yinertia <= 0) || \ (o->blockd && o->yinertia >= 0)) { if (!(o->flags & FLAG_IGNORE_SOLID)) o->state = 20; } } switch(o->state) { case 0: { // set appropriate frame for initial direction o->sprite = (o->xinertia < 0) ? SPR_BUTE_ARROW_LEFT : SPR_BUTE_ARROW_RIGHT; o->frame = (o->yinertia < 0) ? 0 : 2; o->state = 1; } case 1: { if (++o->timer == 4) o->flags &= ~FLAG_IGNORE_SOLID; if (o->timer > 10) o->state = 10; } break; case 10: { o->state = 11; // slow down a bit (was going real fast from bow) o->xinertia *= 3; o->xinertia /= 4; o->yinertia *= 3; o->yinertia /= 4; } case 11: { o->yinertia += 0x20; ANIMATE_FWD(10); if (o->frame > 4) o->frame = 4; } break; case 20: // hit something { o->state = 21; o->timer = 0; o->damage = 0; o->xinertia = 0; o->yinertia = 0; } case 21: { o->timer++; if (o->timer > 30) o->invisible = (o->timer & 2); if (o->timer > 61) o->Delete(); } break; } LIMITY(0x5ff); }
void ai_doctor_shot_trail(Object *o) { ANIMATE_FWD(3); if (o->frame > 3) o->Delete(); }
// Kulala void ai_giant_jelly(Object *o) { switch(o->state) { case 0: // frozen/in stasis. waiting for player to shoot. o->frame = 4; if (o->shaketime) { quake(30); o->state = 10; o->frame = 0; o->timer = 0; } break; case 10: // falling { o->flags |= FLAG_SHOOTABLE; o->flags &= ~FLAG_INVULNERABLE; if (++o->timer > 40) { o->timer = 0; o->animtimer = 0; o->state = 11; } } break; case 11: // animate thrust { ANIMATE_FWD(5); if (o->frame >= 3) { o->frame = 3; o->state = 12; } } break; case 12: // thrusting upwards { o->yinertia = -0x155; if (++o->timer > 20) { o->state = 10; o->frame = 0; o->timer = 0; } } break; case 20: // shot/freeze over/go invulnerable { o->frame = 4; o->xinertia >>= 1; o->yinertia += 0x20; if (!o->shaketime) { o->state = 10; o->frame = 0; o->timer = 30; } } break; } if (o->shaketime) { if (++o->timer3 > 12) { o->state = 20; o->frame = 4; o->flags &= ~FLAG_SHOOTABLE; o->flags |= FLAG_INVULNERABLE; } } else { o->timer3 = 0; } if (o->state >= 10) { if (o->blockl) { o->timer2 = 50; o->dir = RIGHT; } if (o->blockr) { o->timer2 = 50; o->dir = LEFT; } if (o->timer2 > 0) { o->timer2--; XACCEL(0x80); } else { o->timer2 = 50; FACEPLAYER; } o->yinertia += 0x10; if (o->blockd) o->yinertia = -0x300; } LIMITX(0x100); LIMITY(0x300); }