More CScriptSpecialFunction; start rstl::map/red_black_tree

Former-commit-id: 87c0a6041cb0323ce783997cf5be2754f70b8977
This commit is contained in:
Luke Street 2022-10-03 00:49:11 -04:00
parent 1b617eee75
commit cd85b46d6d
16 changed files with 279 additions and 151 deletions

View File

@ -31,8 +31,10 @@ public:
// WrapPi__5CMathFf weak // WrapPi__5CMathFf weak
// WrapTwoPi__5CMathFf weak // WrapTwoPi__5CMathFf weak
// FastFmod__5CMathFfff weak // FastFmod__5CMathFfff weak
// Min<f>__5CMathFRCfRCf weak template < typename T >
// Max<f>__5CMathFRCfRCf weak 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 // InvSqrtF__5CMathFf global
// FastArcCosR__5CMathFf global // FastArcCosR__5CMathFf global
// SlowCosineR__5CMathFf global // SlowCosineR__5CMathFf global
@ -41,9 +43,9 @@ public:
// GetBezierPoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global // GetBezierPoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global
// ClampRadians__5CMathFf weak // ClampRadians__5CMathFf weak
// ModF__5CMathFff weak // ModF__5CMathFff weak
// Deg2Rad__5CMathFf weak static f32 Deg2Rad(f32 deg) { return Deg2Rev(deg) * (M_PIF * 2.f); }
// Deg2Rev__5CMathFf weak static f32 Deg2Rev(f32 deg) { return deg * (1.f / 360.f); }
// ArcCosineR__5CMathFf global static f32 ArcCosineR(f32 v);
// FloorF__5CMathFf global // FloorF__5CMathFf global
// BaryToWorld__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3f global // BaryToWorld__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3f global
// GetCatmullRomSplinePoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global // GetCatmullRomSplinePoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global

View File

@ -6,6 +6,9 @@
#include "Kyoto/Math/CMatrix3f.hpp" #include "Kyoto/Math/CMatrix3f.hpp"
#include "Kyoto/Math/CTransform4f.hpp" #include "Kyoto/Math/CTransform4f.hpp"
class CRelAngle;
class CUnitVector3f;
class CQuaternion { class CQuaternion {
public: public:
CQuaternion(f32 w, f32 x, f32 y, f32 z) : w(w), x(x), y(y), z(z) {} CQuaternion(f32 w, f32 x, f32 y, f32 z) : w(w), x(x), y(y), z(z) {}
@ -35,8 +38,8 @@ public:
// AngleFrom__11CQuaternionCFRC11CQuaternion // AngleFrom__11CQuaternionCFRC11CQuaternion
// BuildEquivalent__11CQuaternionCFv // BuildEquivalent__11CQuaternionCFv
// BuildNormalized__11CQuaternionCFv // BuildNormalized__11CQuaternionCFv
// AxisAngle__11CQuaternionFRC13CUnitVector3fRC9CRelAngle static CQuaternion AxisAngle(const CUnitVector3f&, const CRelAngle&);
// Transform__11CQuaternionCFRC9CVector3f CVector3f Transform(const CVector3f&) const;
// XRotation__11CQuaternionFRC9CRelAngle // XRotation__11CQuaternionFRC9CRelAngle
// YRotation__11CQuaternionFRC9CRelAngle // YRotation__11CQuaternionFRC9CRelAngle
// ZRotation__11CQuaternionFRC9CRelAngle // ZRotation__11CQuaternionFRC9CRelAngle
@ -49,7 +52,7 @@ public:
// f64 y = -this->y; // f64 y = -this->y;
// f64 z = -this->z; // f64 z = -this->z;
return CQuaternion(w, -x, -y, -z); return CQuaternion(w, -x, -y, -z);
} }
static CQuaternion FromMatrixRows(const CVector3f&, const CVector3f&, const CVector3f&); static CQuaternion FromMatrixRows(const CVector3f&, const CVector3f&, const CVector3f&);
static CQuaternion FromMatrix(const CMatrix3f&); static CQuaternion FromMatrix(const CMatrix3f&);

