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()
{
g_RenderTimings++;
g_DefaultSeconds = float(g_RenderTimings) / 60.f;
g_RenderTimings = (g_RenderTimings + 1) % u32(900*60);
g_DefaultSeconds = g_RenderTimings / 60.f;
}
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)
: x4_selfIdx(idx)
{
xf0_24_postConstructed = false;
xf0_25_active = true;
xf0_26_tokensReady = false;
xf0_27_paused = false;
xf0_28_validated = false;
x8_nameSTRG = in.readUint32Big();
xc_transform.read34RowMajor(in);
x3c_invTransform = xc_transform.inverse();
@ -463,6 +467,12 @@ CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
CGameArea::CGameArea(CAssetId 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())
for (auto& req : xf8_loadTransactions)
req->WaitUntilComplete();
@ -905,7 +915,7 @@ void CGameArea::AllocNewAreaData(int offset, int size)
bool CGameArea::Invalidate(CStateManager* mgr)
{
if (xf0_24_postConstructed)
if (!xf0_24_postConstructed)
{
ClearTokenList();

View File

@ -117,18 +117,11 @@ class CGameArea : public IGameArea
u32 xec_totalResourcesSize = 0;
union
{
struct
{
bool xf0_24_postConstructed : 1;
bool xf0_25_active : 1;
bool xf0_26_tokensReady : 1;
bool xf0_27_paused : 1;
bool xf0_28_validated : 1;
};
u32 _dummy = 0;
};
enum class EPhase
{
@ -361,7 +354,7 @@ public:
s32 GetDockCount() const { return xcc_docks.size(); }
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
{
if (!x12c_postConstructed)

View File

@ -37,6 +37,8 @@ set(WORLD_SOURCES
CScriptCounter.hpp CScriptCounter.cpp
CScriptEffect.hpp CScriptEffect.cpp
CScriptSteam.hpp CScriptSteam.cpp
CScriptRipple.hpp CScriptRipple.cpp
CScriptBallTrigger.hpp CScriptBallTrigger.cpp
CScriptPlatform.hpp CScriptPlatform.cpp
CScriptSound.hpp CScriptSound.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 "TCastTo.hpp"
namespace urde
{
@ -7,6 +8,47 @@ static const CMaterialList skGunMaterialList = { EMaterialTypes::Solid, EMateria
EMaterialTypes::Orbit, EMaterialTypes::Target };
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,
const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb,
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__
#include "CPhysicsActor.hpp"
#include "CDamageInfo.hpp"
namespace urde
{
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
@ -25,6 +76,9 @@ public:
const zeus::CTransform& xf, CModelData&& mData, const zeus::CAABox& aabb,
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
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)
{
if (!area->xf0_24_postConstructed)
if (!area->IsPostConstructed())
{
MoveToChain(area, EChain::Loading);
return true;

View File

@ -53,7 +53,11 @@
#include "CScriptSpawnPoint.hpp"
#include "CScriptSpecialFunction.hpp"
#include "CScriptSteam.hpp"
#include "CScriptRipple.hpp"
#include "CScriptBallTrigger.hpp"
#include "CScriptTargetingPoint.hpp"
#include "CScriptStreamedMusic.hpp"
#include "CScriptGunTurret.hpp"
#include "CScriptSwitch.hpp"
#include "CScriptTimer.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)
{
if (!EnsurePropertyCount(propCount, 4, "Ripple"))
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)
{
if (!EnsurePropertyCount(propCount, 9, "BallTrigger"))
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)
{
if (!EnsurePropertyCount(propCount, 4, "TargetingPoint"))
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)
@ -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)
{
if (!EnsurePropertyCount(propCount, CScriptGunTurretData::GetMinProperties(), "GunTurret"))
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)