Add CScriptTrigger

This commit is contained in:
Henrique Gemignani Passos Lima 2022-10-20 19:32:57 +03:00
parent 89d1d945dc
commit 865e2d58f2
No known key found for this signature in database
GPG Key ID: E224F951761145F8
10 changed files with 474 additions and 21 deletions

View File

@ -3,8 +3,8 @@
.section .data
.balign 8
.global lbl_803DA4D8
lbl_803DA4D8:
.global __vt__14CScriptTrigger
__vt__14CScriptTrigger:
# ROM: 0x3D74D8
.4byte 0
.4byte 0
@ -59,8 +59,8 @@ lbl_805A6F94:
.global lbl_805A8E00
lbl_805A8E00:
.skip 0x4
.global lbl_805A8E04
lbl_805A8E04:
.global sktonOHurtWeaponMode$230
sktonOHurtWeaponMode$230:
.skip 0xC
.section .sdata2, "a"
@ -160,8 +160,8 @@ GetInhabitants__14CScriptTriggerCFv:
/* 80075D24 00072C84 38 63 00 E8 */ addi r3, r3, 0xe8
/* 80075D28 00072C88 4E 80 00 20 */ blr
.global UpdateInhabitants__14CScriptTriggerFR13CStateManager
UpdateInhabitants__14CScriptTriggerFR13CStateManager:
.global UpdateInhabitants__14CScriptTriggerFfR13CStateManager
UpdateInhabitants__14CScriptTriggerFfR13CStateManager:
/* 80075D2C 00072C8C 94 21 FE 50 */ stwu r1, -0x1b0(r1)
/* 80075D30 00072C90 7C 08 02 A6 */ mflr r0
/* 80075D34 00072C94 90 01 01 B4 */ stw r0, 0x1b4(r1)
@ -687,7 +687,7 @@ Think__14CScriptTriggerFfR13CStateManager:
/* 800764D8 00073438 88 03 00 30 */ lbz r0, 0x30(r3)
/* 800764DC 0007343C 54 00 CF FF */ rlwinm. r0, r0, 0x19, 0x1f, 0x1f
/* 800764E0 00073440 41 82 00 08 */ beq lbl_800764E8
/* 800764E4 00073444 4B FF F8 49 */ bl UpdateInhabitants__14CScriptTriggerFR13CStateManager
/* 800764E4 00073444 4B FF F8 49 */ bl UpdateInhabitants__14CScriptTriggerFfR13CStateManager
lbl_800764E8:
/* 800764E8 00073448 80 01 00 14 */ lwz r0, 0x14(r1)
/* 800764EC 0007344C 7C 08 03 A6 */ mtlr r0
@ -1136,12 +1136,12 @@ lbl_80076B24:
/* 80076B50 00073AB0 88 0D A2 40 */ lbz r0, lbl_805A8E00@sda21(r13)
/* 80076B54 00073AB4 7C 00 07 75 */ extsb. r0, r0
/* 80076B58 00073AB8 40 82 00 3C */ bne lbl_80076B94
/* 80076B5C 00073ABC 38 ED A2 44 */ addi r7, r13, lbl_805A8E04@sda21
/* 80076B5C 00073ABC 38 ED A2 44 */ addi r7, r13, sktonOHurtWeaponMode$230@sda21
/* 80076B60 00073AC0 38 C0 00 00 */ li r6, 0
/* 80076B64 00073AC4 88 07 00 04 */ lbz r0, 4(r7)
/* 80076B68 00073AC8 50 C0 3E 30 */ rlwimi r0, r6, 7, 0x18, 0x18
/* 80076B6C 00073ACC 38 80 00 01 */ li r4, 1
/* 80076B70 00073AD0 90 CD A2 44 */ stw r6, lbl_805A8E04@sda21(r13)
/* 80076B70 00073AD0 90 CD A2 44 */ stw r6, sktonOHurtWeaponMode$230@sda21(r13)
/* 80076B74 00073AD4 54 05 06 3E */ clrlwi r5, r0, 0x18
/* 80076B78 00073AD8 50 C5 36 72 */ rlwimi r5, r6, 6, 0x19, 0x19
/* 80076B7C 00073ADC 98 07 00 04 */ stb r0, 4(r7)
@ -1152,14 +1152,14 @@ lbl_80076B24:
/* 80076B90 00073AF0 98 8D A2 40 */ stb r4, lbl_805A8E00@sda21(r13)
lbl_80076B94:
/* 80076B94 00073AF4 C0 23 00 00 */ lfs f1, 0(r3)
/* 80076B98 00073AF8 38 8D A2 44 */ addi r4, r13, lbl_805A8E04@sda21
/* 80076B98 00073AF8 38 8D A2 44 */ addi r4, r13, sktonOHurtWeaponMode$230@sda21
/* 80076B9C 00073AFC C0 42 88 D8 */ lfs f2, lbl_805AA5F8@sda21(r2)
/* 80076BA0 00073B00 38 A0 00 00 */ li r5, 0
/* 80076BA4 00073B04 C0 02 88 D0 */ lfs f0, lbl_805AA5F0@sda21(r2)
/* 80076BA8 00073B08 38 60 00 00 */ li r3, 0
/* 80076BAC 00073B0C EC 22 00 72 */ fmuls f1, f2, f1
/* 80076BB0 00073B10 88 C4 00 04 */ lbz r6, 4(r4)
/* 80076BB4 00073B14 80 ED A2 44 */ lwz r7, lbl_805A8E04@sda21(r13)
/* 80076BB4 00073B14 80 ED A2 44 */ lwz r7, sktonOHurtWeaponMode$230@sda21(r13)
/* 80076BB8 00073B18 38 80 00 01 */ li r4, 1
/* 80076BBC 00073B1C 88 01 00 D0 */ lbz r0, 0xd0(r1)
/* 80076BC0 00073B20 50 A0 3E 30 */ rlwimi r0, r5, 7, 0x18, 0x18
@ -1225,8 +1225,8 @@ __dt__14CScriptTriggerFv:
/* 80076C9C 00073BFC 93 81 00 10 */ stw r28, 0x10(r1)
/* 80076CA0 00073C00 7C 7C 1B 79 */ or. r28, r3, r3
/* 80076CA4 00073C04 41 82 00 90 */ beq lbl_80076D34
/* 80076CA8 00073C08 3C 60 80 3E */ lis r3, lbl_803DA4D8@ha
/* 80076CAC 00073C0C 38 03 A4 D8 */ addi r0, r3, lbl_803DA4D8@l
/* 80076CA8 00073C08 3C 60 80 3E */ lis r3, __vt__14CScriptTrigger@ha
/* 80076CAC 00073C0C 38 03 A4 D8 */ addi r0, r3, __vt__14CScriptTrigger@l
/* 80076CB0 00073C10 90 1C 00 00 */ stw r0, 0(r28)
/* 80076CB4 00073C14 83 FC 00 EC */ lwz r31, 0xec(r28)
/* 80076CB8 00073C18 83 DC 00 F0 */ lwz r30, 0xf0(r28)
@ -1255,7 +1255,7 @@ lbl_80076CD4:
lbl_80076D0C:
/* 80076D0C 00073C6C 38 7C 00 E8 */ addi r3, r28, 0xe8
/* 80076D10 00073C70 38 80 FF FF */ li r4, -1
/* 80076D14 00073C74 48 00 02 E1 */ bl sub_80076ff4
/* 80076D14 00073C74 48 00 02 E1 */ bl "__dt__Q24rstl67list<Q214CScriptTrigger14CObjectTracker,Q24rstl17rmemory_allocator>Fv"
/* 80076D18 00073C78 7F 83 E3 78 */ mr r3, r28
/* 80076D1C 00073C7C 38 80 00 00 */ li r4, 0
/* 80076D20 00073C80 4B FD E9 D1 */ bl __dt__6CActorFv
@ -1335,9 +1335,9 @@ lbl_80076D34:
/* 80076E38 00073D98 38 61 00 B8 */ addi r3, r1, 0xb8
/* 80076E3C 00073D9C 38 80 FF FF */ li r4, -1
/* 80076E40 00073DA0 48 09 FC 0D */ bl __dt__10CModelDataFv
/* 80076E44 00073DA4 3C 60 80 3E */ lis r3, lbl_803DA4D8@ha
/* 80076E44 00073DA4 3C 60 80 3E */ lis r3, __vt__14CScriptTrigger@ha
/* 80076E48 00073DA8 38 94 00 F4 */ addi r4, r20, 0xf4
/* 80076E4C 00073DAC 38 63 A4 D8 */ addi r3, r3, lbl_803DA4D8@l
/* 80076E4C 00073DAC 38 63 A4 D8 */ addi r3, r3, __vt__14CScriptTrigger@l
/* 80076E50 00073DB0 38 00 00 00 */ li r0, 0
/* 80076E54 00073DB4 90 74 00 00 */ stw r3, 0(r20)
/* 80076E58 00073DB8 7F 63 DB 78 */ mr r3, r27
@ -1452,8 +1452,8 @@ lbl_80076FCC:
/* 80076FEC 00073F4C 38 21 00 10 */ addi r1, r1, 0x10
/* 80076FF0 00073F50 4E 80 00 20 */ blr
.global sub_80076ff4
sub_80076ff4:
.global "__dt__Q24rstl67list<Q214CScriptTrigger14CObjectTracker,Q24rstl17rmemory_allocator>Fv"
"__dt__Q24rstl67list<Q214CScriptTrigger14CObjectTracker,Q24rstl17rmemory_allocator>Fv":
/* 80076FF4 00073F54 94 21 FF E0 */ stwu r1, -0x20(r1)
/* 80076FF8 00073F58 7C 08 02 A6 */ mflr r0
/* 80076FFC 00073F5C 90 01 00 24 */ stw r0, 0x24(r1)

