void ai_npc_sue(Object *o) { switch(o->state) { case 0: // stand and blink o->timer = 0; o->frame = 0; o->xinertia = 0; o->sue.carried_by = NULL; randblink(o, 1, 4); break; case 3: // walking case 4: // walking case 5: // face away ai_generic_npc(o); break; // got punched by Igor case 6: o->state = 7; o->frame = 7; o->timer = 0; sound(SND_ENEMY_SQUEAK); case 7: if (++o->timer > 10) o->state = 0; break; // got punched extra hard by Igor // flys through air backwards and crashes case 8: o->state = 9; o->frame = 7; o->timer = 0; sound(SND_ENEMY_SQUEAK); o->yinertia = -0x200; XMOVE(-0x400); case 9: if (++o->timer > 3 && o->blockd) { o->state = 10; o->dir ^= 1; } break; case 10: o->xinertia = 0; o->frame = 8; break; // punching the air (when she tells Igor "I'm not afraid of you!") case 11: o->state = 12; o->timer = 0; o->animframe = 0; o->animtimer = 0; case 12: { const static int punchframes[] = { 10, 0 }; o->animate_seq(8, punchframes, 2); } break; // picked up & carried away by Igor case 13: o->frame = 11; o->xinertia = 0; o->yinertia = 0; o->state = 14; // find Igor o->sue.carried_by = FindObjectByID2(501); if (!o->sue.carried_by) NX_ERR("-- Could not find entity carrying Sue (ID 501)\n"); case 14: // being carried--see aftermove routine o->frame = 9; break; // spawn red crystal and call it to us (Undead Core intro) case 15: { o->PushBehind(dr_create_red_crystal(o->x+(128<<CSF), o->y)); o->state = 16; o->xinertia = 0; o->frame = 0; } case 16: { crystal_xmark = o->x - (18<<CSF); crystal_ymark = o->y - (8<<CSF); } break; case 17: // look up (still followed by red crystal) { o->xinertia = 0; o->frame = 12; crystal_xmark = o->x; crystal_ymark = o->y - (8<<CSF); } break; // run away from DOCTOR_GHOST and hide behind player case 20: { o->state = 21; o->frame = 2; o->animtimer = 0; } case 21: { ANIMATE(2, 2, 5); XMOVE(0x400); if (o->x < player->x - (8<<CSF)) { o->dir = RIGHT; o->state = 0; } } break; // run, during "we've got to get out of here" post-undead core cutscene. case 30: { o->state = 31; o->frame = 2; o->animtimer = 0; } case 31: { ANIMATE(2, 2, 5); XMOVE(0x400); } break; case 40: // she jumps off the island { o->state = 41; o->frame = 9; o->yinertia = -0x400; } break; /*default: NX_ERR("-- Sue entered unhandled state %d (0x%02x)\n", o->state, o->state); exit(1);*/ } o->yinertia += 0x40; LIMITX(0x400); LIMITY(0x5ff); }
// doctor as npc before fight void ai_doctor_crowned(Object *o) { switch(o->state) { case 0: { // do this manually instead of a spawn point, // cause he's gonna transform. o->x -= (8 << CSF); o->y -= (16 << CSF); o->state = 1; crystal_xmark = crystal_ymark = 0; crystal_tofront = true; } case 1: // faces away { o->frame = 0; } break; case 10: // goes "ho ho ho" (while still facing away) { o->frame = 0; o->animtimer = 0; o->timer = 0; o->state = 11; } case 11: { ANIMATE(5, 0, 1); // he has to show shrug frame exactly 6 times. // ANIMATE(5) changes frame on every 6th tick // so this is 6*6*nframes(2) = 72 if (++o->timer >= 72) o->state = 1; } break; case 20: // turns around (faces screen instead of away) { o->state = 21; o->frame = 2; } break; case 40: // arm up--presents red crystal { o->state = 41; // spawn the red crystal // one is for when it's behind him, the other is in front. int x = o->x - (6 << CSF); int y = o->y - (8 << CSF); dr_create_red_crystal(x, y); } case 41: { o->frame = 4; } break; case 50: // "ho ho ho" (while facing player) { o->frame = 4; o->animtimer = 0; o->timer = 0; o->state = 51; } case 51: { ANIMATE(5, 4, 5); if (++o->timer >= 72) o->state = 41; } break; } }