Various area streaming fixes, implement missing object loaders

This commit is contained in:
Phillip Stephens 2018-05-07 19:18:18 -07:00
parent 81d2276458
commit 3bc1fc1160
12 changed files with 384 additions and 23 deletions

View File

@ -507,8 +507,8 @@ float CGraphics::GetSecondsMod900()
void CGraphics::TickRenderTimings() void CGraphics::TickRenderTimings()
{ {
g_RenderTimings++; g_RenderTimings = (g_RenderTimings + 1) % u32(900*60);
g_DefaultSeconds = float(g_RenderTimings) / 60.f; g_DefaultSeconds = g_RenderTimings / 60.f;
} }
boo::IGraphicsDataFactory::Platform CGraphics::g_BooPlatform = boo::IGraphicsDataFactory::Platform::Null; boo::IGraphicsDataFactory::Platform CGraphics::g_BooPlatform = boo::IGraphicsDataFactory::Platform::Null;

View File

@ -416,7 +416,11 @@ const zeus::CTransform& CDummyGameArea::IGetTM() const
CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion) CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
: x4_selfIdx(idx) : x4_selfIdx(idx)
{ {
xf0_24_postConstructed = false;
xf0_25_active = true; xf0_25_active = true;
xf0_26_tokensReady = false;
xf0_27_paused = false;
xf0_28_validated = false;
x8_nameSTRG = in.readUint32Big(); x8_nameSTRG = in.readUint32Big();
xc_transform.read34RowMajor(in); xc_transform.read34RowMajor(in);
x3c_invTransform = xc_transform.inverse(); x3c_invTransform = xc_transform.inverse();
@ -463,6 +467,12 @@ CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
CGameArea::CGameArea(CAssetId mreaId) CGameArea::CGameArea(CAssetId mreaId)
: x84_mrea(mreaId) : x84_mrea(mreaId)
{ {
xf0_24_postConstructed = false;
xf0_25_active = false;
xf0_26_tokensReady = false;
xf0_27_paused = false;
xf0_28_validated = false;
while (StartStreamingMainArea()) while (StartStreamingMainArea())
for (auto& req : xf8_loadTransactions) for (auto& req : xf8_loadTransactions)
req->WaitUntilComplete(); req->WaitUntilComplete();
@ -905,7 +915,7 @@ void CGameArea::AllocNewAreaData(int offset, int size)
bool CGameArea::Invalidate(CStateManager* mgr) bool CGameArea::Invalidate(CStateManager* mgr)
{ {
if (xf0_24_postConstructed) if (!xf0_24_postConstructed)
{ {
ClearTokenList(); ClearTokenList();

View File

@ -117,18 +117,11 @@ class CGameArea : public IGameArea
u32 xec_totalResourcesSize = 0; u32 xec_totalResourcesSize = 0;
union
{
struct
{
bool xf0_24_postConstructed : 1; bool xf0_24_postConstructed : 1;
bool xf0_25_active : 1; bool xf0_25_active : 1;
bool xf0_26_tokensReady : 1; bool xf0_26_tokensReady : 1;
bool xf0_27_paused : 1; bool xf0_27_paused : 1;
bool xf0_28_validated : 1; bool xf0_28_validated : 1;
};
u32 _dummy = 0;
};
enum class EPhase enum class EPhase
{ {
@ -361,7 +354,7 @@ public:
s32 GetDockCount() const { return xcc_docks.size(); } s32 GetDockCount() const { return xcc_docks.size(); }
Dock* DockNC(s32 dock) { return &xcc_docks[dock]; } Dock* DockNC(s32 dock) { return &xcc_docks[dock]; }
bool IsPostConstructed() const { return xf0_24_postConstructed && x12c_postConstructed; } bool IsPostConstructed() const { return xf0_24_postConstructed; }
const CPostConstructed* GetPostConstructed() const const CPostConstructed* GetPostConstructed() const
{ {
if (!x12c_postConstructed) if (!x12c_postConstructed)

View File

@ -37,6 +37,8 @@ set(WORLD_SOURCES
CScriptCounter.hpp CScriptCounter.cpp CScriptCounter.hpp CScriptCounter.cpp
CScriptEffect.hpp CScriptEffect.cpp CScriptEffect.hpp CScriptEffect.cpp
CScriptSteam.hpp CScriptSteam.cpp CScriptSteam.hpp CScriptSteam.cpp
CScriptRipple.hpp CScriptRipple.cpp
CScriptBallTrigger.hpp CScriptBallTrigger.cpp
CScriptPlatform.hpp CScriptPlatform.cpp CScriptPlatform.hpp CScriptPlatform.cpp
CScriptSound.hpp CScriptSound.cpp CScriptSound.hpp CScriptSound.cpp
CScriptGenerator.hpp CScriptGenerator.cpp CScriptGenerator.hpp CScriptGenerator.cpp

View File

@ -0,0 +1,107 @@
#include "CScriptBallTrigger.hpp"
#include "CStateManager.hpp"
#include "CPlayer.hpp"
#include "CMorphBall.hpp"
#include "GameGlobalObjects.hpp"
#include "DNAMP1/Tweaks/CTweakPlayer.hpp"
#include "TCastTo.hpp"
namespace urde
{
static zeus::CAABox calculate_ball_aabox()
{
float extent = 0.33f * g_tweakPlayer->GetPlayerBallHalfExtent();
return {-extent, extent};
}
CScriptBallTrigger::CScriptBallTrigger(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CVector3f& pos, const zeus::CVector3f& scale,
bool active, float f1, float f2, float f3, const zeus::CVector3f& vec, bool b2)
: CScriptTrigger(uid, name, info, pos, calculate_ball_aabox(), CDamageInfo(CWeaponMode::Power(), 0.f, 0.f, 0.f), zeus::CVector3f::skZero, ETriggerFlags::DetectMorphedPlayer, active, false, false)
, x150_force(f1)
, x154_minAngle(f2)
, x158_maxDistance(f3)
, x168_24_canApplyForce(false)
, x168_25_stopPlayer(b2)
{
if (vec.canBeNormalized())
x15c_forceAngle = vec.normalized();
}
void CScriptBallTrigger::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptBallTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager & mgr)
{
if (msg == EScriptObjectMessage::Deactivate && GetActive())
{
mgr.GetPlayer().GetMorphBall()->SetBallBoostState(CMorphBall::EBallBoostState::BoostAvailable);
x168_24_canApplyForce = false;
}
CScriptTrigger::AcceptScriptMsg(msg, uid, mgr);
}
void CScriptBallTrigger::Think(float dt, CStateManager& mgr)
{
if (!GetActive())
return;
CScriptTrigger::Think(dt, mgr);
CPlayer& player = mgr.GetPlayer();
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
{
x168_24_canApplyForce = false;
return;
}
const float ballRadius = player.GetMorphBall()->GetBallRadius();
const zeus::CVector3f radiusPosDif = (player.GetTranslation() - (player.GetTranslation() + zeus::CVector3f{0.f, 0.f, ballRadius}));
const float distance = radiusPosDif.magnitude();
if (!x168_24_canApplyForce)
{
if (distance < ballRadius)
x168_24_canApplyForce = true;
else
{
zeus::CVector3f offset = radiusPosDif.normalized();
if (std::cos(zeus::degToRad(x154_minAngle)) < (-offset).dot(x15c_forceAngle) && distance < x158_maxDistance)
{
float force = zeus::min((1.f / dt * distance), x150_force * (distance * distance));
player.ApplyForceWR(force * (player.GetMass() * offset), zeus::CAxisAngle::sIdentity);
}
}
}
if (x148_28_playerTriggerProc)
{
zeus::CVector3f offset = GetTranslation() - zeus::CVector3f(0.f, 0.f, ballRadius);
if (x168_25_stopPlayer)
player.Stop();
player.MoveToWR(offset, dt);
}
else
x168_24_canApplyForce = false;
}
void CScriptBallTrigger::InhabitantAdded(CActor& act, CStateManager& /*mgr*/)
{
if (TCastToPtr<CPlayer> player = act)
player->GetMorphBall()->SetBallBoostState(CMorphBall::EBallBoostState::BoostDisabled);
}
void CScriptBallTrigger::InhabitantExited(CActor& act, CStateManager &)
{
if (TCastToPtr<CPlayer> player = act)
{
player->GetMorphBall()->SetBallBoostState(CMorphBall::EBallBoostState::BoostAvailable);
x168_24_canApplyForce = false;
}
}
}

View File

@ -0,0 +1,27 @@
#ifndef __URDE_CSCRIPTBALLTRIGGER_HPP__
#define __URDE_CSCRIPTBALLTRIGGER_HPP__
#include "CScriptTrigger.hpp"
namespace urde
{
class CScriptBallTrigger : public CScriptTrigger
{
float x150_force;
float x154_minAngle;
float x158_maxDistance;
zeus::CVector3f x15c_forceAngle = zeus::CVector3f::skZero;
bool x168_24_canApplyForce : 1;
bool x168_25_stopPlayer : 1;
public:
CScriptBallTrigger(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CVector3f&,
const zeus::CVector3f&, bool, float, float, float, const zeus::CVector3f&, bool);
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager& mgr);
void InhabitantAdded(CActor&, CStateManager&);
void InhabitantExited(CActor&, CStateManager&);
};
}
#endif // __URDE_CSCRIPTBALLTRIGGER_HPP

View File

@ -1,4 +1,5 @@
#include "CScriptGunTurret.hpp" #include "CScriptGunTurret.hpp"
#include "TCastTo.hpp"
namespace urde namespace urde
{ {
@ -7,6 +8,47 @@ static const CMaterialList skGunMaterialList = { EMaterialTypes::Solid, EMateria
EMaterialTypes::Orbit, EMaterialTypes::Target }; EMaterialTypes::Orbit, EMaterialTypes::Target };
static const CMaterialList skTurretMaterialList = { EMaterialTypes::Character }; static const CMaterialList skTurretMaterialList = { EMaterialTypes::Character };
CScriptGunTurretData::CScriptGunTurretData(CInputStream& in, s32 propCount)
: x0_(in.readFloatBig()),
x4_(in.readFloatBig()),
x8_(in.readFloatBig()),
xc_(in.readFloatBig()),
x10_(in.readFloatBig()),
x14_(in.readFloatBig()),
x1c_(zeus::degToRad(in.readFloatBig())),
x20_(zeus::degToRad(in.readFloatBig())),
x24_(zeus::degToRad(in.readFloatBig())),
x28_(zeus::degToRad(in.readFloatBig())),
x2c_(in.readFloatBig()),
x30_(in.readFloatBig()),
x34_(in.readFloatBig()),
x38_(in.readFloatBig()),
x3c_(propCount >= 48 ? in.readBool() : false),
x40_(in.readUint32Big()),
x44_(in),
x60_(in.readUint32Big()),
x64_(in.readUint32Big()),
x68_(in.readUint32Big()),
x6c_(in.readUint32Big()),
x70_(in.readUint32Big()),
x74_(in.readUint32Big()),
x78_(propCount >= 44 ? in.readUint32Big() : -1),
x7c_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)),
x7e_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)),
x80_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)),
x82_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)),
x84_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF)),
x86_(propCount >= 45 ? CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF) : -1),
x88_(in.readUint32Big()),
x8c_(in.readUint32Big()),
x90_(in.readUint32Big()),
x94_(in.readUint32Big()),
x98_(in.readUint32Big()),
x9c_(propCount >= 47 ? in.readFloatBig() : 3.f),
xa0_(propCount >= 46 ? in.readBool() : false)
{
}
CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurretComponent comp, const CEntityInfo& info, CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurretComponent comp, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb,
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
@ -18,4 +60,9 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret
} }
void CScriptGunTurret::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
} }