View File

@ -47,6 +47,7 @@ public:
void SetKnockBackPower(float k) { x14_knockback = k; }
float GetDamage() const { return x8_damage; }
void SetDamage(float d) { x8_damage = d; }
bool HasNoDamage() const { return x8_damage <= 0.0f; }
float GetDamage(const CDamageVulnerability& dVuln) const;
float GetRadiusDamage() const { return xc_radiusDamage; }
void SetRadiusDamage(float r) { xc_radiusDamage = r; }

View File

@ -120,6 +120,7 @@ public:
CEntity* ObjectById(TUniqueId uid);
const CEntity* GetObjectById(TUniqueId uid) const;
TEditorId GetEditorIdForUniqueId(TUniqueId) const;
TUniqueId GetIdForScript(TEditorId eid) const;
TIdListResult GetIdListForScript(TEditorId) const;
@ -198,6 +199,9 @@ public:
return xf90_deferredTransition == kSMT_MessageScreen;
}
void SetLastTriggerId(TUniqueId uid) { xf74_lastTrigger = uid; }
TUniqueId GetLastTriggerId() const { return xf74_lastTrigger; }
void SetLastRelayId(const TUniqueId& uid) { xf76_lastRelay = uid; }
TUniqueId* GetLastRelayIdPtr() { return &xf76_lastRelay; }
TUniqueId GetLastRelayId() const { return xf76_lastRelay; }