View File

@ -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

View File

@ -9,6 +9,7 @@ typedef const f32 (*ConstMtxPtr)[4];
class CInputStream; class CInputStream;
class CMatrix3f; class CMatrix3f;
class CRelAngle;
class CTransform4f { class CTransform4f {
public: public:
@ -61,9 +62,9 @@ public:
CTransform4f MultiplyIgnoreTranslation(const CTransform4f& other) const; CTransform4f MultiplyIgnoreTranslation(const CTransform4f& other) const;
// Orthonormalize__12CTransform4fFv // Orthonormalize__12CTransform4fFv
CVector3f Rotate(const CVector3f& in) const; CVector3f Rotate(const CVector3f& in) const;
// RotateLocalX__12CTransform4fFRC9CRelAngle void RotateLocalX(const CRelAngle& angle);
// RotateLocalY__12CTransform4fFRC9CRelAngle void RotateLocalY(const CRelAngle& angle);
// RotateLocalZ__12CTransform4fFRC9CRelAngle void RotateLocalZ(const CRelAngle& angle);
// RotateX__12CTransform4fFRC9CRelAngle // RotateX__12CTransform4fFRC9CRelAngle
// RotateY__12CTransform4fFRC9CRelAngle // RotateY__12CTransform4fFRC9CRelAngle
// RotateZ__12CTransform4fFRC9CRelAngle // RotateZ__12CTransform4fFRC9CRelAngle

View File

@ -7,11 +7,8 @@
class CUnitVector3f : public CVector3f { class CUnitVector3f : public CVector3f {
public: public:
enum ENormalize { CUnitVector3f(f32 x, f32 y, f32 z) : CVector3f(x, y, z) { Normalize(); }
// TODO CUnitVector3f(const CVector3f& vec) : CVector3f(vec) { Normalize(); }
};
CUnitVector3f(f32 x, f32 y, f32 z);
CUnitVector3f(const CVector3f& vec);
// TODO // TODO
}; };
CHECK_SIZEOF(CUnitVector3f, 0xc) CHECK_SIZEOF(CUnitVector3f, 0xc)

View File

@ -267,6 +267,7 @@ public:
} }
CVector3f GetTranslation() const { return x34_transform.GetTranslation(); } CVector3f GetTranslation() const { return x34_transform.GetTranslation(); }
void SetTranslation(const CVector3f& vec); void SetTranslation(const CVector3f& vec);
CTransform4f GetLocatorTransform(const rstl::string& segName) const;
CTransform4f GetScaledLocatorTransform(const rstl::string& segName) const; CTransform4f GetScaledLocatorTransform(const rstl::string& segName) const;
/// ???? /// ????

View File

@ -17,15 +17,24 @@ class CDamageInfo {
public: public:
CDamageInfo() CDamageInfo()
: x0_weaponMode(), x8_damage(0.f), xc_radiusDamage(0.f), x10_radius(0.f), x14_knockback(0.f), x18_24_noImmunity(false) {} : x0_weaponMode()
, x8_damage(0.f)
explicit CDamageInfo(CInputStream& in); , xc_radiusDamage(0.f)
, x10_radius(0.f)
CDamageInfo(const CWeaponMode& mode, float damage, float radius, float knockback) , x14_knockback(0.f)
: x0_weaponMode(mode), x8_damage(damage), xc_radiusDamage(damage), x10_radius(radius), x14_knockback(knockback), x18_24_noImmunity(false) {} , 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); CDamageInfo(const CDamageInfo&, float);
explicit CDamageInfo(const SShotParam& other); CDamageInfo(const SShotParam& other);
CDamageInfo& operator=(const SShotParam& other); CDamageInfo& operator=(const SShotParam& other);
const CWeaponMode& GetWeaponMode() const { return x0_weaponMode; } const CWeaponMode& GetWeaponMode() const { return x0_weaponMode; }

View File