View File

@ -2,13 +2,64 @@
#define __URDE_CSCRIPTGUNTURRET_HPP__ #define __URDE_CSCRIPTGUNTURRET_HPP__
#include "CPhysicsActor.hpp" #include "CPhysicsActor.hpp"
#include "CDamageInfo.hpp"
namespace urde namespace urde
{ {
class CScriptGunTurretData class CScriptGunTurretData
{ {
float x0_;
float x4_;
float x8_;
float xc_;
float x10_;
float x14_;
float x18_ = 30.f;
float x1c_;
float x20_;
float x24_;
float x28_;
float x2c_;
float x30_;
float x34_;
float x38_;
bool x3c_;
u32 x40_;
CDamageInfo x44_;
u32 x60_;
u32 x64_;
u32 x68_;
u32 x6c_;
u32 x70_;
u32 x74_;
u32 x78_;
u16 x7c_;
u16 x7e_;
u16 x80_;
u16 x82_;
u16 x84_;
u16 x86_;
u32 x88_;
float x8c_;
u32 x90_;
u32 x94_;
u32 x98_;
float x9c_;
bool xa0_;
static constexpr s32 skMinProperties = 43;
public:
CScriptGunTurretData(CInputStream&, s32);
const CAssetId& GetPanningEffectRes() const;
const CAssetId& GetChargingEffectRes() const;
const CAssetId& GetFrozenEffectRes() const;
const CAssetId& GetTargettingLightRes() const;
const CAssetId& GetDeactivateLightRes() const;
const CAssetId& GetIdleLightRes() const;
const CDamageInfo& GetProjectileDamage() const;
const CAssetId& GetProjectileRes() const;
u16 GetUnFreezeSoundId() const;
void GetIntoDeactivateDelay() const;
static s32 GetMinProperties() { return skMinProperties; }
}; };
class CScriptGunTurret : public CPhysicsActor class CScriptGunTurret : public CPhysicsActor
@ -25,6 +76,9 @@ public:
const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb, const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb,
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
const CActorParameters& aParms, const CScriptGunTurretData& turretData); const CActorParameters& aParms, const CScriptGunTurretData& turretData);
void Accept(IVisitor&);
}; };
} }

