2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 00:27:42 +00:00

Fix doors and various area streaming bugs

This commit is contained in:
2018-05-01 17:43:31 -07:00
parent 711c3e0d2c
commit 734b25cad3
35 changed files with 189 additions and 284 deletions

View File

@@ -16,7 +16,7 @@ namespace urde
static CMaterialList MakeDoorMaterialList(bool open)
{
CMaterialList ret;
ret.Add(EMaterialTypes::Solid);
//ret.Add(EMaterialTypes::Solid);
ret.Add(EMaterialTypes::Immovable);
ret.Add(EMaterialTypes::Orbit);
if (!open)
@@ -27,20 +27,24 @@ static CMaterialList MakeDoorMaterialList(bool open)
CScriptDoor::CScriptDoor(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParms,
const zeus::CVector3f&, const zeus::CAABox& aabb, bool active,
bool open, bool b2, float f1, bool ballDoor)
const zeus::CVector3f& vec, const zeus::CAABox& aabb, bool active,
bool open, bool b2, float animLen, bool ballDoor)
: CPhysicsActor(uid, active, name, info, xf, std::move(mData), MakeDoorMaterialList(open),
aabb, SMoverData(1.f), actParms, 0.3f, 0.1f)
{
x258_ = f1;
x2a8_29_ballDoor = ballDoor;
x258_animLen = animLen;
x2a8_24_ = false;
x2a8_25_ = open;
x2a8_26_useConservativeCameraDistance = open;
x2a8_26_isOpen = open;
x2a8_27_ = false;
x2a8_28_ = b2;
x2a8_27_ = true;
x2a8_29_ballDoor = ballDoor;
x2a8_30_ = false;
x264_ = GetBoundingBox();
x284_modelBounds = x64_modelData->GetBounds(xf.getRotation());
x29c_ = vec;
xe6_27_thermalVisorFlags = 1;
if (open)
SetDoorAnimation(EDoorAnimType::Open);
@@ -68,17 +72,17 @@ void CScriptDoor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStat
if (!GetActive())
return;
if (x27c_partner1 == kInvalidUniqueId || uid != x27c_partner1)
if (x27c_partner1 != kInvalidUniqueId && x27c_partner1 != uid)
return;
if (x2a8_26_useConservativeCameraDistance)
if (x2a8_26_isOpen)
{
if (x27e_partner2 != kInvalidUniqueId)
{
if (CEntity* ent = mgr.ObjectById(x27e_partner2))
mgr.SendScriptMsg(ent, GetUniqueId(), EScriptObjectMessage::Close);
}
x2a8_26_useConservativeCameraDistance = false;
x2a8_26_isOpen = false;
SetDoorAnimation(EDoorAnimType::Close);
mgr.GetCameraManager()->GetBallCamera()->DoorClosing(GetUniqueId());
}
@@ -95,13 +99,13 @@ void CScriptDoor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStat
{
if (TCastToPtr<CScriptDoor> door = mgr.ObjectById(x27c_partner1))
{
if (x2a8_26_useConservativeCameraDistance)
if (x2a8_26_isOpen)
return;
x2a8_30_ = true;
mgr.SendScriptMsg(door, GetUniqueId(), EScriptObjectMessage::Close);
}
}
else if (x2a8_26_useConservativeCameraDistance)
else if (x2a8_26_isOpen)
{
x2a8_30_ = true;
if (TCastToPtr<CScriptDoor> door = mgr.ObjectById(x27e_partner2))
@@ -109,7 +113,7 @@ void CScriptDoor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStat
mgr.SendScriptMsg(door, GetUniqueId(), EScriptObjectMessage::Close);
x2a8_30_ = true;
}
x2a8_26_useConservativeCameraDistance = false;
x2a8_26_isOpen = false;
SetDoorAnimation(EDoorAnimType::Close);
mgr.GetCameraManager()->GetBallCamera()->DoorClosing(GetUniqueId());
}
@@ -117,7 +121,7 @@ void CScriptDoor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStat
}
case EScriptObjectMessage::Open:
{
if (!GetActive() || x2a8_26_useConservativeCameraDistance)
if (!GetActive() || x2a8_26_isOpen)
return;
u32 doorCond = TCastToConstPtr<CScriptDoor>(mgr.GetObjectById(uid)) ? 2 : GetDoorOpenCondition(mgr);
@@ -172,11 +176,8 @@ void CScriptDoor::Think(float dt, CStateManager& mgr)
if (!GetActive())
return;
if (!x2a8_26_useConservativeCameraDistance)
{
if (x25c_ < 0.5f)
x25c_ += dt;
}
if (!x2a8_26_isOpen && x25c_animTime < 0.5f)
x25c_animTime += dt;
if (x2a8_27_ && GetDoorOpenCondition(mgr) == 2)
{
@@ -191,33 +192,42 @@ void CScriptDoor::Think(float dt, CStateManager& mgr)
x2a8_28_ = false;
x2a8_24_ = false;
SendScriptMsgs(EScriptObjectState::Closed, mgr, EScriptObjectMessage::Decrement);
x25c_animTime = 0.f;
x2a8_30_ = false;
x25c_ = 0.f;
}
if (x2a8_26_useConservativeCameraDistance && x64_modelData->IsAnimating())
if (x2a8_26_isOpen && !x64_modelData->IsAnimating())
RemoveMaterial(EMaterialTypes::Solid, EMaterialTypes::Occluder, EMaterialTypes::Orbit, EMaterialTypes::Scannable, mgr);
else if (x2a8_25_ && x64_modelData->IsAnimating())
{
x2a8_25_ = false;
mgr.GetCameraManager()->GetBallCamera()->DoorClosed(GetUniqueId());
x2a8_28_ = false;
x2a8_27_ = false;
SendScriptMsgs(EScriptObjectState::Closed, mgr, EScriptObjectMessage::None);
}
if (GetScannableObjectInfo())
AddMaterial(EMaterialTypes::Solid, EMaterialTypes::Metal, EMaterialTypes::Occluder, EMaterialTypes::Orbit, EMaterialTypes::Scannable, mgr);
else
AddMaterial(EMaterialTypes::Solid, EMaterialTypes::Metal, EMaterialTypes::Occluder, EMaterialTypes::Orbit, mgr);
{
if (x2a8_25_ && !x64_modelData->IsAnimating())
{
x2a8_25_ = false;
mgr.GetCameraManager()->GetBallCamera()->DoorClosed(GetUniqueId());
x2a8_28_ = false;
x2a8_27_ = false;
SendScriptMsgs(EScriptObjectState::Closed, mgr, EScriptObjectMessage::None);
}
if (GetScannableObjectInfo())
AddMaterial(/*EMaterialTypes::Solid, */EMaterialTypes::Metal, EMaterialTypes::Occluder, EMaterialTypes::Orbit, EMaterialTypes::Scannable, mgr);
else
AddMaterial(/*EMaterialTypes::Solid, */EMaterialTypes::Metal, EMaterialTypes::Occluder, EMaterialTypes::Orbit, mgr);
}
if (x64_modelData->IsAnimating())
UpdateAnimation((x64_modelData->GetAnimationDuration(s32(x260_doorState)) / x258_) * dt, mgr, true);
{
float f1 = x64_modelData->GetAnimationDuration(s32(x260_doorState));
float f0 = x258_animLen;
f0 = f1 / f0;
f1 = f0 * dt;
UpdateAnimation(f1, mgr, true);
}
xe7_31_targetable = mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::Scan;
}
void CScriptDoor::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager &mgr)
void CScriptDoor::AddToRenderer(const zeus::CFrustum& /*frustum*/, const CStateManager &mgr) const
{
if (!xe4_30_outOfFrustum)
CPhysicsActor::Render(mgr);
@@ -226,9 +236,9 @@ void CScriptDoor::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager
/* ORIGINAL 0-00 OFFSET: 8007E0BC */
void CScriptDoor::ForceClosed(CStateManager & mgr)
{
if (x2a8_26_useConservativeCameraDistance)
if (x2a8_26_isOpen)
{
x2a8_26_useConservativeCameraDistance = false;
x2a8_26_isOpen = false;
x2a8_25_ = false;
mgr.GetCameraManager()->GetBallCamera()->DoorClosing(x8_uid);
@@ -237,7 +247,7 @@ void CScriptDoor::ForceClosed(CStateManager & mgr)
SetDoorAnimation(EDoorAnimType::Close);
SendScriptMsgs(EScriptObjectState::Closed, mgr, EScriptObjectMessage::None);
x25c_ = 0.f;
x25c_animTime = 0.f;
x2a8_27_ = false;
x2a8_30_ = false;
}
@@ -252,14 +262,16 @@ void CScriptDoor::ForceClosed(CStateManager & mgr)
/* ORIGINAL 0-00 OFFSET: 8007E1C4 */
bool CScriptDoor::IsConnectedToArea(const CStateManager& mgr, TAreaId areaId)
{
const CScriptDock* dock = TCastToConstPtr<CScriptDock>(mgr.GetObjectById(x282_dockId));
if (dock)
const CScriptDock* dockEnt = TCastToConstPtr<CScriptDock>(mgr.GetObjectById(x282_dockId));
if (dockEnt)
{
if (dock->GetDestinationAreaId() == areaId)
if (dockEnt->GetAreaId() == areaId)
return true;
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(areaId);
if (area->GetDock(dock->GetDockId())->GetConnectedAreaId(dock->GetDockReference(mgr)) == areaId)
const CWorld* world = mgr.GetWorld();
const CGameArea* area = world->GetAreaAlways(dockEnt->GetAreaId());
const CGameArea::Dock* dock = area->GetDock(dockEnt->GetDockId());
if (dock->GetConnectedAreaId(dockEnt->GetDockReference(mgr)) == areaId)
return true;
}
return false;
@@ -270,13 +282,11 @@ void CScriptDoor::OpenDoor(TUniqueId uid, CStateManager& mgr)
{
TEditorId eid = mgr.GetEditorIdForUniqueId(uid);
mgr.MapWorldInfo()->SetDoorVisited(eid, true);
x2a8_26_useConservativeCameraDistance = true;
x2a8_26_isOpen = true;
x2a8_25_ = true;
x2a8_27_ = false;
const CScriptDoor* door = TCastToConstPtr<CScriptDoor>(mgr.GetObjectById(uid));
if (door)
if (const CScriptDoor* door = TCastToConstPtr<CScriptDoor>(mgr.GetObjectById(uid)))
x27c_partner1 = door->GetUniqueId();
SetDoorAnimation(EDoorAnimType::Open);
@@ -295,7 +305,7 @@ void CScriptDoor::OpenDoor(TUniqueId uid, CStateManager& mgr)
if(TCastToConstPtr<CScriptDock> dock2 = mgr.GetObjectById(door->x282_dockId))
{
if (dock1->GetCurrentConnectedAreaId(mgr) == dock2->GetDestinationAreaId() && dock2->GetCurrentConnectedAreaId(mgr) == dock1->GetDestinationAreaId())
if (dock1->GetCurrentConnectedAreaId(mgr) == dock2->GetAreaId() && dock2->GetCurrentConnectedAreaId(mgr) == dock1->GetAreaId())
{
x27e_partner2 = door->GetUniqueId();
mgr.SendScriptMsg(ent, GetUniqueId(), EScriptObjectMessage::Open);
@@ -323,18 +333,18 @@ u32 CScriptDoor::GetDoorOpenCondition(CStateManager& mgr)
if (!dock)
return 2;
if (x25c_ < 0.05f || x2a8_30_)
if (x25c_animTime < 0.05f || x2a8_30_)
return 1;
TAreaId destArea = dock->GetDestinationAreaId();
if (destArea < 0 || destArea > mgr.GetWorld()->GetNumAreas())
TAreaId destArea = dock->GetAreaId();
if (destArea < 0 || destArea >= mgr.GetWorld()->GetNumAreas())
return 0;
if (!mgr.GetWorld()->AreSkyNeedsMet())
return 1;
TAreaId connArea = mgr.GetWorld()->GetAreaAlways(
dock->GetDestinationAreaId())->GetDock(
dock->GetAreaId())->GetDock(
dock->GetDockId())->GetConnectedAreaId(dock->GetDockReference(mgr));
if (connArea == kInvalidAreaId)
@@ -370,7 +380,7 @@ u32 CScriptDoor::GetDoorOpenCondition(CStateManager& mgr)
if (aliveArea->GetAreaId() == area->GetAreaId())
continue;
if (aliveArea->IsFinishedOccluding())
if (!aliveArea->IsFinishedOccluding())
return 1;
}