From f3de60cc7c7fa9a5e99fa3f07d9889d1fa0bd05e Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Sat, 12 Apr 2025 15:59:37 -0500 Subject: [PATCH 1/4] zNPCTypeBossSandy: Add SandyLimbSpring struct from DWARF data --- src/SB/Game/zNPCTypeBossSandy.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/SB/Game/zNPCTypeBossSandy.h b/src/SB/Game/zNPCTypeBossSandy.h index cbd5280fb..1914bfea5 100644 --- a/src/SB/Game/zNPCTypeBossSandy.h +++ b/src/SB/Game/zNPCTypeBossSandy.h @@ -342,6 +342,15 @@ struct SandyLimbSpring xBound* bound; }; +struct SandyLimbSpring +{ + F32 node1; + F32 vel1; + F32 node2; + F32 vel2; + xBound* bound; +}; + void zNPCBSandy_AddBoundEntsToGrid(zScene*); void zNPCBSandy_GameIsPaused(zScene*); From c39a779826844875e1516bf63a5577ce411aa4cb Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 18 Apr 2025 11:06:03 -0500 Subject: [PATCH 2/4] zNPCTypeBossSandy: sit, getUp, runToRope, clothesline callbacks --- src/SB/Game/zNPCTypeBossSandy.cpp | 147 +++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/src/SB/Game/zNPCTypeBossSandy.cpp b/src/SB/Game/zNPCTypeBossSandy.cpp index 64c78f188..e2922ceb6 100644 --- a/src/SB/Game/zNPCTypeBossSandy.cpp +++ b/src/SB/Game/zNPCTypeBossSandy.cpp @@ -15,6 +15,7 @@ #include "xMarkerAsset.h" #include "zCamera.h" #include "zGrid.h" +#include "zAssetTypes.h" extern const char bossSandyStrings[]; @@ -966,10 +967,148 @@ static S32 leapCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*) return nextgoal; } -static S32 sitCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*); -static S32 getUpCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*); -static S32 runToRopeCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*); -static S32 clotheslineCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*); +static S32 sitCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*) +{ + zNPCGoalBossSandySit* sit = (zNPCGoalBossSandySit*)rawgoal; + zNPCBSandy* sandy = (zNPCBSandy*)sit->psyche->clt_owner; + S32 nextgoal = 0; + + if (sandy->round == 3 && sHeadPopOffFactor > 0.0f) + { + xSndPlay3D(xStrHash("B101_SC_headoff1"), 2.31f, 0.0f, 0x0, 0x0, sandy, 30.0f, SND_CAT_GAME, + 0.0f); + *trantype = GOAL_TRAN_SET; + nextgoal = 'NGB5'; + } + else if (sit->sitFlags & 0x1) + { + if (sit->timeInGoal > sit->totalTime) + { + if (sandy->round == 1) + { + nextgoal = 'NGB9'; + *trantype = GOAL_TRAN_SET; + } + else + { + nextgoal = 'NGB5'; + *trantype = GOAL_TRAN_SET; + } + } + } + else if (sit->timeInGoal > 5.0f) + { + nextgoal = 'NGB9'; + *trantype = GOAL_TRAN_SET; + } + + return nextgoal; +} + +static S32 getUpCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*) +{ + zNPCGoalBossSandyRunToRope* runGoal = (zNPCGoalBossSandyRunToRope*)rawgoal; + zNPCBSandy* sandy = (zNPCBSandy*)runGoal->psyche->clt_owner; + S32 nextgoal = 0; + xVec3 pcFuturePos; + F32 futureDist; + + xVec3Sub(&pcFuturePos, (xVec3*)&globals.player.ent.model->Mat->pos, + (xVec3*)&sandy->model->Mat->pos); + + pcFuturePos.y = 0.0f; + futureDist = xVec3Length2(&pcFuturePos); + + if (sandy->AnimTimeRemain(NULL) < 1.7f * dt) + { + if ((sandy->round == 1 && !(sandy->hitPoints > 6)) || + (sandy->round == 2 && !(sandy->hitPoints > 3)) || + (sandy->round == 3 && !(sandy->hitPoints > 0)) || (globals.player.ControlOff)) + { + nextgoal = 'NGB1'; + *trantype = GOAL_TRAN_SET; + } + else if (sandy->bossFlags & 0x2) + { + sandy->bossFlags &= ~0x2; + nextgoal = 'NGB2'; + *trantype = GOAL_TRAN_SET; + } + else if (futureDist < 12.0f) + { + nextgoal = 'NGB4'; + *trantype = GOAL_TRAN_SET; + } + else + { + nextgoal = 'NGB3'; + *trantype = GOAL_TRAN_SET; + } + } + + return nextgoal; +} + +static S32 runToRopeCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*) +{ + zNPCGoalBossSandyRunToRope* runGoal = (zNPCGoalBossSandyRunToRope*)rawgoal; + zNPCBSandy* sandy = (zNPCBSandy*)runGoal->psyche->clt_owner; + S32 nextgoal = 0; + F32 projection; + xVec3 newPos; + + xVec3Sub(&newPos, &sandy->bouncePoint[sandy->fromRope], (xVec3*)&sandy->model->Mat->pos); + + newPos.y = 0.0f; + projection = xVec3Dot(&newPos, &sandy->ropeNormal[sandy->fromRope]); + + if (globals.player.ControlOff != FALSE) + { + nextgoal = 'NGB1'; + *trantype = GOAL_TRAN_SET; + } + else if (projection > 0.0f) + { + nextgoal = 'NGB;'; + *trantype = GOAL_TRAN_SET; + sandy->boundFlags[10] &= ~0x10; + sandy->boundFlags[12] &= ~0x10; + } + + return nextgoal; +} + +static S32 clotheslineCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, void*) +{ + zNPCGoalBossSandyClothesline* cl = (zNPCGoalBossSandyClothesline*)rawgoal; + zNPCBSandy* sandy = (zNPCBSandy*)cl->psyche->clt_owner; + S32 nextgoal = 0; + + if (cl->stage == 2 && sandy->AnimTimeRemain(NULL) < 1.7f * dt) + { + sandy->boundFlags[10] &= ~0x10; + sandy->boundFlags[12] &= ~0x10; + + if (globals.player.ControlOff) + { + nextgoal = 'NGB1'; + *trantype = GOAL_TRAN_SET; + } + else if (sandy->bossFlags & 0x2) + { + sandy->bossFlags &= ~0x2; + nextgoal = 'NGB2'; + *trantype = GOAL_TRAN_SET; + } + else + { + nextgoal = 'NGB3'; + *trantype = GOAL_TRAN_SET; + } + } + + return nextgoal; +} S32 zNPCGoalBossSandyIdle::Enter(F32 dt, void* updCtxt) { From a038275fc1f9fee8f7b671d5dcb2b292cebaf20e Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 18 Apr 2025 11:06:41 -0500 Subject: [PATCH 3/4] zNPCTypeBossSandy: zNPCGoalBossSandyIdle virtual implementations --- src/SB/Game/zNPCTypeBossSandy.cpp | 52 +++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/SB/Game/zNPCTypeBossSandy.cpp b/src/SB/Game/zNPCTypeBossSandy.cpp index e2922ceb6..f95568bdf 100644 --- a/src/SB/Game/zNPCTypeBossSandy.cpp +++ b/src/SB/Game/zNPCTypeBossSandy.cpp @@ -1112,13 +1112,61 @@ static S32 clotheslineCB(xGoal* rawgoal, void*, en_trantype* trantype, F32 dt, v S32 zNPCGoalBossSandyIdle::Enter(F32 dt, void* updCtxt) { - zNPCBSandy* sandy; + zNPCBSandy* sandy = (zNPCBSandy*)psyche->clt_owner; - // xVec3Init(); + timeInGoal = 0.0f; + sandy->bossFlags |= 0x20; + + xVec3Init(&sandy->frame->vel, 0.0f, 0.0f, 0.0f); + + sandy->boundFlags[10] |= 0x10; + sandy->boundFlags[12] |= 0x10; return zNPCGoalCommon::Enter(dt, updCtxt); } +S32 zNPCGoalBossSandyIdle::Process(en_trantype* trantype, F32 dt, void* updCtxt, xScene* xscn) +{ + zNPCBSandy* sandy = (zNPCBSandy*)psyche->clt_owner; + + timeInGoal += dt; + + xVec3 newAt; + xVec3Sub(&newAt, (xVec3*)&globals.player.ent.model->Mat->pos, (xVec3*)&sandy->model->Mat->pos); + + newAt.y = 0.0f; + + xVec3Normalize(&newAt, &newAt); + xVec3SMul((xVec3*)&sandy->frame->mat.at, (xVec3*)&sandy->model->Mat->at, 0.98f); + + xVec3AddScaled((xVec3*)&sandy->frame->mat.at, &newAt, 0.02f); + + sandy->frame->mat.at.y = 0.0f; + xVec3Normalize(&sandy->frame->mat.at, &sandy->frame->mat.at); + xVec3Cross(&sandy->frame->mat.right, &sandy->frame->mat.up, &sandy->frame->mat.at); + + sandy->frame->mat.pos.y = 0.0f; + xVec3Dot(&newAt, (xVec3*)&sandy->model->Mat->right); + + F32 lerp = 1.0f; + lerp -= 0.02f; + sandy->model->Anim->Single->BilinearLerp[0] = lerp; + sandy->model->Anim->Single->Blend->BilinearLerp[0] = lerp; + + return xGoal::Process(trantype, dt, updCtxt, xscn); +} + +S32 zNPCGoalBossSandyIdle::Exit(F32 dt, void* updCtxt) +{ + zNPCBSandy* sandy = (zNPCBSandy*)psyche->clt_owner; + + sandy->bossFlags &= ~0x20; + sandy->boundFlags[10] &= ~0x10; + sandy->boundFlags[12] &= ~0x10; + + return xGoal::Exit(dt, updCtxt); +} + void xBinaryCamera::add_tweaks(char const*) { } From d0550744f8b84ac3bda14671eb503761cb8abb5c Mon Sep 17 00:00:00 2001 From: Josh Sanchez Date: Fri, 18 Apr 2025 11:13:07 -0500 Subject: [PATCH 4/4] Fix: Remove redef of SandyLimbSpring bc rebasing is hard --- src/SB/Game/zNPCTypeBossSandy.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/SB/Game/zNPCTypeBossSandy.h b/src/SB/Game/zNPCTypeBossSandy.h index 1914bfea5..cbd5280fb 100644 --- a/src/SB/Game/zNPCTypeBossSandy.h +++ b/src/SB/Game/zNPCTypeBossSandy.h @@ -342,15 +342,6 @@ struct SandyLimbSpring xBound* bound; }; -struct SandyLimbSpring -{ - F32 node1; - F32 vel1; - F32 node2; - F32 vel2; - xBound* bound; -}; - void zNPCBSandy_AddBoundEntsToGrid(zScene*); void zNPCBSandy_GameIsPaused(zScene*);