void ai_bute_flying(Object *o) { //AIDEBUG; if (run_bute_defeated(o, BUTE_HP)) return; switch(o->state) { case 0: { o->invisible = true; o->state = 1; } case 1: { if (o->dir == LEFT) { if (player->x > (o->x - (288<<CSF)) && \ player->x < (o->x - (272<<CSF))) { o->state = 10; } } else { if (player->x < (o->x + (288<<CSF)) && \ player->x > (o->x + (272<<CSF))) { o->state = 10; } } } break; case 10: { o->state = 11; o->invisible = false; o->flags |= FLAG_SHOOTABLE; o->damage = 5; } case 11: { FACEPLAYER; ANIMATE(1, 0, 1); XACCEL(0x10); o->yinertia += (o->y > player->y) ? -0x10 : 0x10; LIMITX(0x5ff); LIMITY(0x5ff); if ((o->blockl && o->xinertia < 0) || \ (o->blockr && o->xinertia > 0)) { o->xinertia = -o->xinertia; } if ((o->blockd && o->yinertia > 0) || \ (o->blocku && o->yinertia < 0)) { o->yinertia = -o->yinertia; } } break; } }
void ai_mesa(Object *o) { if (run_bute_defeated(o, MESA_HP)) return; switch(o->state) { case 0: { o->y += (4<<CSF); o->state = 1; } case 1: { ANIMATE(40, 0, 1); FACEPLAYER; if (pdistlx(320<<CSF) && pdistly(160<<CSF)) { if (++o->timer > 50) o->state = 10; } } break; case 10: { o->state = 11; o->timer = 0; o->frame = 2; // hand down int x = o->x + ((o->dir == LEFT) ? (7<<CSF) : -(7<<CSF)); int y = o->y + (10<<CSF); o->linkedobject = CreateObject(x, y, OBJ_MESA_BLOCK); o->linkedobject->linkedobject = o; } case 11: { if (++o->timer > 50) { o->state = 20; o->timer = 0; o->frame = 3; // hand up, throwing if (o->linkedobject) { Object *&block = o->linkedobject; block->y = (o->y - (4<<CSF)); block->xinertia = (o->dir == RIGHT) ? 0x400 : -0x400; block->yinertia = -0x400; block->state = 1; sound(SND_EM_FIRE); block->linkedobject = NULL; o->linkedobject = NULL; } } } break; case 20: { if (++o->timer > 20) { // throw again, if player still near o->state = 1; o->timer = 0; } } break; } o->yinertia += 0x55; LIMITY(0x5ff); }
void ai_bute_archer(Object *o) { if (run_bute_defeated(o, BUTE_HP)) return; switch(o->state) { case 0: // waiting for player (when haven't seen him yet) { if ((o->dir == LEFT && player->CenterX() < o->CenterX()) || \ (o->dir == RIGHT && player->CenterX() > o->CenterX())) { if (pdistlx(320<<CSF) && pdistly(160<<CSF)) { o->state = 10; } } } break; // aiming--can track player here for a brief period case 10: { FACEPLAYER; if (!pdistlx(224<<CSF) || player->y <= (o->y - (8<<CSF))) { o->frame = 4; // shooting up o->timer2 = 1; } else { o->frame = 1; // shooting straight o->timer2 = 0; } if (++o->timer > 10) { o->state = 20; o->timer = 0; } } break; // flashing to fire case 20: { if (o->timer2 == 0) ANIMATE(0, 1, 2) else ANIMATE(0, 4, 5) if (++o->timer > 30) o->state = 30; } break; // fire case 30: { o->state = 31; o->timer = 0; Object *arrow = CreateObject(o->CenterX(), o->CenterY(), OBJ_BUTE_ARROW); arrow->xinertia = (o->dir == RIGHT) ? 0x600 : -0x600; if (o->timer2 == 1) // shooting up arrow->yinertia = -0x600; // frame: arrow away o->frame = (o->timer2 == 1) ? 6 : 3; } case 31: { if (++o->timer > 30) { o->state = 40; o->frame = 0; o->timer = random(50, 150); } } break; // after fire, and the "woken up" waiting-for-player state case 40: { if (pdistlx(352<<CSF) && pdistly(240<<CSF)) { if (--o->timer < 0) o->state = 10; // fire again } else { // player got away, do nothing until he returns o->timer = 150; } } break; } }
void ai_bute_sword(Object *o) { if (run_bute_defeated(o, BUTE_HP)) return; switch(o->state) { case 0: { o->flags |= (FLAG_SHOOTABLE | FLAG_INVULNERABLE); o->nxflags |= NXFLAG_FOLLOW_SLOPE; o->damage = 0; o->state = 1; } case 1: // lying in wait { FACEPLAYER; if (pdistlx(128<<CSF) && \ pdistly2(128<<CSF, 16<<CSF)) { o->state = 10; } } break; // wait a moment, then start running at player case 10: { o->flags |= FLAG_INVULNERABLE; o->damage = 0; o->frame = 0; o->state = 11; o->timer = 0; } case 11: { if (++o->timer > 30) { o->state = 20; o->timer = 0; } } break; // run at player and jump case 20: { o->flags &= ~FLAG_INVULNERABLE; o->state = 21; FACEPLAYER; } case 21: { ANIMATE(3, 0, 1); XMOVE(0x400); if (pdistlx(40<<CSF)) { o->xinertia /= 2; o->yinertia = -0x300; o->state = 30; o->frame = 2; // sword back, jumping sound(SND_ENEMY_JUMP); } else if (++o->timer > 50) { // timeout, p got away o->state = 10; o->xinertia = 0; } } break; // jumping up case 30: { if (o->yinertia > -0x80) { o->frame = 3; // sword swipe fwd o->damage = 9; o->state = 31; o->timer = 0; } } break; // swiping sword, in air case 31: { if (++o->timer > 2) { o->timer = 0; o->frame = 4; // sword down, in front } if (o->blockd && o->yinertia > 0) { o->xinertia = 0; o->damage = 3; o->state = 32; o->timer = 0; } } break; case 32: { if (++o->timer > 30) { o->state = 10; o->timer = 0; } } break; } o->yinertia += 0x20; LIMITY(0x5ff); }