View File

@ -0,0 +1,11 @@
#ifndef _CSCRIPTSTEAM
#define _CSCRIPTSTEAM
#include "MetroidPrime/ScriptObjects/CScriptTrigger.hpp"
class CScriptSteam : public CScriptTrigger {
public:
};
#endif // _CSCRIPTSTEAM

View File

@ -0,0 +1,78 @@
#ifndef _CSCRIPTTRIGGER
#define _CSCRIPTTRIGGER
#include "MetroidPrime/CActor.hpp"
#include "MetroidPrime/CDamageInfo.hpp"
#include "rstl/list.hpp"
enum ETriggerFlags {
kTFL_None = 0,
kTFL_DetectPlayer = (1 << 0),
kTFL_DetectAI = (1 << 1),
kTFL_DetectProjectiles1 = (1 << 2),
kTFL_DetectProjectiles2 = (1 << 3),
kTFL_DetectProjectiles3 = (1 << 4),
kTFL_DetectProjectiles4 = (1 << 5),
kTFL_DetectBombs = (1 << 6),
kTFL_DetectPowerBombs = (1 << 7),
kTFL_DetectProjectiles5 = (1 << 8),
kTFL_DetectProjectiles6 = (1 << 9),
kTFL_DetectProjectiles7 = (1 << 10),
kTFL_KillOnEnter = (1 << 11),
kTFL_DetectMorphedPlayer = (1 << 12),
kTFL_UseCollisionImpulses = (1 << 13),
kTFL_DetectCamera = (1 << 14),
kTFL_UseBooleanIntersection = (1 << 15),
kTFL_DetectUnmorphedPlayer = (1 << 16),
kTFL_BlockEnvironmentalEffects = (1 << 17)
};
class CScriptTrigger : public CActor {
public:
class CObjectTracker {
TUniqueId x0_id;
public:
explicit CObjectTracker(TUniqueId id) : x0_id(id) {}
TUniqueId GetObjectId() const { return x0_id; }
bool operator==(const CObjectTracker& other) const { return x0_id == other.x0_id; }
};
rstl::list< CObjectTracker > xe8_inhabitants;
CDamageInfo x100_damageInfo;
CVector3f x11c_forceField;
float x128_forceMagnitude;
uint x12c_flags;
CAABox x130_bounds;
bool x148_24_detectCamera : 1;
bool x148_25_camSubmerged : 1;
bool x148_26_deactivateOnEntered : 1;
bool x148_27_deactivateOnExited : 1;
bool x148_28_playerTriggerProc : 1;
bool x148_29_didPhazonDamage : 1;
public:
CScriptTrigger(TUniqueId, const rstl::string& name, const CEntityInfo& info, const CVector3f& pos,
const CAABox&, const CDamageInfo& dInfo, const CVector3f& orientedForce,
uint triggerFlags, bool active, bool deactivateOnEntered, bool deactivateOnExited);
~CScriptTrigger();
void Touch(CActor&, CStateManager&);
CAABox GetTriggerBoundsWR() const;
rstl::optional_object<CAABox> GetTouchBounds() const override;
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
void Think(float, CStateManager&) override;
void UpdateInhabitants(float, CStateManager&);
const rstl::list<CObjectTracker>& GetInhabitants() const;
const CScriptTrigger::CObjectTracker* FindObject(TUniqueId);
void Accept(IVisitor& visitor) override;
virtual void InhabitantAdded(CActor&, CStateManager&);
virtual void InhabitantIdle(CActor&, CStateManager&);
virtual void InhabitantExited(CActor&, CStateManager&);
virtual void InhabitantRejected(CActor&, CStateManager&);
};
#endif // _CSCRIPTTRIGGER

