diff --git a/asm/MetroidPrime/ScriptObjects/CScriptCoverPoint.s b/asm/MetroidPrime/ScriptObjects/CScriptCoverPoint.s index 43a67af9..1a4655d3 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptCoverPoint.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptCoverPoint.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E0BF8 -lbl_803E0BF8: +.global __vt__17CScriptCoverPoint +__vt__17CScriptCoverPoint: # ROM: 0x3DDBF8 .4byte 0 .4byte 0 @@ -79,9 +79,9 @@ __dt__17CScriptCoverPointFv: /* 8012D31C 0012A27C 93 C1 00 08 */ stw r30, 8(r1) /* 8012D320 0012A280 7C 7E 1B 79 */ or. r30, r3, r3 /* 8012D324 0012A284 41 82 00 3C */ beq lbl_8012D360 -/* 8012D328 0012A288 3C 60 80 3E */ lis r3, lbl_803E0BF8@ha +/* 8012D328 0012A288 3C 60 80 3E */ lis r3, __vt__17CScriptCoverPoint@ha /* 8012D32C 0012A28C 34 1E 01 00 */ addic. r0, r30, 0x100 -/* 8012D330 0012A290 38 03 0B F8 */ addi r0, r3, lbl_803E0BF8@l +/* 8012D330 0012A290 38 03 0B F8 */ addi r0, r3, __vt__17CScriptCoverPoint@l /* 8012D334 0012A294 90 1E 00 00 */ stw r0, 0(r30) /* 8012D338 0012A298 41 82 00 0C */ beq lbl_8012D344 /* 8012D33C 0012A29C 38 00 00 00 */ li r0, 0 @@ -453,9 +453,9 @@ Accept__17CScriptCoverPointFR8IVisitor: /* 8012D7FC 0012A75C 38 61 00 B8 */ addi r3, r1, 0xb8 /* 8012D800 0012A760 38 80 FF FF */ li r4, -1 /* 8012D804 0012A764 4B FE 92 49 */ bl __dt__10CModelDataFv -/* 8012D808 0012A768 3C 60 80 3E */ lis r3, lbl_803E0BF8@ha +/* 8012D808 0012A768 3C 60 80 3E */ lis r3, __vt__17CScriptCoverPoint@ha /* 8012D80C 0012A76C C0 02 98 A4 */ lfs f0, lbl_805AB5C4@sda21(r2) -/* 8012D810 0012A770 38 03 0B F8 */ addi r0, r3, lbl_803E0BF8@l +/* 8012D810 0012A770 38 03 0B F8 */ addi r0, r3, __vt__17CScriptCoverPoint@l /* 8012D814 0012A774 90 1E 00 00 */ stw r0, 0(r30) /* 8012D818 0012A778 EC 20 07 72 */ fmuls f1, f0, f29 /* 8012D81C 0012A77C 93 9E 00 E8 */ stw r28, 0xe8(r30) diff --git a/configure.py b/configure.py index 6f281a8e..4b5b274a 100755 --- a/configure.py +++ b/configure.py @@ -175,7 +175,7 @@ LIBS = [ ["MetroidPrime/CRippleManager", False], ["MetroidPrime/Player/CGrappleArm", False], "MetroidPrime/Enemies/CSpacePirate", - "MetroidPrime/ScriptObjects/CScriptCoverPoint", + ["MetroidPrime/ScriptObjects/CScriptCoverPoint", False], "MetroidPrime/Cameras/CPathCamera", "MetroidPrime/CFluidPlane", "MetroidPrime/CFluidPlaneManager", diff --git a/include/MetroidPrime/ScriptObjects/CScriptCoverPoint.hpp b/include/MetroidPrime/ScriptObjects/CScriptCoverPoint.hpp new file mode 100644 index 00000000..5869fdeb --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptCoverPoint.hpp @@ -0,0 +1,51 @@ +#ifndef _CSCRIPTCOVERPOINT +#define _CSCRIPTCOVERPOINT + +#include "MetroidPrime/CActor.hpp" + +#include "Kyoto/Animation/CharacterCommon.hpp" + +class CScriptCoverPoint : public CActor { +public: + CScriptCoverPoint(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, bool active, uint flags, bool crouch, float horizontalAngle, + float verticalAngle, float coverTime); + + void Accept(IVisitor& visitor) override; + void Think(float, CStateManager&) override; + void AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override; + void Render(const CStateManager&) const override; + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override; + rstl::optional_object< CAABox > GetTouchBounds() const override; + + bool ShouldCrouch() const; + bool ShouldStay() const; + bool ShouldWallHang() const; + bool ShouldLandHere() const; + void SetInUse(bool inUse); + bool GetInUse(TUniqueId uid) const; + bool Blown(const CVector3f& pos) const; + float GetSinSqVerticalAngle() const; + float GetCosHorizontalAngle() const; + pas::ECoverDirection GetAttackDirection() const; + void Reserve(TUniqueId id) { xfa_occupant = id; } + +private: + // bool xe8_26_landHere : 1; + // bool xe8_27_wallHang : 1; + // bool xe8_28_stay : 1; + // bool xe8_29_ : 1; + // bool xe8_30_attackDirection : 1; + uint xe8_flags; + float xec_cosHorizontalAngle; + float xf0_sinVerticalAngle; + float xf4_coverTime; + bool xf8_24_crouch : 1; + bool xf8_25_inUse : 1; + TUniqueId xfa_occupant; + TUniqueId xfc_retreating; + rstl::optional_object< CAABox > x100_touchBounds; + float x11c_timeLeft; +}; + +#endif // _CSCRIPTCOVERPOINT diff --git a/src/MetroidPrime/ScriptObjects/CScriptCoverPoint.cpp b/src/MetroidPrime/ScriptObjects/CScriptCoverPoint.cpp new file mode 100644 index 00000000..bba944f6 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptCoverPoint.cpp @@ -0,0 +1,128 @@ +#include "MetroidPrime/ScriptObjects/CScriptCoverPoint.hpp" + +#include "MetroidPrime/CActorParameters.hpp" + +CScriptCoverPoint::CScriptCoverPoint(TUniqueId uid, const rstl::string& name, + const CEntityInfo& info, const CTransform4f& xf, bool active, + uint flags, bool crouch, float horizontalAngle, + float verticalAngle, float coverTime) +: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(kMT_NoStepLogic), + CActorParameters::None(), kInvalidUniqueId) +, xe8_flags(flags) +, xec_cosHorizontalAngle(cosf(horizontalAngle * 0.008726646f)) +, xf0_sinVerticalAngle(sinf(verticalAngle * 0.008726646f)) +, xf4_coverTime(coverTime) +, xf8_24_crouch(crouch) +, xf8_25_inUse(false) +, xfa_occupant(kInvalidUniqueId) +, xfc_retreating(kInvalidUniqueId) +, x100_touchBounds(CAABox(xf.GetTranslation(), xf.GetTranslation())) +, x11c_timeLeft(0.f) {} + +void CScriptCoverPoint::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CScriptCoverPoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, + CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, uid, mgr); + + switch (msg) { + case kSM_InitializedInArea: + rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); + for (; conn != GetConnectionList().end(); ++conn) { + if (conn->x0_state == kSS_Retreat) { + xfc_retreating = mgr.GetIdForScript(conn->x8_objId); + break; + } + } + default: + break; + } +} + +pas::ECoverDirection CScriptCoverPoint::GetAttackDirection() const { + return pas::ECoverDirection(xe8_flags); +} + +bool CScriptCoverPoint::ShouldCrouch() const { return xf8_24_crouch; } + +bool CScriptCoverPoint::ShouldStay() const { return xe8_flags >> 3 & 1; } + +bool CScriptCoverPoint::ShouldWallHang() const { return xe8_flags >> 4 & 1; } + +bool CScriptCoverPoint::ShouldLandHere() const { return xe8_flags >> 5 & 1; } + +float CScriptCoverPoint::GetCosHorizontalAngle() const { return xec_cosHorizontalAngle; } + +float CScriptCoverPoint::GetSinSqVerticalAngle() const { + return xf0_sinVerticalAngle * xf0_sinVerticalAngle; +} + +bool CScriptCoverPoint::Blown(const CVector3f& point) const { + bool result = true; + + if (GetActive()) { + if (ShouldWallHang()) { + result = false; + } else { + CVector3f posDif = point - GetTransform().GetTranslation(); + float magnitude = posDif.Magnitude(); + posDif *= 1.f / magnitude; + if (magnitude > 8.0f) { + CVector3f normDif(posDif.DropZ()); + normDif.Normalize(); + + CVector3f frontVec(GetTransform().GetForward().DropZ()); + frontVec.Normalize(); + + if (CVector3f::Dot(frontVec, normDif) > GetCosHorizontalAngle() && + (posDif.GetZ() * posDif.GetZ()) < GetSinSqVerticalAngle()) + result = false; + } + } + } + return result; +} + +bool CScriptCoverPoint::GetInUse(TUniqueId uid) const { + // bool result = false; + // do { + // if (!xf8_25_inUse && !(x11c_timeLeft > 0.f)) { + // if (xfa_occupant == kInvalidUniqueId) + // break; + // if (uid == kInvalidUniqueId) + // break; + // if (xfa_occupant == uid) + // break; + // } + // result = true; + // } while (false); + // return result; + + bool result = false; + if (!xf8_25_inUse && !(x11c_timeLeft > 0.f)) { + if (xfa_occupant != kInvalidUniqueId && uid != kInvalidUniqueId && xfa_occupant != uid) + result = true; + } else { + result = true; + } + return result; +} + +void CScriptCoverPoint::SetInUse(bool inUse) { + xf8_25_inUse = inUse; + if (!xf8_25_inUse) + x11c_timeLeft = xf4_coverTime; +} + +void CScriptCoverPoint::Think(float delta, CStateManager&) { + if (x11c_timeLeft > 0.f) + x11c_timeLeft -= delta; +} + +void CScriptCoverPoint::AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override {} + +void CScriptCoverPoint::Render(const CStateManager&) const override {} + +rstl::optional_object< CAABox > CScriptCoverPoint::GetTouchBounds() const { + return x100_touchBounds; +}