View File

@ -0,0 +1,46 @@
#include "CScriptRipple.hpp"
#include "CStateManager.hpp"
#include "CScriptWater.hpp"
#include "TCastTo.hpp"
namespace urde
{
CScriptRipple::CScriptRipple(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CVector3f& vec, bool active, float f1)
: CEntity(uid, info, active, name)
, x34_magnitude(f1 >= 0.f ? f1 : 0.5f)
, x38_center(vec)
{
}
void CScriptRipple::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptRipple::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::Play)
{
if (!GetActive())
return;
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Active || conn.x4_msg != EScriptObjectMessage::Next)
continue;
auto search = mgr.GetIdListForScript(conn.x8_objId);
for (auto it = search.first; it != search.second; ++it)
{
if (TCastToPtr<CScriptWater> water = mgr.ObjectById(it->second))
water->GetFluidPlane().AddRipple(x34_magnitude, GetUniqueId(), x38_center, *water, mgr);
}
}
return;
}
CEntity::AcceptScriptMsg(msg, uid, mgr);
}
}

View File

@ -0,0 +1,21 @@
#ifndef __URDE_CSCRIPTRIPPLE_HPP__
#define __URDE_CSCRIPTRIPPLE_HPP__
#include "CEntity.hpp"
#include "zeus/CVector3f.hpp"
namespace urde
{
class CScriptRipple : public CEntity
{
float x34_magnitude;
zeus::CVector3f x38_center;
public:
CScriptRipple(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CVector3f&, bool, float);
void Accept(IVisitor&);
void Think(float, CStateManager&) {}
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
};
}
#endif // __URDE_CSCRIPTRIPPLE_HPP__