View File

@ -22,6 +22,8 @@ public:
int /*EProjectileAttrib?*/) const override;
void FluidFXThink(EFluidState, CScriptWater&, CStateManager&) override;
EProjectileAttrib GetAttribField() const { return xe8_projectileAttribs; }
private:
EProjectileAttrib xe8_projectileAttribs;
TUniqueId xec_ownerId;

View File

@ -68,6 +68,7 @@ private:
void set_prev(node* prev) { x0_prev = prev; }
void set_next(node* next) { x4_next = next; }
T* get_value() { return reinterpret_cast< T* >(&x8_item); }
const T* get_value() const { return reinterpret_cast< const T* >(&x8_item); }
};
node* create_node(node* prev, node* next, const T& val) {
@ -103,9 +104,9 @@ public:
return *this;
}
const_iterator operator--(int) const { return const_iterator(this->current->x0_prev); }
const T* get_pointer() const { return current->x8_item; }
const T& operator*() const { return *current->x8_item; }
const T* operator->() const { return current->x8_item; }
const T* get_pointer() const { return current->get_value(); }
const T& operator*() const { return *current->get_value(); }
const T* operator->() const { return current->get_value(); }
bool operator==(const const_iterator& other) const { return current == other.current; }
bool operator!=(const const_iterator& other) const { return current != other.current; }

View File

@ -51,6 +51,9 @@ public:
T& operator*() { return data(); }
T* operator->() { return &data(); }
const T& operator*() const { return data(); }
const T* operator->() const { return &data(); }
private:
uchar m_data[sizeof(T)];

View File

@ -0,0 +1 @@
#include "MetroidPrime/ScriptObjects/CScriptSteam.hpp"

View File

