From 87c0a6041cb0323ce783997cf5be2754f70b8977 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 3 Oct 2022 00:49:11 -0400 Subject: [PATCH] More CScriptSpecialFunction; start rstl::map/red_black_tree --- include/Kyoto/Math/CMath.hpp | 12 +- include/Kyoto/Math/CQuaternion.hpp | 11 +- include/Kyoto/Math/CRelAngle.hpp | 48 ++++ include/Kyoto/Math/CTransform4f.hpp | 7 +- include/Kyoto/Math/CUnitVector3f.hpp | 7 +- include/MetroidPrime/CActor.hpp | 1 + include/MetroidPrime/CDamageInfo.hpp | 25 +- include/MetroidPrime/CModelData.hpp | 1 - include/MetroidPrime/CPhysicsActor.hpp | 2 + include/MetroidPrime/CStateManager.hpp | 6 +- include/MetroidPrime/TGameTypes.hpp | 8 +- include/MetroidPrime/Weapons/WeaponTypes.hpp | 10 +- include/rstl/map.hpp | 18 +- include/rstl/pointer_iterator.hpp | 1 + include/rstl/red_black_tree.hpp | 44 +++- .../ScriptObjects/CScriptSpecialFunction.cpp | 229 +++++++++--------- 16 files changed, 279 insertions(+), 151 deletions(-) create mode 100644 include/Kyoto/Math/CRelAngle.hpp diff --git a/include/Kyoto/Math/CMath.hpp b/include/Kyoto/Math/CMath.hpp index 753c2c98..1d21d084 100644 --- a/include/Kyoto/Math/CMath.hpp +++ b/include/Kyoto/Math/CMath.hpp @@ -31,8 +31,10 @@ public: // WrapPi__5CMathFf weak // WrapTwoPi__5CMathFf weak // FastFmod__5CMathFfff weak - // Min__5CMathFRCfRCf weak - // Max__5CMathFRCfRCf weak + template < typename T > + static const T& Min(const T& a, const T& b); + template < typename T > + static const T& Max(const T& a, const T& b); // InvSqrtF__5CMathFf global // FastArcCosR__5CMathFf global // SlowCosineR__5CMathFf global @@ -41,9 +43,9 @@ public: // GetBezierPoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global // ClampRadians__5CMathFf weak // ModF__5CMathFff weak - // Deg2Rad__5CMathFf weak - // Deg2Rev__5CMathFf weak - // ArcCosineR__5CMathFf global + static f32 Deg2Rad(f32 deg) { return Deg2Rev(deg) * (M_PIF * 2.f); } + static f32 Deg2Rev(f32 deg) { return deg * (1.f / 360.f); } + static f32 ArcCosineR(f32 v); // FloorF__5CMathFf global // BaryToWorld__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3f global // GetCatmullRomSplinePoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global diff --git a/include/Kyoto/Math/CQuaternion.hpp b/include/Kyoto/Math/CQuaternion.hpp index 3b97b863..d36f2cc6 100644 --- a/include/Kyoto/Math/CQuaternion.hpp +++ b/include/Kyoto/Math/CQuaternion.hpp @@ -6,6 +6,9 @@ #include "Kyoto/Math/CMatrix3f.hpp" #include "Kyoto/Math/CTransform4f.hpp" +class CRelAngle; +class CUnitVector3f; + class CQuaternion { public: CQuaternion(f32 w, f32 x, f32 y, f32 z) : w(w), x(x), y(y), z(z) {} @@ -35,21 +38,21 @@ public: // AngleFrom__11CQuaternionCFRC11CQuaternion // BuildEquivalent__11CQuaternionCFv // BuildNormalized__11CQuaternionCFv - // AxisAngle__11CQuaternionFRC13CUnitVector3fRC9CRelAngle - // Transform__11CQuaternionCFRC9CVector3f + static CQuaternion AxisAngle(const CUnitVector3f&, const CRelAngle&); + CVector3f Transform(const CVector3f&) const; // XRotation__11CQuaternionFRC9CRelAngle // YRotation__11CQuaternionFRC9CRelAngle // ZRotation__11CQuaternionFRC9CRelAngle // BuildTransform__11CQuaternionCFv CTransform4f BuildTransform4f() const; CTransform4f BuildTransform4f(const CVector3f&) const; - CQuaternion BuildInverted() const { + CQuaternion BuildInverted() const { // f64 w = this->w; // f64 x = -this->x; // f64 y = -this->y; // f64 z = -this->z; return CQuaternion(w, -x, -y, -z); - } + } static CQuaternion FromMatrixRows(const CVector3f&, const CVector3f&, const CVector3f&); static CQuaternion FromMatrix(const CMatrix3f&); diff --git a/include/Kyoto/Math/CRelAngle.hpp b/include/Kyoto/Math/CRelAngle.hpp new file mode 100644 index 00000000..1f1f622b --- /dev/null +++ b/include/Kyoto/Math/CRelAngle.hpp @@ -0,0 +1,48 @@ +#ifndef _CRELANGLE_HPP +#define _CRELANGLE_HPP + +#include "types.h" + +#include "Kyoto/Math/CMath.hpp" + +class CRelAngle { +public: + f32 AsDegrees() const { return x0_angle * (180.f / M_PIF); } + f32 AsRadians() const { return x0_angle; } + // ArcCosine__9CRelAngleFf weak + + CRelAngle& operator+=(const CRelAngle& v) { + x0_angle += v.x0_angle; + return *this; + } + CRelAngle& operator-=(const CRelAngle& v) { + x0_angle -= v.x0_angle; + return *this; + } + CRelAngle& operator*=(f32 v) { + x0_angle *= v; + return *this; + } + CRelAngle& operator/=(f32 v) { + x0_angle /= v; + return *this; + } + + // __lt__9CRelAngleCFRC9CRelAngle + + static CRelAngle FromDegrees(f32 deg) { return CRelAngle(deg * (M_PIF / 180.f)); } + static CRelAngle FromRadians(f32 rad) { return CRelAngle(rad); } + +private: + CRelAngle(f32 rad) : x0_angle(rad) {} + + float x0_angle; +}; +CHECK_SIZEOF(CRelAngle, 0x4) + +// __mi__FRC9CRelAngleRC9CRelAngle +// __pl__FRC9CRelAngleRC9CRelAngle +// __dv__FRC9CRelAnglef +// sine__FRC9CRelAngle + +#endif diff --git a/include/Kyoto/Math/CTransform4f.hpp b/include/Kyoto/Math/CTransform4f.hpp index cddbc552..031755b2 100644 --- a/include/Kyoto/Math/CTransform4f.hpp +++ b/include/Kyoto/Math/CTransform4f.hpp @@ -9,6 +9,7 @@ typedef const f32 (*ConstMtxPtr)[4]; class CInputStream; class CMatrix3f; +class CRelAngle; class CTransform4f { public: @@ -61,9 +62,9 @@ public: CTransform4f MultiplyIgnoreTranslation(const CTransform4f& other) const; // Orthonormalize__12CTransform4fFv CVector3f Rotate(const CVector3f& in) const; - // RotateLocalX__12CTransform4fFRC9CRelAngle - // RotateLocalY__12CTransform4fFRC9CRelAngle - // RotateLocalZ__12CTransform4fFRC9CRelAngle + void RotateLocalX(const CRelAngle& angle); + void RotateLocalY(const CRelAngle& angle); + void RotateLocalZ(const CRelAngle& angle); // RotateX__12CTransform4fFRC9CRelAngle // RotateY__12CTransform4fFRC9CRelAngle // RotateZ__12CTransform4fFRC9CRelAngle diff --git a/include/Kyoto/Math/CUnitVector3f.hpp b/include/Kyoto/Math/CUnitVector3f.hpp index f09c8730..fbd59220 100644 --- a/include/Kyoto/Math/CUnitVector3f.hpp +++ b/include/Kyoto/Math/CUnitVector3f.hpp @@ -7,11 +7,8 @@ class CUnitVector3f : public CVector3f { public: - enum ENormalize { - // TODO - }; - CUnitVector3f(f32 x, f32 y, f32 z); - CUnitVector3f(const CVector3f& vec); + CUnitVector3f(f32 x, f32 y, f32 z) : CVector3f(x, y, z) { Normalize(); } + CUnitVector3f(const CVector3f& vec) : CVector3f(vec) { Normalize(); } // TODO }; CHECK_SIZEOF(CUnitVector3f, 0xc) diff --git a/include/MetroidPrime/CActor.hpp b/include/MetroidPrime/CActor.hpp index 86fa7dac..5d3486a6 100644 --- a/include/MetroidPrime/CActor.hpp +++ b/include/MetroidPrime/CActor.hpp @@ -267,6 +267,7 @@ public: } CVector3f GetTranslation() const { return x34_transform.GetTranslation(); } void SetTranslation(const CVector3f& vec); + CTransform4f GetLocatorTransform(const rstl::string& segName) const; CTransform4f GetScaledLocatorTransform(const rstl::string& segName) const; /// ???? diff --git a/include/MetroidPrime/CDamageInfo.hpp b/include/MetroidPrime/CDamageInfo.hpp index 50e33cc1..440f1092 100644 --- a/include/MetroidPrime/CDamageInfo.hpp +++ b/include/MetroidPrime/CDamageInfo.hpp @@ -17,15 +17,24 @@ class CDamageInfo { public: CDamageInfo() - : x0_weaponMode(), x8_damage(0.f), xc_radiusDamage(0.f), x10_radius(0.f), x14_knockback(0.f), x18_24_noImmunity(false) {} - - explicit CDamageInfo(CInputStream& in); - - CDamageInfo(const CWeaponMode& mode, float damage, float radius, float knockback) - : x0_weaponMode(mode), x8_damage(damage), xc_radiusDamage(damage), x10_radius(radius), x14_knockback(knockback), x18_24_noImmunity(false) {} - + : x0_weaponMode() + , x8_damage(0.f) + , xc_radiusDamage(0.f) + , x10_radius(0.f) + , x14_knockback(0.f) + , x18_24_noImmunity(false) {} + CDamageInfo(const CWeaponMode& mode, float damage, float radius, float knockback, + bool noImmunity = false) + : x0_weaponMode(mode) + , x8_damage(damage) + , xc_radiusDamage(damage) + , x10_radius(radius) + , x14_knockback(knockback) + , x18_24_noImmunity(noImmunity) {} + CDamageInfo(CInputStream& in); CDamageInfo(const CDamageInfo&, float); - explicit CDamageInfo(const SShotParam& other); + CDamageInfo(const SShotParam& other); + CDamageInfo& operator=(const SShotParam& other); const CWeaponMode& GetWeaponMode() const { return x0_weaponMode; } diff --git a/include/MetroidPrime/CModelData.hpp b/include/MetroidPrime/CModelData.hpp index 375cc1ae..0e36e02c 100644 --- a/include/MetroidPrime/CModelData.hpp +++ b/include/MetroidPrime/CModelData.hpp @@ -39,7 +39,6 @@ public: }; // TODO these probably aren't real - bool HasAnimData() const { return xc_animData.get() != nullptr; } bool HasNormalModel() const { return x1c_normalModel; } CModelData(); diff --git a/include/MetroidPrime/CPhysicsActor.hpp b/include/MetroidPrime/CPhysicsActor.hpp index 57e63a11..ca81f8f1 100644 --- a/include/MetroidPrime/CPhysicsActor.hpp +++ b/include/MetroidPrime/CPhysicsActor.hpp @@ -67,7 +67,9 @@ public: CAABox GetBoundingBox() const; void MoveCollisionPrimitive(const CVector3f&); + void SetVelocityWR(const CVector3f&); void SetAngularVelocityWR(const CAxisAngle& angVel); + void ClearForcesAndTorques(); void Stop(); CMotionState GetMotionState() const; diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index dea89c7c..3a8d2cc7 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -16,6 +16,7 @@ #include "rstl/auto_ptr.hpp" #include "rstl/list.hpp" +#include "rstl/map.hpp" #include "rstl/pair.hpp" #include "rstl/rc_ptr.hpp" #include "rstl/reserved_vector.hpp" @@ -77,6 +78,9 @@ struct SOnScreenTex { class CStateManager : public TOneStatic< CStateManager > { public: + typedef rstl::map< TEditorId, TUniqueId > TIdList; + typedef rstl::pair< TIdList::const_iterator, TIdList::const_iterator > TIdListResult; + void ResetEscapeSequenceTimer(float); void SendScriptMsg(TUniqueId uid, TEditorId target, EScriptObjectMessage msg, EScriptObjectState state); @@ -97,7 +101,7 @@ public: CEntity* ObjectById(TUniqueId uid); const CEntity* GetObjectById(TUniqueId uid) const; TUniqueId GetIdForScript(TEditorId eid) const; - // GetIdListForScript(TEditorId) const; + TIdListResult GetIdListForScript(TEditorId) const; CMazeState* CurrentMaze(); const CMazeState* GetCurrentMaze() const; diff --git a/include/MetroidPrime/TGameTypes.hpp b/include/MetroidPrime/TGameTypes.hpp index 66f891b2..675d73d2 100644 --- a/include/MetroidPrime/TGameTypes.hpp +++ b/include/MetroidPrime/TGameTypes.hpp @@ -55,7 +55,13 @@ struct TUniqueId { private: }; -// CHECK_SIZEOF(TUniqueId, 0x2) +CHECK_SIZEOF(TUniqueId, 0x2) + +// struct TGameScriptId { +// TEditorId editorId; +// bool b; +// }; +// CHECK_SIZEOF(TGameScriptId, 0x8) typedef u16 TSfxId; static TSfxId InvalidSfxId = 0xFFFFu; diff --git a/include/MetroidPrime/Weapons/WeaponTypes.hpp b/include/MetroidPrime/Weapons/WeaponTypes.hpp index 9463c8de..baaccfe3 100644 --- a/include/MetroidPrime/Weapons/WeaponTypes.hpp +++ b/include/MetroidPrime/Weapons/WeaponTypes.hpp @@ -28,9 +28,13 @@ class CWeaponMode { bool x4_26_instantKill : 1; public: - explicit CWeaponMode(EWeaponType type = kWT_None, bool charged = false, bool comboed = false, bool instaKill = false) - : x0_weaponType(type), x4_24_charged(charged), x4_25_comboed(comboed), x4_26_instantKill(instaKill) {} - + explicit CWeaponMode(EWeaponType type = kWT_None, bool charged = false, bool comboed = false, + bool instaKill = false) + : x0_weaponType(type) + , x4_24_charged(charged) + , x4_25_comboed(comboed) + , x4_26_instantKill(instaKill) {} + EWeaponType GetType() const { return x0_weaponType; } bool IsCharged() const { return x4_24_charged; } diff --git a/include/rstl/map.hpp b/include/rstl/map.hpp index c31484ee..e514412f 100644 --- a/include/rstl/map.hpp +++ b/include/rstl/map.hpp @@ -3,14 +3,30 @@ #include "types.h" +#include "rstl/pair.hpp" #include "rstl/red_black_tree.hpp" #include "rstl/rmemory_allocator.hpp" namespace rstl { template < typename K, typename V, typename Cmp = less< K >, typename Alloc = rmemory_allocator > class map { - u8 pad[0x14]; +public: + typedef pair< K, V > value_type; + +private: + typedef red_black_tree< K, value_type, 1, select1st< value_type >, Cmp, Alloc > rep_type; + +public: + typedef pair< K, V > value_type; + // typedef typename rep_type::iterator iterator; + typedef typename rep_type::const_iterator const_iterator; + +private: + rep_type inner; }; + +typedef map< char, char > unk_map; +CHECK_SIZEOF(unk_map, 0x14) } // namespace rstl #endif diff --git a/include/rstl/pointer_iterator.hpp b/include/rstl/pointer_iterator.hpp index fe2cc2b2..5def7bdb 100644 --- a/include/rstl/pointer_iterator.hpp +++ b/include/rstl/pointer_iterator.hpp @@ -16,6 +16,7 @@ template < typename T, typename Vec, typename Alloc > class const_pointer_iterator { public: typedef random_access_iterator_tag iterator_category; + typedef T* value_type; const_pointer_iterator() : current(nullptr) {} const_pointer_iterator(const T* begin) : current(const_cast< T* >(begin)) {} diff --git a/include/rstl/red_black_tree.hpp b/include/rstl/red_black_tree.hpp index 7eb06064..c0c343a3 100644 --- a/include/rstl/red_black_tree.hpp +++ b/include/rstl/red_black_tree.hpp @@ -3,6 +3,8 @@ #include "types.h" +#include "rstl/rmemory_allocator.hpp" + namespace rstl { template < typename P > struct select1st {}; @@ -10,7 +12,45 @@ struct select1st {}; template < typename T > struct less {}; -template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T > > -class red_black_tree {}; +enum node_color { + kNC_Red, + kNC_Black, +}; + +template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T >, + typename Alloc = rmemory_allocator > +class red_black_tree { +private: + struct node { + node_color mColor; + node* mParent; + node* mLeft; + node* mRight; + P mValue; + }; + struct header {}; + +public: + struct const_iterator { + node* mNode; + const header* mHeader; + + const P* operator->() const { return &mNode->mValue; } + bool operator==(const const_iterator& other) const { + return mNode == other.mNode && mHeader == other.mHeader; + } + bool operator!=(const const_iterator& other) const { + return mNode != other.mNode || mHeader != other.mHeader; + } + }; + +private: + u8 x0_; + u8 x1_; + uint x4_; + uint x8_; + uint xc_; + uint x10_; +}; }; // namespace rstl #endif diff --git a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp index 6b0fc0e6..57d34757 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp @@ -16,6 +16,8 @@ #include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Math/CFrustumPlanes.hpp" #include "Kyoto/Math/CMath.hpp" +#include "Kyoto/Math/CRelAngle.hpp" +#include "Kyoto/Math/CUnitVector3f.hpp" #include "Kyoto/Math/CVector2i.hpp" #include "rstl/math.hpp" @@ -606,33 +608,30 @@ void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr) { void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManager& mgr) { if (x1a8_ringState != kRS_Breakup) { - for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); - it != x198_ringControllers.end(); ++it) { - if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { + for (int i = 0; i < x198_ringControllers.size(); ++i) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x198_ringControllers[i].x0_id))) { CTransform4f newXf = act->GetTransform(); - // TODO - // newXf.rotateLocalZ(zeus::degToRad(it->x4_rotateSpeed * dt)); + newXf.RotateLocalZ(CRelAngle::FromDegrees(dt * x198_ringControllers[i].x4_rotateSpeed)); act->SetTransform(newXf); } } } switch (x1a8_ringState) { + case kRS_Scramble: + break; case kRS_Breakup: { float minMag = 0.f; - for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); - it != x198_ringControllers.end(); ++it) { - if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { - // TODO: CTransform api differences - // act->SetTranslation(act->GetTranform().basis[1] * 50.f * dt + act->GetTranslation()); - // minMag = std::min(act->GetTranslation().magnitude(), minMag); + for (int i = 0; i < x198_ringControllers.size(); ++i) { + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x198_ringControllers[i].x0_id))) { + act->SetTranslation(act->GetTranslation() + act->GetTransform().GetForward() * 50.f * dt); + minMag = rstl::min_val(minMag, act->GetTranslation().Magnitude()); } } CalculateRenderBounds(); - if (minMag != 0.f) { - /* Never actually happens */ - for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); - it != x198_ringControllers.end(); ++it) { - if (CEntity* ent = mgr.ObjectById(it->x0_id)) { + if (minMag) { + // Never actually happens + for (int i = 0; i < x198_ringControllers.size(); ++i) { + if (CEntity* ent = mgr.ObjectById(x198_ringControllers[i].x0_id)) { ent->SetActive(false); } } @@ -641,35 +640,39 @@ void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManage break; } case kRS_Rotate: { - // x1ac_ringRotateTarget = CQuaternion::fromAxisAngle(zeus::skUp, zeus::degToRad(xfc_float1 * - // (x1b8_ringReverse ? 1.f : -1.f) * dt)) - // .transform(x1ac_ringRotateTarget); + x1ac_ringRotateTarget = + CQuaternion::AxisAngle( + CVector3f(0.f, 0.f, 1.f), + CRelAngle::FromDegrees(xfc_float1 * (x1b8_ringReverse ? 1.f : -1.f) * dt)) + .Transform(x1ac_ringRotateTarget); bool allReachedTarget = true; - for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); - it != x198_ringControllers.end(); ++it) { - if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { - /*CVector3f lookDirFlat = act->GetTransform().basis[1]; - lookDirFlat.SetZ(0.f); - lookDirFlat.Normalize(); - if (std::acos(CMath::Clamp(-1.f, lookDirFlat.Dot(x1ac_ringRotateTarget), 1.f)) <= - zeus::degToRad((xfc_float1 + std::fabs(rc.x4_rotateSpeed)) / 30.f)) { - CTransform4f newXf = zeus::lookAt(zeus::skZero3f, x1ac_ringRotateTarget); - newXf.origin = act->GetTranslation(); + for (int i = 0; i < x198_ringControllers.size(); ++i) { + if (x198_ringControllers[i].x8_reachedTarget) { + continue; + } + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x198_ringControllers[i].x0_id))) { + CVector3f forward = act->GetTransform().GetForward(); + forward.SetZ(0.f); + forward.Normalize(); + float f1 = CMath::Limit(CVector3f::Dot(forward, x1ac_ringRotateTarget), 1.f); + float f2 = (xfc_float1 + CMath::AbsF(x198_ringControllers[i].x4_rotateSpeed)) / 30.f; + if (CMath::ArcCosineR(f1) <= CMath::Deg2Rad(f2)) { + CTransform4f newXf = CTransform4f::LookAt(CVector3f::Zero(), x1ac_ringRotateTarget); + newXf.SetTranslation(act->GetTranslation()); act->SetTransform(newXf); - rc.x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1; - rc.x8_reachedTarget = true; + x198_ringControllers[i].x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1; + x198_ringControllers[i].x8_reachedTarget = true; } else { allReachedTarget = false; break; - }*/ + } } } if (allReachedTarget) { SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); x1a8_ringState = kRS_Stopped; - for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); - it != x198_ringControllers.end(); ++it) { - it->x8_reachedTarget = false; + for (int i = 0; i < x198_ringControllers.size(); ++i) { + x198_ringControllers[i].x8_reachedTarget = false; } } break; @@ -686,20 +689,21 @@ void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr) continue; } - /* - const auto search = mgr.GetIdListForScript(conn->x8_objId); - for (auto it = search.first; it != search.second; ++it) { - if (const TCastToConstPtr act = mgr.GetObjectById(it->second)) { - const CTransform4f xf = act->GetTransform() * act->GetLocatorTransform(xec_locatorName); - CPlayer& pl = mgr.GetPlayer(); - pl.SetTransform(xf); - pl.SetVelocityWR({}); - pl.SetAngularVelocityWR({}); - pl.ClearForcesAndTorques(); + const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId); + if (it.first != it.second) { + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it.first->second))) { + if (!act->HasAnimation()) { + continue; + } + CTransform4f xf = act->GetTransform() * act->GetLocatorTransform(xec_locatorName); + CPlayer* player = mgr.Player(); + player->SetTransform(xf); + player->SetVelocityWR(CVector3f::Zero()); + player->SetAngularVelocityWR(CAxisAngle::Identity()); + player->ClearForcesAndTorques(); return; } } - */ } } @@ -846,28 +850,31 @@ void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr) continue; } - // GetIdListForScript seems very different between Ghidra and Metaforce - // const auto search = mgr.GetIdListForScript(conn->x8_objId); - - rstl::pair< TUniqueId, TUniqueId >* it; - if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it->second))) { - if (conn->x4_msg == kSM_Activate && - (act->HasModelData() && act->GetModelData()->HasAnimData()) && act->GetActive()) { - followedAct = it->second; - } else if (conn->x4_msg == kSM_Deactivate) { - followerAct = it->second; + const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId); + if (it.first != it.second) { + TUniqueId uid = it.first->second; + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(uid))) { + if (conn->x4_msg == kSM_Activate && act->HasAnimation()) { + if (!act->GetActive()) { + return; + } + followedAct = uid; + } else if (conn->x4_msg == kSM_Deactivate) { + followerAct = uid; + } } } } - if (followerAct == kInvalidUniqueId || followedAct == kInvalidUniqueId) { - return; + if (followerAct != kInvalidUniqueId && followedAct != kInvalidUniqueId) { + const CActor* fromAct = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct)); + CActor* toAct = TCastToPtr< CActor >(mgr.ObjectById(followerAct)); + if (fromAct && toAct) { + CTransform4f xf = + fromAct->GetTransform() * fromAct->GetScaledLocatorTransform(xec_locatorName); + toAct->SetTransform(xf); + } } - - const CActor* fromAct = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct)); - CActor* toAct = TCastToPtr< CActor >(mgr.ObjectById(followerAct)); - toAct->SetTransform(fromAct->GetTransform() * - fromAct->GetScaledLocatorTransform(xec_locatorName)); } void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr) { @@ -880,22 +887,25 @@ void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr) continue; } - // GetIdListForScript seems very different between Ghidra and Metaforce - // const auto search = mgr.GetIdListForScript(conn->x8_objId); - - rstl::pair< TUniqueId, TUniqueId >* it; - if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it->second))) { - if (conn->x4_msg == kSM_Activate && act->GetActive()) { - followedAct = it->second; - } else if (conn->x4_msg == kSM_Deactivate) { - followerAct = it->second; + const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId); + if (it.first != it.second) { + TUniqueId uid = it.first->second; + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(uid))) { + if (conn->x4_msg == kSM_Activate) { + if (!act->GetActive()) { + return; + } + followedAct = uid; + } else if (conn->x4_msg == kSM_Deactivate) { + followerAct = uid; + } } } } const CActor* followed = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct)); CActor* follower = TCastToPtr< CActor >(mgr.ObjectById(followerAct)); - if (followed && follower) { + if (follower && followed) { follower->SetTransform(followed->GetTransform()); } } @@ -957,7 +967,7 @@ void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) { } void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) { - if ((float(mgr.GetInputFrameIdx()) / 3600.f) < 0.5f) { + if ((static_cast< float >(mgr.GetInputFrameIdx() % 3600)) / 3600.f < 0.5f) { SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); } else { SendScriptMsgs(kSS_Zero, mgr, kSM_None); @@ -965,49 +975,35 @@ void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) { } void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) { - const CPlayerState& playerState = *mgr.GetPlayerState(); - CPlayer& player = *mgr.Player(); - - /* Make sure we're not currently set to take damage, if so reset our state to be as if we're not - */ + const CPlayer* player = mgr.GetPlayer(); + bool inArea = player->GetAreaIdAlways() == GetAreaIdAlways(); + bool immune = mgr.GetPlayerState()->GetCurrentSuitRaw() > CPlayerState::kPS_Power; if (x1e4_31_inAreaDamage) { - x1e4_31_inAreaDamage = false; - player.DecrementPhazon(); - SendScriptMsgs(kSS_Exited, mgr, kSM_None); - mgr.SetIsFullThreat(false); - } - return; - - if (!x1e4_31_inAreaDamage) { - if (player.GetAreaIdAlways() != GetAreaIdAlways() || - playerState.GetCurrentSuitRaw() != CPlayerState::kPS_Power) { + if (!inArea || immune) { + x1e4_31_inAreaDamage = false; + mgr.Player()->DecrementPhazon(); + SendScriptMsgs(kSS_Exited, mgr, kSM_None); + mgr.SetIsFullThreat(false); return; } + } else if (!inArea || immune) { + return; + } else { x1e4_31_inAreaDamage = true; - player.IncrementPhazon(); + mgr.Player()->IncrementPhazon(); SendScriptMsgs(kSS_Entered, mgr, kSM_None); mgr.SetIsFullThreat(true); - } else if (player.GetAreaIdAlways() != GetAreaIdAlways() || - playerState.GetCurrentSuitRaw() != CPlayerState::kPS_Power) { - x1e4_31_inAreaDamage = false; - player.DecrementPhazon(); - SendScriptMsgs(kSS_Exited, mgr, kSM_None); - mgr.SetIsFullThreat(false); - return; } - CMaterialList includeList(kMT_Solid); - CMaterialList excudeList(0); - CMaterialFilter filter(CMaterialFilter::MakeIncludeExclude(includeList, excudeList)); - - CDamageInfo dInfo(CWeaponMode(kWT_Heat), xfc_float1 * dt, 0.f, 0.f); - dInfo.SetNoImmunity(true); - mgr.ApplyDamage(GetUniqueId(), player.GetUniqueId(), GetUniqueId(), dInfo, filter, + CDamageInfo dInfo(CWeaponMode(kWT_Heat), xfc_float1 * dt, 0.f, 0.f, true); + mgr.ApplyDamage(GetUniqueId(), player->GetUniqueId(), GetUniqueId(), dInfo, + CMaterialFilter::MakeIncludeExclude(CMaterialList(kMT_Solid), CMaterialList()), CVector3f::Zero()); } void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) { const float deltaScale = dt * xfc_float1; + const float f2 = x100_float2; for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); conn != GetConnectionList().end(); ++conn) { @@ -1015,22 +1011,21 @@ void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) { continue; } - if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(mgr.GetIdForScript(conn->x8_objId)))) { - CModelData* mData = act->ModelData(); - if (mData && (mData->HasAnimData() || mData->HasNormalModel())) { - CVector3f scale = mData->GetScale(); - + TUniqueId uid = mgr.GetIdForScript(conn->x8_objId); + if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(uid))) { + if (act->HasModelData()) { + CVector3f scale = act->GetModelData()->GetScale(); + f32 x, y, z; if (deltaScale > 0.f) { - scale = CVector3f(rstl::min_val(deltaScale + scale.GetX(), x100_float2), - rstl::min_val(deltaScale + scale.GetY(), x100_float2), - rstl::min_val(deltaScale + scale.GetZ(), x100_float2)); + x = CMath::Min(deltaScale + scale.GetX(), f2); + y = CMath::Min(deltaScale + scale.GetY(), f2); + z = CMath::Min(deltaScale + scale.GetZ(), f2); } else { - scale = CVector3f(rstl::max_val(deltaScale + scale.GetX(), x100_float2), - rstl::max_val(deltaScale + scale.GetY(), x100_float2), - rstl::max_val(deltaScale + scale.GetZ(), x100_float2)); + x = CMath::Max(deltaScale + scale.GetX(), f2); + y = CMath::Max(deltaScale + scale.GetY(), f2); + z = CMath::Max(deltaScale + scale.GetZ(), f2); } - - mData->SetScale(scale); + act->ModelData()->SetScale(CVector3f(x, y, z)); } } }