From dc3759db5ec2d6bf1d5fd7f6f882925c26569954 Mon Sep 17 00:00:00 2001 From: escape209 Date: Mon, 30 Sep 2024 06:22:53 +0100 Subject: [PATCH] zNPCTypeRobot AnimTable stuff --- src/SB/Game/zNPCTypeRobot.cpp | 842 +++++++++++++++++++++++++++++++++- src/SB/Game/zNPCTypeRobot.h | 41 ++ 2 files changed, 882 insertions(+), 1 deletion(-) diff --git a/src/SB/Game/zNPCTypeRobot.cpp b/src/SB/Game/zNPCTypeRobot.cpp index f92fff55..fa8499f5 100644 --- a/src/SB/Game/zNPCTypeRobot.cpp +++ b/src/SB/Game/zNPCTypeRobot.cpp @@ -1,10 +1,14 @@ #include "zNPCTypeRobot.h" +#include "zNPCSupplement.h" #include "zNPCGoalRobo.h" #include "zNPCTypes.h" #include "zNPCGoalStd.h" #include "xFactory.h" +#include "xMath.h" + +#include "xAnim.h" #include #include "zGlobals.h" @@ -17,11 +21,94 @@ extern S32 g_needuvincr_bzzt; extern S32 g_needuvincr_nightlight; extern S32 g_needuvincr_slickshield; extern S32 cnt_alerthokey__11zNPCFodBzzt; + extern NPCSndTrax g_sndTrax_Robot[2]; extern NPCSndTrax g_sndTrax_Fodder; +extern NPCSndTrax g_sndTrax_FodBomb[6]; +extern NPCSndTrax g_sndTrax_FodBzzt[3]; +extern NPCSndTrax g_sndTrax_Chomper[4]; +extern NPCSndTrax g_sndTrax_Hammer[3]; +extern NPCSndTrax g_sndTrax_TarTar[4]; + +extern NPCSndTrax g_sndTrax_Monsoon[]; +extern NPCSndTrax g_sndTrax_Sleepy[]; +extern NPCSndTrax g_sndTrax_ArfArf[]; +extern NPCSndTrax g_sndTrax_ArfDog[]; +extern NPCSndTrax g_sndTrax_Chuck[]; +extern NPCSndTrax g_sndTrax_Tubelet[]; +extern NPCSndTrax g_sndTrax_Slick[]; +extern NPCSndTrax g_sndTrax_Glove[]; + extern F32 zNPCRobot_f_0_0; extern F32 zNPCRobot_f_1_0; +S32 rast_blink; // zNPCFodBomb + +char* g_strz_roboanim[41] = +{ + "Unknown", + "Idle01", + "Fidget01", + "Move01", + "Notice01", + "Taunt01", + "Respawn01", + "LassoGrab01", + "LassoHold01", + "StunBegin01", + "StunLoop01", + "EndTag_Standard", + "AlertIdle01", + "AlertMove01", + "Attack01", + "Attack02", + "Attack03", + "AttackBegin01", + "AttackLoop01", + "AttackEnd01", + "HurtKnock01", + "HurtSmash01", + "HurtBash01", + "LassoYank01", + "PatPickup01", + "PatCarry01", + "PatThrowBegin01", + "PatThrowLoop01", + "Sleep01", + "TeleportBegin01", + "TeleportLoop01", + "TeleportEnd01", + "Launch01", + "LaunchEnd01", + "DanceBegin01", + "DanceLoop01", + "DanceEnd01", + "Death01", + "Death02", + "DodgeBBowl01", + "DodgeBCruise01" +}; + +char* g_strz_nytlytanim[2] = +{ + "Unknown", + "Light_Idle01" +}; + +char* g_strz_shieldanim[2] = +{ + "Unknown", + "Shield_Idle01" +}; + +char* g_strz_ttsanim[2] = +{ + "Unknown", + "TarTar_Slosh01" +}; + +extern char stringBase[]; + void zNPCRobot_Timestep(F32 dt); void zNPCSleepy_Timestep(F32 dt); void zNPCFodBzzt_DoTheHokeyPokey(F32 dt); @@ -237,6 +324,197 @@ void zNPCRobot::Init(xEntAsset* asset) this->flags1.flg_basenpc |= 8; } +void zNPCHammer::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_vuln |= 0x60000000; + idx_neckBone = -1; +} + +void zNPCFodder::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_move |= 0x10; + flg_vuln &= 0x9effffff; + idx_neckBone = 3; +} + +void zNPCArfArf::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_move |= 2; + flg_vuln &= ~0x60000000; + idx_neckBone = -1; +} + +void zNPCCritter::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_vuln = 0; + idx_neckBone = -1; +} + +void zNPCFodBomb::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_move |= 0x10; + flg_vuln &= 0x9effffff; + idx_neckBone = 3; + rast_blink = 0; +} + +void zNPCSleepy::ParseINI() +{ + static F32 rad_minimum; + + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Sleepy[0]; + NPCS_SndTablePrepare(&g_sndTrax_Sleepy[0]); + // Scheduling issue with init. + if (init == 0) + { + rad_minimum = 5.0f; + init = 1; + } + float fVar1 = cfg_npc->rad_detect; + cfg_npc->rad_detect = MAX(rad_minimum, fVar1); +} + +void zNPCMonsoon::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Monsoon[0]; + NPCS_SndTablePrepare(&g_sndTrax_Monsoon[0]); +} + +void zNPCSlick::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Slick[0]; + NPCS_SndTablePrepare(&g_sndTrax_Slick[0]); +} + +void zNPCChuck::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Chuck[0]; + NPCS_SndTablePrepare(&g_sndTrax_Chuck[0]); +} + +void zNPCTubeSlave::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Tubelet[0]; + NPCS_SndTablePrepare(&g_sndTrax_Tubelet[0]); +} + +void zNPCTubelet::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Tubelet[0]; + NPCS_SndTablePrepare(&g_sndTrax_Tubelet[0]); +} + +void zNPCArfDog::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_ArfDog[0]; + NPCS_SndTablePrepare(&g_sndTrax_ArfDog[0]); +} + +void zNPCArfArf::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_ArfArf[0]; + NPCS_SndTablePrepare(&g_sndTrax_ArfArf[0]); +} + +void zNPCTarTar::ParseINI() +{ + zNPCRobot::ParseINI(); + cfg_npc->snd_trax = &g_sndTrax_TarTar[0]; + NPCS_SndTablePrepare(&g_sndTrax_TarTar[0]); +} + +void zNPCGlove::ParseINI() +{ + NPCConfig* cfg = cfg_npc; + zNPCRobot::ParseINI(); + cfg->snd_trax = &g_sndTrax_Glove[0]; + NPCS_SndTablePrepare(&g_sndTrax_Glove[0]); +} + +void zNPCHammer::ParseINI() +{ + zNPCRobot::ParseINI(); + cfg_npc->snd_trax = &g_sndTrax_Hammer[0]; + NPCS_SndTablePrepare(&g_sndTrax_Hammer[0]); +} + +void zNPCChomper::ParseINI() +{ + zNPCRobot::ParseINI(); + cfg_npc->snd_trax = &g_sndTrax_Chomper[0]; + NPCS_SndTablePrepare(&g_sndTrax_Chomper[0]); +} + +void zNPCFodBomb::ParseINI() +{ + zNPCRobot::ParseINI(); + cfg_npc->snd_trax = &g_sndTrax_FodBomb[0]; + NPCS_SndTablePrepare(&g_sndTrax_FodBomb[0]); +} + +void zNPCFodBzzt::ParseINI() +{ + zNPCRobot::ParseINI(); + cfg_npc->snd_trax = &g_sndTrax_FodBzzt[0]; + NPCS_SndTablePrepare(&g_sndTrax_FodBzzt[0]); +} + +void zNPCArfDog::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_move |= 2; + flg_vuln &= 0x9effffff; + idx_neckBone = -1; + rast_blink = 0; +} + +void zNPCGlove::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_vuln = -1; + idx_neckBone = -1; + NPAR_PartySetup(NPAR_TYP_GLOVEDUST, 0, 0); +} + +void zNPCChuck::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_move &= 0xfffffffd; + flg_move |= 4; + flg_vuln &= 0x9fffffff; + idx_neckBone = -1; + NPAR_PartySetup(NPAR_TYP_CHUCKSPLASH, 0, 0); +} + +void zNPCTarTar::Init(xEntAsset* asset) +{ + zNPCRobot::Init(asset); + flg_vuln &= 0x9fffffff; + idx_neckBone = -1; + NPAR_PartySetup(NPAR_TYP_TARTARGUNK, 0, 0); +} + void zNPCRobot::Reset() { NPCConfig* conf = cfg_npc; @@ -491,8 +769,570 @@ void zNPCFodder::LassoModelIndex(S32* idxgrab, S32* idxhold) *idxhold = -1; } -S32 xEntIsEnabled(xEnt* ent) +void ZNPC_AnimTable_RobotBase(xAnimTable*); + +void ZNPC_AnimTable_RobotBase(xAnimTable* table) +{ + int ourAnims[17] = + { + 0x01, + 0x03, + 0x02, + 0x04, + 0x05, + 0x07, + 0x08, + 0x17, + 0x09, + 0x0a, + 0x14, + 0x16, + 0x15, + 0x25, + 0x26, + 0x06, + 0x00 + }; + + xAnimTableNewState(table, g_strz_roboanim[0x01], 0x110, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x03], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x02], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x04], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x05], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + xAnimTableNewState(table, g_strz_roboanim[0x14], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x16], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x15], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + xAnimTableNewState(table, g_strz_roboanim[0x25], 0x00, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x26], 0x00, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + xAnimTableNewState(table, g_strz_roboanim[0x06], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x07], 0x020, 0x2000000, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x08], 0x010, 0x2000000, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + xAnimTableNewState(table, g_strz_roboanim[0x17], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + xAnimTableNewState(table, g_strz_roboanim[0x09], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_roboanim[0x0a], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(table, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(table, g_strz_roboanim[0x07], g_strz_roboanim[0x08], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(table, g_strz_roboanim[0x09], g_strz_roboanim[0x0a], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(table, g_strz_roboanim[0x14], g_strz_roboanim[0x25], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(table, g_strz_roboanim[0x16], g_strz_roboanim[0x25], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(table, g_strz_roboanim[0x15], g_strz_roboanim[0x25], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + +} + +xAnimTable* ZNPC_AnimTable_Fodder() +{ + int ourAnims[16] = + { + 0x01, + 0x03, + 0x02, + 0x04, + 0x05, + 0x22, + 0x23, + 0x24, + 0x0e, + 0x14, + 0x16, + 0x15, + 0x25, + 0x26, + 0x06, + 0x00 + }; + + xAnimTable *pxVar1 = (xAnimTable *)xAnimTableNew(stringBase + 0x221, NULL, 0); // "zNPCFodder" + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x01], 0x110, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x03], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x02], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x04], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x05], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x22], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x23], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x24], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x14], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x16], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x15], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x25], 0x000, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x26], 0x000, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x06], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x14], g_strz_roboanim[0x25], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x16], g_strz_roboanim[0x25], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x15], g_strz_roboanim[0x25], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x22], g_strz_roboanim[0x23], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_Hammer() +{ + int ourAnims[6] = + { + 0x0e, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x00, + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x22c, NULL, 0); // "zNPCHammer" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x18], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x19], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1a], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1b], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x18], g_strz_roboanim[0x19], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x1a], g_strz_roboanim[0x1b], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_TarTar() +{ + int ourAnims[4] = + { + 0x0c, + 0x11, + 0x0e, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x237, NULL, 0); // "zNPCTarTar" + ZNPC_AnimTable_RobotBase(pxVar1); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0c], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x11], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x11], g_strz_roboanim[0x0e], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x0e], g_strz_roboanim[0x0c], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x04], g_strz_roboanim[0x0c], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_TTSauce() +{ + int ourAnims[6] = + { + 0x0e, + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x00, + }; + + xAnimTable *pxVar1 = (xAnimTable *)xAnimTableNew(stringBase + 0x242, NULL, 0); // "TarTarSauce" + + xAnimTableNewState(pxVar1, g_strz_ttsanim[1], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_GLove() +{ + int ourAnims[8] = + { + 0x18, + 0x19, + 0x1a, + 0x1b, + 0x11, + 0x12, + 0x13, + 0x00, + }; + + xAnimTable *pxVar1 = (xAnimTable *)xAnimTableNew(stringBase + 0x24e, NULL, 0); // "zNPCGlove" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x11], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x12], 0x10, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x13], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x18], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x19], 0x10, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1a], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1b], 0x10, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x1a], g_strz_roboanim[0x1b], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x11], g_strz_roboanim[0x12], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x18], g_strz_roboanim[0x19], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_Monsoon() +{ + int ourAnims[5] = + { + 0x0c, + 0x0d, + 0x11, + 0x12, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x258, NULL, 0); // "zNPCMonsoon" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0c], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0d], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x11], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x12], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x11], g_strz_roboanim[0x12], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_ThunderCloud() +{ + int ourAnims[3] = + { + 0x01, + 0x02, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x264, NULL, 0); // "ThunderCloud" + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x01], 0x010, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x02], 0x010, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_NightLight() +{ + int ourAnims[2] = + { + 0x01, + 0x00 + }; + + xAnimTable* pxVar1 = xAnimTableNew(stringBase + 0x271, NULL, 0); // "NightLight" + + xAnimTableNewState(pxVar1, g_strz_nytlytanim[1], 0x010, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_nytlytanim, ourAnims, 1, 0.2f); + + return pxVar1; +} + +// Regalloc +xAnimTable* ZNPC_AnimTable_SleepyTime() +{ + int ourAnims[3] = + { + 0x0c, + 0x0e, + 0x00 + }; + + xAnimTable* pxVar1 = xAnimTableNew(stringBase + 0x27c, NULL, 0); // "zNPCSleepy" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0c], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_ArfDog() +{ + int ourAnims[17] = + { + 0x01, + 0x03, + 0x02, + 0x04, + 0x05, + 0x20, + 0x21, + 0x0c, + 0x0d, + 0x12, + 0x14, + 0x16, + 0x15, + 0x25, + 0x26, + 0x06, + 0x00 + }; + + xAnimTable *pxVar1 = (xAnimTable *)xAnimTableNew(stringBase + 0x287, NULL, 0); // "zNPCArfDog" + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x01], 0x110, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x03], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x02], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x04], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x05], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x20], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x21], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0c], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0d], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x12], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x14], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x16], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x15], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x25], 0x000, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x26], 0x000, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x06], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_ArfArf() +{ + int ourAnims[7] = + { + 0x0e, + 0x0f, + 0x10, + 0x1d, + 0x1e, + 0x1f, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x292, NULL, 0); // "zNPCArfArf" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0f], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x10], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1d], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1e], 0x00, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x1f], 0x20, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x1d], g_strz_roboanim[0x1e], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_Chuck() +{ + int ourAnims[4] = + { + 0x0c, + 0x0d, + 0x0e, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x29d, NULL, 0); // "zNPCChuck" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0c], 0x110, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0d], 0x110, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x0e], g_strz_roboanim[0x0c], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x04], g_strz_roboanim[0x0c], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x04], g_strz_roboanim[0x0c], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +// Regalloc +xAnimTable* ZNPC_AnimTable_Tubelet() +{ + int ourAnims[2] = + { + 0x0e, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x2a7, NULL, 0); // "zNPCTubelet" + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x0e], 0x10, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + return pxVar1; +} + +char* g_strz_flotanim[2]; + +xAnimTable* ZNPC_AnimTable_FloatDevice() +{ + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x2b3, NULL, 0); // "FloatDevice" + xAnimTableNewState(pxVar1, g_strz_flotanim[0x01], 0x10, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_SlickShield() +{ + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x2c6, NULL, 0); // "SlickBubbleShield" + xAnimTableNewState(pxVar1, g_strz_shieldanim[0x01], 0x10, 1, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + return pxVar1; +} + +xAnimTable* ZNPC_AnimTable_Slick() +{ + int ourAnims[4] = + { + 0x11, + 0x12, + 0x13, + 0x00 + }; + + xAnimTable *pxVar1 = xAnimTableNew(stringBase + 0x2d8, NULL, 0); // "zNPCSlick" + + ZNPC_AnimTable_RobotBase(pxVar1); + + xAnimTableNewState(pxVar1, g_strz_roboanim[0x11], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x12], 0x010, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(pxVar1, g_strz_roboanim[0x13], 0x020, 0, 1.0f, NULL, NULL, 0.0f, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + + NPCC_BuildStandardAnimTran(pxVar1, g_strz_roboanim, ourAnims, 1, 0.2f); + + xAnimTableNewTransition(pxVar1, g_strz_roboanim[0x11], g_strz_roboanim[0x12], NULL, NULL, 0x10, 0, 0.0f, 0.0f, 0, 0, 0.2f, NULL); + + return pxVar1; +} + +#if 0 +// Would work if IsDying() returned bool. +// Some code relies on IsDying() returning S32, though. +// e.g. zNPCRobot::NewTime +bool zNPCTubelet::IsDying() +{ + return tubestat == TUBE_STAT_DEAD; +} +#endif + +void zNPCTubelet::Reset() +{ + tubestat = TUBE_STAT_BORN; + zNPCRobot::Reset(); + NPCConfig* cfg = cfg_npc; + hitpoints = cfg->pts_damage; + ModelAtomicHide(0, NULL); + ModelAtomicHide(1, NULL); + ModelAtomicHide(4, NULL); +} + +void zNPCFodBzzt::Reset() +{ + zNPCRobot::Reset(); +} + +void zNPCMonsoon::Reset() +{ + zNPCRobot::Reset(); +} + +void zNPCArfDog::Reset() +{ + zNPCRobot::Reset(); + BlinkReset(); +} + +void zNPCSlick::Reset() +{ + zNPCRobot::Reset(); + tmr_repairShield = 0.0f; + tmr_invuln = 0.0f; + alf_shieldDesired = 0.0f; + alf_shieldCurrent = 0.0f; + rad_shield = 0.0f; +} + +void zNPCChuck::Reset() +{ + zNPCRobot::Reset(); + xModelInstance* minst = ModelAtomicHide(1, NULL); + if (minst != NULL) + { + minst->Flags &= 0xfffe; + } +} + +void zNPCArfArf::Reset() +{ + zNPCRobot::Reset(); + for (int i = 0; i < sizeof(flg_puppy) / sizeof(S32); i++) + { + flg_puppy[i] = 1; + } +} + +void zNPCTubeSlave::Reset() +{ + zNPCRobot::Reset(); + flags |= 0x40; + zNPCTubeSlave::WeGotAGig(); +} + +U32 g_hash_roboanim[41]; + +U32 zNPCSleepy::AnimPick(int gid, en_NPC_GOAL_SPOT gspot, xGoal* rawgoal) +{ + U32 uVar1 = 0; + int iVar2 = -1; + + switch (gid) + { + case 'NGR4': + iVar2 = 0xc; + break; + case 'NGR=': + iVar2 = 0xe; + break; + default: + uVar1 = zNPCRobot::AnimPick(gid, gspot, rawgoal); + break; + } + + if (iVar2 >= 0) + { + uVar1 = g_hash_roboanim[iVar2]; + } + + return uVar1; +} + +S32 xEntIsEnabled(xEnt* ent) { return xBaseIsEnabled((xBase*)ent) & 0xff; } diff --git a/src/SB/Game/zNPCTypeRobot.h b/src/SB/Game/zNPCTypeRobot.h index 66582c69..29851848 100644 --- a/src/SB/Game/zNPCTypeRobot.h +++ b/src/SB/Game/zNPCTypeRobot.h @@ -161,6 +161,7 @@ struct zNPCFodder : zNPCRobot void Init(xEntAsset* asset); zNPCLassoInfo* PRIV_GetLassoData(); void LassoModelIndex(S32* idxgrab, S32* idxhold); + void Reset(); }; struct zNPCFodBomb : zNPCRobot @@ -169,6 +170,9 @@ struct zNPCFodBomb : zNPCRobot zNPCFodBomb(S32 myType); zNPCLassoInfo* PRIV_GetLassoData(); + void Reset(); + void Init(xEntAsset*); + void ParseINI(); }; struct zNPCFodBzzt : zNPCRobot @@ -182,7 +186,9 @@ struct zNPCFodBzzt : zNPCRobot zNPCFodBzzt(S32 myType); zNPCLassoInfo* PRIV_GetLassoData(); + void Reset(); void DiscoReset(); + void ParseINI(); }; struct zNPCChomper : zNPCRobot @@ -192,37 +198,53 @@ struct zNPCChomper : zNPCRobot zNPCChomper(S32 myType); zNPCLassoInfo* PRIV_GetLassoData(); + void Reset(); + void ParseINI(); }; struct zNPCCritter : zNPCRobot { zNPCCritter(S32 myType); zNPCLassoInfo* PRIV_GetLassoData(); + void Reset(); + void Init(xEntAsset*); }; struct zNPCHammer : zNPCRobot { zNPCHammer(S32 myType); + void Init(xEntAsset*); + void Reset(); + void ParseINI(); }; struct zNPCTarTar : zNPCRobot { zNPCTarTar(S32 myType); + void Reset(); + void Init(xEntAsset*); + void ParseINI(); }; struct zNPCGlove : zNPCRobot { zNPCGlove(S32 myType); + void Init(xEntAsset*); + void ParseINI(); }; struct zNPCMonsoon : zNPCRobot { zNPCMonsoon(S32 myType); U8 FoulWeather(float); + void Reset(); + void ParseINI(); }; struct zNPCSleepy : zNPCRobot { + static S8 init; + S32 flg_sleepy; NPCHazard* haz_patriot; F32 tmr_nextPatriot; @@ -232,6 +254,9 @@ struct zNPCSleepy : zNPCRobot F32 cnt_grpzeez; zNPCSleepy(S32 myType); + void Reset(); + void ParseINI(); + U32 AnimPick(int, en_NPC_GOAL_SPOT, xGoal*); }; struct zNPCArfDog : zNPCRobot @@ -241,6 +266,10 @@ struct zNPCArfDog : zNPCRobot zNPCArfDog(S32 myType); zNPCLassoInfo* PRIV_GetLassoData(); + void Reset(); + void BlinkReset(); + void Init(xEntAsset*); + void ParseINI(); }; struct zNPCArfArf : zNPCRobot @@ -250,6 +279,9 @@ struct zNPCArfArf : zNPCRobot zNPCArfArf(S32 myType); zMovePoint* GetTelepoint(S32 unk); + void Reset(); + void Init(xEntAsset* asset); + void ParseINI(); }; struct zNPCChuck : zNPCRobot @@ -313,6 +345,9 @@ struct zNPCChuck : zNPCRobot IsDying(); // 0xD0 zNPCRobot LassoModelIndex(int*, int*); // 0xD4 zNPCChuck */ + void Reset(); + void Init(xEntAsset*); + void ParseINI(); }; enum en_tubestat @@ -350,6 +385,9 @@ struct zNPCTubelet : zNPCRobot TubeNotice psynote; zNPCTubelet(S32 myType); + void ParseINI(); + void Reset(); + S32 IsDying(); }; enum en_tubespot @@ -375,6 +413,9 @@ struct zNPCTubeSlave : zNPCRobot U8 ColPenFlags() const; U8 ColChkFlags() const; S32 CanRope(); + void Reset(); + void WeGotAGig(); + void ParseINI(); }; struct zNPCSlick : zNPCRobot