More CScriptSpecialFunction; start rstl::map/red_black_tree

Former-commit-id: 87c0a6041c
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
// WrapTwoPi__5CMathFf weak
// FastFmod__5CMathFfff weak
// Min<f>__5CMathFRCfRCf weak
// Max<f>__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

View File

@ -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&);

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

View File

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

View File

@ -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;
/// ????

View File

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

View File

@ -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();

View File

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

View File

@ -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;
// <unk> GetIdListForScript(TEditorId) const;
TIdListResult GetIdListForScript(TEditorId) const;
CMazeState* CurrentMaze();
const CMazeState* GetCurrentMaze() const;

View File

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

View File

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

View File

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

View File

@ -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)) {}

View File

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

View File

@ -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<CActor> 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));
}
}
}