@ -0,0 +1,352 @@
#include "MetroidPrime/ScriptObjects/CScriptTrigger.hpp"
#include "MetroidPrime/CActorParameters.hpp"
#include "MetroidPrime/CDamageVulnerability.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "MetroidPrime/Player/CPlayer.hpp"
#include "MetroidPrime/Weapons/CWeapon.hpp"
#include "MetroidPrime/Cameras/CCameraManager.hpp"
#include "MetroidPrime/Cameras/CGameCamera.hpp"
CScriptTrigger::CScriptTrigger(TUniqueId uid, const rstl::string& name, const CEntityInfo& info,
const CVector3f& pos, const CAABox& bounds, const CDamageInfo& dInfo,
const CVector3f& forceField, uint triggerFlags, bool active,
bool deactivateOnEntered, bool deactivateOnExited)
: CActor(uid, active, name, info, CTransform4f::Translate(pos), CModelData::CModelDataNull(),
CMaterialList(kMT_Trigger), CActorParameters::None(), kInvalidUniqueId)
, x100_damageInfo(dInfo)
, x11c_forceField(forceField)
, x128_forceMagnitude(forceField.Magnitude())
, x12c_flags(triggerFlags)
, x130_bounds(bounds)
, x148_24_detectCamera(false)
, x148_25_camSubmerged(false)
, x148_26_deactivateOnEntered(deactivateOnEntered)
, x148_27_deactivateOnExited(deactivateOnExited)
, x148_28_playerTriggerProc(false)
, x148_29_didPhazonDamage(false) {
SetCallTouch(false);
}
CScriptTrigger::~CScriptTrigger() {
xe8_inhabitants.clear();
if (x12c_flags & 0x11000) {
x12c_flags = x12c_flags & 0xfffeefff;
x12c_flags = x12c_flags | 1;
}
}
void CScriptTrigger::Touch(CActor& act, CStateManager& mgr) {
if (act.GetActive() && !act.GetMaterialList().HasMaterial(kMT_Trigger)) {
if (FindObject(act.GetUniqueId()) == nullptr) {
uint testFlags = kTFL_None;
CPlayer* pl = TCastToPtr< CPlayer >(act);
if (pl) {
if (x128_forceMagnitude > 0.f && (x12c_flags & kTFL_DetectPlayer != 0)) {
if (mgr.GetLastTriggerId() != kInvalidUniqueId) {
return;
}
mgr.SetLastTriggerId(GetUniqueId());
}
testFlags |= kTFL_DetectPlayer;
if (pl->GetMorphballTransitionState() == CPlayer::kMS_Unmorphed) {
testFlags |= kTFL_DetectUnmorphedPlayer;
}
if (pl->GetMorphballTransitionState() == CPlayer::kMS_Morphed) {
testFlags |= kTFL_DetectMorphedPlayer;
}
}
if (TCastToPtr< CPatterned >(act)) {
testFlags |= kTFL_DetectAI;
}
if (TCastToPtr< CGameProjectile >(act)) {
testFlags |= kTFL_DetectProjectiles1 | kTFL_DetectProjectiles2 | kTFL_DetectProjectiles3 |
kTFL_DetectProjectiles4 | kTFL_DetectProjectiles5 | kTFL_DetectProjectiles6 |
kTFL_DetectProjectiles7;
} else if (const CWeapon* weap = TCastToConstPtr< CWeapon >(act)) {
if ((weap->GetAttribField() & kPA_Bombs) == kPA_Bombs) {
testFlags |= kTFL_DetectBombs;
} else if ((weap->GetAttribField() & kPA_PowerBombs) == kPA_PowerBombs) {
testFlags |= kTFL_DetectPowerBombs;
}
}
if (testFlags & x12c_flags) {
xe8_inhabitants.push_back(CObjectTracker(act.GetUniqueId()));
InhabitantAdded(act, mgr);
if ((testFlags & kTFL_DetectPlayer) && pl) {
if (x148_28_playerTriggerProc != true) {
x148_28_playerTriggerProc = true;
pl = mgr.Player();
if (x148_29_didPhazonDamage) {
pl->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
if (!x100_damageInfo.HasNoDamage()) {
const CDamageVulnerability* dVuln = pl->GetDamageVulnerability();
bool phazonHurt = dVuln->WeaponHurts(x100_damageInfo.GetWeaponMode(), false);
if (x100_damageInfo.GetWeaponMode().GetType() == kWT_Phazon) {
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::kIT_PhazonSuit)) {
phazonHurt = false;
}
}
if (phazonHurt) {
pl->IncrementPhazon();
x148_29_didPhazonDamage = true;
}
}
}
}
SendScriptMsgs(kSS_Entered, mgr, kSM_None);
if (x148_26_deactivateOnEntered) {
mgr.SendScriptMsg(GetUniqueId(), mgr.GetEditorIdForUniqueId(GetUniqueId()),
kSM_Deactivate, kSS_Entered);
if (act.HealthInfo(mgr) && x100_damageInfo.GetDamage() > 0.f) {
mgr.ApplyDamage(GetUniqueId(), act.GetUniqueId(), GetUniqueId(), x100_damageInfo,
CMaterialFilter::MakeIncludeExclude(SolidMaterial, CMaterialList(0)),
CVector3f::Zero());
}
}
if (x12c_flags & kTFL_KillOnEnter) {
CHealthInfo* hInfo = act.HealthInfo(mgr);
if (hInfo) {
static CWeaponMode sktonOHurtWeaponMode(kWT_Power, false, false, true);
CDamageInfo dmg(sktonOHurtWeaponMode, 10.f * hInfo->GetHP(), 0.f, 0.f);
mgr.ApplyDamage(GetUniqueId(), act.GetUniqueId(), GetUniqueId(), dmg,
CMaterialFilter::MakeIncludeExclude(SolidMaterial, CMaterialList(0)),
CVector3f::Zero());
}
}
} else {
InhabitantRejected(act, mgr);
}
}
}
}
CAABox CScriptTrigger::GetTriggerBoundsWR() const {
return CAABox(x130_bounds.GetMinPoint() + x34_transform.GetTranslation(),
x130_bounds.GetMaxPoint() + x34_transform.GetTranslation());
}
rstl::optional_object< CAABox > CScriptTrigger::GetTouchBounds() const override {
if (x30_24_active) {
return GetTriggerBoundsWR();
}
return rstl::optional_object_null();
}
void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
CStateManager& mgr) override {
if (GetActive()) {
if (msg == kSM_Deactivate) {
xe8_inhabitants.clear();
x148_25_camSubmerged = false;
if (x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false;
CPlayer* player = mgr.Player();
if (x148_29_didPhazonDamage) {
player->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
if (x8_uid == mgr.GetLastTriggerId()) {
mgr.SetLastTriggerId(kInvalidUniqueId);
}
}
} else if (msg == kSM_Deleted) {
if (x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false;
CPlayer* player = mgr.Player();
if (x148_29_didPhazonDamage) {
player->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
if (x8_uid == mgr.GetLastTriggerId()) {
mgr.SetLastTriggerId(kInvalidUniqueId);
}
}
}
}
CActor::AcceptScriptMsg(msg, uid, mgr);
}
void CScriptTrigger::Think(float dt, CStateManager& mgr) override {
if (GetActive()) {
UpdateInhabitants(dt, mgr);
}
}
void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) {
bool sendInside = false;
bool sendExited = false;
rstl::list<CObjectTracker>::iterator nextIt;
for (rstl::list<CObjectTracker>::iterator it = xe8_inhabitants.begin(); it != xe8_inhabitants.end(); it = nextIt) {
nextIt = it;
++nextIt;
if (CActor* act = TCastToPtr<CActor>(mgr.ObjectById(it->GetObjectId()))) {
bool playerValid = true;
if (it->GetObjectId() == mgr.GetPlayer()->GetUniqueId()) {
if ((x12c_flags & kTFL_DetectPlayer == 0) &&
((mgr.GetPlayer()->GetMorphballTransitionState() == CPlayer::kMS_Morphed &&
(x12c_flags & kTFL_DetectUnmorphedPlayer)) ||
(mgr.GetPlayer()->GetMorphballTransitionState() == CPlayer::kMS_Unmorphed &&
(x12c_flags & kTFL_DetectMorphedPlayer)))) {
playerValid = false;
}
if (!playerValid) {
xe8_inhabitants.erase(it);
sendExited = true;
if (x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
if (mgr.GetLastTriggerId() == GetUniqueId()) {
mgr.SetLastTriggerId(kInvalidUniqueId);
}
}
InhabitantExited(*act, mgr);
continue;
}
}
rstl::optional_object< CAABox > touchBounds = GetTouchBounds();
rstl::optional_object< CAABox > actTouchBounds = act->GetTouchBounds();
if (touchBounds.valid() && actTouchBounds.valid() && touchBounds->DoBoundsOverlap(*actTouchBounds)) {
sendInside = true;
InhabitantIdle(*act, mgr);
if (act->HealthInfo(mgr) && x100_damageInfo.GetDamage() > 0.f) {
// mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), GetUniqueId(), {x100_damageInfo, dt},
// CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), zeus::skZero3f);
}
if (x128_forceMagnitude > 0.f) {
if (CPhysicsActor* pact = TCastToPtr<CPhysicsActor>(act)) {
float forceMult = 1.f;
if ((x12c_flags & kTFL_UseBooleanIntersection)) {
forceMult = touchBounds->GetBooleanIntersection(*actTouchBounds).GetVolume() / actTouchBounds->GetVolume();
}
const CVector3f force = forceMult * x11c_forceField;
if ((x12c_flags & kTFL_UseCollisionImpulses)) {
pact->ApplyImpulseWR(force, CAxisAngle());
pact->UseCollisionImpulses();
} else {
pact->ApplyForceWR(force, CAxisAngle());
}
}
}
} else {
const TUniqueId tmpId = it->GetObjectId();
xe8_inhabitants.erase(it);
sendExited = true;
if (mgr.GetPlayer()->GetUniqueId() == tmpId && x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
if (mgr.GetLastTriggerId() == GetUniqueId())
mgr.SetLastTriggerId(kInvalidUniqueId);
}
InhabitantExited(*act, mgr);
}
} else {
const TUniqueId tmpId = it->GetObjectId();
xe8_inhabitants.erase(it);
if (mgr.GetPlayer()->GetUniqueId() == tmpId && x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
if (mgr.GetLastTriggerId() == GetUniqueId()) {
mgr.SetLastTriggerId(kInvalidUniqueId);
}
}
}
}
if ((x12c_flags & kTFL_DetectCamera) || x148_24_detectCamera) {
CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
const bool camInTrigger = GetTriggerBoundsWR().PointInside(cam->GetTranslation());
if (x148_25_camSubmerged) {
if (!camInTrigger) {
x148_25_camSubmerged = false;
if ((x12c_flags & kTFL_DetectCamera)) {
sendExited = true;
InhabitantExited(*cam, mgr);
}
} else {
if ((x12c_flags & kTFL_DetectCamera)) {
InhabitantIdle(*cam, mgr);
sendInside = true;
}
}
} else {
if (camInTrigger) {
x148_25_camSubmerged = true;
if ((x12c_flags & kTFL_DetectCamera)) {
InhabitantAdded(*cam, mgr);
SendScriptMsgs(kSS_Entered, mgr, kSM_None);
}
}
}
}
if (sendInside) {
SendScriptMsgs(kSS_Inside, mgr, kSM_None);
}
if (sendExited) {
SendScriptMsgs(kSS_Exited, mgr, kSM_None);
if (x148_27_deactivateOnExited) {
mgr.SendScriptMsg(GetUniqueId(), mgr.GetEditorIdForUniqueId(GetUniqueId()), kSM_Deactivate,
kSS_Exited);
}
}
}
const rstl::list< CScriptTrigger::CObjectTracker >& CScriptTrigger::GetInhabitants() const {
return xe8_inhabitants;
}
const CScriptTrigger::CObjectTracker* CScriptTrigger::FindObject(TUniqueId id) {
for (rstl::list< CScriptTrigger::CObjectTracker >::const_iterator it = GetInhabitants().begin();
it != GetInhabitants().end(); ++it) {
if (it->GetObjectId() == id) {
return &*it;
}
}
return nullptr;
}
void CScriptTrigger::Accept(IVisitor& visitor) override { visitor.Visit(*this); }
void CScriptTrigger::InhabitantAdded(CActor&, CStateManager&) {}
void CScriptTrigger::InhabitantIdle(CActor&, CStateManager&) {}
void CScriptTrigger::InhabitantExited(CActor&, CStateManager&) {}
void CScriptTrigger::InhabitantRejected(CActor&, CStateManager&) {}