From 96acfa6a9ab3a93f0b09b1fb80899607d0a4d698 Mon Sep 17 00:00:00 2001 From: bluisblu <53455507+bluisblu@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:38:16 -0500 Subject: [PATCH 1/2] zNPCTypeDuplotron work --- src/SB/Core/x/xBehaveMgr.cpp | 35 +- src/SB/Core/x/xBehaviour.h | 12 +- src/SB/Game/zNPCTypeDuplotron.cpp | 562 +++++++++++++++++++++++++++--- src/SB/Game/zNPCTypeDuplotron.h | 18 +- 4 files changed, 550 insertions(+), 77 deletions(-) diff --git a/src/SB/Core/x/xBehaveMgr.cpp b/src/SB/Core/x/xBehaveMgr.cpp index d79691971..7e38c0ea9 100644 --- a/src/SB/Core/x/xBehaveMgr.cpp +++ b/src/SB/Core/x/xBehaveMgr.cpp @@ -243,21 +243,20 @@ S32 xPsyche::GoalPopToBase(S32 overpend) if (this->flg_psyche & 4) { return 0; - } - else if (this->staktop < 1) + } + else if (this->staktop < 1) { return 0; } - else - { - xPsyche::GoalPop(this->goalstak[0]->GetID(), overpend); + else + { + xPsyche::GoalPop(this->goalstak[0]->GetID(), overpend); if ((this->pendtype != PEND_TRAN_NONE) && ((this->flg_psyche & 1))) { this->ForceTran(0.01f, NULL); - } return 1; - } + } } xGoal* xPsyche::GetCurGoal() const @@ -296,12 +295,12 @@ S32 xPsyche::GIDOfPending() const } } -xGoal* xPsyche::GetPrevRecovery(S32 gid) +xGoal* xPsyche::GetPrevRecovery(S32 gid) const { S32 idx_start = -1; S32 i; xGoal* recgoal = NULL; - xGoal* tmpgoal = NULL; + xGoal* tmpgoal = NULL; if (gid == 0) { @@ -311,7 +310,7 @@ xGoal* xPsyche::GetPrevRecovery(S32 gid) if (tmpgoal->GetFlags() & 8) { recgoal = tmpgoal; - break; + break; } } } @@ -333,7 +332,7 @@ xGoal* xPsyche::GetPrevRecovery(S32 gid) if (tmpgoal->GetFlags() & 8) { recgoal = tmpgoal; - break; + break; } } } @@ -355,7 +354,7 @@ F32 xPsyche::TimerGet(en_xpsytime tymr) { return -1.0f; } - return *(&this->tmr_stack[0][this->staktop] + tymr); // ...what? + return *(&this->tmr_stack[0][this->staktop] + tymr); // ...what? } void xPsyche::TimerClear() @@ -364,8 +363,8 @@ void xPsyche::TimerClear() { return; } - // Missing unreachable branch here. Otherwise functionally identical. - this->tmr_stack[0][this->staktop] = 0.0f; + // Missing unreachable branch here. Otherwise functionally identical. + this->tmr_stack[0][this->staktop] = 0.0f; } void xPsyche::TimerUpdate(F32 dt) @@ -373,9 +372,9 @@ void xPsyche::TimerUpdate(F32 dt) F32* p; if (this->staktop < 0) { - return; + return; } - p = &this->tmr_stack[0][this->staktop]; - *p += dt; -} \ No newline at end of file + p = &this->tmr_stack[0][this->staktop]; + *p += dt; +} diff --git a/src/SB/Core/x/xBehaviour.h b/src/SB/Core/x/xBehaviour.h index 7a5dc5fc9..eb0999b25 100644 --- a/src/SB/Core/x/xBehaviour.h +++ b/src/SB/Core/x/xBehaviour.h @@ -116,7 +116,7 @@ struct xPsyche : RyzMemData { return gid_safegoal; } - xGoal* GetPrevRecovery(S32 gid); + xGoal* GetPrevRecovery(S32 gid) const; S32 Timestep(F32 dt, void* updCtxt); xGoal* FindGoal(S32 gid); S32 GoalSet(S32 gid, S32 r5); @@ -132,15 +132,15 @@ struct xPsyche : RyzMemData void BrainExtend(); void BrainEnd(); xGoal* AddGoal(S32 gid, void* createData); - void ForceTran(F32, void*); + void ForceTran(F32, void*); void FreshWipe(); - F32 TimerGet(en_xpsytime tymr); - void TimerClear(); - void SetTopState(en_GOALSTATE); + F32 TimerGet(en_xpsytime tymr); + void TimerClear(); + void SetTopState(en_GOALSTATE); void SetOwner(xBase*, void*); void KillBrain(xFactory*); void Lobotomy(xFactory*); - void TimerUpdate(F32 dt); + void TimerUpdate(F32 dt); void SetSafety(S32 goalID) { gid_safegoal = goalID; diff --git a/src/SB/Game/zNPCTypeDuplotron.cpp b/src/SB/Game/zNPCTypeDuplotron.cpp index 4d4b6f232..d298918d0 100644 --- a/src/SB/Game/zNPCTypeDuplotron.cpp +++ b/src/SB/Game/zNPCTypeDuplotron.cpp @@ -1,27 +1,44 @@ #include "zNPCTypeDuplotron.h" +#include "rwplcore.h" +#include "xEvent.h" +#include "xFactory.h" +#include "xGroup.h" +#include "xMathInlines.h" +#include "zBase.h" +#include "zGlobals.h" +#include "zMovePoint.h" +#include "zNPCGoalCommon.h" +#include "zNPCGoals.h" +#include "zNPCSpawner.h" +#include "zNPCSupport.h" #include "zNPCTypeCommon.h" #include "zNPCTypes.h" #include "xMath3.h" #include "xstransvc.h" - -#define ANIM_Unk1 1 -#define ANIM_Unk2 2 -#define ANIM_Unk3 3 // TEMP NAMES -#define ANIM_Unk4 4 -#define ANIM_UNKNOWN 5 - -extern U32 g_hash_dupoanim[5]; -extern char* g_strz_dupoanim[5]; - -extern zParEmitter* g_pemit_smoky; -extern zParEmitter* g_pemit_steam; -extern zParEmitter* g_pemit_overheat; -extern xParEmitterCustomSettings g_parf_smoky; -extern xParEmitterCustomSettings g_parf_steam; -extern xParEmitterCustomSettings g_parf_overheat; - -extern char* zNPCTypeDuplotron_strings[]; +#include "zScene.h" + +#define ANIM_Unknown 0 +#define ANIM_Idle01 1 +#define ANIM_Spawn01 2 +#define ANIM_Shiver01 3 +#define ANIM_Hurt01 4 + +extern U32 g_hash_dupoanim[5] = {}; +extern char* g_strz_dupoanim[5] = { "Unknown", "Idle01", "Spawn01", "Shiver01", "Hurt01" }; +static zParEmitter* g_pemit_smoky; +static zParEmitter* g_pemit_steam; +static zParEmitter* g_pemit_overheat; +RwRaster* zNPCDuplotron::rast_blinky = NULL; +static xParEmitterCustomSettings g_parf_smoky; +static xParEmitterCustomSettings g_parf_steam; +static xParEmitterCustomSettings g_parf_overheat; + +void __deadstripped_zNPCTypeDuplotron() +{ + // Also exists in NPCBlinker::Render + static RxObjSpace3DVertex blink_vtxbuf[2][14]; +} void ZNPC_Duplotron_Startup() { @@ -35,10 +52,6 @@ void ZNPC_Duplotron_Shutdown() { } -void ZNPC_Duplotron_ScenePrepare() -{ -} - void zNPCDuplotron_SceneFinish() { DUPO_KillEffects(); @@ -81,64 +94,350 @@ void ZNPC_Destroy_Duplotron(xFactoryInst* inst) xAnimTable* ZNPC_AnimTable_Duplotron() { - S32 ourAnims[5] = { //Literally no clue what the names should be. - ANIM_Unk1, ANIM_Unk2, ANIM_Unk3, ANIM_Unk4, ANIM_UNKNOWN - }; - xAnimTable* table = xAnimTableNew("zNPCDupltron", NULL, 0); - xAnimTableNewState(table, g_strz_dupoanim[ANIM_Unk1], 0x10, 0, 1, NULL, NULL, 0, NULL, NULL, - xAnimDefaultBeforeEnter, NULL, NULL); - xAnimTableNewState(table, g_strz_dupoanim[ANIM_Unk2], 0x20, 0, 1, NULL, NULL, 0, NULL, - NULL, //Needs a bit of attention - xAnimDefaultBeforeEnter, NULL, - NULL); //Only pushing cus im done with it for now - xAnimTableNewState(table, g_strz_dupoanim[ANIM_Unk3], 0x10, 0, 1, NULL, NULL, 0, NULL, NULL, - xAnimDefaultBeforeEnter, NULL, NULL); - xAnimTableNewState(table, g_strz_dupoanim[ANIM_Unk4], 0, 0, 1, NULL, NULL, 0, NULL, NULL, - xAnimDefaultBeforeEnter, NULL, NULL); - - NPCC_BuildStandardAnimTran(table, g_strz_dupoanim, ourAnims, 1, 0.2); + S32 ourAnims[5] = { ANIM_Idle01, ANIM_Spawn01, ANIM_Shiver01, ANIM_Hurt01, ANIM_Unknown }; + + // clang-format off + xAnimTableNewState(table, g_strz_dupoanim[ANIM_Idle01], 0x10, 0, 1, NULL, NULL, 0, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_dupoanim[ANIM_Spawn01], 0x20, 0, 1, NULL, NULL, 0, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_dupoanim[ANIM_Shiver01], 0x10, 0, 1, NULL, NULL, 0, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + xAnimTableNewState(table, g_strz_dupoanim[ANIM_Hurt01], 0, 0, 1, NULL, NULL, 0, NULL, NULL, xAnimDefaultBeforeEnter, NULL, NULL); + // clang-format on + + NPCC_BuildStandardAnimTran(table, g_strz_dupoanim, ourAnims, 1, 0.2f); return table; } +void zNPCDuplotron::Init(xEntAsset* asset) +{ + zNPCCommon::Init(asset); + this->flg_move = 1; + this->flg_vuln = -0xfff9; + this->flg_vuln &= ~0x60000000; + this->flg_vuln &= ~0x1000000; + this->rast_blinky = NULL; + return; +} + +void zNPCDuplotron::Setup() +{ + RwTexture* tmp_txtr; + en_SM_WAVE_MODE wm; + + this->spawner = zNPCSpawner_GetInstance(); + if (this->spawner != NULL) + { + this->spawner->Subscribe(this); + } + zNPCCommon::Setup(); + if (this->spawner != NULL) + { + switch (this->npcset.duploWaveMode) + { + case NPCP_DUPOWAVE_DISCREET: + wm = SM_WAVE_DISCREET; + break; + + case NPCP_DUPOWAVE_CONTINUOUS: + default: + wm = SM_WAVE_CONTINUOUS; + break; + } + + this->spawner->SetWaveMode(wm, this->npcset.duploSpawnDelay, + this->npcset.duploSpawnLifeMax); + } + this->cfg_npc->snd_trax = g_sndTrax_Duplotron; + NPCS_SndTablePrepare(g_sndTrax_Duplotron); + if ((this->rast_blinky == NULL) && + (tmp_txtr = NPCC_FindRWTexture("fx_duplotron_lamp"), tmp_txtr != NULL)) + { + this->rast_blinky = tmp_txtr->raster; + } + return; +} + void zNPCDuplotron::ParseINI() { zNPCCommon::ParseINI(); } +void zNPCDuplotron::Reset() +{ + zNPCCommon::Reset(); + if (this->spawner != NULL) + { + this->spawner->Reset(); + } + this->flags |= 0x40; + this->psy_instinct->GoalSet(NPC_GOAL_DUPLOLIVE, 1); + return; +} + +void zNPCDuplotron::ParseLinks() +{ + zNPCCommon::ParseLinks(); + + if (this->spawner != NULL) + { + for (S32 i = 0; i < this->linkCount; i++) + { + xLinkAsset* link = &this->link[i]; + + if (link->dstEvent == eEventConnectToChild) + { + xSceneID2Name(globals.sceneCur, this->id); + xSceneID2Name(globals.sceneCur, link->dstAssetID); + + xBase* mychild = zSceneFindObject(link->dstAssetID); + if (mychild != NULL) + { + this->ParseChild(mychild); + } + } + } + } + + return; +} + void zNPCDuplotron::BUpdate(xVec3* pos) { zNPCCommon::BUpdate(pos); } -// 100% match that needs the full vtable to be filled out -// because it induces vtable generation +void zNPCDuplotron::ParseChild(xBase* child) +{ + S32 i; + + switch (child->baseType) + { + case eBaseTypeMovePoint: + this->spawner->AddSpawnPoint((zMovePoint*)child); + break; + case eBaseTypeNPC: + this->spawner->AddSpawnNPC((zNPCCommon*)child); + break; + case eBaseTypeGroup: + { + xGroup* grp = (xGroup*)child; + S32 cnt = xGroupGetCount(grp); + for (i = 0; i < cnt; i++) + { + xBase* grpitem = xGroupGetItemPtr(grp, i); + if (grpitem != NULL) + { + U8 grpitemType = grpitem->baseType; + if (grpitemType == eBaseTypeMovePoint) + { + this->spawner->AddSpawnPoint((zMovePoint*)grpitem); + } + else if (grpitemType == eBaseTypeNPC) + { + this->spawner->AddSpawnNPC((zNPCCommon*)grpitem); + } + else if (grpitemType == eBaseTypeGroup) + { + this->ParseChild(grpitem); + } + } + } + break; + } + + default: + xSceneID2Name(globals.sceneCur, child->id); + break; + } + + return; +} + +void zNPCDuplotron::Process(xScene* xscn, F32 dt) +{ + xPsyche* psy; + + if (this->spawner != NULL) + { + this->spawner->Timestep(dt); + } + psy = this->psy_instinct; + if (psy != NULL) + { + psy->Timestep(dt, NULL); + } + zNPCCommon::Process(xscn, dt); + return; +} + void zNPCDuplotron::SelfSetup() { psy_instinct = xBehaveMgr_GetSelf()->Subscribe(this, 0); xPsyche* psy = psy_instinct; psy->BrainBegin(); - psy->AddGoal(0x4E474430, NULL); - psy->AddGoal(0x4E474431, NULL); - psy->AddGoal(0x4E474E37, NULL); + psy->AddGoal(NPC_GOAL_DUPLOLIVE, NULL); + psy->AddGoal(NPC_GOAL_DUPLODEAD, NULL); + psy->AddGoal(NPC_GOAL_LIMBO, NULL); psy->BrainEnd(); - psy->SetSafety(0x4E474430); + psy->SetSafety(NPC_GOAL_DUPLOLIVE); +} + +U32 zNPCDuplotron::AnimPick(S32 gid, en_NPC_GOAL_SPOT gspot, xGoal*) +{ + S32 idx = -1; + U32 animId = ANIM_Unknown; + + switch (gid) + { + case NPC_GOAL_DUPLOLIVE: + if (gspot == NPC_GSPOT_START) + { + idx = ANIM_Idle01; + } + else if (gspot == NPC_GSPOT_RESUME) + { + idx = ANIM_Idle01; + } + else if (gspot == NPC_GSPOT_STARTALT) + { + idx = ANIM_Shiver01; + } + else if (gspot == NPC_GSPOT_ALTA) + { + idx = ANIM_Spawn01; + } + else if (gspot == NPC_GSPOT_ALTB) + { + idx = ANIM_Hurt01; + } + else + { + idx = ANIM_Idle01; + } + break; + case NPC_GOAL_DUPLODEAD: + idx = ANIM_Hurt01; + break; + case NPC_GOAL_LIMBO: + idx = ANIM_Idle01; + break; + default: + idx = ANIM_Idle01; + break; + } + if (idx >= 0) + { + animId = g_hash_dupoanim[idx]; + } + + return animId; +} + +void zNPCDuplotron::DuploNotice(en_SM_NOTICES note, void* data) +{ + if (this->spawner != NULL) + { + this->spawner->Notify(note, data); + } } S32 zNPCDuplotron::IsAlive() { xPsyche* psy = this->psy_instinct; - //psy->GIDOfActive(); - return psy->GIDOfActive(); + return psy->GIDOfActive() != NPC_GOAL_DUPLODEAD; +} + +S32 zNPCDuplotron::NPCMessage(NPCMsg* mail) +{ + S32 handled; + + // From the dwarf but I can't find a way to use it that also matches: + //xPsyche* psy = this->psy_instinct; + + if (this->psy_instinct != NULL) + { + zNPCGoalCommon* curgoal = (zNPCGoalCommon*)(psy_instinct->GetCurGoal()); + if (curgoal != NULL) + { + handled = curgoal->NPCMessage(mail); + } + + if (!handled) + { + zNPCGoalCommon* recgoal = (zNPCGoalCommon*)(psy_instinct->GetPrevRecovery(0)); + if (recgoal && recgoal != curgoal) + { + handled = recgoal->NPCMessage(mail); + } + } + } + + if (!handled) + { + handled = this->DupoHandleMail(mail); + } + + if (!handled) + { + handled = zNPCCommon::NPCMessage(mail); + } + + return handled; +} + +S32 zNPCDuplotron::DupoHandleMail(NPCMsg* mail) +{ + S32 handled = 1; + + switch (mail->msgid) + { + case NPC_MID_SYSEVENT: + switch (mail->sysevent.toEvent) + { + case eEventDuploKillKids: + this->DuploNotice(SM_NOTE_KILLKIDS, NULL); + break; + case eEventDuploPause: + this->DuploNotice(SM_NOTE_DUPPAUSE, NULL); + break; + case eEventDuploResume: + this->DuploNotice(SM_NOTE_DUPRESUME, NULL); + break; + case eEventNPCSetActiveOff: + this->DuploNotice(SM_NOTE_DUPPAUSE, NULL); + handled = 0; + break; + case eEventDuploWaveBegin: + case eEventDuploWaveComplete: + case eEventDuploNPCBorn: + case eEventDuploNPCKilled: + case eEventDuploExpiredMaxNPC: + break; + case eEventNPCSetActiveOn: + handled = 0; + break; + default: + handled = 0; + break; + } + break; + case NPC_MID_DAMAGE: + break; + default: + handled = 0; + break; + } + + return handled; } // non-matching: scheduling? void DUPO_InitEffects() { - g_pemit_smoky = zParEmitterFind(zNPCTypeDuplotron_strings[7]); // "PAREMIT_DUPLO_SMOKE" - g_pemit_steam = zParEmitterFind(zNPCTypeDuplotron_strings[8]); // "PAREMIT_DUPLO_STEAM" - g_pemit_overheat = zParEmitterFind(zNPCTypeDuplotron_strings[9]); // "PAREMIT_DUPLO_OVERHEAT" + g_pemit_smoky = zParEmitterFind("PAREMIT_DUPLO_SMOKE"); + g_pemit_steam = zParEmitterFind("PAREMIT_DUPLO_STEAM"); + g_pemit_overheat = zParEmitterFind("PAREMIT_DUPLO_OVERHEAT"); g_parf_smoky.custom_flags = 0x100; xVec3Copy(&g_parf_smoky.pos, &g_O3); @@ -156,6 +455,171 @@ void DUPO_KillEffects() { } +void zNPCDuplotron::VFXSmokeStack(F32 dt) +{ + static const xVec3 vec_emitOffset = {}; + + NPCC_TmrCycle(&dt, 1.0f, this->tmr_smokeCycle); + + if (this->IsAttackFrame(-1.0f, 0) != 0) + { + F32 ds2_cam = NPCC_ds2_toCam(this->Pos(), 0x0); + if (!(ds2_cam > SQ(25.0f))) + { + // temp var needed for .sdata2 match + F32 s = isin(this->tmr_smokeCycle * 2.0f * PI); + S32 npar = 5.0f * s; + if (0 < npar) + { + xVec3* pos_emit = NULL; + *pos_emit = vec_emitOffset; + xMat3x3RMulVec(pos_emit, (xMat3x3*)this->BoneMat(0xb), pos_emit); + *pos_emit += *(xVec3*)this->BonePos(0xb); + xMat3x3RMulVec(pos_emit, (xMat3x3*)this->BoneMat(0), pos_emit); + *pos_emit += *(xVec3*)this->BonePos(0); + for (S32 i = 0; i < npar; i++) + { + xVec3Copy(&g_parf_smoky.pos, pos_emit); + F32 rand = xurand(); + g_parf_smoky.pos.y += 0.1f; + g_parf_smoky.pos.x += 0.1f * (2.0f * (rand - 0.5f)); + rand = xurand(); + g_parf_smoky.pos.z += 0.1f * (2.0f * (rand - 0.5f)); + xParEmitterEmitCustom(g_pemit_smoky, dt, &g_parf_smoky); + } + } + } + } + return; +} + +void zNPCDuplotron::VFXOverheat(F32 dt, F32) +{ + static S32 idx_steam[2] = { 12, -1 }; + static S32 idx_smoke[4] = { 7, 8, 9, -1 }; + + S32 rc; + xVec3 dir_emit; + xVec3 pos_emit; + + if (xEntIsVisible(this)) + { + if (((this->model)->Flags & 0x400) == 0) + { + static S32 skip = 0; + + if (++skip >= 5) + { + skip = 0; + + for (rc = *idx_smoke; -1 < rc; rc++) + { + if (this->GetVertPos(*(en_mdlvert*)rc, &pos_emit)) + { + xVec3Copy(&g_parf_overheat.pos, &pos_emit); + xVec3Sub(&dir_emit, &pos_emit, xEntGetCenter(this)); + xVec3Normalize(&dir_emit, &dir_emit); + xVec3SMul(&g_parf_overheat.vel, &dir_emit, + xVec3Length(&(g_pemit_overheat->tasset)->vel)); + } + } + + for (rc = *idx_steam; -1 < rc; rc++) + { + if (this->GetVertPos(*(en_mdlvert*)rc, &pos_emit)) + { + xVec3Copy(&g_parf_steam.pos, &pos_emit); + xVec3Sub(&dir_emit, &pos_emit, xEntGetCenter(this)); + xVec3Normalize(&dir_emit, &dir_emit); + xVec3SMul(&g_parf_steam.vel, &dir_emit, + xVec3Length(&(g_pemit_steam->tasset)->vel)); + xParEmitterEmitCustom(g_pemit_steam, dt, &g_parf_steam); + } + } + } + } + } + return; +} + +void zNPCDuplotron::VFXCycleLights(F32 dt, S32 fastpace) +{ + S32 amPaused; + + if (this->tmr_blink < 0.0f) + { + this->idx_blink = this->idx_blink + 1; + if (this->idx_blink >= 5) + { + this->idx_blink = 0; + } + this->tmr_blink = 0.5f; + } + + this->tmr_blink = MAX(-1.0f, this->tmr_blink - dt); + + if (fastpace != 0) + { + this->tmr_blink = MAX(-1.0f, this->tmr_blink - dt); + } + + if (1 < fastpace) + { + this->tmr_blink = MAX(-1.0f, this->tmr_blink - dt); + } + + if ((this->spawner != NULL) && ((this->spawner->flg_spawner & 4) != 0)) + { + amPaused = true; + } + else + { + if (this->spawner == NULL) + { + amPaused = true; + } + else + { + amPaused = false; + } + } + + for (S32 i = 1; i <= 5; i++) + + { + if (amPaused) + { + this->ModelAtomicHide(i, NULL); + } + else if (fastpace > 0) + { + if ((xrand() & 0x800000) != 0) + { + this->ModelAtomicShow(i, NULL); + } + else + { + this->ModelAtomicHide(i, NULL); + } + } + else + { + if (i == this->idx_blink + 1) + { + this->ModelAtomicShow(i, NULL); + } + else + { + this->ModelAtomicHide(i, NULL); + } + } + } + + return; +} + +// .text (68) + zNPCDuplotron::zNPCDuplotron(S32 myType) : zNPCCommon(myType) { } diff --git a/src/SB/Game/zNPCTypeDuplotron.h b/src/SB/Game/zNPCTypeDuplotron.h index a116fd997..35c92cf15 100644 --- a/src/SB/Game/zNPCTypeDuplotron.h +++ b/src/SB/Game/zNPCTypeDuplotron.h @@ -10,17 +10,27 @@ struct zNPCDuplotron : zNPCCommon F32 tmr_blink; S32 idx_blink; + static RwRaster* rast_blinky; + zNPCDuplotron(S32 myType); + void Init(xEntAsset* asset); + void Setup(); + void ParseINI(); + void Reset(); + void ParseLinks(); + void BUpdate(xVec3*); + void ParseChild(xBase* child); + void Process(xScene* xscn, F32 dt); void SelfSetup(); + U32 AnimPick(S32 gid, en_NPC_GOAL_SPOT gspot, xGoal*); + void DuploNotice(en_SM_NOTICES note, void* data); S32 IsAlive(); + S32 NPCMessage(NPCMsg* mail); + S32 DupoHandleMail(NPCMsg* mail); void VFXSmokeStack(F32 dt); void VFXOverheat(F32 dt, F32); void VFXCycleLights(F32 dt, S32 fastpace); - void ParseINI(); - void Reset(); - void BUpdate(xVec3*); - void Process(xScene*, float); // zNPCTypeCommon overrides void Move(xScene*, F32 dt, xEntFrame*); From c9ab1587ad44e7ab2ebeed22d52d35a8ed9e1b06 Mon Sep 17 00:00:00 2001 From: bluisblu <53455507+bluisblu@users.noreply.github.com> Date: Wed, 19 Nov 2025 22:46:32 -0500 Subject: [PATCH 2/2] cleanup --- src/SB/Game/zNPCTypeDuplotron.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/SB/Game/zNPCTypeDuplotron.cpp b/src/SB/Game/zNPCTypeDuplotron.cpp index d298918d0..d36e0cbb3 100644 --- a/src/SB/Game/zNPCTypeDuplotron.cpp +++ b/src/SB/Game/zNPCTypeDuplotron.cpp @@ -1,22 +1,9 @@ -#include "zNPCTypeDuplotron.h" -#include "rwplcore.h" -#include "xEvent.h" -#include "xFactory.h" #include "xGroup.h" #include "xMathInlines.h" -#include "zBase.h" #include "zGlobals.h" -#include "zMovePoint.h" #include "zNPCGoalCommon.h" -#include "zNPCGoals.h" -#include "zNPCSpawner.h" #include "zNPCSupport.h" -#include "zNPCTypeCommon.h" -#include "zNPCTypes.h" -#include "xMath3.h" - -#include "xstransvc.h" -#include "zScene.h" +#include "zNPCTypeDuplotron.h" #define ANIM_Unknown 0 #define ANIM_Idle01 1 @@ -42,7 +29,7 @@ void __deadstripped_zNPCTypeDuplotron() void ZNPC_Duplotron_Startup() { - for (int i = 0; i < 5; i++) + for (S32 i = 0; i < 5; i++) { g_hash_dupoanim[i] = xStrHash(g_strz_dupoanim[i]); } @@ -618,8 +605,6 @@ void zNPCDuplotron::VFXCycleLights(F32 dt, S32 fastpace) return; } -// .text (68) - zNPCDuplotron::zNPCDuplotron(S32 myType) : zNPCCommon(myType) { }