mirror of
https://github.com/bfbbdecomp/bfbb.git
synced 2024-11-27 00:21:00 +00:00
zNPC stuff (#382)
This commit is contained in:
parent
bba9a114d6
commit
ec767cb6ce
@ -26,6 +26,8 @@ struct xBehaveMgr : RyzMemData
|
||||
void operator delete(void*, U16);
|
||||
};
|
||||
|
||||
void xBehaveMgr_ScenePrepare();
|
||||
void xBehaveMgr_SceneReset();
|
||||
void xBehaveMgr_Startup();
|
||||
void xBehaveMgr_Shutdown();
|
||||
xBehaveMgr* xBehaveMgr_GetSelf();
|
||||
|
@ -235,6 +235,123 @@ void zNPCGoalTubeLasso::ChkPrelimTran(en_trantype* trantype, int* nextgoal)
|
||||
}
|
||||
}
|
||||
|
||||
S32 zNPCGoalPatThrow::Enter(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCRobot* npc = (zNPCRobot *)(psyche->clt_owner);
|
||||
NPCGlyph* glyph = npc->glyf_stun;
|
||||
if (glyph != NULL)
|
||||
{
|
||||
glyph->Discard();
|
||||
}
|
||||
npc->glyf_stun = NULL;
|
||||
zNPCGoalCommon::Enter(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalTubeAttack::LaserRender()
|
||||
{
|
||||
zNPCTubeSlave::laser.Render(&paul.pos_laserSource, &paul.pos_laserTarget);
|
||||
}
|
||||
|
||||
void zNPCGoalTubeAttack::MaryzFury()
|
||||
{
|
||||
zNPCTubelet* npc = *(zNPCTubelet **)(&psyche->clt_owner);
|
||||
NPCHazard* haz = HAZ_Acquire();
|
||||
if (haz != NULL)
|
||||
{
|
||||
haz->ConfigHelper(NPC_HAZ_TUBELETBLAST);
|
||||
haz->SetNPCOwner(npc);
|
||||
xVec3* center = xEntGetCenter(npc);
|
||||
haz->Start(center, -1.0f);
|
||||
U32 sndID = xStrHash("Tube_pop");
|
||||
xSndPlay3D(sndID, 0.77f, 0.0f, 0x80, 0, &haz->pos_hazard, 5.0f, 15.0f, SND_CAT_GAME, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
S32 zNPCGoalStunned::Enter(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCRobot* npc = (zNPCRobot *)(psyche->clt_owner);
|
||||
if (!(flg_info & 0x10))
|
||||
{
|
||||
F32 stun = npc->cfg_npc->tym_stun;
|
||||
npc->tmr_stunned = (stun * (0.25f * (xurand() - 0.5f)) + stun);
|
||||
}
|
||||
flg_info = 0;
|
||||
npc->VelStop();
|
||||
zNPCGoalCommon::Enter(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalTubeLasso::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner));
|
||||
|
||||
zNPCGoalTubeDying* tubedie = (zNPCGoalTubeDying*)psyche->FindGoal(0x4e475255);
|
||||
tubedie->DeathByLasso(npc->Pos());
|
||||
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalDeflate::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner));
|
||||
xModelInstance* mdl_wig = npc->ModelAtomicShow(4, NULL);
|
||||
|
||||
mdl_wig->Scale.assign(1.0f);
|
||||
npc->RestoreColFlags();
|
||||
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalTubeDying::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner));
|
||||
xModelInstance* mdl_wig = npc->ModelAtomicFind(4, -1, NULL);
|
||||
|
||||
mdl_wig->Scale.assign(1.0f);
|
||||
npc->RestoreColFlags();
|
||||
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalTeleport::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCRobot* npc = ((zNPCSleepy*)(psyche->clt_owner));
|
||||
|
||||
npc->flg_move |= 2;
|
||||
npc->flg_move &= 0xFFFFFFFB;
|
||||
|
||||
npc->RestoreColFlags();
|
||||
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalTubeBonked::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCSleepy* npc = ((zNPCSleepy*)(psyche->clt_owner));
|
||||
npc->ModelAtomicShow(0, NULL);
|
||||
npc->ModelAtomicHide(1, NULL);
|
||||
npc->ModelAtomicHide(4, NULL);
|
||||
npc->ShowerConfetti(NULL);
|
||||
npc->SndPlayRandom(NPC_STYP_UNBONKED);
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalAlertGlove::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCGlove* npc = ((zNPCGlove*)(psyche->clt_owner));
|
||||
npc->flg_vuln |= 0x00100000;
|
||||
npc->flg_vuln |= 0x82010000;
|
||||
zNPC_SNDStop(eNPCSnd_GloveAttack);
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalAlertSleepy::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCSleepy* npc = ((zNPCSleepy*)(psyche->clt_owner));
|
||||
npc->ModelAtomicHide(1, NULL);
|
||||
zNPC_SNDStop(eNPCSnd_SleepyAttack);
|
||||
xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
void zNPCGoalTubePal::ChkPrelimTran(en_trantype* trantype, int* nextgoal)
|
||||
{
|
||||
zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner));
|
||||
@ -1025,6 +1142,23 @@ S32 NPCArena::IncludesPlayer(F32 rad_thresh, xVec3* vec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
NPCGlyph* GLYF_Acquire(en_npcglyph);
|
||||
|
||||
F32 zNPCGoalEvilPat::GlyphStart()
|
||||
{
|
||||
static xVec3 ang_delta = { DEG2RAD(2.1f), 0.0f, 0.0f };
|
||||
static xVec3 scale = { 0.75f, 0.75f, 0.75f };
|
||||
|
||||
zNPCRobot* robot = (zNPCRobot*)psyche->clt_owner;
|
||||
robot->glyf_stun = GLYF_Acquire(NPC_GLYPH_DAZED);
|
||||
if (robot->glyf_stun != NULL)
|
||||
{
|
||||
robot->glyf_stun->Enable(1);
|
||||
robot->glyf_stun->RotSet(&ang_delta, 0);
|
||||
robot->glyf_stun->ScaleSet(&scale);
|
||||
}
|
||||
}
|
||||
|
||||
S32 NPCArena::IsReady()
|
||||
{
|
||||
return rad_arena > 1.0f;
|
||||
@ -1482,12 +1616,63 @@ S32 zNPCGoalKnock::Exit(F32 dt, void* updCtxt)
|
||||
return xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
void zNPCGoalTubeBonked::CheckForTran(en_trantype* trantype, int* nextgoal)
|
||||
{
|
||||
zNPCTubeSlave* npc = (zNPCTubeSlave *)(psyche->clt_owner);
|
||||
|
||||
switch (npc->tub_pete->tubestat)
|
||||
{
|
||||
case TUBE_STAT_BORN:
|
||||
if (npc->hitpoints != 0)
|
||||
{
|
||||
*nextgoal = NPC_GOAL_TUBEBIRTH;
|
||||
*trantype = GOAL_TRAN_SET;
|
||||
}
|
||||
break;
|
||||
case TUBE_STAT_DUCKLING:
|
||||
if (npc->hitpoints != 0)
|
||||
{
|
||||
*nextgoal = NPC_GOAL_TUBEDUCKLING;
|
||||
*trantype = GOAL_TRAN_SET;
|
||||
}
|
||||
break;
|
||||
case TUBE_STAT_ATTACK:
|
||||
if (npc->hitpoints != 0)
|
||||
{
|
||||
*nextgoal = NPC_GOAL_TUBEATTACK;
|
||||
*trantype = GOAL_TRAN_SET;
|
||||
}
|
||||
break;
|
||||
case TUBE_STAT_LASSO:
|
||||
*nextgoal = NPC_GOAL_TUBELASSO;
|
||||
*trantype = GOAL_TRAN_SET;
|
||||
break;
|
||||
case TUBE_STAT_DYING:
|
||||
case TUBE_STAT_DEAD:
|
||||
*nextgoal = NPC_GOAL_TUBEDYING;
|
||||
*trantype = GOAL_TRAN_SET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
S32 zNPCGoalAlertHammer::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCHammer* npc = ((zNPCHammer*)(psyche->clt_owner));
|
||||
return xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalAlert::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner));
|
||||
if (npc->inf_battle != NULL)
|
||||
{
|
||||
npc->inf_battle->LeaveBattle(npc);
|
||||
}
|
||||
npc->inf_battle = NULL;
|
||||
flg_user = 1;
|
||||
return xGoal::Exit(dt, updCtxt);
|
||||
}
|
||||
|
||||
S32 zNPCGoalLassoBase::Exit(F32 dt, void* updCtxt)
|
||||
{
|
||||
zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner));
|
||||
|
@ -556,6 +556,8 @@ public:
|
||||
S32 flg_attack; // offset 0x58, size 0x4
|
||||
en_slepatak sleepattack; // offset 0x5C, size 0x4
|
||||
F32 tmr_minAttack; // offset 0x60, size 0x4
|
||||
|
||||
S32 Exit(F32, void*);
|
||||
};
|
||||
|
||||
class zNPCGoalChase : public zNPCGoalCommon
|
||||
@ -711,6 +713,7 @@ public:
|
||||
}
|
||||
S32 Suspend(F32 dt, void* updCtxt);
|
||||
S32 Resume(F32 dt, void* updCtxt);
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
F32 tmr_attack; // offset 0x4C, size 0x4
|
||||
F32 tmr_minAttack; // offset 0x50, size 0x4
|
||||
xVec3 pos_began; // offset 0x54, size 0xC
|
||||
@ -909,7 +912,7 @@ public:
|
||||
xGoal::AddFlags(0x20000);
|
||||
flg_npcgauto &= 0xfffffff9;
|
||||
}
|
||||
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
S32 flg_alert; // offset 0x4C, size 0x4
|
||||
};
|
||||
|
||||
@ -1046,6 +1049,7 @@ public:
|
||||
}
|
||||
|
||||
S32 Enter(F32 dt, void* updCtxt);
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
void ChkPrelimTran(en_trantype* trantype, int* nextgoal);
|
||||
};
|
||||
|
||||
@ -1071,6 +1075,7 @@ public:
|
||||
}
|
||||
|
||||
S32 DeathByLasso(const xVec3*);
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
S32 flg_tubedying; // offset 0x4C, size 0x4
|
||||
F32 spd_gothatway; // offset 0x50, size 0x4
|
||||
S32 cnt_loop; // offset 0x54, size 0x4
|
||||
@ -1091,6 +1096,9 @@ public:
|
||||
F32 tmr_recover; // offset 0x4C, size 0x4
|
||||
F32 ang_spinrate; // offset 0x50, size 0x4
|
||||
xVec3 vec_offsetPete; // offset 0x54, size 0xC
|
||||
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
void CheckForTran(en_trantype*, int*);
|
||||
};
|
||||
|
||||
class zNPCGoalTubeBirth : public zNPCGoalCommon
|
||||
@ -1118,8 +1126,10 @@ public:
|
||||
void AttackDataReset();
|
||||
S32 Enter(F32 dt, void* updCtxt);
|
||||
S32 Resume(F32 dt, void* updCtxt);
|
||||
bool MarySpinUp(float);
|
||||
S32 LaserRender();
|
||||
void MaryzBlessing();
|
||||
void MaryzFury();
|
||||
S32 MarySpinDown(F32 dt);
|
||||
void ChkPrelimTran(en_trantype* trantype, int* nextgoal);
|
||||
S32 flg_attack; // offset 0x4C, size 0x4
|
||||
@ -1189,6 +1199,8 @@ public:
|
||||
SetFlags(2);
|
||||
}
|
||||
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
|
||||
F32 spd_gothatway; // offset 0x4C, size 0x4
|
||||
S32 cnt_loop; // offset 0x50, size 0x4
|
||||
F32 scl_shrink; // offset 0x54, size 0x4
|
||||
@ -1268,6 +1280,7 @@ public:
|
||||
}
|
||||
|
||||
S32 NPCMessage(NPCMsg* msg);
|
||||
S32 Exit(F32 dt, void* updCtxt);
|
||||
F32 tmr_countdown; // offset 0x4C, size 0x4
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "zNPCTypeCommon.h"
|
||||
#include "zNPCTypes.h"
|
||||
|
||||
void zNPCMsg_SceneReset();
|
||||
void zNPCMsg_ScenePrepare();
|
||||
void zNPCMsg_Startup();
|
||||
void zNPCMsg_Shutdown();
|
||||
void zNPCMsg_AreaNotify(zNPCCommon* sender, en_NPC_MSG_ID msgid, F32 rad, S32 filter,
|
||||
|
@ -1,14 +1,38 @@
|
||||
#include "zNPCMgr.h"
|
||||
#include "zNPCTypeCommon.h"
|
||||
#include "zNPCTypeRobot.h"
|
||||
#include "zNPCTypeVillager.h"
|
||||
#include "zNPCTypeSubBoss.h"
|
||||
#include "zNPCTypeBoss.h"
|
||||
#include "zNPCTypeDuplotron.h"
|
||||
#include "zNPCTypes.h"
|
||||
#include "zNPCSpawner.h"
|
||||
#include "zNPCMessenger.h"
|
||||
#include "zGlobals.h"
|
||||
|
||||
#include "xBehaveMgr.h"
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern S32 g_modinit;
|
||||
extern zNPCMgr* g_npcmgr;
|
||||
|
||||
S32 g_firstFrameUpdateAllNPC;
|
||||
|
||||
struct NPCMTypeTable
|
||||
{
|
||||
en_NPCTYPES useNPCType;
|
||||
char* modelName;
|
||||
unsigned int hashOfName;
|
||||
} g_tbltype[250];
|
||||
|
||||
struct NPCBrainTableEntry
|
||||
{
|
||||
char* name;
|
||||
en_NPCTYPES type;
|
||||
unsigned int id;
|
||||
} g_brainTable[63];
|
||||
|
||||
zNPCMgr* zNPCMgrSelf()
|
||||
{
|
||||
return g_npcmgr;
|
||||
@ -19,8 +43,14 @@ st_XORDEREDARRAY* zNPCMgr_GetNPCList()
|
||||
return &zNPCMgrSelf()->npclist;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Can't find the new operator declaration for some reason?
|
||||
void zNPCMgr::ScenePostInit()
|
||||
{
|
||||
zNPCCommon_ScenePostInit();
|
||||
zNPCRobot_ScenePostInit();
|
||||
zNPCVillager_ScenePostInit();
|
||||
zNPCDuplotron_ScenePostInit();
|
||||
}
|
||||
|
||||
void zNPCMgr_Startup()
|
||||
{
|
||||
if (g_modinit++ == 0)
|
||||
@ -28,13 +58,10 @@ void zNPCMgr_Startup()
|
||||
xBehaveMgr_Startup();
|
||||
zNPCMgr* npc = new (0x4e50434d, NULL) zNPCMgr(); //NPCM
|
||||
g_npcmgr = npc;
|
||||
Startup(npc);
|
||||
npc->Startup();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Doesn't set r4 to 1 before calling the delete operator...
|
||||
void zNPCMgr_Shutdown()
|
||||
{
|
||||
g_modinit--;
|
||||
@ -109,8 +136,59 @@ void zNPCMgr::Shutdown()
|
||||
zNPCMsg_Shutdown();
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Need to define all the functions.
|
||||
void zNPCMgr::PrepTypeTable()
|
||||
{
|
||||
for (NPCMTypeTable* p = &g_tbltype[0]; p->useNPCType != NPC_TYPE_UNKNOWN; p++)
|
||||
{
|
||||
p->hashOfName = xStrHash(p->modelName);
|
||||
}
|
||||
|
||||
for (int i = 0; i < (S32)(sizeof(g_brainTable) / sizeof(NPCBrainTableEntry)); i++)
|
||||
{
|
||||
g_brainTable[i].id = xStrHash(g_brainTable[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
void zNPCMgr::SceneReset()
|
||||
{
|
||||
zNPCCommon_SceneReset();
|
||||
zNPCRobot_SceneReset();
|
||||
zNPCVillager_SceneReset();
|
||||
zNPCMsg_SceneReset();
|
||||
xBehaveMgr_SceneReset();
|
||||
BackdoorUpdateAllNPCsOnce(globals.sceneCur, 0.01666666f);
|
||||
}
|
||||
|
||||
S32 zNPCMgr_OrdTest_npcid(const void* vkey, void* vitem)
|
||||
{
|
||||
S32 rc;
|
||||
void* key = *(void**)(vitem);
|
||||
|
||||
if (vkey < key)
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
else if (vkey > key)
|
||||
{
|
||||
rc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void zNPCMgr::ScenePostSetup()
|
||||
{
|
||||
for (int i = 0; i < npclist.cnt; i++)
|
||||
{
|
||||
xNPCBasic* npc = (xNPCBasic*)npclist.list[i];
|
||||
npc->PostSetup();
|
||||
}
|
||||
}
|
||||
|
||||
void zNPCMgr::ScenePrepare(S32 npccnt)
|
||||
{
|
||||
XOrdInit(&this->npclist, npccnt, 0);
|
||||
@ -126,8 +204,6 @@ void zNPCMgr::ScenePrepare(S32 npccnt)
|
||||
g_firstFrameUpdateAllNPC = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
S32 zNPCMgr_OrdComp_npcid(void* vkey, void* vitem)
|
||||
{
|
||||
S32 rc;
|
||||
|
@ -14,6 +14,10 @@ struct zNPCMgr : RyzMemData
|
||||
xBase selfbase;
|
||||
|
||||
zNPCMgr();
|
||||
S32 NPCTypeForModel(U32, U32);
|
||||
void BackdoorUpdateAllNPCsOnce(xScene*, F32);
|
||||
void PrepTypeTable();
|
||||
void Startup();
|
||||
void Shutdown();
|
||||
void ScenePrepare(S32 npccnt);
|
||||
void SceneFinish();
|
||||
|
@ -25,6 +25,7 @@ protected:
|
||||
~zNPCBoss();
|
||||
};
|
||||
|
||||
void zNPCBoss_ScenePrepare();
|
||||
void ZNPC_Boss_Startup();
|
||||
void ZNPC_Boss_Shutdown();
|
||||
xFactoryInst* ZNPC_Create_Boss(S32 who, RyzMemGrow* grow, void*);
|
||||
|
@ -616,6 +616,7 @@ struct NPCMsg
|
||||
xFactoryInst* ZNPC_Create_Common(S32 who, RyzMemGrow* grow, void*);
|
||||
void ZNPC_Destroy_Common(xFactoryInst* inst);
|
||||
void zNPCCommon_ScenePrepare();
|
||||
void zNPCCommon_ScenePostInit();
|
||||
void zNPCCommon_SceneFinish();
|
||||
void zNPCPlyrSnd_Reset();
|
||||
void zNPCPlyrSnd_Update(F32 dt);
|
||||
|
@ -30,8 +30,9 @@ struct zNPCDuplotron : zNPCCommon
|
||||
};
|
||||
|
||||
extern U32 g_hash_dupoanim[5];
|
||||
|
||||
void zNPCDuplotron_ScenePrepare();
|
||||
void ZNPC_Duplotron_Startup();
|
||||
void zNPCDuplotron_ScenePostInit();
|
||||
void ZNPC_Duplotron_Shutdown();
|
||||
xFactoryInst* ZNPC_Create_Duplotron(S32 who, RyzMemGrow* grow, void*);
|
||||
void ZNPC_Destroy_Duplotron(xFactoryInst* inst);
|
||||
|
@ -45,7 +45,7 @@ struct NPCLaser
|
||||
|
||||
void ColorSet(const RwRGBA*, const RwRGBA*);
|
||||
U32 TextureGet();
|
||||
static void Render(xVec3&, xVec3&);
|
||||
void Render(xVec3*, xVec3*);
|
||||
void UVScrollUpdate(F32);
|
||||
void Prepare();
|
||||
};
|
||||
@ -547,6 +547,7 @@ struct zNPCSlick : zNPCRobot
|
||||
void ShieldFX(F32 dt);
|
||||
};
|
||||
|
||||
void zNPCRobot_SceneReset();
|
||||
void ZNPC_Robot_Startup();
|
||||
void ZNPC_Robot_Shutdown();
|
||||
void zNPCRobot_ScenePrepare();
|
||||
|
@ -18,6 +18,7 @@ struct zNPCSubBoss : zNPCCommon
|
||||
virtual U8 PhysicsFlags() const;
|
||||
};
|
||||
|
||||
void zNPCSubBoss_ScenePrepare();
|
||||
void ZNPC_SubBoss_Startup();
|
||||
void ZNPC_SubBoss_Shutdown();
|
||||
void zNPCSubBoss_ScenePrepare();
|
||||
|
@ -182,6 +182,9 @@ xAnimTable* ZNPC_AnimTable_BalloonBoy(xAnimTable* callerTable);
|
||||
xAnimTable* ZNPC_AnimTable_SuperFriend(xAnimTable* callerTable);
|
||||
void FOLK_KillEffects();
|
||||
void FOLK_InitEffects();
|
||||
void zNPCVillager_ScenePostInit();
|
||||
void zNPCVillager_ScenePrepare();
|
||||
void zNPCVillager_SceneReset();
|
||||
void ZNPC_Villager_Startup();
|
||||
void ZNPC_Villager_Shutdown();
|
||||
xFactoryInst* ZNPC_Create_Villager(S32 who, RyzMemGrow* growCtxt, void*);
|
||||
|
Loading…
Reference in New Issue
Block a user