//------------------------------------------------------------------------- /* Copyright (C) 1997, 2005 - 3D Realms Entertainment This file is part of Shadow Warrior version 1.2 Shadow Warrior 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Original Source: 1997 - Frank Maddin and Jim Norwood Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms */ //------------------------------------------------------------------------- #include "ns.h" #include "build.h" #include "names2.h" #include "panel.h" #include "misc.h" #include "tags.h" #include "ai.h" #include "sector.h" #include "sprite.h" BEGIN_SW_NS ANIMATOR NullToiletGirl; ATTRIBUTE ToiletGirlAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 3, // MaxWeapons; { 0, 0, DIGI_TOILETGIRLSCREAM, DIGI_TOILETGIRLPAIN, DIGI_TOILETGIRLSCREAM, 0,0,0,0,0 } }; ////////////////////// // // TOILETGIRL STAND // ////////////////////// #define TOILETGIRL_RATE 60 ANIMATOR NullToiletGirl,DoToiletGirl; STATE s_ToiletGirlStand[2] = { {TOILETGIRL_R0 + 0, TOILETGIRL_RATE, DoToiletGirl, &s_ToiletGirlStand[1]}, {TOILETGIRL_R0 + 1, TOILETGIRL_RATE, DoToiletGirl, &s_ToiletGirlStand[0]} }; ////////////////////// // // TOILETGIRL PAIN // ////////////////////// #define TOILETGIRL_PAIN_RATE 32 #define TOILETGIRL_PAIN_R0 TOILETGIRL_R0 ANIMATOR ToiletGirlPain; STATE s_ToiletGirlPain[2] = { {TOILETGIRL_PAIN_R0 + 0, TOILETGIRL_PAIN_RATE, ToiletGirlPain, &s_ToiletGirlPain[1]}, {TOILETGIRL_PAIN_R0 + 0, 0|SF_QUICK_CALL, InitActorDecide, &s_ToiletGirlPain[0]} }; ////////////////////// // // TOILETGIRL UZI // ////////////////////// #define TOILETGIRL_UZI_RATE 8 #define TOILETGIRL_FIRE_R0 TOILETGIRL_R0 + 2 ANIMATOR InitEnemyUzi,ToiletGirlUzi; STATE s_ToiletGirlUzi[16] = { {TOILETGIRL_FIRE_R0 + 0, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[1]}, {TOILETGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[2]}, {TOILETGIRL_FIRE_R0 + 1, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[3]}, {TOILETGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[4]}, {TOILETGIRL_FIRE_R0 + 0, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[5]}, {TOILETGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[6]}, {TOILETGIRL_FIRE_R0 + 1, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[7]}, {TOILETGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[8]}, {TOILETGIRL_FIRE_R0 + 0, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[9]}, {TOILETGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[10]}, {TOILETGIRL_FIRE_R0 + 1, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[11]}, {TOILETGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[12]}, {TOILETGIRL_FIRE_R0 + 0, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[13]}, {TOILETGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[14]}, {TOILETGIRL_FIRE_R0 + 1, TOILETGIRL_UZI_RATE, ToiletGirlUzi, &s_ToiletGirlUzi[15]}, {TOILETGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_ToiletGirlUzi[0]}, }; int SetupToiletGirl(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,TOILETGIRL_R0,s_ToiletGirlStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_ToiletGirlStand); u->Attrib = &ToiletGirlAttrib; u->StateEnd = s_ToiletGirlStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 38; sp->yrepeat = 32; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = TOILETGIRL_R0; u->FlagOwner = 0; u->ID = TOILETGIRL_R0; RESET(u->Flags, SPR_XFLIP_TOGGLE); return 0; } int DoToiletGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,ActorMid(u->targetActor),u->targetActor->s().sectnum); if (u->FlagOwner != 1) { if (RandomRange(1000) > 980) { short choose_snd; choose_snd = RANDOM_P2(1024<<4)>>4; if (!SoundValidAndActive(sp, CHAN_ToiletFart)) { if (choose_snd > 750) PlaySound(DIGI_TOILETGIRLFART1, sp, v3df_dontpan, CHAN_ToiletFart); else if (choose_snd > 350) PlaySound(DIGI_TOILETGIRLFART2, sp, v3df_dontpan, CHAN_ToiletFart); else PlaySound(DIGI_TOILETGIRLFART3, sp, v3df_dontpan, CHAN_ToiletFart); } } } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RandomRange(1000<<8)>>8 > 500) PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_ToiletGirlUzi); u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } // take damage from environment DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int NullToiletGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,u->targetActor->s().z,u->targetActor->s().sectnum); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RandomRange(1000<<8)>>8 > 500) PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_ToiletGirlUzi); u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } return 0; } int ToiletGirlUzi(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { u->WaitTics = RandomRange(240)+120; ChangeState(actor,s_ToiletGirlStand); u->FlagOwner = 0; } return 0; } int ToiletGirlPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; NullToiletGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_ToiletGirlStand); return 0; } ////////////////////////////////////////////////////////////////////////////////////////////// ANIMATOR NullWashGirl; ATTRIBUTE WashGirlAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 3, // MaxWeapons; { 0, 0, DIGI_TOILETGIRLSCREAM, DIGI_TOILETGIRLPAIN, DIGI_TOILETGIRLSCREAM, 0,0,0,0,0 } }; ////////////////////// // // WASHGIRL STAND // ////////////////////// #define WASHGIRL_RATE 60 ANIMATOR NullWashGirl,DoWashGirl; STATE s_WashGirlStand[2] = { {WASHGIRL_R0 + 0, WASHGIRL_RATE, DoWashGirl, &s_WashGirlStand[1]}, {WASHGIRL_R0 + 1, WASHGIRL_RATE, DoWashGirl, &s_WashGirlStand[0]} }; #define WASHGIRL_RATE2 20 STATE s_WashGirlStandScrub[2] = { {WASHGIRL_R0 + 0, WASHGIRL_RATE2, DoWashGirl, &s_WashGirlStandScrub[1]}, {WASHGIRL_R0 + 1, WASHGIRL_RATE2, DoWashGirl, &s_WashGirlStandScrub[0]} }; ////////////////////// // // WASHGIRL PAIN // ////////////////////// #define WASHGIRL_PAIN_RATE 30 #define WASHGIRL_PAIN_R0 WASHGIRL_R0 ANIMATOR WashGirlPain; STATE s_WashGirlPain[2] = { {WASHGIRL_PAIN_R0 + 0, WASHGIRL_PAIN_RATE, WashGirlPain, &s_WashGirlPain[1]}, {WASHGIRL_PAIN_R0 + 0, 0|SF_QUICK_CALL, InitActorDecide, &s_WashGirlPain[0]} }; ////////////////////// // // WASHGIRL UZI // ////////////////////// #define WASHGIRL_UZI_RATE 8 #define WASHGIRL_FIRE_R0 WASHGIRL_R0 + 2 ANIMATOR InitEnemyUzi,WashGirlUzi; STATE s_WashGirlUzi[16] = { {WASHGIRL_FIRE_R0 + 0, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[1]}, {WASHGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[2]}, {WASHGIRL_FIRE_R0 + 1, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[3]}, {WASHGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[4]}, {WASHGIRL_FIRE_R0 + 0, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[5]}, {WASHGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[6]}, {WASHGIRL_FIRE_R0 + 1, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[7]}, {WASHGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[8]}, {WASHGIRL_FIRE_R0 + 0, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[9]}, {WASHGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[10]}, {WASHGIRL_FIRE_R0 + 1, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[11]}, {WASHGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[12]}, {WASHGIRL_FIRE_R0 + 0, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[13]}, {WASHGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[14]}, {WASHGIRL_FIRE_R0 + 1, WASHGIRL_UZI_RATE, WashGirlUzi, &s_WashGirlUzi[15]}, {WASHGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_WashGirlUzi[0]}, }; int SetupWashGirl(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,WASHGIRL_R0,s_WashGirlStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_WashGirlStand); u->Attrib = &WashGirlAttrib; u->StateEnd = s_WashGirlStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 28; sp->yrepeat = 24; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = WASHGIRL_R0; u->FlagOwner = 0; u->ID = WASHGIRL_R0; RESET(u->Flags, SPR_XFLIP_TOGGLE); return 0; } int DoWashGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,ActorMid(u->targetActor),u->targetActor->s().sectnum); if (RandomRange(1000) > 980 && u->ShellNum <= 0) { if (!SoundValidAndActive(sp, CHAN_AnimeSing)) { if (RANDOM_P2(1024<<4)>>4 > 500) PlaySound(DIGI_ANIMESING1, sp, v3df_dontpan, CHAN_AnimeSing); else PlaySound(DIGI_ANIMESING2, sp, v3df_dontpan, CHAN_AnimeSing); } ChangeState(actor,s_WashGirlStandScrub); u->ShellNum = RandomRange(2*120)+240; } else { if (u->ShellNum > 0) { if ((u->ShellNum -= ACTORMOVETICS) < 0) { ChangeState(actor,s_WashGirlStand); u->ShellNum = 0; } } } if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RandomRange(1000<<8)>>8 > 500) PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_WashGirlUzi); u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } // take damage from environment DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int NullWashGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,u->targetActor->s().z,u->targetActor->s().sectnum); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { if (RandomRange(1000<<8)>>8 > 500) PlaySound(DIGI_ANIMEMAD1, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_ANIMEMAD2, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_WashGirlUzi); u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } return 0; } int WashGirlUzi(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { u->WaitTics = RandomRange(240)+120; ChangeState(actor,s_WashGirlStand); u->FlagOwner = 0; } return 0; } int WashGirlPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; NullWashGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_WashGirlStand); return 0; } ////////////////////////////////////////////////////////////////////////////////////////////// ATTRIBUTE TrashCanAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 0, // MaxWeapons; {0, 0, DIGI_TRASHLID, DIGI_TRASHLID, 0, 0,0,0,0,0} }; ////////////////////// // // TRASHCAN STAND // ////////////////////// #define TRASHCAN_RATE 120 #define TRASHCAN_R0 TRASHCAN ANIMATOR NullTrashCan,DoTrashCan; STATE s_TrashCanStand[1] = { {TRASHCAN_R0 + 0, TRASHCAN_RATE, DoTrashCan, &s_TrashCanStand[0]} }; ////////////////////// // // TRASHCAN PAIN // ////////////////////// #define TRASHCAN_PAIN_RATE 8 #define TRASHCAN_PAIN_R0 TRASHCAN ANIMATOR TrashCanPain, TrashCanStand; STATE s_TrashCanPain[7] = { {TRASHCAN_PAIN_R0 + 0, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[1]}, {TRASHCAN_PAIN_R0 + 1, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[2]}, {TRASHCAN_PAIN_R0 + 2, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[3]}, {TRASHCAN_PAIN_R0 + 3, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[4]}, {TRASHCAN_PAIN_R0 + 4, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[5]}, {TRASHCAN_PAIN_R0 + 5, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[6]}, {TRASHCAN_PAIN_R0 + 6, TRASHCAN_PAIN_RATE, TrashCanPain, &s_TrashCanPain[0]} }; int SetupTrashCan(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,TRASHCAN,s_TrashCanStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_TrashCanStand); u->Attrib = &TrashCanAttrib; u->StateEnd = s_TrashCanStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 46; sp->yrepeat = 42; sp->xvel = sp->yvel = sp->zvel = 0; u->ID = TRASHCAN; RESET(u->Flags, SPR_XFLIP_TOGGLE); RESET(sp->extra, SPRX_PLAYER_OR_ENEMY); return 0; } int DoTrashCan(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (TEST(u->Flags,SPR_SLIDING)) DoActorSlide(actor); if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int TrashCanPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (TEST(u->Flags,SPR_SLIDING)) DoActorSlide(actor); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_TrashCanStand); return 0; } ////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // PACHINKO WIN LIGHT //////////////////////////////////////////////////////////////////// ATTRIBUTE PachinkoLightAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 0, // MaxWeapons; {0, 0, DIGI_TRASHLID, DIGI_TRASHLID, 0, 0,0,0,0,0} }; #define PACHINKOLIGHT_RATE 120 #define PACHINKOLIGHT_R0 623 STATE s_PachinkoLightStand[] = { {PACHINKOLIGHT_R0 + 0, PACHINKOLIGHT_RATE, NullAnimator, &s_PachinkoLightStand[0]} }; ANIMATOR PachinkoLightOperate; STATE s_PachinkoLightOperate[] = { {PACHINKOLIGHT_R0 - 0, 12, PachinkoLightOperate, &s_PachinkoLightOperate[1]}, {PACHINKOLIGHT_R0 - 1, 12, PachinkoLightOperate, &s_PachinkoLightOperate[2]}, {PACHINKOLIGHT_R0 - 2, 12, PachinkoLightOperate, &s_PachinkoLightOperate[3]}, {PACHINKOLIGHT_R0 - 3, 12, PachinkoLightOperate, &s_PachinkoLightOperate[4]}, {PACHINKOLIGHT_R0 - 4, 12, PachinkoLightOperate, &s_PachinkoLightOperate[5]}, {PACHINKOLIGHT_R0 - 5, 12, PachinkoLightOperate, &s_PachinkoLightOperate[0]}, }; int SetupPachinkoLight(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,PACHINKOLIGHT_R0,s_PachinkoLightStand); u->Health = 1; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_PachinkoLightStand); u->Attrib = &PachinkoLightAttrib; u->StateEnd = s_PachinkoLightStand; u->Rot = 0; u->RotNum = 0; u->ID = PACHINKOLIGHT_R0; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = TAG_PACHINKOLIGHT; sp->shade = -2; u->spal = sp->pal; RESET(u->Flags, SPR_XFLIP_TOGGLE); RESET(sp->extra, SPRX_PLAYER_OR_ENEMY); return 0; } int PachinkoLightOperate(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; if ((u->WaitTics -= ACTORMOVETICS) <= 0) { sp->shade = -2; ChangeState(actor,s_PachinkoLightStand); } return 0; } //////////////////////////////////////////////////////////////////// // PACHINKO MACHINE #1 //////////////////////////////////////////////////////////////////// CVAR(Bool, Pachinko_Win_Cheat, false, 0) ATTRIBUTE Pachinko1Attrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 0, // MaxWeapons; {0, 0, DIGI_TRASHLID, DIGI_TRASHLID, 0, 0,0,0,0,0} }; #define PACHINKO1_RATE 120 #define PACHINKO1_R0 PACHINKO1 STATE s_Pachinko1Stand[] = { {PACHINKO1_R0 + 0, PACHINKO1_RATE, NullAnimator, &s_Pachinko1Stand[0]} }; ANIMATOR Pachinko1Operate,PachinkoCheckWin; STATE s_Pachinko1Operate[] = { {PACHINKO1_R0 + 0, 12, Pachinko1Operate, &s_Pachinko1Operate[1]}, {PACHINKO1_R0 + 1, 12, Pachinko1Operate, &s_Pachinko1Operate[2]}, {PACHINKO1_R0 + 2, 12, Pachinko1Operate, &s_Pachinko1Operate[3]}, {PACHINKO1_R0 + 3, 12, Pachinko1Operate, &s_Pachinko1Operate[4]}, {PACHINKO1_R0 + 4, 12, Pachinko1Operate, &s_Pachinko1Operate[5]}, {PACHINKO1_R0 + 5, 12, Pachinko1Operate, &s_Pachinko1Operate[6]}, {PACHINKO1_R0 + 6, 12, Pachinko1Operate, &s_Pachinko1Operate[7]}, {PACHINKO1_R0 + 7, 12, Pachinko1Operate, &s_Pachinko1Operate[8]}, {PACHINKO1_R0 + 8, 12, Pachinko1Operate, &s_Pachinko1Operate[9]}, {PACHINKO1_R0 + 9, 12, Pachinko1Operate, &s_Pachinko1Operate[10]}, {PACHINKO1_R0 + 10, 12, Pachinko1Operate, &s_Pachinko1Operate[11]}, {PACHINKO1_R0 + 11, 12, Pachinko1Operate, &s_Pachinko1Operate[12]}, {PACHINKO1_R0 + 12, 12, Pachinko1Operate, &s_Pachinko1Operate[13]}, {PACHINKO1_R0 + 13, 12, Pachinko1Operate, &s_Pachinko1Operate[14]}, {PACHINKO1_R0 + 14, 12, Pachinko1Operate, &s_Pachinko1Operate[15]}, {PACHINKO1_R0 + 15, 12, Pachinko1Operate, &s_Pachinko1Operate[16]}, {PACHINKO1_R0 + 16, 12, Pachinko1Operate, &s_Pachinko1Operate[17]}, {PACHINKO1_R0 + 17, 12, Pachinko1Operate, &s_Pachinko1Operate[18]}, {PACHINKO1_R0 + 18, 12, Pachinko1Operate, &s_Pachinko1Operate[19]}, {PACHINKO1_R0 + 19, 12, Pachinko1Operate, &s_Pachinko1Operate[20]}, {PACHINKO1_R0 + 20, 12, Pachinko1Operate, &s_Pachinko1Operate[21]}, {PACHINKO1_R0 + 21, 12, Pachinko1Operate, &s_Pachinko1Operate[22]}, {PACHINKO1_R0 + 22, SF_QUICK_CALL, PachinkoCheckWin, &s_Pachinko1Stand[0]} }; int SetupPachinko1(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,PACHINKO1,s_Pachinko1Stand); u->Health = 1; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_Pachinko1Stand); u->Attrib = &Pachinko1Attrib; u->StateEnd = s_Pachinko1Stand; u->Rot = 0; u->RotNum = 0; u->ID = PACHINKO1; sp->yvel = sp->zvel = 0; sp->lotag = PACHINKO1; RESET(u->Flags, SPR_XFLIP_TOGGLE); RESET(sp->extra, SPRX_PLAYER_OR_ENEMY); return 0; } int PachinkoCheckWin(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = &sprite[SpriteNum]; u->WaitTics = 0; // Can operate it again now //Printf("bool1 = %d",TEST_BOOL1(sp)); // You already won, no more from this machine! if (TEST_BOOL1(sp)) return 0; // Well? Did I win????! /*short rnd = */RandomRange(1000); if (RandomRange(1000) > 900 || Pachinko_Win_Cheat) { int i; SPRITEp tsp; USERp tu; // Do a possible combo switch if (ComboSwitchTest(TAG_COMBO_SWITCH_EVERYTHING, sp->hitag)) { DoMatchEverything(Player+myconnectindex, sp->hitag, ON); } ActorCoughItem(SpriteNum); // I WON! I WON! PlaySound(DIGI_PALARM, sp, v3df_none); // Can't win any more now! SET_BOOL1(sp); // Turn on the pachinko lights StatIterator it(STAT_ENEMY); while ((i = it.NextIndex()) >= 0) { tsp = &sprite[i]; tu = User[i].Data(); if (tsp->lotag == TAG_PACHINKOLIGHT) { if (tsp->hitag == SP_TAG5(sp)) { tsp->shade = -90; // Full brightness tu->WaitTics = SEC(3); // Flash ChangeSpriteState(i,s_PachinkoLightOperate); } } } } //{ //if(rnd > 950) // PlayerSound(DIGI_SHISEISI, pp, v3df_follow|v3df_dontpan,pp); //else //if(rnd > 900) // PlayerSound(DIGI_YOULOOKSTUPID, pp, v3df_follow|v3df_dontpan,pp); //else //if(rnd > 850) // PlayerSound(DIGI_HURTBAD5, pp, v3df_follow|v3df_dontpan,pp); //} return 0; } int Pachinko1Operate(DSWActor* actor) { USER* u = actor->u(); SPRITEp sp = u->s(); short rnd; rnd = RandomRange(1000); if (rnd > 900) { rnd = RandomRange(1000); // TEMP SOUNDS: Need pachinko sounds! if (rnd > 700) PlaySound(DIGI_PROLL1, sp, v3df_none); else if (rnd > 400) PlaySound(DIGI_PROLL2, sp, v3df_none); else PlaySound(DIGI_PROLL3, sp, v3df_none); } return 0; } //////////////////////////////////////////////////////////////////// // PACHINKO MACHINE #2 //////////////////////////////////////////////////////////////////// ATTRIBUTE Pachinko2Attrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 0, // MaxWeapons; {0, 0, DIGI_TRASHLID, DIGI_TRASHLID, 0, 0,0,0,0,0} }; #define PACHINKO2_RATE 120 #define PACHINKO2_R0 PACHINKO2 STATE s_Pachinko2Stand[] = { {PACHINKO2_R0 + 0, PACHINKO2_RATE, NullAnimator, &s_Pachinko2Stand[0]} }; ANIMATOR Pachinko2Operate; STATE s_Pachinko2Operate[] = { {PACHINKO2_R0 + 0, 12, Pachinko1Operate, &s_Pachinko2Operate[1]}, {PACHINKO2_R0 + 1, 12, Pachinko1Operate, &s_Pachinko2Operate[2]}, {PACHINKO2_R0 + 2, 12, Pachinko1Operate, &s_Pachinko2Operate[3]}, {PACHINKO2_R0 + 3, 12, Pachinko1Operate, &s_Pachinko2Operate[4]}, {PACHINKO2_R0 + 4, 12, Pachinko1Operate, &s_Pachinko2Operate[5]}, {PACHINKO2_R0 + 5, 12, Pachinko1Operate, &s_Pachinko2Operate[6]}, {PACHINKO2_R0 + 6, 12, Pachinko1Operate, &s_Pachinko2Operate[7]}, {PACHINKO2_R0 + 7, 12, Pachinko1Operate, &s_Pachinko2Operate[8]}, {PACHINKO2_R0 + 8, 12, Pachinko1Operate, &s_Pachinko2Operate[9]}, {PACHINKO2_R0 + 9, 12, Pachinko1Operate, &s_Pachinko2Operate[10]}, {PACHINKO2_R0 + 10, 12, Pachinko1Operate, &s_Pachinko2Operate[11]}, {PACHINKO2_R0 + 11, 12, Pachinko1Operate, &s_Pachinko2Operate[12]}, {PACHINKO2_R0 + 12, 12, Pachinko1Operate, &s_Pachinko2Operate[13]}, {PACHINKO2_R0 + 13, 12, Pachinko1Operate, &s_Pachinko2Operate[14]}, {PACHINKO2_R0 + 14, 12, Pachinko1Operate, &s_Pachinko2Operate[15]}, {PACHINKO2_R0 + 15, 12, Pachinko1Operate, &s_Pachinko2Operate[16]}, {PACHINKO2_R0 + 16, 12, Pachinko1Operate, &s_Pachinko2Operate[17]}, {PACHINKO2_R0 + 17, 12, Pachinko1Operate, &s_Pachinko2Operate[18]}, {PACHINKO2_R0 + 18, 12, Pachinko1Operate, &s_Pachinko2Operate[19]}, {PACHINKO2_R0 + 19, 12, Pachinko1Operate, &s_Pachinko2Operate[20]}, {PACHINKO2_R0 + 20, 12, Pachinko1Operate, &s_Pachinko2Operate[21]}, {PACHINKO2_R0 + 21, 12, Pachinko1Operate, &s_Pachinko2Operate[22]}, {PACHINKO2_R0 + 22, SF_QUICK_CALL, PachinkoCheckWin, &s_Pachinko2Stand[0]} }; int SetupPachinko2(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,PACHINKO2,s_Pachinko2Stand); u->Health = 1; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_Pachinko2Stand); u->Attrib = &Pachinko2Attrib; u->StateEnd = s_Pachinko2Stand; u->Rot = 0; u->RotNum = 0; u->ID = PACHINKO2; sp->yvel = sp->zvel = 0; sp->lotag = PACHINKO2; RESET(u->Flags, SPR_XFLIP_TOGGLE); RESET(sp->extra, SPRX_PLAYER_OR_ENEMY); return 0; } //////////////////////////////////////////////////////////////////// // PACHINKO MACHINE #3 //////////////////////////////////////////////////////////////////// ATTRIBUTE Pachinko3Attrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 0, // MaxWeapons; {0, 0, DIGI_TRASHLID, DIGI_TRASHLID, 0, 0,0,0,0,0} }; #define PACHINKO3_RATE 120 #define PACHINKO3_R0 PACHINKO3 STATE s_Pachinko3Stand[] = { {PACHINKO3_R0 + 0, PACHINKO3_RATE, NullAnimator, &s_Pachinko3Stand[0]} }; ANIMATOR Pachinko3Operate; STATE s_Pachinko3Operate[] = { {PACHINKO3_R0 + 0, 12, Pachinko1Operate, &s_Pachinko3Operate[1]}, {PACHINKO3_R0 + 1, 12, Pachinko1Operate, &s_Pachinko3Operate[2]}, {PACHINKO3_R0 + 2, 12, Pachinko1Operate, &s_Pachinko3Operate[3]}, {PACHINKO3_R0 + 3, 12, Pachinko1Operate, &s_Pachinko3Operate[4]}, {PACHINKO3_R0 + 4, 12, Pachinko1Operate, &s_Pachinko3Operate[5]}, {PACHINKO3_R0 + 5, 12, Pachinko1Operate, &s_Pachinko3Operate[6]}, {PACHINKO3_R0 + 6, 12, Pachinko1Operate, &s_Pachinko3Operate[7]}, {PACHINKO3_R0 + 7, 12, Pachinko1Operate, &s_Pachinko3Operate[8]}, {PACHINKO3_R0 + 8, 12, Pachinko1Operate, &s_Pachinko3Operate[9]}, {PACHINKO3_R0 + 9, 12, Pachinko1Operate, &s_Pachinko3Operate[10]}, {PACHINKO3_R0 + 10, 12, Pachinko1Operate, &s_Pachinko3Operate[11]}, {PACHINKO3_R0 + 11, 12, Pachinko1Operate, &s_Pachinko3Operate[12]}, {PACHINKO3_R0 + 12, 12, Pachinko1Operate, &s_Pachinko3Operate[13]}, {PACHINKO3_R0 + 13, 12, Pachinko1Operate, &s_Pachinko3Operate[14]}, {PACHINKO3_R0 + 14, 12, Pachinko1Operate, &s_Pachinko3Operate[15]}, {PACHINKO3_R0 + 15, 12, Pachinko1Operate, &s_Pachinko3Operate[16]}, {PACHINKO3_R0 + 16, 12, Pachinko1Operate, &s_Pachinko3Operate[17]}, {PACHINKO3_R0 + 17, 12, Pachinko1Operate, &s_Pachinko3Operate[18]}, {PACHINKO3_R0 + 18, 12, Pachinko1Operate, &s_Pachinko3Operate[19]}, {PACHINKO3_R0 + 19, 12, Pachinko1Operate, &s_Pachinko3Operate[20]}, {PACHINKO3_R0 + 20, 12, Pachinko1Operate, &s_Pachinko3Operate[21]}, {PACHINKO3_R0 + 21, 12, Pachinko1Operate, &s_Pachinko3Operate[22]}, {PACHINKO3_R0 + 22, SF_QUICK_CALL, PachinkoCheckWin, &s_Pachinko3Stand[0]} }; int SetupPachinko3(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,PACHINKO3,s_Pachinko3Stand); u->Health = 1; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_Pachinko3Stand); u->Attrib = &Pachinko3Attrib; u->StateEnd = s_Pachinko3Stand; u->Rot = 0; u->RotNum = 0; u->ID = PACHINKO3; sp->yvel = sp->zvel = 0; sp->lotag = PACHINKO3; RESET(u->Flags, SPR_XFLIP_TOGGLE); RESET(sp->extra, SPRX_PLAYER_OR_ENEMY); return 0; } //////////////////////////////////////////////////////////////////// // PACHINKO MACHINE #4 //////////////////////////////////////////////////////////////////// ATTRIBUTE Pachinko4Attrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 0, // MaxWeapons; {0, 0, DIGI_TRASHLID, DIGI_TRASHLID, 0, 0,0,0,0,0} }; #define PACHINKO4_RATE 120 #define PACHINKO4_R0 PACHINKO4 STATE s_Pachinko4Stand[] = { {PACHINKO4_R0 + 0, PACHINKO4_RATE, NullAnimator, &s_Pachinko4Stand[0]} }; ANIMATOR Pachinko4Operate; STATE s_Pachinko4Operate[] = { {PACHINKO4_R0 + 0, 12, Pachinko1Operate, &s_Pachinko4Operate[1]}, {PACHINKO4_R0 + 1, 12, Pachinko1Operate, &s_Pachinko4Operate[2]}, {PACHINKO4_R0 + 2, 12, Pachinko1Operate, &s_Pachinko4Operate[3]}, {PACHINKO4_R0 + 3, 12, Pachinko1Operate, &s_Pachinko4Operate[4]}, {PACHINKO4_R0 + 4, 12, Pachinko1Operate, &s_Pachinko4Operate[5]}, {PACHINKO4_R0 + 5, 12, Pachinko1Operate, &s_Pachinko4Operate[6]}, {PACHINKO4_R0 + 6, 12, Pachinko1Operate, &s_Pachinko4Operate[7]}, {PACHINKO4_R0 + 7, 12, Pachinko1Operate, &s_Pachinko4Operate[8]}, {PACHINKO4_R0 + 8, 12, Pachinko1Operate, &s_Pachinko4Operate[9]}, {PACHINKO4_R0 + 9, 12, Pachinko1Operate, &s_Pachinko4Operate[10]}, {PACHINKO4_R0 + 10, 12, Pachinko1Operate, &s_Pachinko4Operate[11]}, {PACHINKO4_R0 + 11, 12, Pachinko1Operate, &s_Pachinko4Operate[12]}, {PACHINKO4_R0 + 12, 12, Pachinko1Operate, &s_Pachinko4Operate[13]}, {PACHINKO4_R0 + 13, 12, Pachinko1Operate, &s_Pachinko4Operate[14]}, {PACHINKO4_R0 + 14, 12, Pachinko1Operate, &s_Pachinko4Operate[15]}, {PACHINKO4_R0 + 15, 12, Pachinko1Operate, &s_Pachinko4Operate[16]}, {PACHINKO4_R0 + 16, 12, Pachinko1Operate, &s_Pachinko4Operate[17]}, {PACHINKO4_R0 + 17, 12, Pachinko1Operate, &s_Pachinko4Operate[18]}, {PACHINKO4_R0 + 18, 12, Pachinko1Operate, &s_Pachinko4Operate[19]}, {PACHINKO4_R0 + 19, 12, Pachinko1Operate, &s_Pachinko4Operate[20]}, {PACHINKO4_R0 + 20, 12, Pachinko1Operate, &s_Pachinko4Operate[21]}, {PACHINKO4_R0 + 21, 12, Pachinko1Operate, &s_Pachinko4Operate[22]}, {PACHINKO4_R0 + 22, SF_QUICK_CALL, PachinkoCheckWin, &s_Pachinko4Stand[0]} }; int SetupPachinko4(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,PACHINKO4,s_Pachinko4Stand); u->Health = 1; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_Pachinko4Stand); u->Attrib = &Pachinko4Attrib; u->StateEnd = s_Pachinko4Stand; u->Rot = 0; u->RotNum = 0; u->ID = PACHINKO4; sp->yvel = sp->zvel = 0; sp->lotag = PACHINKO4; RESET(u->Flags, SPR_XFLIP_TOGGLE); RESET(sp->extra, SPRX_PLAYER_OR_ENEMY); return 0; } //////////////////////////////////////////////////////////////////////////////// ANIMATOR NullCarGirl; ATTRIBUTE CarGirlAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 3, // MaxWeapons; { 0, 0, DIGI_TOILETGIRLSCREAM, DIGI_TOILETGIRLPAIN, DIGI_TOILETGIRLSCREAM, 0,0,0,0,0 } }; ////////////////////// // // CARGIRL STAND // ////////////////////// #define CARGIRL_RATE 60 ANIMATOR NullCarGirl,DoCarGirl; STATE s_CarGirlStand[2] = { {CARGIRL_R0 + 0, CARGIRL_RATE, DoCarGirl, &s_CarGirlStand[1]}, {CARGIRL_R0 + 1, CARGIRL_RATE, DoCarGirl, &s_CarGirlStand[0]} }; ////////////////////// // // CARGIRL PAIN // ////////////////////// #define CARGIRL_PAIN_RATE 32 #define CARGIRL_PAIN_R0 CARGIRL_R0 ANIMATOR CarGirlPain; STATE s_CarGirlPain[2] = { {CARGIRL_PAIN_R0 + 0, CARGIRL_PAIN_RATE, CarGirlPain, &s_CarGirlPain[1]}, {CARGIRL_PAIN_R0 + 0, 0|SF_QUICK_CALL, InitActorDecide, &s_CarGirlPain[0]} }; ////////////////////// // // CARGIRL UZI // ////////////////////// #define CARGIRL_UZI_RATE 8 #define CARGIRL_FIRE_R0 CARGIRL_R0 + 2 ANIMATOR InitEnemyUzi,CarGirlUzi; STATE s_CarGirlUzi[16] = { {CARGIRL_FIRE_R0 + 0, 240, CarGirlUzi, &s_CarGirlUzi[1]}, {CARGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[2]}, {CARGIRL_FIRE_R0 + 1, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[3]}, {CARGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[4]}, {CARGIRL_FIRE_R0 + 0, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[5]}, {CARGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[6]}, {CARGIRL_FIRE_R0 + 1, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[7]}, {CARGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[8]}, {CARGIRL_FIRE_R0 + 0, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[9]}, {CARGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[10]}, {CARGIRL_FIRE_R0 + 1, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[11]}, {CARGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[12]}, {CARGIRL_FIRE_R0 + 0, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[13]}, {CARGIRL_FIRE_R0 + 0, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[14]}, {CARGIRL_FIRE_R0 + 1, CARGIRL_UZI_RATE, CarGirlUzi, &s_CarGirlUzi[15]}, {CARGIRL_FIRE_R0 + 1, 0 | SF_QUICK_CALL, InitEnemyUzi, &s_CarGirlUzi[0]}, }; int SetupCarGirl(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,CARGIRL_R0,s_CarGirlStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_CarGirlStand); u->Attrib = &CarGirlAttrib; u->StateEnd = s_CarGirlStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 29; sp->yrepeat = 25; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = CARGIRL_R0; u->FlagOwner = 0; u->ID = CARGIRL_R0; RESET(u->Flags, SPR_XFLIP_TOGGLE); SET(sp->cstat, CSTAT_SPRITE_XFLIP); return 0; } int DoCarGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,ActorMid(u->targetActor),u->targetActor->s().sectnum); if (u->FlagOwner == 1) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750) PlaySound(DIGI_LANI049, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) PlaySound(DIGI_LANI051, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI052, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI054, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_CarGirlUzi); u->WaitTics = SEC(3)+SEC(RandomRange(2<<8)>>8); u->FlagOwner = 0; } } //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } // take damage from environment DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int NullCarGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,u->targetActor->s().z,u->targetActor->s().sectnum); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750) PlaySound(DIGI_LANI049, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) PlaySound(DIGI_LANI051, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI052, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI054, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_CarGirlUzi); u->WaitTics = SEC(3)+SEC(RandomRange(2<<8)>>8); u->FlagOwner = 0; } return 0; } int CarGirlUzi(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { u->WaitTics = RandomRange(240)+120; ChangeState(actor,s_CarGirlStand); u->FlagOwner = 0; } return 0; } int CarGirlPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; NullCarGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_CarGirlStand); return 0; } //////////////////////////////////////////////////////////////////////////////// ANIMATOR NullMechanicGirl; ATTRIBUTE MechanicGirlAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 3, // MaxWeapons; { 0, 0, DIGI_TOILETGIRLSCREAM, DIGI_TOILETGIRLPAIN, DIGI_TOILETGIRLSCREAM, 0,0,0,0,0 } }; ////////////////////// // // MECHANICGIRL STAND // ////////////////////// #define MECHANICGIRL_RATE 60 ANIMATOR NullMechanicGirl,DoMechanicGirl; STATE s_MechanicGirlStand[2] = { {MECHANICGIRL_R0 + 0, MECHANICGIRL_RATE, DoMechanicGirl, &s_MechanicGirlStand[1]}, {MECHANICGIRL_R0 + 1, MECHANICGIRL_RATE, DoMechanicGirl, &s_MechanicGirlStand[0]} }; ////////////////////// // // MECHANICGIRL PAIN // ////////////////////// #define MECHANICGIRL_PAIN_RATE 32 #define MECHANICGIRL_PAIN_R0 MECHANICGIRL_R0 ANIMATOR MechanicGirlPain; STATE s_MechanicGirlPain[2] = { {MECHANICGIRL_PAIN_R0 + 0, MECHANICGIRL_PAIN_RATE, MechanicGirlPain, &s_MechanicGirlPain[1]}, {MECHANICGIRL_PAIN_R0 + 0, 0|SF_QUICK_CALL, InitActorDecide, &s_MechanicGirlPain[0]} }; ////////////////////// // // MECHANICGIRL DRILL // ////////////////////// #define MECHANICGIRL_DRILL_RATE 32 #define MECHANICGIRL_DRILL_R0 MECHANICGIRL_R0 + 2 ANIMATOR MechanicGirlDrill; STATE s_MechanicGirlDrill[2] = { {MECHANICGIRL_DRILL_R0 + 0, MECHANICGIRL_DRILL_RATE, MechanicGirlDrill, &s_MechanicGirlDrill[1]}, {MECHANICGIRL_DRILL_R0 + 1, MECHANICGIRL_DRILL_RATE, MechanicGirlDrill, &s_MechanicGirlDrill[0]}, }; int SetupMechanicGirl(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,MECHANICGIRL_R0,s_MechanicGirlStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_MechanicGirlStand); u->Attrib = &MechanicGirlAttrib; u->StateEnd = s_MechanicGirlStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 27; sp->yrepeat = 26; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = MECHANICGIRL_R0; u->FlagOwner = 0; u->ID = MECHANICGIRL_R0; RESET(u->Flags, SPR_XFLIP_TOGGLE); return 0; } int DoMechanicGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,ActorMid(u->targetActor),u->targetActor->s().sectnum); if (u->FlagOwner == 1) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750) PlaySound(DIGI_LANI073, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) PlaySound(DIGI_LANI075, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI077, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI079, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_MechanicGirlDrill); u->WaitTics = SEC(1)+SEC(RandomRange(2<<8)>>8); u->FlagOwner = 0; } } //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } // take damage from environment DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int NullMechanicGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,u->targetActor->s().z,u->targetActor->s().sectnum); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750) PlaySound(DIGI_LANI073, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) PlaySound(DIGI_LANI075, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI077, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI079, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_MechanicGirlDrill); u->WaitTics = SEC(1)+SEC(RandomRange(2<<8)>>8); u->FlagOwner = 0; } return 0; } int MechanicGirlDrill(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { u->WaitTics = RandomRange(240)+120; ChangeState(actor,s_MechanicGirlStand); u->FlagOwner = 0; } return 0; } int MechanicGirlPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; NullMechanicGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_MechanicGirlStand); return 0; } //////////////////////////////////////////////////////////////////////////////// ANIMATOR NullSailorGirl; ATTRIBUTE SailorGirlAttrib = { {0, 0, 0, 0}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 3, // MaxWeapons; { 0, 0, DIGI_TOILETGIRLSCREAM, DIGI_TOILETGIRLPAIN, DIGI_TOILETGIRLSCREAM, 0,0,0,0,0 } }; ////////////////////// // // SAILORGIRL STAND // ////////////////////// #define SAILORGIRL_RATE 60 ANIMATOR NullSailorGirl,DoSailorGirl; STATE s_SailorGirlStand[2] = { {SAILORGIRL_R0 + 0, SAILORGIRL_RATE, DoSailorGirl, &s_SailorGirlStand[1]}, {SAILORGIRL_R0 + 1, SAILORGIRL_RATE, DoSailorGirl, &s_SailorGirlStand[0]} }; ////////////////////// // // SAILORGIRL PAIN // ////////////////////// #define SAILORGIRL_PAIN_RATE 32 #define SAILORGIRL_PAIN_R0 SAILORGIRL_R0 ANIMATOR SailorGirlPain; STATE s_SailorGirlPain[2] = { {SAILORGIRL_PAIN_R0 + 0, SAILORGIRL_PAIN_RATE, SailorGirlPain, &s_SailorGirlPain[1]}, {SAILORGIRL_PAIN_R0 + 0, 0|SF_QUICK_CALL, InitActorDecide, &s_SailorGirlPain[0]} }; ////////////////////// // // SAILORGIRL UZI // ////////////////////// #define SAILORGIRL_UZI_RATE 128 #define SAILORGIRL_FIRE_R0 SAILORGIRL_R0 + 2 ANIMATOR InitEnemyUzi,SailorGirlThrow; STATE s_SailorGirlThrow[] = { {SAILORGIRL_FIRE_R0 + 0, SAILORGIRL_UZI_RATE, SailorGirlThrow, &s_SailorGirlThrow[0]}, }; short alreadythrew; int SetupSailorGirl(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,SAILORGIRL_R0,s_SailorGirlStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_SailorGirlStand); u->Attrib = &SailorGirlAttrib; u->StateEnd = s_SailorGirlStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 28; sp->yrepeat = 26; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = SAILORGIRL_R0; u->FlagOwner = 0; u->ID = SAILORGIRL_R0; RESET(u->Flags, SPR_XFLIP_TOGGLE); alreadythrew = 0; return 0; } int DoSailorGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,ActorMid(u->targetActor),u->targetActor->s().sectnum); if (u->FlagOwner == 1) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750 && alreadythrew < 3) { ActorCoughItem(SpriteNum); alreadythrew++; PlaySound(DIGI_LANI060, sp, v3df_dontpan, CHAN_AnimeMad); } else if (choose > 500) PlaySound(DIGI_LANI063, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI065, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI066, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_SailorGirlThrow); u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } } //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } // take damage from environment DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int NullSailorGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; static short alreadythrew = 0; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,u->targetActor->s().z,u->targetActor->s().sectnum); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750 && alreadythrew < 3) { ActorCoughItem(SpriteNum); alreadythrew++; PlaySound(DIGI_LANI060, sp, v3df_dontpan, CHAN_AnimeMad); } else if (choose > 500) PlaySound(DIGI_LANI063, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI065, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI066, sp, v3df_dontpan, CHAN_AnimeMad); } ChangeState(actor,s_SailorGirlThrow); u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } return 0; } int SailorGirlThrow(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { u->WaitTics = RandomRange(240)+120; ChangeState(actor,s_SailorGirlStand); u->FlagOwner = 0; } return 0; } int SailorGirlPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; NullSailorGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_SailorGirlStand); return 0; } //////////////////////////////////////////////////////////////////////////////// ANIMATOR NullPruneGirl; ATTRIBUTE PruneGirlAttrib = { {450, 450, 450, 450}, // Speeds {0, 0, 0, 0}, // Tic Adjusts 3, // MaxWeapons; //{DIGI_PRUNECACKLE3, DIGI_PRUNECACKLE, DIGI_TOILETGIRLSCREAM, { 0,0, DIGI_TOILETGIRLSCREAM, DIGI_TOILETGIRLPAIN, DIGI_TOILETGIRLSCREAM, 0,0,0,0,0 } }; ////////////////////// // // PRUNEGIRL STAND // ////////////////////// #define PRUNEGIRL_RATE 60 ANIMATOR NullPruneGirl,DoPruneGirl; STATE s_PruneGirlStand[2] = { {PRUNEGIRL_R0 + 0, PRUNEGIRL_RATE, DoPruneGirl, &s_PruneGirlStand[1]}, {PRUNEGIRL_R0 + 1, PRUNEGIRL_RATE, DoPruneGirl, &s_PruneGirlStand[0]} }; ////////////////////// // // PRUNEGIRL PAIN // ////////////////////// #define PRUNEGIRL_PAIN_RATE 32 #define PRUNEGIRL_PAIN_R0 PRUNEGIRL_R0 ANIMATOR PruneGirlPain; STATE s_PruneGirlPain[2] = { {PRUNEGIRL_PAIN_R0 + 0, PRUNEGIRL_PAIN_RATE, PruneGirlPain, &s_PruneGirlPain[1]}, {PRUNEGIRL_PAIN_R0 + 0, 0|SF_QUICK_CALL, InitActorDecide, &s_PruneGirlPain[0]} }; int SetupPruneGirl(short SpriteNum) { auto actor = &swActors[SpriteNum]; SPRITEp sp = &actor->s(); USERp u; ANIMATOR DoActorDecide; if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE)) { u = User[SpriteNum].Data(); ASSERT(u); } else { u = SpawnUser(SpriteNum,PRUNEGIRL_R0,s_PruneGirlStand); u->Health = 60; } EnemyDefaults(SpriteNum, nullptr, nullptr); ChangeState(actor,s_PruneGirlStand); u->Attrib = &PruneGirlAttrib; u->StateEnd = s_PruneGirlStand; u->Rot = 0; u->RotNum = 0; sp->xrepeat = 33; sp->yrepeat = 28; sp->xvel = sp->yvel = sp->zvel = 0; sp->lotag = PRUNEGIRL_R0; u->FlagOwner = 0; u->ID = PRUNEGIRL_R0; RESET(u->Flags, SPR_XFLIP_TOGGLE); return 0; } int DoPruneGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,ActorMid(u->targetActor),u->targetActor->s().sectnum); if (u->FlagOwner == 1) { if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = STD_RANDOM_RANGE(1000); if (choose > 750) PlaySound(DIGI_LANI089, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI093, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI095, sp, v3df_dontpan, CHAN_AnimeMad); } u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } } else { if (!SoundValidAndActive(sp, CHAN_CoyHandle)) { short choose; choose = STD_RANDOM_RANGE(1000); if (choose > 990) PlaySound(DIGI_PRUNECACKLE, sp, v3df_dontpan, CHAN_CoyHandle); else if (choose > 985) PlaySound(DIGI_PRUNECACKLE2, sp, v3df_dontpan, CHAN_CoyHandle); else if (choose > 980) PlaySound(DIGI_PRUNECACKLE3, sp, v3df_dontpan, CHAN_CoyHandle); else if (choose > 975) PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_CoyHandle); } } //(*u->ActorActionFunc) (SpriteNum); // stay on floor unless doing certain things if (!TEST(u->Flags, SPR_JUMPING | SPR_FALLING | SPR_CLIMBING)) { KeepActorOnFloor(actor); } // take damage from environment DoActorSectorDamage(actor); sp->xvel = sp->yvel = sp->zvel = 0; return 0; } int NullPruneGirl(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; SPRITEp sp = User[SpriteNum]->SpriteP; bool ICanSee = false; DoActorPickClosePlayer(actor); ICanSee = FAFcansee(sp->x,sp->y,SPRITEp_MID(sp),sp->sectnum,u->targetActor->s().x,u->targetActor->s().y,u->targetActor->s().z,u->targetActor->s().sectnum); if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if (u->FlagOwner != 1) { } else if ((u->WaitTics -= ACTORMOVETICS) <= 0 && ICanSee) { if (!SoundValidAndActive(sp, CHAN_AnimeMad)) { short choose; choose = RandomRange(1000); if (choose > 750) PlaySound(DIGI_LANI089, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 500) PlaySound(DIGI_LANI091, sp, v3df_dontpan, CHAN_AnimeMad); else if (choose > 250) PlaySound(DIGI_LANI093, sp, v3df_dontpan, CHAN_AnimeMad); else PlaySound(DIGI_LANI095, sp, v3df_dontpan, CHAN_AnimeMad); } u->WaitTics = SEC(1)+SEC(RandomRange(3<<8)>>8); u->FlagOwner = 0; } return 0; } int PruneGirlUzi(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; if (!TEST(u->Flags,SPR_CLIMBING)) KeepActorOnFloor(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) { u->WaitTics = RandomRange(240)+120; ChangeState(actor,s_PruneGirlStand); u->FlagOwner = 0; } return 0; } int PruneGirlPain(DSWActor* actor) { USER* u = actor->u(); int SpriteNum = u->SpriteNum; NullPruneGirl(actor); if ((u->WaitTics -= ACTORMOVETICS) <= 0) ChangeState(actor,s_PruneGirlStand); return 0; } #include "saveable.h" static saveable_code saveable_miscactr_code[] = { SAVE_CODE(DoToiletGirl), SAVE_CODE(NullToiletGirl), SAVE_CODE(ToiletGirlUzi), SAVE_CODE(ToiletGirlPain), SAVE_CODE(DoWashGirl), SAVE_CODE(NullWashGirl), SAVE_CODE(WashGirlUzi), SAVE_CODE(WashGirlPain), SAVE_CODE(DoTrashCan), SAVE_CODE(TrashCanPain), SAVE_CODE(PachinkoLightOperate), SAVE_CODE(PachinkoCheckWin), SAVE_CODE(Pachinko1Operate), SAVE_CODE(DoCarGirl), SAVE_CODE(NullCarGirl), SAVE_CODE(CarGirlUzi), SAVE_CODE(CarGirlPain), SAVE_CODE(DoMechanicGirl), SAVE_CODE(NullMechanicGirl), SAVE_CODE(MechanicGirlDrill), SAVE_CODE(MechanicGirlPain), SAVE_CODE(DoSailorGirl), SAVE_CODE(NullSailorGirl), SAVE_CODE(SailorGirlThrow), SAVE_CODE(SailorGirlPain), SAVE_CODE(DoPruneGirl), SAVE_CODE(NullPruneGirl), SAVE_CODE(PruneGirlUzi), SAVE_CODE(PruneGirlPain), }; static saveable_data saveable_miscactr_data[] = { SAVE_DATA(ToiletGirlAttrib), SAVE_DATA(WashGirlAttrib), SAVE_DATA(TrashCanAttrib), SAVE_DATA(PachinkoLightAttrib), SAVE_DATA(Pachinko1Attrib), SAVE_DATA(Pachinko2Attrib), SAVE_DATA(Pachinko3Attrib), SAVE_DATA(Pachinko4Attrib), SAVE_DATA(CarGirlAttrib), SAVE_DATA(MechanicGirlAttrib), SAVE_DATA(SailorGirlAttrib), SAVE_DATA(PruneGirlAttrib), SAVE_DATA(s_ToiletGirlStand), SAVE_DATA(s_ToiletGirlPain), SAVE_DATA(s_ToiletGirlUzi), SAVE_DATA(s_WashGirlStand), SAVE_DATA(s_WashGirlStandScrub), SAVE_DATA(s_WashGirlPain), SAVE_DATA(s_WashGirlUzi), SAVE_DATA(s_TrashCanStand), SAVE_DATA(s_TrashCanPain), SAVE_DATA(s_PachinkoLightStand), SAVE_DATA(s_PachinkoLightOperate), SAVE_DATA(s_Pachinko1Stand), SAVE_DATA(s_Pachinko1Operate), SAVE_DATA(s_Pachinko2Stand), SAVE_DATA(s_Pachinko2Operate), SAVE_DATA(s_Pachinko3Stand), SAVE_DATA(s_Pachinko3Operate), SAVE_DATA(s_Pachinko4Stand), SAVE_DATA(s_Pachinko4Operate), SAVE_DATA(s_CarGirlStand), SAVE_DATA(s_CarGirlPain), SAVE_DATA(s_CarGirlUzi), SAVE_DATA(s_MechanicGirlStand), SAVE_DATA(s_MechanicGirlPain), SAVE_DATA(s_MechanicGirlDrill), SAVE_DATA(s_SailorGirlStand), SAVE_DATA(s_SailorGirlPain), SAVE_DATA(s_SailorGirlThrow), SAVE_DATA(s_PruneGirlStand), SAVE_DATA(s_PruneGirlPain) }; saveable_module saveable_miscactr = { // code saveable_miscactr_code, SIZ(saveable_miscactr_code), // data saveable_miscactr_data, SIZ(saveable_miscactr_data) }; END_SW_NS