@ -39,7 +39,6 @@ public:
}; };
// TODO these probably aren't real // TODO these probably aren't real
bool HasAnimData() const { return xc_animData.get() != nullptr; }
bool HasNormalModel() const { return x1c_normalModel; } bool HasNormalModel() const { return x1c_normalModel; }
CModelData(); CModelData();

View File

@ -67,7 +67,9 @@ public:
CAABox GetBoundingBox() const; CAABox GetBoundingBox() const;
void MoveCollisionPrimitive(const CVector3f&); void MoveCollisionPrimitive(const CVector3f&);
void SetVelocityWR(const CVector3f&);
void SetAngularVelocityWR(const CAxisAngle& angVel); void SetAngularVelocityWR(const CAxisAngle& angVel);
void ClearForcesAndTorques();
void Stop(); void Stop();
CMotionState GetMotionState() const; CMotionState GetMotionState() const;

View File

@ -16,6 +16,7 @@
#include "rstl/auto_ptr.hpp" #include "rstl/auto_ptr.hpp"
#include "rstl/list.hpp" #include "rstl/list.hpp"
#include "rstl/map.hpp"
#include "rstl/pair.hpp" #include "rstl/pair.hpp"
#include "rstl/rc_ptr.hpp" #include "rstl/rc_ptr.hpp"
#include "rstl/reserved_vector.hpp" #include "rstl/reserved_vector.hpp"
@ -77,6 +78,9 @@ struct SOnScreenTex {
class CStateManager : public TOneStatic< CStateManager > { class CStateManager : public TOneStatic< CStateManager > {
public: public:
typedef rstl::map< TEditorId, TUniqueId > TIdList;
typedef rstl::pair< TIdList::const_iterator, TIdList::const_iterator > TIdListResult;
void ResetEscapeSequenceTimer(float); void ResetEscapeSequenceTimer(float);
void SendScriptMsg(TUniqueId uid, TEditorId target, EScriptObjectMessage msg, void SendScriptMsg(TUniqueId uid, TEditorId target, EScriptObjectMessage msg,
EScriptObjectState state); EScriptObjectState state);
@ -97,7 +101,7 @@ public:
CEntity* ObjectById(TUniqueId uid); CEntity* ObjectById(TUniqueId uid);
const CEntity* GetObjectById(TUniqueId uid) const; const CEntity* GetObjectById(TUniqueId uid) const;
TUniqueId GetIdForScript(TEditorId eid) const; TUniqueId GetIdForScript(TEditorId eid) const;
// <unk> GetIdListForScript(TEditorId) const; TIdListResult GetIdListForScript(TEditorId) const;
CMazeState* CurrentMaze(); CMazeState* CurrentMaze();
const CMazeState* GetCurrentMaze() const; const CMazeState* GetCurrentMaze() const;

View File

@ -55,7 +55,13 @@ struct TUniqueId {
private: private:
}; };
// CHECK_SIZEOF(TUniqueId, 0x2) CHECK_SIZEOF(TUniqueId, 0x2)
// struct TGameScriptId {
// TEditorId editorId;
// bool b;
// };
// CHECK_SIZEOF(TGameScriptId, 0x8)
typedef u16 TSfxId; typedef u16 TSfxId;
static TSfxId InvalidSfxId = 0xFFFFu; static TSfxId InvalidSfxId = 0xFFFFu;

View File

@ -28,8 +28,12 @@ class CWeaponMode {
bool x4_26_instantKill : 1; bool x4_26_instantKill : 1;
public: public:
explicit CWeaponMode(EWeaponType type = kWT_None, bool charged = false, bool comboed = false, bool instaKill = false) explicit CWeaponMode(EWeaponType type = kWT_None, bool charged = false, bool comboed = false,
: x0_weaponType(type), x4_24_charged(charged), x4_25_comboed(comboed), x4_26_instantKill(instaKill) {} bool instaKill = false)
: x0_weaponType(type)
, x4_24_charged(charged)
, x4_25_comboed(comboed)
, x4_26_instantKill(instaKill) {}
EWeaponType GetType() const { return x0_weaponType; } EWeaponType GetType() const { return x0_weaponType; }

View File

@ -3,14 +3,30 @@
#include "types.h" #include "types.h"
#include "rstl/pair.hpp"
#include "rstl/red_black_tree.hpp" #include "rstl/red_black_tree.hpp"
#include "rstl/rmemory_allocator.hpp" #include "rstl/rmemory_allocator.hpp"
namespace rstl { namespace rstl {
template < typename K, typename V, typename Cmp = less< K >, typename Alloc = rmemory_allocator > template < typename K, typename V, typename Cmp = less< K >, typename Alloc = rmemory_allocator >
class map { 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 } // namespace rstl
#endif #endif

View File

@ -16,6 +16,7 @@ template < typename T, typename Vec, typename Alloc >
class const_pointer_iterator { class const_pointer_iterator {
public: public:
typedef random_access_iterator_tag iterator_category; typedef random_access_iterator_tag iterator_category;
typedef T* value_type;
const_pointer_iterator() : current(nullptr) {} const_pointer_iterator() : current(nullptr) {}
const_pointer_iterator(const T* begin) : current(const_cast< T* >(begin)) {} const_pointer_iterator(const T* begin) : current(const_cast< T* >(begin)) {}

View File

@ -3,6 +3,8 @@
#include "types.h" #include "types.h"
#include "rstl/rmemory_allocator.hpp"
namespace rstl { namespace rstl {
template < typename P > template < typename P >
struct select1st {}; struct select1st {};
@ -10,7 +12,45 @@ struct select1st {};
template < typename T > template < typename T >
struct less {}; struct less {};
template < typename T, typename P, int U, typename S = select1st< P >, typename Cmp = less< T > > enum node_color {
class red_black_tree {}; 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 }; // namespace rstl
#endif #endif

View File

@ -16,6 +16,8 @@
#include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Audio/CSfxManager.hpp"
#include "Kyoto/Math/CFrustumPlanes.hpp" #include "Kyoto/Math/CFrustumPlanes.hpp"
#include "Kyoto/Math/CMath.hpp" #include "Kyoto/Math/CMath.hpp"
#include "Kyoto/Math/CRelAngle.hpp"
#include "Kyoto/Math/CUnitVector3f.hpp"
#include "Kyoto/Math/CVector2i.hpp" #include "Kyoto/Math/CVector2i.hpp"
#include "rstl/math.hpp" #include "rstl/math.hpp"
@ -606,33 +608,30 @@ void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr) {
void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManager& mgr) { void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManager& mgr) {
if (x1a8_ringState != kRS_Breakup) { if (x1a8_ringState != kRS_Breakup) {
for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); for (int i = 0; i < x198_ringControllers.size(); ++i) {
it != x198_ringControllers.end(); ++it) { if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x198_ringControllers[i].x0_id))) {
if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) {
CTransform4f newXf = act->GetTransform(); CTransform4f newXf = act->GetTransform();
// TODO newXf.RotateLocalZ(CRelAngle::FromDegrees(dt * x198_ringControllers[i].x4_rotateSpeed));
// newXf.rotateLocalZ(zeus::degToRad(it->x4_rotateSpeed * dt));
act->SetTransform(newXf); act->SetTransform(newXf);
} }
} }
} }
switch (x1a8_ringState) { switch (x1a8_ringState) {
case kRS_Scramble:
break;
case kRS_Breakup: { case kRS_Breakup: {
float minMag = 0.f; float minMag = 0.f;
for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); for (int i = 0; i < x198_ringControllers.size(); ++i) {
it != x198_ringControllers.end(); ++it) { if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x198_ringControllers[i].x0_id))) {
if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { act->SetTranslation(act->GetTranslation() + act->GetTransform().GetForward() * 50.f * dt);
// TODO: CTransform api differences minMag = rstl::min_val(minMag, act->GetTranslation().Magnitude());
// act->SetTranslation(act->GetTranform().basis[1] * 50.f * dt + act->GetTranslation());
// minMag = std::min(act->GetTranslation().magnitude(), minMag);
} }
} }
CalculateRenderBounds(); CalculateRenderBounds();
if (minMag != 0.f) { if (minMag) {
/* Never actually happens */ // Never actually happens
for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); for (int i = 0; i < x198_ringControllers.size(); ++i) {
it != x198_ringControllers.end(); ++it) { if (CEntity* ent = mgr.ObjectById(x198_ringControllers[i].x0_id)) {
if (CEntity* ent = mgr.ObjectById(it->x0_id)) {
ent->SetActive(false); ent->SetActive(false);
} }
} }
@ -641,35 +640,39 @@ void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManage
break; break;
} }
case kRS_Rotate: { case kRS_Rotate: {
// x1ac_ringRotateTarget = CQuaternion::fromAxisAngle(zeus::skUp, zeus::degToRad(xfc_float1 * x1ac_ringRotateTarget =
// (x1b8_ringReverse ? 1.f : -1.f) * dt)) CQuaternion::AxisAngle(
// .transform(x1ac_ringRotateTarget); CVector3f(0.f, 0.f, 1.f),
CRelAngle::FromDegrees(xfc_float1 * (x1b8_ringReverse ? 1.f : -1.f) * dt))
.Transform(x1ac_ringRotateTarget);
bool allReachedTarget = true; bool allReachedTarget = true;
for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); for (int i = 0; i < x198_ringControllers.size(); ++i) {
it != x198_ringControllers.end(); ++it) { if (x198_ringControllers[i].x8_reachedTarget) {
if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(it->x0_id))) { continue;
/*CVector3f lookDirFlat = act->GetTransform().basis[1]; }
lookDirFlat.SetZ(0.f); if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(x198_ringControllers[i].x0_id))) {
lookDirFlat.Normalize(); CVector3f forward = act->GetTransform().GetForward();
if (std::acos(CMath::Clamp(-1.f, lookDirFlat.Dot(x1ac_ringRotateTarget), 1.f)) <= forward.SetZ(0.f);
zeus::degToRad((xfc_float1 + std::fabs(rc.x4_rotateSpeed)) / 30.f)) { forward.Normalize();
CTransform4f newXf = zeus::lookAt(zeus::skZero3f, x1ac_ringRotateTarget); float f1 = CMath::Limit(CVector3f::Dot(forward, x1ac_ringRotateTarget), 1.f);
newXf.origin = act->GetTranslation(); 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); act->SetTransform(newXf);
rc.x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1; x198_ringControllers[i].x4_rotateSpeed = (x1b8_ringReverse ? 1.f : -1.f) * xfc_float1;
rc.x8_reachedTarget = true; x198_ringControllers[i].x8_reachedTarget = true;
} else { } else {
allReachedTarget = false; allReachedTarget = false;
break; break;
}*/ }
} }
} }
if (allReachedTarget) { if (allReachedTarget) {
SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); SendScriptMsgs(kSS_MaxReached, mgr, kSM_None);
x1a8_ringState = kRS_Stopped; x1a8_ringState = kRS_Stopped;
for (rstl::vector< SRingController >::iterator it = x198_ringControllers.begin(); for (int i = 0; i < x198_ringControllers.size(); ++i) {
it != x198_ringControllers.end(); ++it) { x198_ringControllers[i].x8_reachedTarget = false;
it->x8_reachedTarget = false;
} }
} }
break; break;
@ -686,20 +689,21 @@ void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr)
continue; continue;
} }
/* const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId);
const auto search = mgr.GetIdListForScript(conn->x8_objId); if (it.first != it.second) {
for (auto it = search.first; it != search.second; ++it) { if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it.first->second))) {
if (const TCastToConstPtr<CActor> act = mgr.GetObjectById(it->second)) { if (!act->HasAnimation()) {
const CTransform4f xf = act->GetTransform() * act->GetLocatorTransform(xec_locatorName); continue;
CPlayer& pl = mgr.GetPlayer(); }
pl.SetTransform(xf); CTransform4f xf = act->GetTransform() * act->GetLocatorTransform(xec_locatorName);
pl.SetVelocityWR({}); CPlayer* player = mgr.Player();
pl.SetAngularVelocityWR({}); player->SetTransform(xf);
pl.ClearForcesAndTorques(); player->SetVelocityWR(CVector3f::Zero());
player->SetAngularVelocityWR(CAxisAngle::Identity());
player->ClearForcesAndTorques();
return; return;
} }
} }
*/
} }
} }
@ -846,28 +850,31 @@ void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr)
continue; continue;
} }
// GetIdListForScript seems very different between Ghidra and Metaforce const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId);
// const auto search = mgr.GetIdListForScript(conn->x8_objId); if (it.first != it.second) {
TUniqueId uid = it.first->second;
rstl::pair< TUniqueId, TUniqueId >* it; if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(uid))) {
if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it->second))) { if (conn->x4_msg == kSM_Activate && act->HasAnimation()) {
if (conn->x4_msg == kSM_Activate && if (!act->GetActive()) {
(act->HasModelData() && act->GetModelData()->HasAnimData()) && act->GetActive()) { return;
followedAct = it->second; }
} else if (conn->x4_msg == kSM_Deactivate) { followedAct = uid;
followerAct = it->second; } else if (conn->x4_msg == kSM_Deactivate) {
followerAct = uid;
}
} }
} }
} }
if (followerAct == kInvalidUniqueId || followedAct == kInvalidUniqueId) { if (followerAct != kInvalidUniqueId && followedAct != kInvalidUniqueId) {
return; 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) { void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr) {
@ -880,22 +887,25 @@ void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr)
continue; continue;
} }
// GetIdListForScript seems very different between Ghidra and Metaforce const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId);
// const auto search = mgr.GetIdListForScript(conn->x8_objId); if (it.first != it.second) {
TUniqueId uid = it.first->second;
rstl::pair< TUniqueId, TUniqueId >* it; if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(uid))) {
if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(it->second))) { if (conn->x4_msg == kSM_Activate) {
if (conn->x4_msg == kSM_Activate && act->GetActive()) { if (!act->GetActive()) {
followedAct = it->second; return;
} else if (conn->x4_msg == kSM_Deactivate) { }
followerAct = it->second; followedAct = uid;
} else if (conn->x4_msg == kSM_Deactivate) {
followerAct = uid;
}
} }
} }
} }
const CActor* followed = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct)); const CActor* followed = TCastToConstPtr< CActor >(mgr.GetObjectById(followedAct));
CActor* follower = TCastToPtr< CActor >(mgr.ObjectById(followerAct)); CActor* follower = TCastToPtr< CActor >(mgr.ObjectById(followerAct));
if (followed && follower) { if (follower && followed) {
follower->SetTransform(followed->GetTransform()); follower->SetTransform(followed->GetTransform());
} }
} }
@ -957,7 +967,7 @@ void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) {
} }
void CScriptSpecialFunction::ThinkRainSimulator(float, 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); SendScriptMsgs(kSS_MaxReached, mgr, kSM_None);
} else { } else {
SendScriptMsgs(kSS_Zero, mgr, kSM_None); SendScriptMsgs(kSS_Zero, mgr, kSM_None);
@ -965,49 +975,35 @@ void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) {
} }
void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) { void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) {
const CPlayerState& playerState = *mgr.GetPlayerState(); const CPlayer* player = mgr.GetPlayer();
CPlayer& player = *mgr.Player(); bool inArea = player->GetAreaIdAlways() == GetAreaIdAlways();
bool immune = mgr.GetPlayerState()->GetCurrentSuitRaw() > CPlayerState::kPS_Power;
/* Make sure we're not currently set to take damage, if so reset our state to be as if we're not
*/
if (x1e4_31_inAreaDamage) { if (x1e4_31_inAreaDamage) {
x1e4_31_inAreaDamage = false; if (!inArea || immune) {
player.DecrementPhazon(); x1e4_31_inAreaDamage = false;
SendScriptMsgs(kSS_Exited, mgr, kSM_None); mgr.Player()->DecrementPhazon();
mgr.SetIsFullThreat(false); SendScriptMsgs(kSS_Exited, mgr, kSM_None);
} mgr.SetIsFullThreat(false);
return;
if (!x1e4_31_inAreaDamage) {
if (player.GetAreaIdAlways() != GetAreaIdAlways() ||
playerState.GetCurrentSuitRaw() != CPlayerState::kPS_Power) {
return; return;
} }
} else if (!inArea || immune) {
return;
} else {
x1e4_31_inAreaDamage = true; x1e4_31_inAreaDamage = true;
player.IncrementPhazon(); mgr.Player()->IncrementPhazon();
SendScriptMsgs(kSS_Entered, mgr, kSM_None); SendScriptMsgs(kSS_Entered, mgr, kSM_None);
mgr.SetIsFullThreat(true); 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); CDamageInfo dInfo(CWeaponMode(kWT_Heat), xfc_float1 * dt, 0.f, 0.f, true);
CMaterialList excudeList(0); mgr.ApplyDamage(GetUniqueId(), player->GetUniqueId(), GetUniqueId(), dInfo,
CMaterialFilter filter(CMaterialFilter::MakeIncludeExclude(includeList, excudeList)); CMaterialFilter::MakeIncludeExclude(CMaterialList(kMT_Solid), CMaterialList()),
CDamageInfo dInfo(CWeaponMode(kWT_Heat), xfc_float1 * dt, 0.f, 0.f);
dInfo.SetNoImmunity(true);
mgr.ApplyDamage(GetUniqueId(), player.GetUniqueId(), GetUniqueId(), dInfo, filter,
CVector3f::Zero()); CVector3f::Zero());
} }
void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) { void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) {
const float deltaScale = dt * xfc_float1; const float deltaScale = dt * xfc_float1;
const float f2 = x100_float2;
for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin(); for (rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin();
conn != GetConnectionList().end(); ++conn) { conn != GetConnectionList().end(); ++conn) {
@ -1015,22 +1011,21 @@ void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) {
continue; continue;
} }
if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(mgr.GetIdForScript(conn->x8_objId)))) { TUniqueId uid = mgr.GetIdForScript(conn->x8_objId);
CModelData* mData = act->ModelData(); if (CActor* act = TCastToPtr< CActor >(mgr.ObjectById(uid))) {
if (mData && (mData->HasAnimData() || mData->HasNormalModel())) { if (act->HasModelData()) {
CVector3f scale = mData->GetScale(); CVector3f scale = act->GetModelData()->GetScale();
f32 x, y, z;
if (deltaScale > 0.f) { if (deltaScale > 0.f) {
scale = CVector3f(rstl::min_val(deltaScale + scale.GetX(), x100_float2), x = CMath::Min(deltaScale + scale.GetX(), f2);
rstl::min_val(deltaScale + scale.GetY(), x100_float2), y = CMath::Min(deltaScale + scale.GetY(), f2);
rstl::min_val(deltaScale + scale.GetZ(), x100_float2)); z = CMath::Min(deltaScale + scale.GetZ(), f2);
} else { } else {
scale = CVector3f(rstl::max_val(deltaScale + scale.GetX(), x100_float2), x = CMath::Max(deltaScale + scale.GetX(), f2);
rstl::max_val(deltaScale + scale.GetY(), x100_float2), y = CMath::Max(deltaScale + scale.GetY(), f2);
rstl::max_val(deltaScale + scale.GetZ(), x100_float2)); z = CMath::Max(deltaScale + scale.GetZ(), f2);
} }
act->ModelData()->SetScale(CVector3f(x, y, z));
mData->SetScale(scale);
} }
} }
} }