diff --git a/configure.py b/configure.py index dc64659d6..6460232ba 100644 --- a/configure.py +++ b/configure.py @@ -551,7 +551,7 @@ def MatchingFor(*versions): Object(NonMatching, "SB/Game/zNPCGoalStd.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Game/zNPCGoalRobo.cpp", extra_cflags=["-sym on"]), Object(Matching, "SB/Game/zNPCGoalTiki.cpp", extra_cflags=["-sym on"]), - Object(NonMatching, "SB/Game/zNPCMessenger.cpp"), + Object(NonMatching, "SB/Game/zNPCMessenger.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Game/zNPCMgr.cpp", extra_cflags=["-sym on"]), Object(Matching, "SB/Game/zNPCTypes.cpp"), Object(NonMatching, "SB/Game/zNPCTypeCommon.cpp"), diff --git a/src/SB/Game/zEntCruiseBubble.cpp b/src/SB/Game/zEntCruiseBubble.cpp index d0b55d61c..27bd996dc 100644 --- a/src/SB/Game/zEntCruiseBubble.cpp +++ b/src/SB/Game/zEntCruiseBubble.cpp @@ -12,6 +12,7 @@ #include "zEntTrigger.h" #include "zGameExtras.h" #include "zGlobals.h" +#include "zGrid.h" #include "zNPCHazard.h" #include "zNPCTypeCommon.h" #include "zPlatform.h" diff --git a/src/SB/Game/zEntPlayer.cpp b/src/SB/Game/zEntPlayer.cpp index 51a25f56c..2c3448b9a 100644 --- a/src/SB/Game/zEntPlayer.cpp +++ b/src/SB/Game/zEntPlayer.cpp @@ -36,6 +36,7 @@ #include "zEntPlayerOOBState.h" #include "zEntTeleportBox.h" #include "zGame.h" +#include "zGrid.h" #include "zGameExtras.h" #include "zGlobals.h" #include "zGoo.h" diff --git a/src/SB/Game/zNPCGoalRobo.cpp b/src/SB/Game/zNPCGoalRobo.cpp index f13220d2a..37a0d60b5 100644 --- a/src/SB/Game/zNPCGoalRobo.cpp +++ b/src/SB/Game/zNPCGoalRobo.cpp @@ -10,6 +10,7 @@ #include "xMath3.h" #include "xMathInlines.h" #include "zNPCGoalRobo.h" +#include "zNPCGoals.h" #include "zNPCGoalStd.h" #include "zNPCHazard.h" #include "zNPCSndLists.h" diff --git a/src/SB/Game/zNPCMessenger.cpp b/src/SB/Game/zNPCMessenger.cpp index ad72306f5..2a924b113 100644 --- a/src/SB/Game/zNPCMessenger.cpp +++ b/src/SB/Game/zNPCMessenger.cpp @@ -1,18 +1,32 @@ #include "zNPCMessenger.h" +#include "math.h" +#include "xEnt.h" #include "xordarray.h" +#include "xMathInlines.h" +#include "zGlobals.h" +#include "zNPCMgr.h" +#include "zNPCTypeCommon.h" +#include "zNPCTypeRobot.h" +#include "zNPCTypes.h" #include -static NPCPSData g_postoffice; -static NPCMsg g_msgdata; +static NPCPSData g_postoffice = {}; static S32 g_lockarea; -NPCPSData* NPCPS_postOffice() +// see comment in header for why this is declared here +static S32 NPCPS_flagForMID(en_NPC_MSG_ID); + +void zNPCMsg_Startup() { - return &g_postoffice; + NPCPSData* tempStartup; + + tempStartup = NPCPS_postOffice(); + NPCPS_CltPoolInit(tempStartup, 0x20); + NPCPS_MsgPoolInit(tempStartup, 0x40); } -void zNPCCommon::Stun(F32) +void zNPCMsg_Shutdown() { } @@ -25,52 +39,123 @@ void zNPCMsg_SceneFinish() return zNPCMsg_SceneReset(); } -void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, U32 unk0) +void zNPCMsg_SceneReset() +{ + NPCPSData* tempReset; + + tempReset = NPCPS_postOffice(); + NPCPS_CltPoolReset(tempReset); + NPCPS_MsgPoolReset(tempReset); +} + +void zNPCMsg_Timestep(xScene*, F32 dt) +{ + NPCPSData* office = NPCPS_postOffice(); + + for (S32 i = office->quelist.cnt - 1; i >= 0; i--) + { + NPCMsg* inmsg = (NPCMsg*)office->quelist.list[i]; + + inmsg->tmr_delay = MAX(-1.0f, inmsg->tmr_delay - dt); + + if (inmsg->tmr_delay < 0.0f) + { + zNPCMsg_SendMsg(inmsg, -1.0f, 0); + + XOrdRemove(&office->quelist, 0, i); + + NPCPS_freeMsg(inmsg); + } + } +} + +void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, U32 npc_id) { static NPCMsg msg; memset(&msg, 0, sizeof(NPCMsg)); msg.msgid = msgevent; - msg.sendto = unk0; + msg.sendto = npc_id; + // float scheduling issue zNPCMsg_SendMsg(&msg, -1.0f, 0); } -void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, zNPCCommon* npc) +void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, zNPCCommon* npc_sendto) { static NPCMsg msg; - memset(&msg, 0, sizeof(NPCMsg)); msg.msgid = msgevent; - msg.sendto = npc->id; - zNPCMsg_SendMsg(&msg, -1.0f, npc); + msg.sendto = npc_sendto->id; + // float scheduling issue + zNPCMsg_SendMsg(&msg, -1.0f, npc_sendto); } -void zNPCMsg_SendMsg(NPCMsg*, zNPCCommon*) +void zNPCMsg_SendMsg(NPCMsg* inmsg, zNPCCommon* npc_sendto) { + zNPCMsg_SendMsg(inmsg, -1.0f, npc_sendto); } -void zNPCMsg_SendMsg(NPCMsg*, float, zNPCCommon*) +void zNPCMsg_SendMsg(NPCMsg* inmsg, F32 delay, zNPCCommon* npc_sendto) { + if (delay > 0.0f) + { + S32 grabMsg = NPCPS_grabMsg(); + if (grabMsg != NULL) + { + NPCPS_copyMsgInfo((NPCMsg*)grabMsg, inmsg, delay); + NPCPS_queMessage((NPCMsg*)grabMsg); + } + else + { + zNPCMsg_SendMsg(inmsg, -1.0f, npc_sendto); + } + } + else + { + if (npc_sendto == NULL) + { + st_XORDEREDARRAY* npclist = zNPCMgr_GetNPCList(); + S32 idx = XOrdLookup(npclist, (const void*)inmsg->sendto, zNPCMgr_OrdTest_npcid); + if (idx >= 0) + { + npc_sendto = (zNPCCommon*)npclist->list[idx]; + } + } + if (npc_sendto != NULL) + { + npc_sendto->NPCMessage(inmsg); + } + NPCPSData* npcps = NPCPS_postOffice(); + S32 midFlag = NPCPS_flagForMID(inmsg->msgid); + for (S32 i = 0; i < npcps->cltlist.cnt; i++) + { + NPCPSClt* clt = (NPCPSClt*)npcps->cltlist.list[i]; + if ((clt->flg_filter & midFlag) != 0) + { + clt->notify(clt->notedata, inmsg); + } + } + } } -void NPCPS_copyMsgInfo(NPCMsg*, NPCMsg*, float) +static void NPCPS_copyMsgInfo(NPCMsg* msgA, NPCMsg* msgB, F32 delay) { + memcpy(msgA, msgB, 0x44); + msgA->next = NULL; + msgA->tmr_delay = delay; } -void NPCPS_queMessage(NPCMsg* msg) +static void NPCPS_queMessage(NPCMsg* msg) { - NPCPSData* npc; - - npc = NPCPS_postOffice(); - + NPCPSData* npc = NPCPS_postOffice(); XOrdAppend(&npc->quelist, msg); } -S32 NPCPS_flagForMID(en_NPC_MSG_ID) +static S32 NPCPS_flagForMID(en_NPC_MSG_ID) { return NPC_MID_DTRON_NPCAVAIL; } -void NPCPS_MsgPoolInit(NPCPSData* npc, S32 unk) +static void NPCPS_MsgPoolInit(NPCPSData* npc, S32 unk) { XOrdInit(&npc->quelist, unk, 0); npc->msgblob = (NPCMsg*)xMemAlloc(gActiveHeap, unk * sizeof(NPCMsg), 0); @@ -78,17 +163,23 @@ void NPCPS_MsgPoolInit(NPCPSData* npc, S32 unk) NPCPS_MsgPoolReset(npc); } -void NPCPS_MsgPoolReset(NPCPSData* npc) +static void NPCPS_MsgPoolReset(NPCPSData* npc) { - S32 iVar11 = npc->quelist.max; npc->quelist.cnt = 0; - memset(npc->msgblob, 0, npc->quelist.max * sizeof(NPCMsg)); - if (0 < iVar11) + S32 max_msgs = npc->quelist.max; + memset(npc->msgblob, 0, max_msgs * sizeof(NPCMsg)); + npc->msgfree = NULL; + + for (S32 i = 0; i < max_msgs; i++) { + NPCMsg* current_msg = &npc->msgblob[i]; + + current_msg->next = npc->msgfree; + npc->msgfree = current_msg; } } -void NPCPS_CltPoolInit(NPCPSData* npc, S32 unk) +static void NPCPS_CltPoolInit(NPCPSData* npc, S32 unk) { XOrdInit(&npc->cltlist, unk, 0); npc->cltblob = (NPCPSClt*)xMemAlloc(gActiveHeap, unk * 16, 0); @@ -96,111 +187,314 @@ void NPCPS_CltPoolInit(NPCPSData* npc, S32 unk) NPCPS_CltPoolReset(npc); } -void NPCPS_CltPoolReset(NPCPSData*) +static void NPCPS_CltPoolReset(NPCPSData* npc) +{ + S32 max_clts = npc->cltlist.max; + memset(npc->cltblob, 0, max_clts * sizeof(NPCPSClt)); + npc->cltfree = NULL; + for (S32 i = 0; i < max_clts; i++) + { + NPCPSClt* current_clt = &npc->cltblob[i]; + + current_clt->next = npc->cltfree; + npc->cltfree = current_clt; + } + npc->cltlist.cnt = 0; +} + +static NPCPSData* NPCPS_postOffice() { + return &g_postoffice; } -void NPCPS_grabMsg() +static S32 NPCPS_grabMsg() { NPCPSData* npc = NPCPS_postOffice(); - - if (npc->msgfree == 0) + NPCMsg* grabbed_msg = npc->msgfree; + if (grabbed_msg == NULL) { - npc->msgfree = 0; + return 0; } + npc->msgfree = grabbed_msg->next; + grabbed_msg->next = NULL; + return (S32)grabbed_msg; } -void NPCPS_freeMsg(NPCMsg*) +static void NPCPS_freeMsg(NPCMsg* inmsg) { + NPCPSData* post_office = NPCPS_postOffice(); + inmsg->next = post_office->msgfree; + post_office->msgfree = inmsg; } +static NPCMsg g_msgdata; + void zNPCMsg_AreaNotify(zNPCCommon* sender, en_NPC_MSG_ID msgid, F32 rad, S32 filter, - en_NPCTYPES* toNPCType) + en_NPCTYPES toNPCType) { - // TODO: Honestly, I dont know how to finish this. - if (g_lockarea == 0) { g_lockarea = 1; - + // sda scheduling issue + en_NPCTYPES toTypes[2] = { toNPCType, NPC_TYPE_UNKNOWN }; memset(&g_msgdata, 0, sizeof(NPCMsg)); - - if (sender != NULL) - { - g_msgdata.from = NPC_MID_NONE; - } - else - { - msgid = (en_NPC_MSG_ID)'FAKE'; - } - - g_msgdata.from = 0; + g_msgdata.from = (sender != NULL) ? (en_NPC_MSG_ID)sender->id : (en_NPC_MSG_ID)'FAKE'; g_msgdata.msgid = msgid; g_msgdata.sendto = 0; g_msgdata.infotype = NPC_MDAT_BLANK; - - zNPCMsg_AreaNotify(sender, &g_msgdata, rad, filter, toNPCType); + zNPCMsg_AreaNotify(sender, &g_msgdata, rad, filter, toTypes); g_lockarea = 0; } } void zNPCMsg_AreaNotify(zNPCCommon* sender, en_NPC_MSG_ID msgid, F32 rad, S32 filter, - en_NPCTYPES toNPCType) + en_NPCTYPES* toNPCType) { - // TODO: Honestly, I dont know how to finish this. - if (g_lockarea == 0) { g_lockarea = 1; - memset(&g_msgdata, 0, sizeof(NPCMsg)); - - if (sender != NULL) - { - g_msgdata.from = NPC_MID_NONE; - } - else - { - msgid = (en_NPC_MSG_ID)'FAKE'; - } - - g_msgdata.from = 0; + en_NPC_MSG_ID from_id; + g_msgdata.from = (sender != NULL) ? (en_NPC_MSG_ID)sender->id : (en_NPC_MSG_ID)'FAKE'; g_msgdata.msgid = msgid; g_msgdata.sendto = 0; g_msgdata.infotype = NPC_MDAT_BLANK; - - zNPCMsg_AreaNotify(sender, &g_msgdata, rad, filter, &toNPCType); + zNPCMsg_AreaNotify(sender, &g_msgdata, rad, filter, toNPCType); g_lockarea = 0; } } -void zNPCMsg_Startup() +void zNPCMsg_AreaNotify(zNPCCommon* sender, NPCMsg* msg, F32 radius, S32 filter, + en_NPCTYPES* npcTypeList) { - NPCPSData* tempStartup; + F32 radiusSq = SQ(radius); + st_XORDEREDARRAY* npclist = zNPCMgr_GetNPCList(); + xVec3 checkPos; - tempStartup = NPCPS_postOffice(); - NPCPS_CltPoolInit(tempStartup, 0x20); - NPCPS_MsgPoolInit(tempStartup, 0x40); -} + if (filter & 0x100) + { + xVec3Copy(&checkPos, xEntGetPos(&globals.player.ent)); + } + else if (sender != NULL) + { + xVec3Copy(&checkPos, sender->Pos()); + } + else + { + xVec3Copy(&checkPos, &g_O3); + } -void zNPCMsg_SceneReset() -{ - NPCPSData* tempReset; + if (msg->infotype == 0) + { + xVec3Copy(&msg->target.pos_tgt, &checkPos); + msg->target.bas_tgt = sender; + msg->infotype = NPC_MDAT_AREANOTIFY; + } - tempReset = NPCPS_postOffice(); - NPCPS_CltPoolReset(tempReset); - NPCPS_MsgPoolReset(tempReset); -} + for (S32 i = 0; i < npclist->cnt; i++) + { + zNPCCommon* targetNPC = ((zNPCCommon**)npclist->list)[i]; -void zNPCMsg_Timestep(xScene*, float) -{ + if (!(filter & 0x800)) + { + if ((targetNPC->baseFlags & 0x40)) + { + continue; + } + } + + if (sender != NULL && !(filter & 0x8) && targetNPC == (zNPCCommon*)sender) + { + continue; + } + + S32 targetNPCType = targetNPC->SelfType(); + + if (sender != NULL && (filter & 0x200) && (targetNPCType != sender->SelfType())) + { + continue; + } + + if (npcTypeList != NULL && *npcTypeList != NPC_TYPE_UNKNOWN) + { + en_NPCTYPES* typePtr = npcTypeList; + S32 inList = TRUE; + + while (*typePtr != NPC_TYPE_UNKNOWN) + { + if (targetNPCType == *typePtr) + { + inList = FALSE; + break; + } + typePtr++; + } + + if (inList) + { + continue; + } + } + + if ((filter & 0x10) == 0) + { + U32 typePrefix = targetNPCType & 0xffffff00; + + if (typePrefix != 'NTT\0' && typePrefix != 'NTR\0' && typePrefix != 'NTF\0') + { + continue; + } + + if ((typePrefix == 'NTT\0' && !(filter & 0x1)) || + (typePrefix == 'NTR\0' && !(filter & 0x2)) || + (typePrefix == 'NTF\0' && !(filter & 0x4))) + { + continue; + } + } + + if (!(filter & 0x400) && !targetNPC->IsAlive()) + { + continue; + } + + xVec3 vecDiff; + xVec3Sub(&vecDiff, xEntGetPos((xEnt*)targetNPC), &checkPos); + + if (FABS(vecDiff.y) > 2.0f) + { + continue; + } + + vecDiff.y = 0.0f; + if (xVec3Length2(&vecDiff) > radiusSq) + { + continue; + } + + msg->sendto = targetNPC->id; + targetNPC->NPCMessage(msg); + } } -void zNPCMsg_Shutdown() +void zNPCMsg_AreaPlayerStun(F32 stuntime, F32 radius, xVec3* pos) { + st_XORDEREDARRAY* npclist = zNPCMgr_GetNPCList(); + xVec3 from; + + if (pos != NULL) + { + xVec3Copy(&from, pos); + } + else + { + xVec3Copy(&from, xEntGetPos(&globals.player.ent)); + } + + F32 ds2_discard = SQ(radius); + + for (S32 i = 0; i < npclist->cnt; i++) + { + zNPCCommon* npc = (zNPCCommon*)npclist->list[i]; + + if (((npc->baseFlags & 0x40) == 0) && + (npc->model == NULL || (npc->model->Flags & 0x400) == 0) && + (npc->flg_vuln & 0x10000000)) + { + U32 ntyp = npc->SelfType(); + + if ((ntyp & 0xFFFFFF00) == 'NTR\0') + { + zNPCRobot* robo = (zNPCRobot*)npc; + if (robo->IsDying()) + { + continue; + } + } + else + { + if (!npc->IsAlive()) + { + continue; + } + } + + xVec3 diff; + npc->XYZVecToPos(&diff, &from); + + if (FABS(diff.y) > radius) + { + continue; + } + diff.y = 0.0f; + if (xVec3Length2(&diff) > ds2_discard) + { + continue; + } + npc->Stun(stuntime); + } + } } -S32 zNPCCommon::IsAlive() +void zNPCMsg_AreaNPCExplodeNoRobo(zNPCCommon* who, F32 radius, const xVec3* pos_fromHere) { - return 1; + st_XORDEREDARRAY* npclist = zNPCMgr_GetNPCList(); + xVec3 from = (pos_fromHere != NULL) ? *pos_fromHere : *who->Center(); + F32 ds2_discard = SQ(radius); + for (S32 i = 0; i < npclist->cnt; i++) + { + zNPCCommon* npc = (zNPCCommon*)npclist->list[i]; + if (npc == who) + { + continue; + } + if (npc->baseFlags & 0x40) + { + continue; + } + if (npc->model != NULL && (npc->model->Flags & 0x400) != 0) + { + continue; + } + S32 ntyp = npc->SelfType() & 0xFFFFFF00; + if (ntyp == 'NTR\0') + { + continue; + } + xVec3 diff; + F32 ds2_tgt = npc->XYZDstSqToPos(&from, &diff); + if (ds2_tgt > ds2_discard) + { + continue; + } + if (ntyp == 'NTR\0') + { + zNPCRobot* robo = (zNPCRobot*)npc; + if (robo->IsDying() != 0) + { + continue; + } + } + else if (npc->IsAlive() == 0) + { + continue; + } + F32 dst = xsqrt(ds2_tgt); + if (dst > 0.00001f) + { + diff /= dst; + } + else + { + if (FABS(diff.x) > FABS(diff.z)) + { + diff = (diff.x > 0.0f) ? g_X3 : g_NX3; + } + else + { + diff = (diff.z > 0.0f) ? g_Z3 : g_NZ3; + } + } + npc->Damage(DMGTYP_HITBYTOSS, who, &diff); + } } diff --git a/src/SB/Game/zNPCMessenger.h b/src/SB/Game/zNPCMessenger.h index 099d349be..a91e55f24 100644 --- a/src/SB/Game/zNPCMessenger.h +++ b/src/SB/Game/zNPCMessenger.h @@ -1,40 +1,243 @@ #ifndef ZNPCMESSENGER_H #define ZNPCMESSENGER_H -#include "zNPCTypeCommon.h" +#include +#include "xBase.h" +#include "xVec3.h" +#include "zMovePoint.h" #include "zNPCTypes.h" -struct NPCMsg; struct zNPCCommon; +enum en_NPC_MSG_ID +{ + NPC_MID_NONE, + NPC_MID_SYSEVENT, + NPC_MID_RESPAWN, + NPC_MID_DAMAGE, + NPC_MID_EXPLOSION, + NPC_MID_BUNNYHOP, + NPC_MID_DTRON_NPCEMIT, + NPC_MID_DTRON_NPCAVAIL, + NPC_MID_DTRON_ISDEAD, + NPC_MID_CHAT_REQUEST, + NPC_MID_CHAT_DECLINE, + NPC_MID_CHAT_ACCEPT, + NPC_MID_CHAT_DONE, + NPC_MID_CHAT_ABORT, + NPC_MID_TALKSTART, + NPC_MID_TALKON, + NPC_MID_TALKOFF, + NPC_MID_SAWPLYR, + NPC_MID_NEEDMEDIC, + NPC_MID_UNDERATTACK, + NPC_MID_NPCDIED, + NPC_MID_PLYRSPATULA, + NPC_MID_BECOMESCARED, + NPC_MID_NOLONGERSCARED, + NPC_MID_CELEBRATE, + NPC_MID_STUN, + NPC_MID_SCRIPTBEGIN, + NPC_MID_SCRIPTEND, + NPC_MID_SCRIPTHALT, + NPC_MID_DEV_ANIMSPIN, + NPC_MID_DEV_ANIMCYCLE, + NPC_MID_DEV_HEROMODE, + NPC_MID_DEV_DONE, + NPC_MID_NOMORE, + NPC_MID_FORCE = 0x7fffffff +}; + +enum en_NPC_MSG_DATA +{ + NPC_MDAT_BLANK, + NPC_MDAT_SYSEVENT, + NPC_MDAT_BLAST, + NPC_MDAT_CHAT, + NPC_MDAT_SPAWN, + NPC_MDAT_TARGET, + NPC_MDAT_DAMAGE, + NPC_MDAT_STUN, + NPC_MDAT_SCRIPT, + NPC_MDAT_MOUNT, + NPC_MDAT_AREANOTIFY, + NPC_MDAT_NOMORE, + NPC_MDAT_FORCE = 0x7fffffff +}; + +struct NPCSysEvent +{ + S32 doLinkEvents; + S32 handled; + xBase* from; + xBase* to; + U32 toEvent; + F32 toParam[4]; + xBase* toParamWidget; +}; + +struct NPCBlastInfo +{ + xVec3 pos_blast; + F32 rad_blast; + F32 spd_expand; +}; + +struct NPCChatInfo +{ + xVec3 pos_chat; + F32 tym_chat; +}; + +struct NPCSpawnInfo +{ + xVec3 pos_spawn; + zMovePoint* nav_firstMovepoint; + zMovePoint* nav_spawnReference; + S32 spawnSuccess; +}; + +struct NPCTargetInfo +{ + xBase* bas_tgt; + xVec3 pos_tgt; +}; + +enum en_NPC_DAMAGE_TYPE +{ + DMGTYP_UNDECIDED, + DMGTYP_ABOVE, + DMGTYP_BELOW, + DMGTYP_SIDE, + DMGTYP_INSTAKILL, + DMGTYP_KILLEVENT, + DMGTYP_HITBYTOSS, + DMGTYP_NPCATTACK, + DMGTYP_ROPE, + DMGTYP_CRUISEBUBBLE, + DMGTYP_PROJECTILE, + DMGTYP_BOULDER, + DMGTYP_BUBBOWL, + DMGTYP_THUNDER_TIKI_EXPLOSION, + DMGTYP_DAMAGE_SURFACE, + DMGTYP_BUNGEED, + DMGTYP_SURFACE, + DMGTYP_NOMORE, + DMGTYP_FORCEINT = 0x7fffffff +}; + +struct NPCDamageInfo +{ + en_NPC_DAMAGE_TYPE dmg_type; + xBase* dmg_from; + xVec3 vec_dmghit; +}; + +enum en_NPC_CARRY_STATE +{ + zNPCCARRY_NONE, + zNPCCARRY_PICKUP, + zNPCCARRY_THROW, + zNPCCARRY_ATTEMPTPICKUP, + zNPCCARRY_FORCEINT = 0x7fffffff +}; + +struct NPCStunInfo +{ + F32 tym_stuntime; + en_NPC_CARRY_STATE carrystate; + S32 allowStun; +}; + +struct NPCScriptInfo +{ + U32 aid_playanim; +}; + +struct NPCMountInfo +{ + xEnt* ent_toMount; + xCollis* col_forMount; +}; + +struct NPCAreaInfo +{ + zNPCCommon* npc_origin; + xVec3 pos_origin; +}; + + + +struct NPCMsg +{ + en_NPC_MSG_ID msgid; + U32 sendto; + U32 from; + en_NPC_MSG_DATA infotype; // 0xC + union + { + NPCSysEvent sysevent; + NPCBlastInfo blastarea; + NPCChatInfo chatter; + NPCSpawnInfo spawning; + NPCTargetInfo target; + NPCDamageInfo dmgdata; // 0x10 + NPCStunInfo stundata; + NPCScriptInfo scriptdata; + NPCMountInfo mountdata; + NPCAreaInfo areadata; + }; + void* attached; // 0x38 + NPCMsg* next; + F32 tmr_delay; // 0x40 +}; + struct NPCPSClt { - // total size: 0x10 - void (*notify)(void*, NPCMsg*); // offset 0x0, size 0x4 - void* notedata; // offset 0x4, size 0x4 - signed int flg_filter; // offset 0x8, size 0x4 - NPCPSClt* next; // offset 0xC, size 0x4 + void (*notify)(void*, NPCMsg*); // offset 0x0 + void* notedata; // offset 0x4 + signed int flg_filter; // offset 0x8 + NPCPSClt* next; // offset 0xC }; struct NPCPSData { - // total size: 0x30 - NPCPSClt* cltblob; // offset 0x0, size 0x4 - NPCPSClt* cltfree; // offset 0x4, size 0x4 - st_XORDEREDARRAY cltlist; // offset 0x8, size 0x10 - NPCMsg* msgblob; // offset 0x18, size 0x4 - NPCMsg* msgfree; // offset 0x1C, size 0x4 - st_XORDEREDARRAY quelist; // offset 0x20, size 0x10 + NPCPSClt* cltblob; // offset 0x0 + NPCPSClt* cltfree; // offset 0x4 + st_XORDEREDARRAY cltlist; // offset 0x8 + NPCMsg* msgblob; // offset 0x18 + NPCMsg* msgfree; // offset 0x1C + st_XORDEREDARRAY quelist; // offset 0x20 }; -void zNPCMsg_SceneReset(); -void zNPCMsg_ScenePrepare(); void zNPCMsg_Startup(); void zNPCMsg_Shutdown(); -void zNPCMsg_AreaNPCExplodeNoRobo(zNPCCommon* wh, F32 radius, const xVec3* pos_fromHere); - +void zNPCMsg_ScenePrepare(); +void zNPCMsg_SceneReset(); void zNPCMsg_Timestep(xScene* xscn, F32 dt); -void NPCPS_MsgPoolReset(NPCPSData* npc); -void NPCPS_CltPoolReset(NPCPSData* npc); +/* TODO: en_NPC_MSG_ID definition in zNPCTypeCommon.h is causing issues here */ +void zNPCMsg_AreaNotify(zNPCCommon* sender, en_NPC_MSG_ID msgid, F32 rad, S32 filter, + en_NPCTYPES toNPCType); +void zNPCMsg_AreaNotify(zNPCCommon* sender, en_NPC_MSG_ID msgid, F32 rad, S32 filter, + en_NPCTYPES* toNPCType); + + +void zNPCMsg_AreaNotify(zNPCCommon* sender, NPCMsg* msg, F32 radius, S32 filter, + en_NPCTYPES* npcTypeList); +void zNPCMsg_AreaPlayerStun(F32 stuntime, F32 radius, xVec3* pos); +void zNPCMsg_AreaNPCExplodeNoRobo(zNPCCommon* wh, F32 radius, const xVec3* pos_fromHere); +void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, U32 npc_id); +void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, zNPCCommon* npc_sendto); +void zNPCMsg_SendMsg(NPCMsg* inmsg, zNPCCommon* npc_sendto); +void zNPCMsg_SendMsg(NPCMsg* inmsg, F32 delay, zNPCCommon* npc_sendto); +static void NPCPS_copyMsgInfo(NPCMsg*, NPCMsg*, F32); +static void NPCPS_queMessage(NPCMsg* msg); +static void NPCPS_MsgPoolInit(NPCPSData* npc, S32 unk); +static void NPCPS_MsgPoolReset(NPCPSData* npc); +static void NPCPS_CltPoolInit(NPCPSData* npc, S32 unk); +static void NPCPS_CltPoolReset(NPCPSData* npc); +static NPCPSData* NPCPS_postOffice(); +static S32 NPCPS_grabMsg(); +static void NPCPS_freeMsg(NPCMsg* inmsg); #endif diff --git a/src/SB/Game/zNPCMgr.h b/src/SB/Game/zNPCMgr.h index cdd71b4fe..ccc5f9f7d 100644 --- a/src/SB/Game/zNPCMgr.h +++ b/src/SB/Game/zNPCMgr.h @@ -13,7 +13,7 @@ struct zNPCMgr : RyzMemData xFactory* npcFactory; xBehaveMgr* bmgr; xBase selfbase; - + enum en_NPCTYPES NPCTypeForModel(U32 brainID, U32 mdl_hash); void BackdoorUpdateAllNPCsOnce(xScene*, F32); void PrepTypeTable(); @@ -28,23 +28,23 @@ struct zNPCMgr : RyzMemData void ScenePostRender(); void ScenePostParticleRender(); xEnt* CreateNPC(xEntAsset* assdat); - + zNPCMgr() { } - + ~zNPCMgr() { } - + void DBG_Reset() { } - + void DBG_PerfTrack() { } - + /* Use as needed. en_NPCTYPES NPCTypeForModel(U32 brainID, U32 mdl_hash); xEnt* CreateNPC(xEntAsset* asset); @@ -70,5 +70,6 @@ void zNPCMsg_SceneFinish(); xEnt* zNPCMgr_createNPCInst(S32, xEntAsset* assdat); S32 zNPCMgr_OrdComp_npcid(void* vkey, void* vitem); +S32 zNPCMgr_OrdTest_npcid(const void* vkey, void* vitem); #endif diff --git a/src/SB/Game/zNPCTypeCommon.cpp b/src/SB/Game/zNPCTypeCommon.cpp index 0a8d65148..f9c3a2ab7 100644 --- a/src/SB/Game/zNPCTypeCommon.cpp +++ b/src/SB/Game/zNPCTypeCommon.cpp @@ -3,20 +3,26 @@ #include #include +#include "zCombo.h" +#include "zEntButton.h" #include "zEntCruiseBubble.h" #include "zEntTeleportBox.h" #include "zGlobals.h" +#include "zGrid.h" +#include "zNPCGoals.h" #include "zNPCTypes.h" #include "zNPCSndTable.h" #include "zNPCSndLists.h" #include "zNPCSupport.h" #include "zNPCFXCinematic.h" +#include "iCollide.h" #include "iModel.h" #include "iSnd.h" -#include "xString.h" #include "xDebug.h" +#include "xDraw.h" +#include "xString.h" // Finish porting code from bfbbpc repo diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index d7f2c46e3..ed744ca7a 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -8,27 +8,15 @@ #include "xBehaveMgr.h" #include "xEnt.h" #include "xSFX.h" -#include "xstransvc.h" -#include "xDraw.h" -#include "xstransvc.h" -#include "xDraw.h" #include "zNPCSndTable.h" #include "zMovePoint.h" #include "zShrapnel.h" #include "zNPCMessenger.h" -#include "zNPCGoals.h" -#include "zGrid.h" -#include "iCollide.h" -#include "zEntButton.h" -#include "zCombo.h" -#include "zNPCTypes.h" #define XRAY3_USE_MIN (1 << 10) #define XRAY3_USE_MAX (1 << 11) -typedef struct NPCMsg; - class zAnimFxSound; enum en_npcparm @@ -117,37 +105,7 @@ enum en_NPC_GOAL_SPOT NPC_GSPOT_FORCEINT = 0x7fffffff }; -enum en_NPC_CARRY_STATE -{ - zNPCCARRY_NONE, - zNPCCARRY_PICKUP, - zNPCCARRY_THROW, - zNPCCARRY_ATTEMPTPICKUP, - zNPCCARRY_FORCEINT = 0x7fffffff -}; -enum en_NPC_DAMAGE_TYPE -{ - DMGTYP_UNDECIDED, - DMGTYP_ABOVE, - DMGTYP_BELOW, - DMGTYP_SIDE, - DMGTYP_INSTAKILL, - DMGTYP_KILLEVENT, - DMGTYP_HITBYTOSS, - DMGTYP_NPCATTACK, - DMGTYP_ROPE, - DMGTYP_CRUISEBUBBLE, - DMGTYP_PROJECTILE, - DMGTYP_BOULDER, - DMGTYP_BUBBOWL, - DMGTYP_THUNDER_TIKI_EXPLOSION, - DMGTYP_DAMAGE_SURFACE, - DMGTYP_BUNGEED, - DMGTYP_SURFACE, - DMGTYP_NOMORE, - DMGTYP_FORCEINT = 0x7fffffff -}; enum en_npcvibe { @@ -299,62 +257,6 @@ enum en_LASSO_EVENT LASS_EVNT_FORCEINT = 0x7fffffff }; -enum en_NPC_MSG_ID -{ - NPC_MID_NONE, - NPC_MID_SYSEVENT, - NPC_MID_RESPAWN, - NPC_MID_DAMAGE, - NPC_MID_EXPLOSION, - NPC_MID_BUNNYHOP, - NPC_MID_DTRON_NPCEMIT, - NPC_MID_DTRON_NPCAVAIL, - NPC_MID_DTRON_ISDEAD, - NPC_MID_CHAT_REQUEST, - NPC_MID_CHAT_DECLINE, - NPC_MID_CHAT_ACCEPT, - NPC_MID_CHAT_DONE, - NPC_MID_CHAT_ABORT, - NPC_MID_TALKSTART, - NPC_MID_TALKON, - NPC_MID_TALKOFF, - NPC_MID_SAWPLYR, - NPC_MID_NEEDMEDIC, - NPC_MID_UNDERATTACK, - NPC_MID_NPCDIED, - NPC_MID_PLYRSPATULA, - NPC_MID_BECOMESCARED, - NPC_MID_NOLONGERSCARED, - NPC_MID_CELEBRATE, - NPC_MID_STUN, - NPC_MID_SCRIPTBEGIN, - NPC_MID_SCRIPTEND, - NPC_MID_SCRIPTHALT, - NPC_MID_DEV_ANIMSPIN, - NPC_MID_DEV_ANIMCYCLE, - NPC_MID_DEV_HEROMODE, - NPC_MID_DEV_DONE, - NPC_MID_NOMORE, - NPC_MID_FORCE = 0x7fffffff -}; - -enum en_NPC_MSG_DATA -{ - NPC_MDAT_BLANK, - NPC_MDAT_SYSEVENT, - NPC_MDAT_BLAST, - NPC_MDAT_CHAT, - NPC_MDAT_SPAWN, - NPC_MDAT_TARGET, - NPC_MDAT_DAMAGE, - NPC_MDAT_STUN, - NPC_MDAT_SCRIPT, - NPC_MDAT_MOUNT, - NPC_MDAT_AREANOTIFY, - NPC_MDAT_NOMORE, - NPC_MDAT_FORCE = 0x7fffffff -}; - enum en_SM_NOTICES { SM_NOTE_NPCDIED, @@ -534,24 +436,25 @@ struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 // vTable (zNPCCommon) virtual S32 NPCMessage(NPCMsg* mail); - + virtual void RenderExtra() { - } - + virtual void RenderExtraPostParticles() { - } - + virtual void ParseINI(); virtual void ParseLinks(); virtual void ParseProps(); virtual void SelfSetup(); virtual void SelfDestroy(); virtual S32 IsHealthy(); - virtual S32 IsAlive(); + virtual S32 IsAlive() + { + return TRUE; + } virtual void Damage(en_NPC_DAMAGE_TYPE damtype, xBase* who, const xVec3* vec_hit); virtual S32 Respawn(const xVec3* pos, zMovePoint* mvptFirst, zMovePoint* mvptSpawnRef); virtual void DuploOwner(zNPCCommon* duper); @@ -559,7 +462,9 @@ struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 virtual S32 CanRope(); virtual void LassoNotify(en_LASSO_EVENT event); virtual S32 SetCarryState(en_NPC_CARRY_STATE); - virtual void Stun(F32 stuntime); + virtual void Stun(F32 stuntime) + { + } virtual void SpeakBegin(); virtual void SpeakEnd(); virtual void SpeakStart(U32 sound, U32 param_2, S32 param_3); @@ -582,98 +487,7 @@ struct zNPCCommon : xNPCBasic //Size of zNPCCommon: 0x2A0 ~zNPCCommon(); }; -struct NPCSysEvent -{ - S32 doLinkEvents; - S32 handled; - xBase* from; - xBase* to; - U32 toEvent; - F32 toParam[4]; - xBase* toParamWidget; -}; - -struct NPCBlastInfo -{ - xVec3 pos_blast; - F32 rad_blast; - F32 spd_expand; -}; -struct NPCChatInfo -{ - xVec3 pos_chat; - F32 tym_chat; -}; - -struct NPCSpawnInfo -{ - xVec3 pos_spawn; - zMovePoint* nav_firstMovepoint; - zMovePoint* nav_spawnReference; - S32 spawnSuccess; -}; - -struct NPCTargetInfo -{ - xBase* bas_tgt; - xVec3 pos_tgt; -}; - -struct NPCDamageInfo -{ - en_NPC_DAMAGE_TYPE dmg_type; - xBase* dmg_from; - xVec3 vec_dmghit; -}; - -struct NPCStunInfo -{ - F32 tym_stuntime; - en_NPC_CARRY_STATE carrystate; - S32 allowStun; -}; - -struct NPCScriptInfo -{ - U32 aid_playanim; -}; - -struct NPCMountInfo -{ - xEnt* ent_toMount; - xCollis* col_forMount; -}; - -struct NPCAreaInfo -{ - zNPCCommon* npc_origin; - xVec3 pos_origin; -}; - -struct NPCMsg -{ - en_NPC_MSG_ID msgid; - U32 sendto; - U32 from; - en_NPC_MSG_DATA infotype; // 0xC - union - { - NPCSysEvent sysevent; - NPCBlastInfo blastarea; - NPCChatInfo chatter; - NPCSpawnInfo spawning; - NPCTargetInfo target; - NPCDamageInfo dmgdata; // 0x10 - NPCStunInfo stundata; - NPCScriptInfo scriptdata; - NPCMountInfo mountdata; - NPCAreaInfo areadata; - }; - void* attached; // 0x38 - NPCMsg* next; - F32 tmr_delay; // 0x40 -}; xFactoryInst* ZNPC_Create_Common(S32 who, RyzMemGrow* grow, void*); void ZNPC_Destroy_Common(xFactoryInst* inst); @@ -712,16 +526,4 @@ void NPCC_BuildStandardAnimTran(xAnimTable* table, char** namelist, S32* ourAnim void zNPCCommon_EjectPhlemOnPawz(); U32 xSndIsPlaying(U32 assetID, U32 parid); -// move to messenger? - -void zNPCMsg_AreaNotify(zNPCCommon* sender, en_NPC_MSG_ID msgid, F32 rad, S32 filter, - en_NPCTYPES toNPCType); -void zNPCMsg_AreaNotify(zNPCCommon*, en_NPC_MSG_ID, F32, S32, en_NPCTYPES*); -void zNPCMsg_AreaNotify(zNPCCommon*, NPCMsg*, F32, S32, en_NPCTYPES*); - -void zNPCMsg_SendMsg(NPCMsg, F32, zNPCCommon*); -void zNPCMsg_SendMsg(en_NPC_MSG_ID msgevent, zNPCCommon* npc_sendto); -void zNPCMsg_SendMsg(NPCMsg* inmsg, zNPCCommon* npc_sendto); -void zNPCMsg_SendMsg(NPCMsg* inmsg, F32 delay, zNPCCommon* npc_sendto); - #endif diff --git a/src/SB/Game/zNPCTypeDuplotron.cpp b/src/SB/Game/zNPCTypeDuplotron.cpp index d36e0cbb3..68553f642 100644 --- a/src/SB/Game/zNPCTypeDuplotron.cpp +++ b/src/SB/Game/zNPCTypeDuplotron.cpp @@ -2,6 +2,7 @@ #include "xMathInlines.h" #include "zGlobals.h" #include "zNPCGoalCommon.h" +#include "zNPCGoals.h" #include "zNPCSupport.h" #include "zNPCTypeDuplotron.h" diff --git a/src/SB/Game/zNPCTypeTiki.cpp b/src/SB/Game/zNPCTypeTiki.cpp index a3d673108..b45ce6db2 100644 --- a/src/SB/Game/zNPCTypeTiki.cpp +++ b/src/SB/Game/zNPCTypeTiki.cpp @@ -5,14 +5,18 @@ #include "xScrFx.h" #include "xutil.h" +#include "zEntButton.h" #include "zGlobals.h" #include "zGoo.h" +#include "zNPCGoals.h" #include "zNPCGoalTiki.h" #include "zNPCHazard.h" #include "zNPCSupplement.h" #include "zNPCTypeTiki.h" #include "zSurface.h" +#include "iCollide.h" + #define ANIM_COUNT 2 #define NUM_PARENTS 4 #define NUM_CHILDREN 4