View File

@ -449,7 +449,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
bool CWorld::ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr) bool CWorld::ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr)
{ {
if (!area->xf0_24_postConstructed) if (!area->IsPostConstructed())
{ {
MoveToChain(area, EChain::Loading); MoveToChain(area, EChain::Loading);
return true; return true;

View File

@ -53,7 +53,11 @@
#include "CScriptSpawnPoint.hpp" #include "CScriptSpawnPoint.hpp"
#include "CScriptSpecialFunction.hpp" #include "CScriptSpecialFunction.hpp"
#include "CScriptSteam.hpp" #include "CScriptSteam.hpp"
#include "CScriptRipple.hpp"
#include "CScriptBallTrigger.hpp"
#include "CScriptTargetingPoint.hpp"
#include "CScriptStreamedMusic.hpp" #include "CScriptStreamedMusic.hpp"
#include "CScriptGunTurret.hpp"
#include "CScriptSwitch.hpp" #include "CScriptSwitch.hpp"
#include "CScriptTimer.hpp" #include "CScriptTimer.hpp"
#include "CScriptVisorFlare.hpp" #include "CScriptVisorFlare.hpp"
@ -1789,17 +1793,43 @@ CEntity* ScriptLoader::LoadSteam(CStateManager& mgr, CInputStream& in, int propC
CEntity* ScriptLoader::LoadRipple(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadRipple(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{ {
if (!EnsurePropertyCount(propCount, 4, "Ripple"))
return nullptr; return nullptr;
std::string_view name = mgr.HashInstanceName(in);
zeus::CVector3f center = zeus::CVector3f::ReadBig(in);
bool active = in.readBool();
float mag = in.readFloatBig();
return new CScriptRipple(mgr.AllocateUniqueId(), name, info, center, active, mag);
} }
CEntity* ScriptLoader::LoadBallTrigger(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadBallTrigger(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{ {
if (!EnsurePropertyCount(propCount, 9, "BallTrigger"))
return nullptr; return nullptr;
std::string_view name = in.readString();
zeus::CVector3f pos = zeus::CVector3f::ReadBig(in);
zeus::CVector3f scale = zeus::CVector3f::ReadBig(in);
bool b1 = in.readBool();
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
zeus::CVector3f vec = zeus::CVector3f::ReadBig(in);
bool b2 = in.readBool();
return new CScriptBallTrigger(mgr.AllocateUniqueId(), name, info, pos, scale, b1, f1, f2, f3, vec, b2);
} }
CEntity* ScriptLoader::LoadTargetingPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadTargetingPoint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{ {
if (!EnsurePropertyCount(propCount, 4, "TargetingPoint"))
return nullptr; return nullptr;
SActorHead aHead = LoadActorHead(in, mgr);
bool active = in.readBool();
return new CScriptTargetingPoint(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform, active);
} }
CEntity* ScriptLoader::LoadEMPulse(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadEMPulse(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
@ -2293,7 +2323,31 @@ CEntity* ScriptLoader::LoadRepulsor(CStateManager& mgr, CInputStream& in, int pr
CEntity* ScriptLoader::LoadGunTurret(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadGunTurret(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{ {
if (!EnsurePropertyCount(propCount, CScriptGunTurretData::GetMinProperties(), "GunTurret"))
return nullptr; return nullptr;
std::string_view name = mgr.HashInstanceName(in);
CScriptGunTurret::ETurretComponent component = CScriptGunTurret::ETurretComponent(in.readUint32Big());
zeus::CTransform xf = LoadEditorTransform(in);
zeus::CVector3f scale = zeus::CVector3f::ReadBig(in);
zeus::CVector3f collisionExtent = zeus::CVector3f::ReadBig(in);
zeus::CVector3f collisionOffset = zeus::CVector3f::ReadBig(in);
CAnimationParameters animParms = LoadAnimationParameters(in);
CActorParameters actParms = LoadActorParameters(in);
CHealthInfo hInfo(in);
CDamageVulnerability dVuln(in);
CScriptGunTurretData turretData(in, propCount);
if (!g_ResFactory->GetResourceTypeById(animParms.GetACSFile()))
return nullptr;
CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
zeus::CAABox aabb = GetCollisionBox(mgr, info.GetAreaId(), collisionExtent, collisionOffset);
if ((collisionExtent.x < 0.f || collisionExtent.y < 0.f || collisionExtent.z < 0.f) || collisionExtent.isZero())
aabb = mData.GetBounds(xf.getRotation());
return new CScriptGunTurret(mgr.AllocateUniqueId(), name, component, info, xf, std::move(mData), aabb, hInfo, dVuln, actParms, turretData);
} }
CEntity* ScriptLoader::LoadFogVolume(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadFogVolume(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)