mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-08 22:27:42 +00:00
Initial CScriptDoor matches
This commit is contained in:
@@ -1891,7 +1891,7 @@ ForceClosed__11CScriptDoorFR13CStateManager = .text:0x8007E0BC; // type:function
|
||||
IsConnectedToArea__11CScriptDoorCFRC13CStateManager7TAreaId = .text:0x8007E1C4; // type:function size:0xD8 scope:global
|
||||
Think__11CScriptDoorFfR13CStateManager = .text:0x8007E29C; // type:function size:0x2B4 scope:global
|
||||
AcceptScriptMsg__11CScriptDoorF20EScriptObjectMessage9TUniqueIdR13CStateManager = .text:0x8007E550; // type:function size:0x480 scope:global
|
||||
SetDoorAnimation__11CScriptDoorFQ211CScriptDoor13EDoorAnimType = .text:0x8007E9D0; // type:function size:0x94 scope:global
|
||||
SetDoorAnimation__11CScriptDoorFQ211CScriptDoor10EDoorState = .text:0x8007E9D0; // type:function size:0x94 scope:global
|
||||
OpenDoor__11CScriptDoorF9TUniqueIdR13CStateManager = .text:0x8007EA64; // type:function size:0x2E8 scope:global
|
||||
GetDoorOpenCondition__11CScriptDoorFR13CStateManager = .text:0x8007ED4C; // type:function size:0x308 scope:global
|
||||
GetOrbitPosition__11CScriptDoorCFRC13CStateManager = .text:0x8007F054; // type:function size:0x34 scope:global
|
||||
@@ -21626,8 +21626,8 @@ lbl_805A8E2C = .sbss:0x805A8E2C; // type:object size:0x4 data:4byte
|
||||
lbl_805A8E30 = .sbss:0x805A8E30; // type:object size:0x8 data:byte
|
||||
lbl_805A8E38 = .sbss:0x805A8E38; // type:object size:0x4 data:4byte
|
||||
lbl_805A8E3C = .sbss:0x805A8E3C; // type:object size:0x4 data:4byte
|
||||
lbl_805A8E40 = .sbss:0x805A8E40; // type:object size:0x4 data:4byte
|
||||
lbl_805A8E44 = .sbss:0x805A8E44; // type:object size:0x1 data:byte
|
||||
i$486 = .sbss:0x805A8E40; // type:object size:0x4 data:4byte
|
||||
init$487 = .sbss:0x805A8E44; // type:object size:0x1 data:byte
|
||||
kLineOfSightIncludeList = .sbss:0x805A8E48; // type:object size:0x4 scope:local data:4byte
|
||||
lbl_805A8E4C = .sbss:0x805A8E4C; // type:object size:0x4 data:4byte
|
||||
kLineOfSightExcludeList = .sbss:0x805A8E50; // type:object size:0x4 scope:local data:4byte
|
||||
|
||||
@@ -1891,7 +1891,7 @@ ForceClosed__11CScriptDoorFR13CStateManager = .text:0x8007E138; // type:function
|
||||
IsConnectedToArea__11CScriptDoorCFRC13CStateManager7TAreaId = .text:0x8007E240; // type:function size:0xD8 scope:global
|
||||
Think__11CScriptDoorFfR13CStateManager = .text:0x8007E318; // type:function size:0x2B4 scope:global
|
||||
AcceptScriptMsg__11CScriptDoorF20EScriptObjectMessage9TUniqueIdR13CStateManager = .text:0x8007E5CC; // type:function size:0x480 scope:global
|
||||
SetDoorAnimation__11CScriptDoorFQ211CScriptDoor13EDoorAnimType = .text:0x8007EA4C; // type:function size:0x94 scope:global
|
||||
SetDoorAnimation__11CScriptDoorFQ211CScriptDoor10EDoorState = .text:0x8007EA4C; // type:function size:0x94 scope:global
|
||||
OpenDoor__11CScriptDoorF9TUniqueIdR13CStateManager = .text:0x8007EAE0; // type:function size:0x2E8 scope:global
|
||||
GetDoorOpenCondition__11CScriptDoorFR13CStateManager = .text:0x8007EDC8; // type:function size:0x308 scope:global
|
||||
GetOrbitPosition__11CScriptDoorCFRC13CStateManager = .text:0x8007F0D0; // type:function size:0x34 scope:global
|
||||
|
||||
@@ -7,6 +7,7 @@ class CMapWorldInfo {
|
||||
public:
|
||||
bool IsAreaVisible(const TAreaId areaId) const;
|
||||
bool IsDoorVisited(const TEditorId eid) const;
|
||||
void SetDoorVisited(TEditorId eid, const bool visited);
|
||||
};
|
||||
|
||||
#endif // _CMAPWORLDINFO
|
||||
|
||||
@@ -291,6 +291,7 @@ public:
|
||||
bool GetInMapScreen() const { return xf94_27_inMapScreen; }
|
||||
void SetIsFullThreat(bool v) { xf94_30_fullThreat = v; }
|
||||
uint GetInputFrameIdx() const { return x8d4_inputFrameIdx; }
|
||||
CMapWorldInfo* MapWorldInfo() const { return x8c0_mapWorldInfo.GetPtr(); }
|
||||
|
||||
private:
|
||||
enum EInitPhase { kIP_LoadWorld, kIP_LoadFirstArea, kIP_Done };
|
||||
|
||||
@@ -143,6 +143,9 @@ public:
|
||||
static CGameArea::CConstChainIterator GetAliveAreasEnd();
|
||||
void StopGlobalSound(ushort soundId);
|
||||
|
||||
int GetNumAreas() const { return x18_areas.size(); }
|
||||
bool AreSkyNeedsMet() const;
|
||||
|
||||
private:
|
||||
enum Phase {
|
||||
kP_Loading,
|
||||
|
||||
@@ -168,6 +168,8 @@ public:
|
||||
void SetClampVelTimer(float v) { x470_clampVelTimer = v; }
|
||||
void SetClampVelRange(float v) { x474_clampVelRange = v; }
|
||||
|
||||
void DoorClosing(TUniqueId uid);
|
||||
|
||||
private:
|
||||
struct SFailsafeState {
|
||||
CTransform4f x0_playerXf;
|
||||
|
||||
63
include/MetroidPrime/ScriptObjects/CScriptDoor.hpp
Normal file
63
include/MetroidPrime/ScriptObjects/CScriptDoor.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#ifndef _CSCRIPTDOOR
|
||||
#define _CSCRIPTDOOR
|
||||
|
||||
#include "MetroidPrime/CPhysicsActor.hpp"
|
||||
|
||||
class CScriptDoor : public CPhysicsActor {
|
||||
public:
|
||||
enum EDoorState {
|
||||
kDS_Open,
|
||||
kDS_Close,
|
||||
kDS_Ready,
|
||||
};
|
||||
|
||||
enum EDoorOpenCondition {
|
||||
kDOC_NotReady,
|
||||
kDOC_Loading,
|
||||
kDOC_Ready,
|
||||
};
|
||||
|
||||
CScriptDoor(TUniqueId uid, const rstl::string& name, const CEntityInfo& info,
|
||||
const CTransform4f& xf, const CModelData& modelData,
|
||||
const CActorParameters& actorParameters, const CVector3f& orbitPosition,
|
||||
const CAABox& bounds, bool active, bool open, bool projectilesCollide,
|
||||
float animationLength, bool ballDoor);
|
||||
|
||||
void SetDoorAnimation(EDoorState state);
|
||||
|
||||
rstl::optional_object< CAABox > GetTouchBounds() const override;
|
||||
|
||||
rstl::optional_object< CAABox > GetProjectileBounds() const;
|
||||
CVector3f GetOrbitPosition(const CStateManager& mgr) const override;
|
||||
|
||||
EDoorOpenCondition GetDoorOpenCondition(CStateManager& mgr);
|
||||
void OpenDoor(TUniqueId uid, CStateManager& mgr);
|
||||
|
||||
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CStateManager& mgr) override;
|
||||
|
||||
const TUniqueId GetDockID() const { return mDockId; }
|
||||
bool IsOpen() const { return mIsOpen; }
|
||||
void SetDoClose(const bool close) { mDoClose = close; }
|
||||
|
||||
private:
|
||||
float mAnimLength;
|
||||
float mAnimTime;
|
||||
EDoorState mDoorState;
|
||||
CAABox x264_;
|
||||
TUniqueId mPartner1;
|
||||
TUniqueId mPartner2;
|
||||
TUniqueId mPrevDoor;
|
||||
TUniqueId mDockId;
|
||||
CAABox mModelBounds;
|
||||
CVector3f mOrbitPos;
|
||||
|
||||
bool mClosing : 1;
|
||||
bool mWasOpen : 1;
|
||||
bool mIsOpen : 1;
|
||||
bool mConditionsMet : 1;
|
||||
bool mProjectilesCollide : 1;
|
||||
bool mBallDoor : 1;
|
||||
bool mDoClose : 1;
|
||||
};
|
||||
|
||||
#endif // _CSCRIPTDOOR
|
||||
248
src/MetroidPrime/ScriptObjects/CScriptDoor.cpp
Normal file
248
src/MetroidPrime/ScriptObjects/CScriptDoor.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
#include "MetroidPrime/ScriptObjects/CScriptDoor.hpp"
|
||||
|
||||
#include "MetroidPrime/CAnimData.hpp"
|
||||
#include "MetroidPrime/CAnimPlaybackParms.hpp"
|
||||
#include "MetroidPrime/CEntity.hpp"
|
||||
#include "MetroidPrime/CEntityInfo.hpp"
|
||||
#include "MetroidPrime/CGameArea.hpp"
|
||||
#include "MetroidPrime/CMapWorldInfo.hpp"
|
||||
#include "MetroidPrime/CObjectList.hpp"
|
||||
#include "MetroidPrime/CPhysicsActor.hpp"
|
||||
#include "MetroidPrime/CWorld.hpp"
|
||||
#include "MetroidPrime/Cameras/CBallCamera.hpp"
|
||||
#include "MetroidPrime/Cameras/CCameraManager.hpp"
|
||||
#include "MetroidPrime/ScriptObjects/CScriptDock.hpp"
|
||||
#include "MetroidPrime/TCastTo.hpp"
|
||||
#include "MetroidPrime/TGameTypes.hpp"
|
||||
|
||||
CScriptDoor::CScriptDoor(TUniqueId uid, const rstl::string& name, const CEntityInfo& info,
|
||||
const CTransform4f& xf, const CModelData& modelData,
|
||||
const CActorParameters& actorParameters, const CVector3f& orbitPosition,
|
||||
const CAABox& bounds, const bool active, const bool open,
|
||||
const bool projectilesCollide, const float animationLength,
|
||||
const bool ballDoor)
|
||||
: CPhysicsActor(uid, active, name, info, xf, modelData,
|
||||
open ? CMaterialList(kMT_Solid, kMT_Immovable, kMT_Orbit)
|
||||
: CMaterialList(kMT_Solid, kMT_Immovable, kMT_Orbit, kMT_Occluder),
|
||||
bounds, SMoverData(1.f), actorParameters, 0.3f, 0.1f)
|
||||
, mAnimLength(animationLength)
|
||||
, mAnimTime(0.f)
|
||||
, mDoorState(kDS_Open)
|
||||
, x264_(GetBoundingBox())
|
||||
, mPartner1(kInvalidUniqueId)
|
||||
, mPartner2(kInvalidUniqueId)
|
||||
, mPrevDoor(kInvalidUniqueId)
|
||||
, mDockId(kInvalidUniqueId)
|
||||
, mModelBounds(modelData.GetBounds(xf.GetRotation()))
|
||||
, mOrbitPos(orbitPosition)
|
||||
, mClosing(false)
|
||||
, mWasOpen(open)
|
||||
, mIsOpen(open)
|
||||
, mConditionsMet(false)
|
||||
, mProjectilesCollide(projectilesCollide)
|
||||
, mBallDoor(ballDoor)
|
||||
, mDoClose(false) {
|
||||
SetThermalFlags(kTF_Cold);
|
||||
|
||||
if (open) {
|
||||
SetDoorAnimation(kDS_Open);
|
||||
}
|
||||
|
||||
SetMass(0.f);
|
||||
}
|
||||
|
||||
rstl::optional_object< CAABox > CScriptDoor::GetTouchBounds() const {
|
||||
if (GetActive() && GetMaterialList().HasMaterial(kMT_Solid)) {
|
||||
return CPhysicsActor::GetBoundingBox();
|
||||
}
|
||||
|
||||
return rstl::optional_object_null();
|
||||
}
|
||||
|
||||
rstl::optional_object< CAABox > CScriptDoor::GetProjectileBounds() const {
|
||||
if (mProjectilesCollide) {
|
||||
return CAABox(mModelBounds.GetMinPoint() + GetTranslation(),
|
||||
mModelBounds.GetMaxPoint() + GetTranslation());
|
||||
}
|
||||
|
||||
return rstl::optional_object_null();
|
||||
}
|
||||
|
||||
CVector3f CScriptDoor::GetOrbitPosition(const CStateManager& mgr) const {
|
||||
return GetTranslation() + mOrbitPos;
|
||||
}
|
||||
|
||||
CScriptDoor::EDoorOpenCondition CScriptDoor::GetDoorOpenCondition(CStateManager& mgr) {
|
||||
return kDOC_Loading;
|
||||
}
|
||||
|
||||
void CScriptDoor::OpenDoor(TUniqueId uid, CStateManager& mgr) {
|
||||
mgr.MapWorldInfo()->SetDoorVisited(mgr.GetEditorIdForUniqueId(uid), true);
|
||||
mIsOpen = true;
|
||||
mWasOpen = true;
|
||||
mConditionsMet = false;
|
||||
mPartner1 = kInvalidUniqueId;
|
||||
mPartner2 = kInvalidUniqueId;
|
||||
|
||||
if (const CScriptDoor* door = TCastToConstPtr< CScriptDoor >(mgr.GetObjectById(uid))) {
|
||||
mPartner1 = door->GetUniqueId();
|
||||
}
|
||||
|
||||
SetDoorAnimation(kDS_Open);
|
||||
|
||||
if (mPartner1 != kInvalidUniqueId) {
|
||||
SendScriptMsgs(kSS_MaxReached, mgr, kSM_None);
|
||||
} else {
|
||||
SendScriptMsgs(kSS_Open, mgr, kSM_None);
|
||||
}
|
||||
|
||||
if (const CScriptDock* dock1 = TCastToConstPtr< CScriptDock >(mgr.GetObjectById(mDockId))) {
|
||||
CObjectList& list = mgr.ObjectListById(kOL_PlatformAndDoor);
|
||||
for (int idx = list.GetFirstObjectIndex(); idx != -1; idx = list.GetNextObjectIndex(idx)) {
|
||||
if (CScriptDoor* door = TCastToPtr< CScriptDoor >(list[idx])) {
|
||||
if (door->GetUniqueId() == uid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (const CScriptDock* dock2 =
|
||||
TCastToConstPtr< CScriptDock >(mgr.GetObjectById(door->GetDockID()))) {
|
||||
if (dock2->GetAreaId() == dock1->GetCurrentConnectedAreaId(mgr) &&
|
||||
dock2->GetCurrentConnectedAreaId(mgr) == dock1->GetAreaId()) {
|
||||
mPartner2 = door->GetUniqueId();
|
||||
mgr.DeliverScriptMsg(door, GetUniqueId(), kSM_Open);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mPartner1 == kInvalidUniqueId && mPartner2 == kInvalidUniqueId) {
|
||||
|
||||
rstl::vector< SConnection >::const_iterator it = GetConnectionList().begin();
|
||||
for (; it != GetConnectionList().end(); ++it) {
|
||||
if (it->x4_msg != kSM_Open) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (const CScriptDoor* door =
|
||||
TCastToConstPtr< CScriptDoor >(mgr.GetObjectById(mgr.GetIdForScript(it->x8_objId)))) {
|
||||
mPartner2 = door->GetUniqueId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptDoor::SetDoorAnimation(EDoorState state) {
|
||||
mDoorState = state;
|
||||
if (HasAnimation()) {
|
||||
AnimationData()->SetAnimation(CAnimPlaybackParms(static_cast< int >(state), -1, 1.f, true),
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptDoor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||
switch (msg) {
|
||||
case kSM_Close: {
|
||||
if (!GetActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mPartner1 == kInvalidUniqueId || mPartner1 == uid) {
|
||||
if (mIsOpen) {
|
||||
if (mPartner2 != kInvalidUniqueId) {
|
||||
// lol, this is its actual name
|
||||
static int i = 0;
|
||||
if (CEntity* ent = mgr.ObjectById(mPartner2)) {
|
||||
++i;
|
||||
mgr.DeliverScriptMsg(ent, GetUniqueId(), kSM_Close);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
mIsOpen = false;
|
||||
SetDoorAnimation(kDS_Close);
|
||||
mgr.GetCameraManager()->BallCamera()->DoorClosing(GetUniqueId());
|
||||
} else if (mConditionsMet) {
|
||||
mConditionsMet = false;
|
||||
SendScriptMsgs(kSS_Closed, mgr, kSM_None);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kSM_Action: {
|
||||
if (mPartner1 != kInvalidUniqueId) {
|
||||
if (CScriptDoor* door = TCastToPtr< CScriptDoor >(mgr.ObjectById(mPartner1))) {
|
||||
if (door->IsOpen()) {
|
||||
mDoClose = true;
|
||||
mgr.DeliverScriptMsg(door, GetUniqueId(), kSM_Close);
|
||||
door->SetDoClose(true);
|
||||
}
|
||||
}
|
||||
} else if (mIsOpen) {
|
||||
mDoClose = true;
|
||||
if (CScriptDoor* door = TCastToPtr< CScriptDoor >(mgr.ObjectById(mPartner2))) {
|
||||
mgr.DeliverScriptMsg(door, GetUniqueId(), kSM_Close);
|
||||
door->SetDoClose(true);
|
||||
}
|
||||
mIsOpen = false;
|
||||
SetDoorAnimation(kDS_Close);
|
||||
mgr.GetCameraManager()->BallCamera()->DoorClosing(GetUniqueId());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kSM_Open: {
|
||||
if (!GetActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mIsOpen) {
|
||||
|
||||
const EDoorOpenCondition cond = TCastToConstPtr< CScriptDoor >(mgr.GetObjectById(uid))
|
||||
? kDOC_Ready
|
||||
: GetDoorOpenCondition(mgr);
|
||||
|
||||
switch (cond) {
|
||||
case kDOC_Loading:
|
||||
mConditionsMet = true;
|
||||
mPrevDoor = uid;
|
||||
break;
|
||||
case kDOC_Ready:
|
||||
OpenDoor(uid, mgr);
|
||||
break;
|
||||
case kDOC_NotReady:
|
||||
default:
|
||||
mWasOpen = false;
|
||||
mClosing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kSM_InitializedInArea: {
|
||||
rstl::vector< SConnection >::const_iterator it = GetConnectionList().begin();
|
||||
for (; it != GetConnectionList().end(); ++it) {
|
||||
if (it->x4_msg != kSM_Increment) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (const CScriptDock* dock =
|
||||
TCastToConstPtr< CScriptDock >(mgr.GetObjectById(mgr.GetIdForScript(it->x8_objId)))) {
|
||||
mDockId = dock->GetUniqueId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kSM_SetToZero:
|
||||
mProjectilesCollide = true;
|
||||
mgr.MapWorldInfo()->SetDoorVisited(mgr.GetEditorIdForUniqueId(GetUniqueId()), true);
|
||||
break;
|
||||
case kSM_SetToMax:
|
||||
mProjectilesCollide = false;
|
||||
break;
|
||||
default:
|
||||
CPhysicsActor::AcceptScriptMsg(msg, uid, mgr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user