From b7783e9597564e428ac3277e786aa2f61d3b2416 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Sat, 5 Nov 2022 01:46:13 +0200 Subject: [PATCH] Match, but don't link CScriptBallTrigger Former-commit-id: 30c893ce356825344c6df542143d4c9edebb33a3 --- asm/MetroidPrime/ScriptLoader.s | 2 +- .../ScriptObjects/CScriptBallTrigger.s | 16 +-- configure.py | 2 +- include/MetroidPrime/Player/CMorphBall.hpp | 23 ++++ include/MetroidPrime/Player/CPlayer.hpp | 3 + .../ScriptObjects/CScriptBallTrigger.hpp | 27 +++++ .../ScriptObjects/CScriptBallTrigger.cpp | 100 ++++++++++++++++++ 7 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 include/MetroidPrime/Player/CMorphBall.hpp create mode 100644 include/MetroidPrime/ScriptObjects/CScriptBallTrigger.hpp create mode 100644 src/MetroidPrime/ScriptObjects/CScriptBallTrigger.cpp diff --git a/asm/MetroidPrime/ScriptLoader.s b/asm/MetroidPrime/ScriptLoader.s index 25bb6a31..6832f933 100644 --- a/asm/MetroidPrime/ScriptLoader.s +++ b/asm/MetroidPrime/ScriptLoader.s @@ -11501,7 +11501,7 @@ lbl_800CF758: /* 800CF84C 000CC7AC 38 E1 00 4C */ addi r7, r1, 0x4c /* 800CF850 000CC7B0 39 01 00 40 */ addi r8, r1, 0x40 /* 800CF854 000CC7B4 39 41 00 1C */ addi r10, r1, 0x1c -/* 800CF858 000CC7B8 48 0A 70 D5 */ bl "__ct__18CScriptBallTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC9CVector3fbfff9CVector3f" +/* 800CF858 000CC7B8 48 0A 70 D5 */ bl "__ct__18CScriptBallTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC9CVector3fbfffRC9CVector3fb" /* 800CF85C 000CC7BC 7C 7D 1B 78 */ mr r29, r3 lbl_800CF860: /* 800CF860 000CC7C0 38 61 00 58 */ addi r3, r1, 0x58 diff --git a/asm/MetroidPrime/ScriptObjects/CScriptBallTrigger.s b/asm/MetroidPrime/ScriptObjects/CScriptBallTrigger.s index fc2b2fb0..45d4221d 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptBallTrigger.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptBallTrigger.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E3E80 -lbl_803E3E80: +.global __vt__18CScriptBallTrigger +__vt__18CScriptBallTrigger: # ROM: 0x3E0E80 .4byte 0 .4byte 0 @@ -328,9 +328,9 @@ __dt__18CScriptBallTriggerFv: /* 801768E0 00173840 93 C1 00 08 */ stw r30, 8(r1) /* 801768E4 00173844 7C 7E 1B 79 */ or. r30, r3, r3 /* 801768E8 00173848 41 82 00 28 */ beq lbl_80176910 -/* 801768EC 0017384C 3C A0 80 3E */ lis r5, lbl_803E3E80@ha +/* 801768EC 0017384C 3C A0 80 3E */ lis r5, __vt__18CScriptBallTrigger@ha /* 801768F0 00173850 38 80 00 00 */ li r4, 0 -/* 801768F4 00173854 38 05 3E 80 */ addi r0, r5, lbl_803E3E80@l +/* 801768F4 00173854 38 05 3E 80 */ addi r0, r5, __vt__18CScriptBallTrigger@l /* 801768F8 00173858 90 1E 00 00 */ stw r0, 0(r30) /* 801768FC 0017385C 4B F0 03 85 */ bl __dt__14CScriptTriggerFv /* 80176900 00173860 7F E0 07 35 */ extsh. r0, r31 @@ -346,8 +346,8 @@ lbl_80176910: /* 80176924 00173884 38 21 00 10 */ addi r1, r1, 0x10 /* 80176928 00173888 4E 80 00 20 */ blr -.global "__ct__18CScriptBallTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC9CVector3fbfff9CVector3f" -"__ct__18CScriptBallTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC9CVector3fbfff9CVector3f": +.global "__ct__18CScriptBallTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC9CVector3fbfffRC9CVector3fb" +"__ct__18CScriptBallTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC9CVector3fbfffRC9CVector3fb": /* 8017692C 0017388C 94 21 FF 40 */ stwu r1, -0xc0(r1) /* 80176930 00173890 7C 08 02 A6 */ mflr r0 /* 80176934 00173894 90 01 00 C4 */ stw r0, 0xc4(r1) @@ -409,9 +409,9 @@ lbl_80176910: /* 80176A14 00173974 39 21 00 30 */ addi r9, r1, 0x30 /* 80176A18 00173978 90 01 00 14 */ stw r0, 0x14(r1) /* 80176A1C 0017397C 4B F0 03 3D */ bl "__ct__14CScriptTriggerF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC9CVector3fRC6CAABoxRC11CDamageInfoRC9CVector3fUibbb" -/* 80176A20 00173980 3C 80 80 3E */ lis r4, lbl_803E3E80@ha +/* 80176A20 00173980 3C 80 80 3E */ lis r4, __vt__18CScriptBallTrigger@ha /* 80176A24 00173984 3C 60 80 5A */ lis r3, sZeroVector__9CVector3f@ha -/* 80176A28 00173988 38 04 3E 80 */ addi r0, r4, lbl_803E3E80@l +/* 80176A28 00173988 38 04 3E 80 */ addi r0, r4, __vt__18CScriptBallTrigger@l /* 80176A2C 0017398C 38 80 00 00 */ li r4, 0 /* 80176A30 00173990 90 1D 00 00 */ stw r0, 0(r29) /* 80176A34 00173994 38 A3 66 A0 */ addi r5, r3, sZeroVector__9CVector3f@l diff --git a/configure.py b/configure.py index 45b708e2..e1b0ca97 100755 --- a/configure.py +++ b/configure.py @@ -238,7 +238,7 @@ LIBS = [ "MetroidPrime/CBoneTracking", ["MetroidPrime/Player/CFaceplateDecoration", False], "MetroidPrime/BodyState/CBSCover", - "MetroidPrime/ScriptObjects/CScriptBallTrigger", + ["MetroidPrime/ScriptObjects/CScriptBallTrigger", False], "MetroidPrime/Weapons/CPlasmaProjectile", "MetroidPrime/Player/CPlayerOrbit", "MetroidPrime/CGameCollision", diff --git a/include/MetroidPrime/Player/CMorphBall.hpp b/include/MetroidPrime/Player/CMorphBall.hpp new file mode 100644 index 00000000..a61d9d4a --- /dev/null +++ b/include/MetroidPrime/Player/CMorphBall.hpp @@ -0,0 +1,23 @@ +#ifndef _CMORPHBALL +#define _CMORPHBALL + +class CMorphBall { +public: + enum EBallBoostState { kBBS_BoostAvailable, kBBS_BoostDisabled }; + + enum ESpiderBallState { kSBS_Inactive, kSBS_Active }; + + enum EBombJumpState { kBJS_BombJumpAvailable, kBJS_BombJumpDisabled }; + + // + + float GetBallRadius() const; + + EBallBoostState GetBallBoostState() const; // { return x1e3c_boostState; } + void SetBallBoostState(EBallBoostState state); + EBombJumpState GetBombJumpState() const; // { return x1e40_bombJumpState; } + void SetBombJumpState(EBombJumpState state); + +}; + +#endif // _CMORPHBALL diff --git a/include/MetroidPrime/Player/CPlayer.hpp b/include/MetroidPrime/Player/CPlayer.hpp index fb77dab4..228272f9 100644 --- a/include/MetroidPrime/Player/CPlayer.hpp +++ b/include/MetroidPrime/Player/CPlayer.hpp @@ -198,6 +198,9 @@ public: CPlayerGun* PlayerGun() { return x490_gun.get(); } const CPlayerGun* GetPlayerGun() const { return x490_gun.get(); } + CMorphBall* MorphBall() { return x768_morphball.get(); } + const CMorphBall* GetMorphBall() const { return x768_morphball.get(); } + ESurfaceRestraints GetCurrentSurfaceRestraint() const { return x2ac_surfaceRestraint; } ESurfaceRestraints GetSurfaceRestraint() const { return x2b0_outOfWaterTicks == 2 ? GetCurrentSurfaceRestraint() : kSR_Water; diff --git a/include/MetroidPrime/ScriptObjects/CScriptBallTrigger.hpp b/include/MetroidPrime/ScriptObjects/CScriptBallTrigger.hpp new file mode 100644 index 00000000..9714889b --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptBallTrigger.hpp @@ -0,0 +1,27 @@ +#ifndef _CSCRIPTBALLTRIGGER +#define _CSCRIPTBALLTRIGGER + +#include "MetroidPrime/ScriptObjects/CScriptTrigger.hpp" + +class CScriptBallTrigger : public CScriptTrigger { +public: + CScriptBallTrigger(TUniqueId, const rstl::string&, const CEntityInfo&, const CVector3f&, + const CVector3f&, bool, float, float, float, const CVector3f&, bool); + ~CScriptBallTrigger(); + + void Accept(IVisitor&) override; + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; + void Think(float, CStateManager& mgr) override; + void InhabitantAdded(CActor&, CStateManager&) override; + void InhabitantExited(CActor&, CStateManager&) override; + +private: + float x150_force; + float x154_minAngle; + float x158_maxDistance; + CVector3f x15c_forceAngle; + bool x168_24_canApplyForce : 1; + bool x168_25_stopPlayer : 1; +}; + +#endif // _CSCRIPTBALLTRIGGER diff --git a/src/MetroidPrime/ScriptObjects/CScriptBallTrigger.cpp b/src/MetroidPrime/ScriptObjects/CScriptBallTrigger.cpp new file mode 100644 index 00000000..c5a70c43 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptBallTrigger.cpp @@ -0,0 +1,100 @@ +#include "MetroidPrime/ScriptObjects/CScriptBallTrigger.hpp" + +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/Player/CMorphBall.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/Tweaks/CTweakPlayer.hpp" + +#include "rstl/math.hpp" + +CAABox calculate_ball_aabox() { + const float extent = 0.33f * gpTweakPlayer->GetPlayerBallHalfExtent(); + return CAABox(CVector3f(-extent, -extent, -extent), CVector3f(extent, extent, extent)); +} + +CScriptBallTrigger::CScriptBallTrigger(TUniqueId uid, const rstl::string& name, + const CEntityInfo& info, const CVector3f& pos, + const CVector3f& scale, bool active, float f1, float f2, + float f3, const CVector3f& vec, bool b2) +: CScriptTrigger(uid, name, info, pos, calculate_ball_aabox(), + CDamageInfo(CWeaponMode::Power(), 0.f, 0.f, 0.f), CVector3f::Zero(), + kTFL_DetectMorphedPlayer, active, false, false) +, x150_force(f1) +, x154_minAngle(f2) +, x158_maxDistance(f3) +, x15c_forceAngle(CVector3f::Zero()) +, x168_24_canApplyForce(false) +, x168_25_stopPlayer(b2) { + + if (vec.CanBeNormalized()) { + x15c_forceAngle = vec.AsNormalized(); + } +} + +CScriptBallTrigger::~CScriptBallTrigger() {} + +void CScriptBallTrigger::InhabitantAdded(CActor& act, CStateManager& /*mgr*/) { + if (CPlayer* player = TCastToPtr< CPlayer >(act)) { + player->MorphBall()->SetBallBoostState(CMorphBall::kBBS_BoostDisabled); + } +} + +void CScriptBallTrigger::InhabitantExited(CActor& act, CStateManager&) { + if (CPlayer* player = TCastToPtr< CPlayer >(act)) { + player->MorphBall()->SetBallBoostState(CMorphBall::kBBS_BoostAvailable); + x168_24_canApplyForce = false; + } +} + +void CScriptBallTrigger::Think(float dt, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + CScriptTrigger::Think(dt, mgr); + CPlayer& player = *mgr.Player(); + const float ballRadius = player.GetMorphBall()->GetBallRadius(); + CVector3f playerTrans = player.GetTranslation() + CVector3f(0.f, 0.f, ballRadius); + + if (player.GetMorphballTransitionState() == CPlayer::kMS_Morphed) { + const CVector3f radiusPosDif = GetTranslation() - playerTrans; + const float distance = radiusPosDif.Magnitude(); + + if (!x168_24_canApplyForce) { + if (distance < ballRadius) { + x168_24_canApplyForce = true; + } else { + const CVector3f offset = radiusPosDif.AsNormalized(); + float angleCos = cosf(x154_minAngle * 0.01745329f); + if (angleCos < CVector3f::Dot(-offset, x15c_forceAngle) && distance < x158_maxDistance) { + float a = x150_force * (x158_maxDistance / (distance * distance)); + float b = 1.f / dt * distance; + const float force = rstl::min_val(a, b); + player.ApplyForceWR(force * (player.GetMass() * offset), CAxisAngle::Identity()); + } + } + } + + if (x148_28_playerTriggerProc) { + const CVector3f offset = GetTranslation() - CVector3f(0.f, 0.f, ballRadius); + if (x168_25_stopPlayer) { + player.Stop(); + } + player.MoveToWR(offset, dt); + } + } else { + x168_24_canApplyForce = false; + } +} + +void CScriptBallTrigger::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CScriptBallTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, + CStateManager& mgr) { + if (msg == kSM_Deactivate && GetActive()) { + mgr.Player()->MorphBall()->SetBallBoostState(CMorphBall::kBBS_BoostAvailable); + x168_24_canApplyForce = false; + } + + CScriptTrigger::AcceptScriptMsg(msg, uid, mgr); +}