From 394551ddd6f0182cf2072e90ad2999a12fff000e Mon Sep 17 00:00:00 2001 From: escape209 Date: Fri, 20 Sep 2024 12:19:31 +0100 Subject: [PATCH] zNPC related matches (#368) * zNPC related matches * More stuff * More things * Slightly more stuff * Last bits for now --- src/SB/Core/x/xFX.h | 1 + src/SB/Core/x/xVec3.h | 1 + src/SB/Game/zNPCGoalRobo.cpp | 1039 +++++++++++++++++++++++++++++++++- src/SB/Game/zNPCGoalRobo.h | 5 +- src/SB/Game/zNPCGoalStd.h | 454 ++++++++++++--- src/SB/Game/zNPCSupplement.h | 1 + src/SB/Game/zNPCSupport.h | 12 + src/SB/Game/zNPCTypeCommon.h | 2 + src/SB/Game/zNPCTypeRobot.h | 7 + 9 files changed, 1446 insertions(+), 76 deletions(-) diff --git a/src/SB/Core/x/xFX.h b/src/SB/Core/x/xFX.h index 855fc119..18bbc9ab 100644 --- a/src/SB/Core/x/xFX.h +++ b/src/SB/Core/x/xFX.h @@ -109,6 +109,7 @@ void xFXFireworksUpdate(F32 dt); void xFXStreakInit(); void xFXStreakUpdate(F32 dt); void xFXStreakRender(); +void xFXStreakStop(U32); void xFXShineInit(); void xFXShineUpdate(F32 dt); void xFXShineRender(); diff --git a/src/SB/Core/x/xVec3.h b/src/SB/Core/x/xVec3.h index 489ee6a7..d1309010 100644 --- a/src/SB/Core/x/xVec3.h +++ b/src/SB/Core/x/xVec3.h @@ -37,6 +37,7 @@ struct xVec3 xVec3& invert(); F32 dot(const xVec3& c) const; xVec3& normalize(); + xVec3& assign(F32 val); }; F32 xVec3Normalize(xVec3* o, const xVec3* v); diff --git a/src/SB/Game/zNPCGoalRobo.cpp b/src/SB/Game/zNPCGoalRobo.cpp index 9eb786cd..cb4970ff 100644 --- a/src/SB/Game/zNPCGoalRobo.cpp +++ b/src/SB/Game/zNPCGoalRobo.cpp @@ -1,4 +1,5 @@ #include "xVec3.h" +#include "xMath.h" #include "xMath3.h" #include "zNPCGoalRobo.h" #include "zNPCTypeRobot.h" @@ -9,8 +10,13 @@ #include "zNPCGoalStd.h" #include "zNPCSupport.h" #include "zNPCGoals.h" +#include "zGameExtras.h" +#include "zNPCSupport.h" +#include "zNPCTypeBoss.h" +#include "zNPCSupplement.h" +#include "zNPCMessenger.h" -F32 f_0 = 0.0f; // needed at file level to change scheduling for +#include "zNPCMgr.h" xFactoryInst* GOALCreate_Robotic(S32 who, RyzMemGrow* grow, void*) { @@ -196,14 +202,226 @@ xFactoryInst* GOALCreate_Robotic(S32 who, RyzMemGrow* grow, void*) return goal; } +void zNPCGoalTubeLasso::ChkPrelimTran(en_trantype* trantype, int* nextgoal) +{ + zNPCTubeSlave* npc = (zNPCTubeSlave*)(psyche->clt_owner); + + switch (npc->tub_pete->tubestat) + { + case TUBE_STAT_BORN: + *nextgoal = NPC_GOAL_TUBEBIRTH; + *trantype = GOAL_TRAN_SET; + break; + case TUBE_STAT_DUCKLING: + *nextgoal = NPC_GOAL_TUBEDUCKLING; + *trantype = GOAL_TRAN_SET; + break; + case TUBE_STAT_ATTACK: + *nextgoal = NPC_GOAL_TUBEATTACK; + *trantype = GOAL_TRAN_SET; + break; + case TUBE_STAT_DYING: + case TUBE_STAT_DEAD: + *nextgoal = NPC_GOAL_TUBEDYING; + *trantype = GOAL_TRAN_SET; + break; + + } + + // ????? + if (*trantype == GOAL_TRAN_NONE) + { + return; + } +} + +void zNPCGoalTubePal::ChkPrelimTran(en_trantype* trantype, int* nextgoal) +{ + zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner)); + + switch (npc->tub_pete->tubestat) + { + case TUBE_STAT_BORN: + *nextgoal = NPC_GOAL_TUBEBIRTH; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_DUCKLING: + *nextgoal = NPC_GOAL_TUBEDUCKLING; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_ATTACK: + *nextgoal = NPC_GOAL_TUBEATTACK; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_LASSO: + *nextgoal = NPC_GOAL_TUBELASSO; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_DYING: + *nextgoal = NPC_GOAL_TUBEDYING; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_DEAD: + *nextgoal = NPC_GOAL_TUBEDEAD; + *trantype = GOAL_TRAN_SET; + return; + } +} + +void zNPCGoalTubeDuckling::ChkPrelimTran(en_trantype* trantype, int* nextgoal) +{ + zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner)); + + switch (npc->tub_pete->tubestat) + { + case TUBE_STAT_BORN: + *nextgoal = NPC_GOAL_TUBEBIRTH; + *trantype = GOAL_TRAN_SET; + break; + case TUBE_STAT_ATTACK: + if (flg_duckling & 2) + { + break; + } + *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; + case TUBE_STAT_DUCKLING: + break; + } + + if (npc->hitpoints == 0) + { + *nextgoal = NPC_GOAL_TUBEBONKED; + *trantype = GOAL_TRAN_PUSH; + } +} + +void zNPCGoalTubeAttack::ChkPrelimTran(en_trantype* trantype, int* nextgoal) +{ + zNPCTubeSlave* npc = (zNPCTubeSlave*)(psyche->clt_owner); + + switch (npc->tub_pete->tubestat) + { + case TUBE_STAT_BORN: + *nextgoal = NPC_GOAL_TUBEBIRTH; + *trantype = GOAL_TRAN_SET; + break; + case TUBE_STAT_DUCKLING: + *nextgoal = NPC_GOAL_TUBEDUCKLING; + *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; + + } + + if (*trantype != 0) + { + return; + } + + if (npc->hitpoints != 0) + { + return; + } + + *nextgoal = NPC_GOAL_TUBEBONKED; + *trantype = GOAL_TRAN_PUSH; +} + +void zNPCGoalTubeBirth::ChkPrelimTran(en_trantype* trantype, int* nextgoal) +{ + zNPCTubeSlave* npc = (zNPCTubeSlave*)(psyche->clt_owner); + + switch (npc->tub_pete->tubestat) + { + case TUBE_STAT_DUCKLING: + *nextgoal = NPC_GOAL_TUBEDUCKLING; + *trantype = GOAL_TRAN_SET; + break; + case TUBE_STAT_ATTACK: + *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; + case TUBE_STAT_BORN: + break; + } + + if (npc->hitpoints != 0) + { + return; + } + + *nextgoal = NPC_GOAL_TUBEBONKED; + *trantype = GOAL_TRAN_PUSH; +} + +void zNPCGoalTubeDead::ChkPrelimTran(en_trantype* trantype, int* nextgoal) +{ + zNPCTubeSlave* npc = (zNPCTubeSlave*)(psyche->clt_owner); + + switch (npc->tub_pete->tubestat) + { + case TUBE_STAT_BORN: + *nextgoal = NPC_GOAL_TUBEBIRTH; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_DUCKLING: + *nextgoal = NPC_GOAL_TUBEDUCKLING; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_ATTACK: + *nextgoal = NPC_GOAL_TUBEATTACK; + *trantype = GOAL_TRAN_SET; + return; + case TUBE_STAT_LASSO: + *nextgoal = NPC_GOAL_TUBELASSO; + *trantype = GOAL_TRAN_SET; + return; + } + return; +} + S32 zNPCGoalAlertFodder::Enter(F32 dt, void* updCtxt) { flg_attack = 0; - tmr_alertfod = f_0; // need non-const float to get scheduling right + tmr_alertfod = 0.0f; alertfod = FODDER_ALERT_NOTICE; return zNPCGoalCommon::Enter(dt, updCtxt); } +S32 zNPCGoalAlertPuppy::Enter(F32 dt, void* updCtxt) +{ + alertpup = PUPPY_ALERT_YAPPY; + return zNPCGoalCommon::Enter(dt, updCtxt); +} + S32 zNPCGoalAlertFodder::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene) { zNPCRobot* npc = (zNPCRobot*)this->psyche->clt_owner; @@ -369,6 +587,21 @@ void zNPCGoalAlertFodder::GetInArena(F32 dt) npc->ThrottleApply(dt, &dir, 0); } +int zNPCGoalAttackFodder::CattleNotify::Notify(en_haznote hazNote, NPCHazard* haz) +{ + switch (hazNote) + { + case HAZ_NOTE_DISCARD: + case HAZ_NOTE_ABORT: + goal->haz_cattle = NULL; + break; + case HAZ_NOTE_HITPLAYER: + goal->flg_attack |= 3; + break; + } + return 0; +} + S32 zNPCGoalAttackFodder::Enter(F32 dt, void* updCtxt) { zNPCRobot* npc = (zNPCRobot*)this->psyche->clt_owner; @@ -395,6 +628,68 @@ S32 zNPCGoalAttackFodder::Enter(F32 dt, void* updCtxt) return this->zNPCGoalPushAnim::Enter(dt, updCtxt); } +S32 zNPCGoalAttackCQC::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = (zNPCCommon*)this->psyche->clt_owner; + flg_attack = 0; + return this->zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalAttackHammer::Exit(F32 dt, void* updCtxt) +{ + FXStreakDone(); + return this->zNPCGoalPushAnim::Exit(dt, updCtxt); +} + +S32 zNPCGoalLassoThrow::Exit(F32 dt, void* updCtxt) +{ + xEnt* ent = (xEnt*)(this->psyche->clt_owner); + + if ((flg_throw & 0x10) == 0) + { + ent->pflags &= 0xfb; + } + + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalKnock::StreakPrep() +{ + streakID = NPCC_StreakCreate(NPC_STRK_TOSSEDROBOT); +} + +S32 zNPCGoalAttackHammer::FXStreakPrep() +{ + streakID[0] = NPCC_StreakCreate(NPC_STRK_HAMMERSMASH_HORZ); + streakID[1] = NPCC_StreakCreate(NPC_STRK_HAMMERSMASH_VERT); +} + +S32 zNPCGoalAttackArfMelee::FXStreakPrep() +{ + for (int i = 0; i < 4; i++) + { + streakID[i] = NPCC_StreakCreate(NPC_STRK_ARFMELEE); + } +} + +S32 zNPCGoalAttackArf::SetAttackMode(S32 a, S32 b) +{ + flg_attack &= 0xfffffff8; + if (a != 0) + { + flg_attack |= 2; + if (b != 0) + { + flg_attack |= 4; + } + } + else + { + flg_attack |= 1; + } + flg_info |= 0x10; +} + S32 zNPCGoalAttackFodder::Exit(F32 dt, void* updCtxt) { if (this->haz_cattle) @@ -406,8 +701,6 @@ S32 zNPCGoalAttackFodder::Exit(F32 dt, void* updCtxt) return this->zNPCGoalPushAnim::Exit(dt, updCtxt); } -#define f_1370 1.0f - S32 zNPCGoalAttackFodder::SyncCattleProd() { xVec3 vec1; @@ -420,7 +713,7 @@ S32 zNPCGoalAttackFodder::SyncCattleProd() return var1; } - if (this->haz_cattle->tmr_remain < f_1370) + if (this->haz_cattle->tmr_remain < 1.0f) { this->haz_cattle->tym_lifespan = npc->AnimDuration(NULL); this->haz_cattle->tmr_remain = npc->AnimTimeRemain(NULL); @@ -456,6 +749,14 @@ S32 zNPCGoalAttackFodder::Process(en_trantype* trantype, F32 dt, void* updCtxt, return this->zNPCGoalPushAnim::Process(trantype, dt, updCtxt, scene); } +S32 zNPCGoalBashed::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene) +{ + xEnt* ent = ((xEnt*)(psyche->clt_owner)); + ent->frame->vel.y = -(dt * 30.0f - ent->frame->vel.y); + ent->frame->mode |= 4; + return this->zNPCGoalLoopAnim::Process(trantype, dt, updCtxt, scene); +} + void zNPCGoalAlertFodBzzt::GetInArena(F32 dt) { zNPCRobot* npc; @@ -480,6 +781,20 @@ void zNPCGoalAlertFodBzzt::GetInArena(F32 dt) npc->ThrottleApply(dt, &dir, 0); } +void zNPCGoalAlertFodBzzt::ToggleOrbit() +{ + if (flg_alert & 1) + { + flg_alert &= -2; + flg_alert |= 2; + } + else + { + flg_alert |= 1; + flg_alert &= -3; + } +} + void zNPCGoalAlertChomper::GetInArena(F32 dt) { zNPCRobot* npc; @@ -677,7 +992,8 @@ void NPCC_DrawPlayerPredict(int, float, float) void NPCLaser::ColorSet(const RwRGBA* unk1, const RwRGBA* unk2) { - // unk2->alpha = unk1->alpha; + rgba[0] = *unk1; + rgba[1] = *unk2; } void xDrawCyl(const xVec3*, float, float, unsigned int) @@ -711,8 +1027,7 @@ S32 NPCArena::IncludesPlayer(F32 rad_thresh, xVec3* vec) S32 NPCArena::IsReady() { - // TODO: not matching, not sure what this is - return this->rad_arena == 1.0f; // @1130 check this float value + return rad_arena > 1.0f; } void NPCBattle::LeaveBattle(zNPCRobot*) @@ -755,3 +1070,711 @@ void xMat3x3RMulVec(xVec3* o, const xMat3x3* m, const xVec3* v) o->y = y; o->z = z; } + +S32 zNPCGoalDogPounce::NPCMessage(NPCMsg* mail) +{ + S32 ret = 0; + switch (mail->msgid) + { + case NPC_MID_DAMAGE: + flg_user = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +S32 zNPCGoalDogPounce::Enter(F32 dt, void* updCtxt) +{ + flg_user = 0; + return zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalDogPounce::Exit(F32 dt, void* updCtxt) +{ + if (flg_user == 0) + { + Detonate(); + } + return zNPCGoalPushAnim::Exit(dt, updCtxt); +} + +S32 zNPCGoalDogBark::Enter(F32 dt, void* updCtxt) +{ + zNPCGoalLoopAnim::LoopCountSet(1); + return zNPCGoalLoopAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalDogDash::Enter(F32 dt, void* updCtxt) +{ + zNPCGoalLoopAnim::LoopCountSet(1); + return zNPCGoalLoopAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalAttackTarTar::Enter(F32 dt, void* updCtxt) +{ + ((zNPCCommon*)(psyche->clt_owner))->VelStop(); + flg_pushanim |= 2; + idx_launch = 1; + flg_attack = 0; + xVec3Copy(&pos_aimbase, &g_O3); + return zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalAttackChomper::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* com = ((zNPCCommon*)(psyche->clt_owner)); + com->VelStop(); + com->SndPlayRandom(NPC_STYP_ATTACK); + + return zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalEvilPat::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* com = ((zNPCCommon*)(psyche->clt_owner)); + + S32 typ = com->SelfType(); + + if ((typ - 'NT\0\0') == 'R3') + { + com->flg_vuln |= 0x80000000; + } + + GlyphStart(); + + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalEvilPat::Exit(F32 dt, void* updCtxt) +{ + zNPCCommon* com = ((zNPCCommon*)(psyche->clt_owner)); + + S32 typ = com->SelfType(); + + if ((typ - 'NT\0\0') == 'R3') + { + com->flg_vuln &= 0x7FFFFFFF; + } + + *(F32*)(&com->snd_queue[6].flg_snd) = -1.0f; + + GlyphStop(); + + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalEvilPat::NPCMessage(NPCMsg* mail) +{ + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + switch (mail->msgid) + { + case NPC_MID_STUN: + F32 stuntime = mail->stundata.tym_stuntime; + F32 blah = (xurand() - 0.5f); + blah = 0.25f * blah; + *(F32*)(&npc->snd_queue[6].flg_snd) = stuntime + (stuntime * blah); + return 1; + } + return 0; +} + +S32 zNPCGoalEvilPat::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene) +{ + U32 nextgoal; + + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + + if (npc->tmr_stunned < 0.0f) + { + *trantype = GOAL_TRAN_SET; + nextgoal = 'NGR4'; + } + else + { + *trantype = GOAL_TRAN_PUSH; + nextgoal = 'NGRa'; + } + + return (*trantype != GOAL_TRAN_NONE) ? nextgoal : xGoal::Process(trantype, dt, updCtxt, scene); +} + +S32 zNPCGoalTaunt::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->SndPlayRandom(NPC_STYP_LAUGH); + zNPCGoalLoopAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalAttackArfMelee::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + FXStreakPrep(); + npc->SndPlayRandom(NPC_STYP_PUNCH); + zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalAttackHammer::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + flg_attack = 0; + FXStreakPrep(); + + npc->GetVertPos(NPC_MDLVERT_ATTACK, &pos_lastVert); + pos_oldVert = pos_lastVert; + + return zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +void zNPCGoalAttackHammer::ModifyAnimSpeed() +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + F32 speed = 1.5f; + U32 cheats = zGameExtras_CheatFlags(); + if ((cheats & 0x800)) + { + speed = 2.5f; + } + xAnimSingle* anim = npc->AnimCurSingle(); + anim->CurrentSpeed = speed; +} + +void zNPCGoalAttackHammer::TellBunnies() +{ + static en_NPCTYPES toTypes[3] = + { + NPC_TYPE_FODDER, + NPC_TYPE_FODBOMB, + NPC_TYPE_CHOMPER + }; + + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + + zNPCMsg_AreaNotify + ( + npc, + NPC_MID_BUNNYHOP, + 8.0f, + 18, + (en_NPCTYPES)toTypes + ); +} + +S32 zNPCGoalEvade::Enter(F32 dt, void* updCtxt) +{ + flg_evade = 0; + + if (xrand() & 0x00800000) + { + flg_evade |= 1; + } + else + { + flg_evade |= 2; + } + + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalHokeyPokey::Enter(F32 dt, void* updCtxt) +{ + zNPCFodBzzt* bzzt = ((zNPCFodBzzt*)(psyche->clt_owner)); + flg_hokey = (xrand() >> 0x17) & 1; + flg_hokey |= 2; + ang_spinrate = 0.0f; + bzzt->DiscoReset(); + return zNPCGoalLoopAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalTubeBirth::Enter(F32 dt, void* updCtxt) +{ + zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner)); + npc->hitpoints = npc->cfg_npc->pts_damage; + npc->VelStop(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertTarTar::Enter(F32 dt, void* updCtxt) +{ + zNPCTarTar* npc = ((zNPCTarTar*)(psyche->clt_owner)); + flg_attack = 0; + alerttart = TARTAR_ALERT_BEGIN; + hoppy = HOPPY_PATTERN_START; + tmr_reload = 0.0f; + npc->VelStop(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertTarTar::Resume(F32 dt, void* updCtxt) +{ + zNPCTarTar* npc = ((zNPCTarTar*)(psyche->clt_owner)); + npc->VelStop(); + flg_info |= 2; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAttackMonsoon::Enter(F32 dt, void* updCtxt) +{ + idx_launch = 0; + flg_pushanim |= 2; + return zNPCGoalPushAnim::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertArf::Enter(F32 dt, void* updCtxt) +{ + alertarf = ARF_ALERT_READY; + tmr_reload = -1.0f; + flg_user = 1; + + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertHammer::Enter(F32 dt, void* updCtxt) +{ + flg_attack = 0; + alertham = HAMMER_ALERT_NOTICE; + + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertChuck::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + alertchuk = CHUCK_ALERT_NOTICE; + npc->VelStop(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalTubeAttack::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->VelStop(); + AttackDataReset(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +void zNPCGoalTubeAttack::MaryzBlessing() +{ + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + npc->hitpoints = 1; + npc->tub_paul->hitpoints = 1; + npc->tub_paul->tub_pete->hitpoints = 1; +} + +S32 zNPCGoalTubeAttack::MarySpinDown(F32 dt) +{ + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + + S32 ret = 0; + + if (mary.ang_spinrate < npc->cfg_npc->spd_turnMax) + { + ret = 1; + } + else + { + mary.ang_spinrate = -((2 * PI) * dt - mary.ang_spinrate); + } + + npc->frame->drot.angle = dt * mary.ang_spinrate; + npc->frame->mode |= 0x20; + return ret; +} + +S32 zNPCGoalAlertChomper::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + alertchomp = CHOMPER_ALERT_NOTICE; + npc->VelStop(); + pos_evade = g_O3; + tmr_evade = -1.0f; + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertMonsoon::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + flg_attack = 0; + alertmony = MONSOON_ALERT_NOTICE; + tmr_reload = 0.0; + xVec3Copy(&pos_corner, npc->Pos()); + zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalTubeLasso::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->VelStop(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalTubeDying::DeathByLasso(const xVec3* vec) +{ + flg_tubedying |= 1; + pos_lassoDeath = *vec; +} + +S32 zNPCGoalAlertSlick::Resume(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->VelStop(); + flg_info |= 2; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAlertSlick::Enter(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + alertslik = SLICK_ALERT_BEGIN; + tmr_reload = -1.0f; + npc->VelStop(); + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAttackSlick::FireOne(S32) +{ + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + return npc->LaunchProjectile(NPC_HAZ_OILBUBBLE, 9.0f, 4.0f, NPC_MDLVERT_ATTACK, 4.0f, 0.1f); +} + +S32 zNPCGoalAttackChuck::BombzAway(F32 param_1) +{ + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + npc->SndPlayRandom(NPC_STYP_ATTACK); + return npc->LaunchProjectile(NPC_HAZ_CHUCKBOMB, 15.0f, 3.0f, NPC_MDLVERT_ATTACK, 4.0f, 0.0f); +} + +S32 zNPCGoalAttackChuck::Exit(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->ModelAtomicHide(1, NULL); + return zNPCGoalPushAnim::Exit(dt, updCtxt); +} + +S32 zNPCGoalAlertTubelet::Enter(F32 dt, void* updCtxt) +{ + zNPCTubeSlave* npc = ((zNPCTubeSlave*)(psyche->clt_owner)); + npc->tubespot = ROBO_TUBE_MARY; + return zNPCGoalCommon::Enter(dt, updCtxt); +} + +S32 zNPCGoalAlertTubelet::Exit(F32 dt, void* updCtxt) +{ + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + zNPC_SNDStop(eNPCSnd_TubeAttack); + npc->pete_attack_last = 0; + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalKnock::Exit(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->VelStop(); + StreakDone(); + + if (!(flg_knock & 4)) + { + npc->pflags &= 0xfb; + } + + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalAlertHammer::Exit(F32 dt, void* updCtxt) +{ + zNPCHammer* npc = ((zNPCHammer*)(psyche->clt_owner)); + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalLassoBase::Exit(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = ((zNPCCommon*)(psyche->clt_owner)); + npc->LassoNotify(LASS_EVNT_ENDED); + return xGoal::Exit(dt, updCtxt); +} + +// Equivalent. Weirdness with reloading zNPCFodBzzt::cnt_alerthokey and regalloc. +S32 zNPCGoalAlertFodBzzt::Exit(F32 dt, void* updCtxt) +{ + zNPCFodBzzt::cnt_alerthokey--; + zNPCFodBzzt::cnt_alerthokey = ~(zNPCFodBzzt::cnt_alerthokey >> 31) & zNPCFodBzzt::cnt_alerthokey; + + zNPC_SNDStop(eNPCSnd_FodBzztAttack); + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalAlertArf::Exit(F32 dt, void* updCtxt) +{ + zNPCArfArf* npc = ((zNPCArfArf*)(psyche->clt_owner)); + flg_info = 0; + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalAlertMonsoon::Exit(F32 dt, void* updCtxt) +{ + return xGoal::Exit(dt, updCtxt); +} + +S32 zNPCGoalAlertTubelet::Resume(F32 dt, void* updCtxt) +{ + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + npc->tubestat = TUBE_STAT_ATTACK; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalTubeAttack::Resume(F32 dt, void* updCtxt) +{ + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + npc->VelStop(); + AttackDataReset(); + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAlertPuppy::Resume(F32 dt, void* updCtxt) +{ + zNPCChomper* npc = ((zNPCChomper*)(psyche->clt_owner)); + flg_info |= 2; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAlertArf::Resume(F32 dt, void* updCtxt) +{ + zNPCArfArf* npc = ((zNPCArfArf*)(psyche->clt_owner)); + flg_info |= 2; + flg_user = 1; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAlertChuck::Resume(F32 dt, void* updCtxt) +{ + zNPCChuck* npc = ((zNPCChuck*)(psyche->clt_owner)); + flg_info |= 2; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAlertMonsoon::Resume(F32 dt, void* updCtxt) +{ + alertmony = MONSOON_ALERT_BEGIN; + flg_attack = 0; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAlertFodBomb::Resume(F32 dt, void* updCtxt) +{ + flg_info |= 2; + return zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalAttackArf::Exit(F32 dt, void* updCtxt) +{ + flg_attack = 0; + return zNPCGoalPushAnim::Exit(dt, updCtxt); +} + +S32 zNPCGoalAttackArfMelee::Exit(F32 dt, void* updCtxt) +{ + FXStreakDone(); + return zNPCGoalPushAnim::Exit(dt, updCtxt); +} + +S32 zNPCGoalAttackArf::LaunchBone(F32 dt, S32 param_2) +{ + zNPCArfArf* npc = ((zNPCArfArf*)(psyche->clt_owner)); + return npc->LaunchProjectile(NPC_HAZ_ARFBONE, 8.0, 3.5, NPC_MDLVERT_ATTACK, 4.0f, 0.35f); +} + +void zNPCGoalKnock::StreakDone() +{ + xFXStreakStop(streakID); + streakID = 0xDEAD; +} + +void zNPCGoalAttackArfMelee::FXStreakDone() +{ + for (S32 i = 0; i < (S32)(sizeof(this->streakID) / sizeof(U32)); i++) + { + xFXStreakStop(streakID[i]); + streakID[i] = 0xDEAD; + } +} + +S32 zNPCGoalAttackHammer::FXStreakDone() +{ + for (S32 i = 0; i < (S32)(sizeof(this->streakID) / sizeof(U32)); i++) + { + xFXStreakStop(streakID[i]); + streakID[i] = 0xDEAD; + } +} + +void zNPCGoalTubeAttack::AttackDataReset() +{ + zNPCTubelet* npc = ((zNPCTubelet*)(psyche->clt_owner)); + flg_attack = 0; + if (npc->tubestat == TUBE_STAT_ATTACK) + { + mary.marystat = TUBE_MARY_WAIT; + mary.ang_spinrate = 0.0; + } + else + { + paul.flg_paul = 1; + paul.cnt_nextlos = -1; + paul.len_laser = 10.0f; + } +} + +S32 zNPCGoalWound::NPCMessage(NPCMsg* msg) +{ + switch (msg->msgid) + { + case NPC_MID_DAMAGE: + return 1; + } + return 0; +} + +S32 zNPCGoalTeleport::NPCMessage(NPCMsg* msg) +{ + switch (msg->msgid) + { + case NPC_MID_DAMAGE: + return 1; + } + return 0; +} + +S32 zNPCGoalAlertTubelet::PeteAttackBegin() +{ + zNPCTubelet* npc = (zNPCTubelet *)(psyche->clt_owner); + npc->pete_attack_last = 1; + zNPC_SNDPlay3D(eNPCSnd_TubeAttack, npc); +} + +S32 zNPCGoalAlertGlove::Resume(F32 dt, void* updCtxt) +{ + zNPCCommon* npc = (zNPCCommon *)(psyche->clt_owner); + npc->flg_vuln &= 0xffefffff; + npc->flg_vuln &= 0x7dfeffff; + tmr_minAttack = 1.0; + zNPC_SNDPlay3D(eNPCSnd_GloveAttack, npc); + zNPCGoalCommon::Resume(dt, updCtxt); +} + +S32 zNPCGoalRespawn::InputInfo(NPCSpawnInfo* info) +{ + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + + flg_info = 0x10; + xVec3Copy(&pos_poofHere, &info->pos_spawn); + + if (info->nav_spawnReference != NULL) + { + npc->nav_curr = info->nav_spawnReference; + } + else + { + npc->nav_curr = info->nav_firstMovepoint; + } + + npc->nav_dest = info->nav_firstMovepoint; + return flg_info; +} + +S32 zNPCGoalStunned::InputInfo(NPCStunInfo* info) +{ + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + flg_info = 0x10; + F32 stunTime = npc->tmr_stunned; + F32 infoStun = info->tym_stuntime; + stunTime = (stunTime > infoStun) ? stunTime : infoStun; + npc->tmr_stunned = stunTime; + return flg_info; +} + +S32 zNPCGoalEvilPat::InputStun(NPCStunInfo* info) +{ + xPsyche* psyche = xGoal::GetPsyche(); + zNPCGoalStunned* stunned = (zNPCGoalStunned *)psyche->FindGoal(NPC_GOAL_STUNNED); + return stunned == NULL ? 0 : stunned->InputInfo(info); +} + +void zNPCGoalEvilPat::GlyphStop() +{ + zNPCRobot* npc = ((zNPCRobot*)(psyche->clt_owner)); + if (npc->glyf_stun != NULL) + { + npc->glyf_stun->Discard(); + } + npc->glyf_stun = NULL; +} + +S32 zNPCGoalAlertFodBzzt::Suspend(F32 dt, void* updCtxt) +{ + zNPCGlove* npc = ((zNPCGlove*)(psyche->clt_owner)); + zNPC_SNDStop(eNPCSnd_FodBzztAttack); + xGoal::Suspend(dt, updCtxt); +} + +S32 zNPCGoalAlertGlove::Suspend(F32 dt, void* updCtxt) +{ + zNPCGlove* npc = ((zNPCGlove*)(psyche->clt_owner)); + npc->flg_vuln |= 0x00100000; + npc->flg_vuln |= 0x82010000; + zNPC_SNDStop(eNPCSnd_GloveAttack); + xGoal::Suspend(dt, updCtxt); +} + +void NPCArena::IncludesNPC(zNPCCommon* npc, float dt, xVec3* vec) +{ + xVec3* pos = npc->Pos(); + IncludesPos(pos, dt, vec); +} + +S32 zNPCGoalDamage::NPCMessage(NPCMsg* msg) +{ + U32 ret = 1; + xPsyche* psyche = (xPsyche *)xGoal::GetPsyche(); + switch (msg->msgid) + { + case NPC_MID_DAMAGE: + if + ( + (msg->infotype == NPC_MDAT_DAMAGE) && + ((msg->dmgdata.dmg_type == DMGTYP_SURFACE) || + (msg->dmgdata.dmg_type == DMGTYP_DAMAGE_SURFACE)) + ) + { + psyche->GoalSet(NPC_GOAL_AFTERLIFE, 0); + } + break; + default: + ret = 0; + break; + } + + return ret; +} + +xVec3& xVec3::assign(float dt) +{ + return assign(dt, dt, dt); +} + +F32 EASE(float rhs) +{ + return rhs * ((rhs * 3.0f) - (rhs * 2.0f) * rhs); +} + +F32 LERP(F32 x, F32 y, F32 z) +{ + return (x * (z - y)) + y; +} + +U8 LERP(float x, U8 y, U8 z) +{ + return (U8)(x * (z - y)) + y; +} \ No newline at end of file diff --git a/src/SB/Game/zNPCGoalRobo.h b/src/SB/Game/zNPCGoalRobo.h index ff2bfdae..7fffc74c 100644 --- a/src/SB/Game/zNPCGoalRobo.h +++ b/src/SB/Game/zNPCGoalRobo.h @@ -6,7 +6,10 @@ class zNPCGoalNotice : public zNPCGoalPushAnim { public: - zNPCGoalNotice(S32); + zNPCGoalNotice(S32 id) : zNPCGoalPushAnim(id) + { + SetFlags(2); + } }; void ROBO_PrepRoboCop(); diff --git a/src/SB/Game/zNPCGoalStd.h b/src/SB/Game/zNPCGoalStd.h index 8a577a62..7aa9dd72 100644 --- a/src/SB/Game/zNPCGoalStd.h +++ b/src/SB/Game/zNPCGoalStd.h @@ -271,7 +271,13 @@ class zNPCGoalAttackChuck : public zNPCGoalPushAnim { // total size: 0x58 public: - zNPCGoalAttackChuck(S32); + zNPCGoalAttackChuck(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + S32 BombzAway(F32); + S32 Exit(F32 dt, void* updCtxt); S32 idx_launch; // offset 0x54, size 0x4 }; @@ -279,21 +285,35 @@ class zNPCGoalLassoBase : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalLassoBase(S32); + zNPCGoalLassoBase(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(12); + } + + S32 Exit(F32 dt, void* updCtxt); }; class zNPCGoalLassoGrab : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalLassoGrab(S32); + zNPCGoalLassoGrab(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + } }; class zNPCGoalLassoThrow : public zNPCGoalCommon { // total size: 0x58 public: - zNPCGoalLassoThrow(S32); + zNPCGoalLassoThrow(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + flg_npcgable |= 1; + } + + S32 Exit(F32 dt, void* updCtxt); S32 flg_throw; // offset 0x4C, size 0x4 S32 floorBounce; // offset 0x50, size 0x4 F32 tmr_colDelay; // offset 0x54, size 0x4 @@ -303,7 +323,12 @@ class zNPCGoalAttackSlick : public zNPCGoalLoopAnim { // total size: 0x70 public: - zNPCGoalAttackSlick(S32); + zNPCGoalAttackSlick(S32 id) : zNPCGoalLoopAnim(id) + { + xGoal::SetFlags(6); + } + + S32 FireOne(S32); S32 idx_launch; // offset 0x6C, size 0x4 }; @@ -311,7 +336,16 @@ class zNPCGoalAttackArfMelee : public zNPCGoalPushAnim { // total size: 0x64 public: - zNPCGoalAttackArfMelee(S32); + zNPCGoalAttackArfMelee(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(6); + } + + S32 Enter(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); + S32 FXStreakPrep(); + void FXStreakDone(); + U32 streakID[4]; // offset 0x54, size 0x10 }; @@ -319,7 +353,14 @@ class zNPCGoalAttackArf : public zNPCGoalPushAnim { // total size: 0x58 public: - zNPCGoalAttackArf(S32); + zNPCGoalAttackArf(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(6); + } + + S32 LaunchBone(F32 dt, S32 param_2); + S32 Exit(F32 dt, void* updCtxt); + S32 SetAttackMode(S32 a, S32 b); S32 flg_attack; // offset 0x54, size 0x4 }; @@ -384,34 +425,62 @@ class zNPCGoalEvilPat : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalEvilPat(S32); + zNPCGoalEvilPat(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(12); + } + + S32 Enter(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); + F32 GlyphStart(); + void GlyphStop(); + S32 NPCMessage(NPCMsg* mail); + S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene); + S32 InputStun(NPCStunInfo* info); }; class zNPCGoalPatCarry : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalPatCarry(S32); + zNPCGoalPatCarry(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + } }; class zNPCGoalStunned : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalStunned(S32); + zNPCGoalStunned(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + } + + S32 InputInfo(NPCStunInfo* info); + S32 Enter(F32 dt, void* updCtxt); }; class zNPCGoalEvade : public zNPCGoalCommon { public: - zNPCGoalEvade(S32); + zNPCGoalEvade(S32 id) : zNPCGoalCommon(id) + { + SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); S32 flg_evade; // offset 0x4C, size 0x4 }; class zNPCGoalGoHome : public zNPCGoalCommon { public: - zNPCGoalGoHome(S32); + zNPCGoalGoHome(S32 id) : zNPCGoalCommon(id) + { + SetFlags(2); + } }; enum en_slepatak @@ -436,7 +505,16 @@ class zNPCGoalAlertArf : public zNPCGoalCommon { // total size: 0x54 public: - zNPCGoalAlertArf(S32); + zNPCGoalAlertArf(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + xGoal::AddFlags(8); + flg_npcgauto &= 0xfffffff9; + } + + S32 Enter(F32 dt, void* updCtxt); + S32 Resume(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); en_alertarf alertarf; // offset 0x4C, size 0x4 F32 tmr_reload; // offset 0x50, size 0x4 }; @@ -455,7 +533,13 @@ class zNPCGoalAlertPuppy : public zNPCGoalCommon { // total size: 0x50 public: - zNPCGoalAlertPuppy(S32); + zNPCGoalAlertPuppy(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + + S32 Resume(F32 dt, void* updCtxt); + S32 Enter(F32 dt, void* updCtxt); enum en_alertpuppy alertpup; // offset 0x4C, size 0x4 }; @@ -463,7 +547,11 @@ class zNPCGoalAlertSleepy : public zNPCGoalCommon { // total size: 0x64 public: - zNPCGoalAlertSleepy(S32); + zNPCGoalAlertSleepy(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + xVec3 dir_attack; // offset 0x4C, size 0xC S32 flg_attack; // offset 0x58, size 0x4 en_slepatak sleepattack; // offset 0x5C, size 0x4 @@ -474,20 +562,31 @@ class zNPCGoalChase : public zNPCGoalCommon { // total size: 0x50 public: - zNPCGoalChase(S32); + zNPCGoalChase(S32 id) : zNPCGoalCommon(id) + { + SetFlags(2); + } + S32 flg_chase; // offset 0x4C, size 0x4 }; struct zNPCGoalTaunt : zNPCGoalLoopAnim { - zNPCGoalTaunt(S32); + zNPCGoalTaunt(S32 id) : zNPCGoalLoopAnim(id) + { + SetFlags(2); + } + S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* xscn); S32 Enter(F32 dt, void* updCtxt); }; struct zNPCGoalPatThrow : zNPCGoalCommon { - zNPCGoalPatThrow(S32); + zNPCGoalPatThrow(S32 id) : zNPCGoalCommon(id) + { + flg_npcgable = 1; + } S32 Enter(F32 dt, void* updCtxt); U8 CollReview(void*); @@ -510,7 +609,12 @@ class zNPCGoalAttackCQC : public zNPCGoalPushAnim { // total size: 0x64 public: - zNPCGoalAttackCQC(S32); + zNPCGoalAttackCQC(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); xVec3 dir_attack; // offset 0x54, size 0xC S32 flg_attack; // offset 0x60, size 0x4 }; @@ -522,7 +626,11 @@ struct zNPCGoalAlertSlick : zNPCGoalCommon F32 tmr_reload; xVec3 pos_corner; - zNPCGoalAlertSlick(S32); + zNPCGoalAlertSlick(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + void MoveCorner(F32 dt); void GetInArena(F32 dt); S32 NPCMessage(NPCMsg* mail); @@ -535,7 +643,16 @@ class zNPCGoalAlertTubelet : public zNPCGoalCommon { // total size: 0x5C public: - zNPCGoalAlertTubelet(S32); + zNPCGoalAlertTubelet(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + + S32 PeteAttackBegin(); + S32 Exit(F32 dt, void* updCtxt); + S32 Enter(F32 dt, void* updCtxt); + S32 Resume(F32 dt, void* updCtxt); + S32 PeteAttackBegin(F32 dt, void* updCtxt); S32 flg_attack; // offset 0x4C, size 0x4 S32 cnt_nextlos; // offset 0x50, size 0x4 F32 len_laser; // offset 0x54, size 0x4 @@ -552,7 +669,11 @@ struct zNPCGoalAlertChuck : zNPCGoalCommon xVec3 dir_zoom; F32 dst_zoom; - zNPCGoalAlertChuck(S32); + zNPCGoalAlertChuck(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + S32 ZoomMove(F32 dt); void GetInArena(F32 dt); S32 Process(en_trantype* trantype, F32 dt, void* updCtxt); @@ -564,7 +685,14 @@ class zNPCGoalAlertMonsoon : public zNPCGoalCommon { // total size: 0x70 public: - zNPCGoalAlertMonsoon(S32); + zNPCGoalAlertMonsoon(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + + S32 Resume(F32 dt, void* updCtxt); + S32 Enter(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); xVec3 dir_attack; // offset 0x4C, size 0xC S32 flg_attack; // offset 0x58, size 0x4 en_alertmony alertmony; // offset 0x5C, size 0x4 @@ -576,7 +704,13 @@ class zNPCGoalAlertGlove : public zNPCGoalCommon { // total size: 0x84 public: - zNPCGoalAlertGlove(S32); + zNPCGoalAlertGlove(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + flg_npcgable |= 1; + } + S32 Suspend(F32 dt, void* updCtxt); + S32 Resume(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 @@ -594,7 +728,11 @@ struct zNPCGoalAlertTarTar : zNPCGoalCommon en_hoppy hoppy; F32 tmr_reload; - zNPCGoalAlertTarTar(S32); + zNPCGoalAlertTarTar(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + void GetInArena(F32 dt); S32 HoppyUpdate(en_trantype* trantype, F32 dt); S32 NPCMessage(NPCMsg* mail); @@ -609,7 +747,11 @@ struct zNPCGoalAlertChomper : zNPCGoalCommon xVec3 pos_evade; F32 tmr_evade; - zNPCGoalAlertChomper(S32); + zNPCGoalAlertChomper(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + S32 CheckSpot(); S32 MoveEvadePos(xVec3* pos, F32 dt); S32 CalcEvadePos(xVec3* pos); @@ -623,7 +765,13 @@ class zNPCGoalAlertHammer : public zNPCGoalCommon { // total size: 0x58 public: - zNPCGoalAlertHammer(S32); + zNPCGoalAlertHammer(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + + S32 Enter(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); S32 flg_attack; // offset 0x4C, size 0x4 en_alertham alertham; // offset 0x50, size 0x4 F32 tmr_alertham; // offset 0x54, size 0x4 @@ -641,33 +789,35 @@ struct zNPCGoalAlertFodBzzt : zNPCGoalCommon RwRGBA rgba_deathRay; S32 cnt_inContact; - zNPCGoalAlertFodBzzt(S32); + zNPCGoalAlertFodBzzt(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + void DeathRayRender(); void DeathRayUpdate(F32 dt); void OrbitPlayer(F32 dt); S32 Process(en_trantype* trantype, F32 dt, void* updCtxt); S32 Resume(F32 dt, void* updCtxt); - S32 Suspend(); - S32 Exit(); + S32 Suspend(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); S32 Enter(F32 dt, void* updCtxt); void GetInArena(F32 dt); + void ToggleOrbit(); }; struct zNPCGoalAttackFodder; -struct CattleNotify : HAZNotify -{ - zNPCGoalAttackFodder* goal; - - CattleNotify(S32 myType); - S32 Notify(en_haznote note); -}; - class zNPCGoalAttackMonsoon : public zNPCGoalPushAnim { // total size: 0x58 public: - zNPCGoalAttackMonsoon(S32); + zNPCGoalAttackMonsoon(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); S32 idx_launch; // offset 0x54, size 0x4 }; @@ -675,7 +825,12 @@ class zNPCGoalAttackTarTar : public zNPCGoalPushAnim { // total size: 0x68 public: - zNPCGoalAttackTarTar(S32); + zNPCGoalAttackTarTar(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); S32 flg_attack; // offset 0x54, size 0x4 S32 idx_launch; // offset 0x58, size 0x4 xVec3 pos_aimbase; // offset 0x5C, size 0xC @@ -685,27 +840,59 @@ class zNPCGoalAttackHammer : public zNPCGoalPushAnim { // total size: 0x78 public: - zNPCGoalAttackHammer(S32); + zNPCGoalAttackHammer(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + void ModifyAnimSpeed(); + S32 Exit(F32 dt, void* updCtxt); + S32 FXStreakPrep(); + S32 FXStreakDone(); + void TellBunnies(); + S32 Enter(F32 dt, void* updCtxt); S32 flg_attack; // offset 0x54, size 0x4 xVec3 pos_lastVert; // offset 0x58, size 0xC xVec3 pos_oldVert; // offset 0x64, size 0xC U32 streakID[2]; // offset 0x70, size 0x8 }; + class zNPCGoalAttackChomper : public zNPCGoalPushAnim { // total size: 0x54 public: - zNPCGoalAttackChomper(S32); + zNPCGoalAttackChomper(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); }; struct zNPCGoalAttackFodder : zNPCGoalPushAnim { + struct CattleNotify : HAZNotify + { + zNPCGoalAttackFodder* goal; + + CattleNotify() + { + + } + + S32 Notify(en_haznote note, NPCHazard*); + }; + xVec3 dir_attack; S32 flg_attack; CattleNotify cbNotify; NPCHazard* haz_cattle; // 0x6C - zNPCGoalAttackFodder(S32); + zNPCGoalAttackFodder(S32 id) : zNPCGoalPushAnim(id), cbNotify() + { + xGoal::SetFlags(2); + } + S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* xscn); S32 Exit(F32 dt, void* updCtxt); S32 Enter(F32 dt, void* updCtxt); @@ -716,7 +903,13 @@ class zNPCGoalAlert : public zNPCGoalCommon { // total size: 0x50 public: - zNPCGoalAlert(S32); + zNPCGoalAlert(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(0x0000C); + xGoal::AddFlags(0x20000); + flg_npcgauto &= 0xfffffff9; + } + S32 flg_alert; // offset 0x4C, size 0x4 }; @@ -724,7 +917,12 @@ class zNPCGoalAlertFodBomb : public zNPCGoalCommon { // total size: 0x5C public: - zNPCGoalAlertFodBomb(S32); + zNPCGoalAlertFodBomb(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + + S32 Resume(F32 dt, void* updCtxt); S32 flg_attack; // offset 0x4C, size 0x4 en_alertbomb alertbomb; // offset 0x50, size 0x4 F32 tmr_nextping; // offset 0x54, size 0x4 @@ -734,7 +932,11 @@ class zNPCGoalAlertFodBomb : public zNPCGoalCommon class zNPCGoalAlertFodder : public zNPCGoalCommon { public: - zNPCGoalAlertFodder(S32); + zNPCGoalAlertFodder(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(6); + } + S32 flg_attack; // offset 0x4C, size 0x4 en_alertfod alertfod; // offset 0x50, size 0x4 F32 tmr_alertfod; // offset 0x54, size 0x4 @@ -755,7 +957,12 @@ struct zNPCGoalDogLaunch : zNPCGoalCommon xParabola parabinfo; F32 tmr_remain; - zNPCGoalDogLaunch(S32); + zNPCGoalDogLaunch(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + flg_npcgable = 1; + } + void BubTrailCone(xVec3* pos, S32 num, xVec3* pos_rand, xVec3* vel_rand, xMat3x3* mat); S32 BallisticUpdate(F32 dt); void PreCollide(); @@ -770,14 +977,23 @@ class zNPCGoalDogBark : public zNPCGoalLoopAnim { // total size: 0x6C public: - zNPCGoalDogBark(S32); + zNPCGoalDogBark(S32 id) : zNPCGoalLoopAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); }; class zNPCGoalDamage : public zNPCGoalCommon { // total size: 0x50 public: - zNPCGoalDamage(S32); + zNPCGoalDamage(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(12); + } + S32 NPCMessage(NPCMsg*); S32 flg_howtodie; // offset 0x4C, size 0x4 }; @@ -785,14 +1001,22 @@ class zNPCGoalBashed : public zNPCGoalLoopAnim { // total size: 0x6C public: - zNPCGoalBashed(S32); + zNPCGoalBashed(S32 id) : zNPCGoalLoopAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* scene); }; class zNPCGoalAfterlife : public zNPCGoalDead { // total size: 0x54 public: - zNPCGoalAfterlife(S32); + zNPCGoalAfterlife(S32 id) : zNPCGoalDead(id) + { + SetFlags(12); + } }; class NPCBullseye @@ -816,21 +1040,37 @@ class zNPCGoalTubeLasso : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalTubeLasso(S32); + zNPCGoalTubeLasso(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(4); + } + + S32 Enter(F32 dt, void* updCtxt); + void ChkPrelimTran(en_trantype* trantype, int* nextgoal); }; class zNPCGoalTubeDead : public zNPCGoalDead { // total size: 0x54 public: - zNPCGoalTubeDead(S32); + zNPCGoalTubeDead(S32 id) : zNPCGoalDead(id) + { + + } + + void ChkPrelimTran(en_trantype*, int*); }; class zNPCGoalTubeDying : public zNPCGoalCommon { // total size: 0x6C public: - zNPCGoalTubeDying(S32); + zNPCGoalTubeDying(S32 id) : zNPCGoalCommon(id) + { + + } + + S32 DeathByLasso(const xVec3*); S32 flg_tubedying; // offset 0x4C, size 0x4 F32 spd_gothatway; // offset 0x50, size 0x4 S32 cnt_loop; // offset 0x54, size 0x4 @@ -843,7 +1083,11 @@ class zNPCGoalTubeBonked : public zNPCGoalCommon { // total size: 0x60 public: - zNPCGoalTubeBonked(S32); + zNPCGoalTubeBonked(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + } + F32 tmr_recover; // offset 0x4C, size 0x4 F32 ang_spinrate; // offset 0x50, size 0x4 xVec3 vec_offsetPete; // offset 0x54, size 0xC @@ -852,7 +1096,13 @@ class zNPCGoalTubeBonked : public zNPCGoalCommon class zNPCGoalTubeBirth : public zNPCGoalCommon { public: - zNPCGoalTubeBirth(S32); + zNPCGoalTubeBirth(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(4); + } + + S32 Enter(F32 dt, void* updCtxt); + void ChkPrelimTran(en_trantype* trantype, int* nextgoal); // total size: 0x4C }; @@ -860,7 +1110,18 @@ class zNPCGoalTubeAttack : public zNPCGoalCommon { // total size: 0x84 public: - zNPCGoalTubeAttack(S32); + zNPCGoalTubeAttack(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(4); + } + + void AttackDataReset(); + S32 Enter(F32 dt, void* updCtxt); + S32 Resume(F32 dt, void* updCtxt); + S32 LaserRender(); + void MaryzBlessing(); + S32 MarySpinDown(F32 dt); + void ChkPrelimTran(en_trantype* trantype, int* nextgoal); S32 flg_attack; // offset 0x4C, size 0x4 union { @@ -889,7 +1150,13 @@ class zNPCGoalTubeDuckling : public zNPCGoalCommon { // total size: 0x70 public: - zNPCGoalTubeDuckling(S32); + zNPCGoalTubeDuckling(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(4); + } + + void ChkPrelimTran(en_trantype* trantype, int* nextgoal); + S32 flg_duckling; // offset 0x4C, size 0x4 F32 tmr_running; // offset 0x50, size 0x4 F32 tmr_hoverCycle; // offset 0x54, size 0x4 @@ -903,14 +1170,25 @@ class zNPCGoalTubePal : public zNPCGoalCommon { // total size: 0x4C public: - zNPCGoalTubePal(S32); + zNPCGoalTubePal(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(0x0000C); + xGoal::AddFlags(0x20000); + flg_npcgauto &= 0xfffffff9; + } + + void ChkPrelimTran(en_trantype* trantype, int* nextgoal); }; class zNPCGoalDeflate : public zNPCGoalCommon { // total size: 0x58 public: - zNPCGoalDeflate(S32); + zNPCGoalDeflate(S32 id) : zNPCGoalCommon(id) + { + SetFlags(2); + } + F32 spd_gothatway; // offset 0x4C, size 0x4 S32 cnt_loop; // offset 0x50, size 0x4 F32 scl_shrink; // offset 0x54, size 0x4 @@ -920,7 +1198,12 @@ class zNPCGoalRespawn : public zNPCGoalCommon { // total size: 0x64 public: - zNPCGoalRespawn(S32); + zNPCGoalRespawn(S32 id) : zNPCGoalCommon(id) + { + SetFlags(2); + } + + S32 InputInfo(NPCSpawnInfo* info); F32 tmr_respawn; // offset 0x4C, size 0x4 F32 tmr_robobits; // offset 0x50, size 0x4 S32 cnt_ring; // offset 0x54, size 0x4 @@ -931,7 +1214,15 @@ class zNPCGoalKnock : public zNPCGoalCommon { // total size: 0x64 public: - zNPCGoalKnock(S32); + zNPCGoalKnock(S32 id) : zNPCGoalCommon(id) + { + SetFlags(2); + flg_npcgable |= 1; + } + + void StreakDone(); + S32 StreakPrep(); + S32 Exit(F32 dt, void* updCtxt); S32 flg_knock; // offset 0x4C, size 0x4 xVec3 pos_bumper; // offset 0x50, size 0xC S32 floorBounce; // offset 0x5C, size 0x4 @@ -942,7 +1233,13 @@ class zNPCGoalWound : public zNPCGoalPushAnim { // total size: 0x64 public: - zNPCGoalWound(S32); + zNPCGoalWound(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + flg_npcgable |= 1; + } + + S32 NPCMessage(NPCMsg*); xVec3 dir_fling; // offset 0x54, size 0xC S32 flg_knock; // offset 0x60, size 0x4 }; @@ -951,7 +1248,12 @@ class zNPCGoalHokeyPokey : public zNPCGoalLoopAnim { // total size: 0x74 public: - zNPCGoalHokeyPokey(S32); + zNPCGoalHokeyPokey(S32 id) : zNPCGoalLoopAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); S32 flg_hokey; // offset 0x6C, size 0x4 F32 ang_spinrate; // offset 0x70, size 0x4 }; @@ -960,7 +1262,12 @@ class zNPCGoalTeleport : public zNPCGoalCommon { // total size: 0x50 public: - zNPCGoalTeleport(S32); + zNPCGoalTeleport(S32 id) : zNPCGoalCommon(id) + { + xGoal::SetFlags(2); + } + + S32 NPCMessage(NPCMsg* msg); F32 tmr_countdown; // offset 0x4C, size 0x4 }; @@ -968,14 +1275,27 @@ class zNPCGoalDogPounce : public zNPCGoalPushAnim { // total size: 0x54 public: - zNPCGoalDogPounce(S32); + zNPCGoalDogPounce(S32 id) : zNPCGoalPushAnim(id) + { + xGoal::SetFlags(2); + } + + S32 NPCMessage(NPCMsg* mail); + S32 Enter(F32 dt, void* updCtxt); + S32 Exit(F32 dt, void* updCtxt); + void Detonate(); }; class zNPCGoalDogDash : public zNPCGoalLoopAnim { // total size: 0x6C public: - zNPCGoalDogDash(S32); + zNPCGoalDogDash(S32 id) : zNPCGoalLoopAnim(id) + { + xGoal::SetFlags(2); + } + + S32 Enter(F32 dt, void* updCtxt); }; xFactoryInst* GOALCreate_Standard(S32 who, RyzMemGrow* grow, void*); diff --git a/src/SB/Game/zNPCSupplement.h b/src/SB/Game/zNPCSupplement.h index 39e0318d..02350575 100644 --- a/src/SB/Game/zNPCSupplement.h +++ b/src/SB/Game/zNPCSupplement.h @@ -116,6 +116,7 @@ void NPCC_ShadowCacheReset(); void NPAR_Timestep(F32 dt); void NPCC_MakeStreakInfo(en_npcstreak styp, StreakInfo* info); void xFXStreakStart(en_npcstreak* styp); +S32 NPCC_StreakCreate(en_npcstreak styp); void UpdateAndRender(NPARMgmt param_1, F32 dt); F32 BOWL3(F32 param_1); F32 QUB(F32 param_1); diff --git a/src/SB/Game/zNPCSupport.h b/src/SB/Game/zNPCSupport.h index 8ccb5fe2..66fd3d6a 100644 --- a/src/SB/Game/zNPCSupport.h +++ b/src/SB/Game/zNPCSupport.h @@ -15,6 +15,16 @@ enum en_npctgt NPC_TGT_FORCEINT = 0x7fffffff }; +enum _tageNPCSnd +{ + eNPCSnd_GloveAttack, + eNPCSnd_SleepyAttack, + eNPCSnd_TubeAttack, + eNPCSnd_FodBzztAttack, + eNPCSnd_JellyfishAttack, + eNPCSnd_Total +}; + struct NPCTarget { en_npctgt typ_target; @@ -48,5 +58,7 @@ xVec3* NPCC_faceDir(xEnt* ent); void NPCC_ang_toXZDir(F32 angle, xVec3* dir); F32 NPCC_aimVary(xVec3* dir_aim, xVec3* pos_src, xVec3* pos_tgt, F32 dst_vary, S32 flg_vary, xVec3* pos_aimPoint); F32 NPCC_ds2_toCam(const xVec3* pos_from, xVec3* delta); +void zNPC_SNDStop(_tageNPCSnd snd); +void zNPC_SNDPlay3D(_tageNPCSnd snd, xEnt*); #endif diff --git a/src/SB/Game/zNPCTypeCommon.h b/src/SB/Game/zNPCTypeCommon.h index 6060af24..09e4abe2 100644 --- a/src/SB/Game/zNPCTypeCommon.h +++ b/src/SB/Game/zNPCTypeCommon.h @@ -407,9 +407,11 @@ struct zNPCCommon : xNPCBasic void ModelScaleSet(F32 x, F32 y, F32 z); void ModelScaleSet(F32 unk); void ModelScaleSet(const xVec3* vec); + xModelInstance* ModelAtomicHide(int index, xModelInstance* mdl); S32 AnimStart(U32 animID, S32 forceRestart); xAnimState* AnimFindState(U32 animID); xAnimState* AnimCurState(); + xAnimSingle* AnimCurSingle(); U32 AnimCurStateID(); void GiveReward(); S32 SndPlayFromSFX(xSFX* sfx, U32* sid_played); diff --git a/src/SB/Game/zNPCTypeRobot.h b/src/SB/Game/zNPCTypeRobot.h index 4e99ddd2..66582c69 100644 --- a/src/SB/Game/zNPCTypeRobot.h +++ b/src/SB/Game/zNPCTypeRobot.h @@ -27,6 +27,7 @@ struct NPCArena F32 DstSqFromHome(xVec3* pos, xVec3* delt); F32 PctFromHome(xVec3* pos); S32 IncludesPos(xVec3* pos, F32 rad_thresh, xVec3* vec); + void IncludesNPC(zNPCCommon*, float, xVec3*); F32 Radius(F32 unk); xVec3* Pos(); S32 IncludesPlayer(F32 rad_thresh, xVec3* vec); @@ -44,6 +45,7 @@ struct NPCLaser void ColorSet(const RwRGBA*, const RwRGBA*); U32 TextureGet(); + static void Render(xVec3&, xVec3&); }; struct NPCBattle @@ -171,6 +173,8 @@ struct zNPCFodBomb : zNPCRobot struct zNPCFodBzzt : zNPCRobot { + volatile static S32 cnt_alerthokey; + RwRGBA rgba_discoLight; F32 tmr_discoLight; xVec3 pos_discoLight; @@ -178,6 +182,7 @@ struct zNPCFodBzzt : zNPCRobot zNPCFodBzzt(S32 myType); zNPCLassoInfo* PRIV_GetLassoData(); + void DiscoReset(); }; struct zNPCChomper : zNPCRobot @@ -358,6 +363,8 @@ enum en_tubespot struct zNPCTubeSlave : zNPCRobot { + static NPCLaser laser; + en_tubespot tubespot; zNPCTubelet* tub_pete;