Initial CScriptSpecialFunction implementations

This commit is contained in:
Phillip Stephens 2018-05-19 22:01:17 -07:00
parent d2c2af326d
commit 259a2d431c
6 changed files with 412 additions and 10 deletions

View File

@ -28,6 +28,7 @@ public:
bool IsWorldVisible(TAreaId) const;
bool IsAreaVisible(TAreaId) const;
bool IsAnythingSet() const;
void SetMapStationUsed(bool val) { x38_mapStationUsed = val; }
};
}

View File

@ -447,6 +447,12 @@ public:
TUniqueId GetBossId() const { return xf18_bossId; }
float GetTotalBossEnergy() const { return xf1c_totalBossEnergy; }
u32 GetBossStringIdx() const { return xf20_bossStringIdx; }
void SetPendingOnScreenTex(CAssetId texId, const zeus::CVector2i& origin, const zeus::CVector2i& extent)
{
xef4_pendingScreenTex.x0_id = texId;
xef4_pendingScreenTex.x4_origin = origin;
xef4_pendingScreenTex.xc_extent = extent;
}
const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; }
void SetViewportScale(const zeus::CVector2f& scale) { xf2c_viewportScale = scale; }
float GetThermalColdScale1() const { return xf24_thermColdScale1; }

View File

@ -6,6 +6,8 @@
#include "GameGlobalObjects.hpp"
#include "CGameState.hpp"
#include "CStateManager.hpp"
#include "IMain.hpp"
#include "CPlayer.hpp"
namespace urde
{
@ -41,10 +43,294 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
void CScriptSpecialFunction::Accept(IVisitor& visitor) { visitor.Visit(this); }
void CScriptSpecialFunction::Think(float, CStateManager&) {}
void CScriptSpecialFunction::Think(float dt, CStateManager& mgr)
{
switch(xe8_function)
{
case ESpecialFunction::PlayerFollowLocator: ThinkPlayerFollowLocator(dt, mgr); break;
case ESpecialFunction::SpinnerController: ThinkSpinnerController(dt, mgr, ESpinnerControllerMode::Zero); break;
case ESpecialFunction::ShotSpinnerController: ThinkSpinnerController(dt, mgr, ESpinnerControllerMode::One); break;
case ESpecialFunction::ObjectFollowLocator: ThinkObjectFollowLocator(dt, mgr); break;
case ESpecialFunction::ObjectFollowObject: ThinkObjectFollowObject(dt, mgr); break;
case ESpecialFunction::ChaffTarget: ThinkChaffTarget(dt, mgr); break;
case ESpecialFunction::ViewFrustumTester:
{
if (x1e4_28_frustumEntered)
{
x1e4_28_frustumEntered = false;
SendScriptMsgs(EScriptObjectState::Entered, mgr, EScriptObjectMessage::None);
}
if (x1e4_29_frustumExited)
{
x1e4_29_frustumExited = false;
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None);
}
break;
}
case ESpecialFunction::SaveStation: ThinkSaveStation(dt, mgr); break;
case ESpecialFunction::IntroBossRingController: ThinkIntroBossRingController(dt, mgr); break;
case ESpecialFunction::RainSimulator: ThinkRainSimulator(dt, mgr); break;
case ESpecialFunction::AreaDamage: ThinkAreaDamage(dt, mgr); break;
case ESpecialFunction::ScaleActor: ThinkActorScale(dt, mgr); break;
case ESpecialFunction::PlayerInAreaRelay: ThinkPlayerInArea(dt, mgr); break;
case ESpecialFunction::Billboard:
{
#if 0
if (x1f0_ && x1e8_->x10_ && x1e5_26_)
{
SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None);
x1e5_26_ = false;
}
#endif
break;
}
default: break;
}
}
void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
if (GetActive() && msg == EScriptObjectMessage::Deactivate && xe8_function == ESpecialFunction::Billboard)
{
mgr.SetPendingOnScreenTex(CAssetId(), zeus::CVector2i(), zeus::CVector2i());
if (x1e8_)
x1e8_ = TLockedToken<CTexture>();
x1e5_26_displayBillboard = false;
}
CActor::AcceptScriptMsg(msg, uid, mgr);
if (xe8_function == ESpecialFunction::ChaffTarget && msg == EScriptObjectMessage::InitializedInArea)
AddMaterial(EMaterialTypes::Target, mgr);
if (GetActive())
{
switch(xe8_function)
{
case ESpecialFunction::HUDFadeIn:
{
if (msg == EScriptObjectMessage::Action)
mgr.Player()->SetHudDisable(xfc_, 0.f, 0.5f);
break;
}
case ESpecialFunction::EscapeSequence:
{
if (msg == EScriptObjectMessage::Action && xfc_ >= 0.f)
mgr.ResetEscapeSequenceTimer(xfc_);
break;
}
case ESpecialFunction::SpinnerController:
{
switch(msg)
{
case EScriptObjectMessage::Stop:
{
x1e4_25_spinnerCanMove = false;
break;
}
case EScriptObjectMessage::Play:
{
x1e4_25_spinnerCanMove = true;
mgr.Player()->SetAngularVelocityWR(zeus::CAxisAngle::sIdentity);
break;
}
case EScriptObjectMessage::Deactivate:
DeleteEmitter(x178_sfxHandle);
break;
default:
break;
}
break;
}
case ESpecialFunction::ShotSpinnerController:
{
switch(msg)
{
case EScriptObjectMessage::Increment:
{
x16c_ = zeus::clamp(0.f, x16c_ + 1.f, 1.f);
SendScriptMsgs(EScriptObjectState::Play, mgr, EScriptObjectMessage::None);
break;
}
case EScriptObjectMessage::SetToMax:
{
SendScriptMsgs(EScriptObjectState::Play, mgr, EScriptObjectMessage::None);
break;
}
case EScriptObjectMessage::SetToZero:
{
x16c_ = -0.5f * x104_;
break;
}
default:
break;
}
break;
}
case ESpecialFunction::MapStation:
{
if (msg == EScriptObjectMessage::Action)
{
mgr.MapWorldInfo()->SetMapStationUsed(true);
const_cast<CMapWorld&>(*mgr.WorldNC()->GetMapWorld()).RecalculateWorldSphere(*mgr.MapWorldInfo(), *mgr.GetWorld());
}
break;
}
case ESpecialFunction::MissileStation:
{
if (msg == EScriptObjectMessage::Action)
{
CPlayerState& pState = *mgr.GetPlayerState().get();
pState.ResetAndIncrPickUp(CPlayerState::EItemType::Missiles, pState.GetItemCapacity(CPlayerState::EItemType::Missiles));
}
break;
}
case ESpecialFunction::PowerBombStation:
{
if (msg == EScriptObjectMessage::Action)
{
CPlayerState& pState = *mgr.GetPlayerState().get();
pState.ResetAndIncrPickUp(CPlayerState::EItemType::PowerBombs, pState.GetItemCapacity(CPlayerState::EItemType::PowerBombs));
}
break;
}
case ESpecialFunction::SaveStation:
{
if (msg == EScriptObjectMessage::Action)
{
g_GameState->GetPlayerState()->IncrPickup(CPlayerState::EItemType::EnergyTanks, 1);
if (g_GameState->GetCardSerial() == 0)
SendScriptMsgs(EScriptObjectState::Closed, mgr, EScriptObjectMessage::None);
else
{
mgr.DeferStateTransition(EStateManagerTransition::SaveGame);
x1e5_24_doSave = true;
}
}
break;
}
case ESpecialFunction::IntroBossRingController:
{
if (x1a8_ != 3)
{
switch(msg)
{
case EScriptObjectMessage::Play:
{
if (x1a8_ != 0)
RingScramble(mgr);
for (SRingController& cont : x198_ringControllers)
{
if (TCastToPtr<CActor> act = mgr.ObjectById(cont.x0_id))
cont.xc_ = act->GetTransform().frontVector();
else
cont.xc_ = zeus::CVector3f::skForward;
}
x1a8_ = 3;
break;
}
case EScriptObjectMessage::SetToZero:
{
x1a8_ = 1;
x1ac_ = GetTranslation() - mgr.GetPlayer().GetTranslation();
x1ac_.z = 0.f;
x1ac_.normalize();
break;
}
case EScriptObjectMessage::Action:
{
RingScramble(mgr);
break;
}
case EScriptObjectMessage::InitializedInArea:
{
x198_ringControllers.reserve(3);
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate)
continue;
auto search = mgr.GetIdListForScript(conn.x8_objId);
for (auto it = search.first; it != search.second; ++it)
{
if (TCastToPtr<CActor> act = mgr.ObjectById(it->second))
{
x198_ringControllers.push_back(SRingController(it->second, 0.f, false));
act->RemoveMaterial(EMaterialTypes::Occluder, mgr);
}
}
//std::sort(x198_ringControllers.begin(), x198_ringControllers.end());
/* TODO: Finish */
}
break;
}
default:
break;
}
}
break;
}
case ESpecialFunction::RadialDamage:
{
if (msg == EScriptObjectMessage::Action)
{
CDamageInfo dInfo = x11c_damageInfo;
dInfo.SetRadius(xfc_);
mgr.ApplyDamageToWorld(GetUniqueId(), *this, GetTranslation(), dInfo, CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}));
}
break;
}
case ESpecialFunction::BossEnergyBar:
{
if (msg == EScriptObjectMessage::Increment)
mgr.SetBossParams(uid, xfc_, u32(x100_) + 86);
else if (msg == EScriptObjectMessage::Decrement)
mgr.SetBossParams(kInvalidUniqueId, 0.f, 0);
break;
}
case ESpecialFunction::EndGame:
{
if (msg == EScriptObjectMessage::Action)
{
switch(GetSpecialEnding(mgr))
{
case 0:
g_Main->SetFlowState(EFlowState::WinBad);
break;
case 1:
g_Main->SetFlowState(EFlowState::WinGood);
break;
case 2:
g_Main->SetFlowState(EFlowState::WinBest);
break;
}
mgr.SetShouldQuitGame(true);
}
break;
}
case ESpecialFunction::CinematicSkip:
{
if (msg == EScriptObjectMessage::Increment)
{
if (ShouldSkipCinematic(mgr))
mgr.SetSkipCinematicSpecialFunction(GetUniqueId());
}
else if (msg == EScriptObjectMessage::Decrement)
{
mgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId);
g_GameState->SystemOptions().SetCinematicState(mgr.GetWorld()->GetWorldAssetId(), GetEditorId(), true);
}
break;
}
case ESpecialFunction::ScriptLayerController:
{
break;
}
}
}
}
void CScriptSpecialFunction::PreRender(CStateManager&, const zeus::CFrustum&) {}
@ -59,6 +345,56 @@ void CScriptSpecialFunction::SkipCinematic(CStateManager& stateMgr)
stateMgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId);
}
void CScriptSpecialFunction::RingMoveCloser(CStateManager &, float)
{
}
void CScriptSpecialFunction::RingMoveAway(CStateManager &, float)
{
}
void CScriptSpecialFunction::ThinkRingPuller(float, CStateManager &)
{
}
void CScriptSpecialFunction::RingScramble(CStateManager &)
{
}
void CScriptSpecialFunction::ThinkIntroBossRingController(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkSpinnerController(float, CStateManager &, CScriptSpecialFunction::ESpinnerControllerMode)
{
}
void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkChaffTarget(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr)
{
float deltaScale = dt * xfc_;
@ -97,8 +433,52 @@ void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr)
}
}
void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkAreaDamage(float, CStateManager &)
{
}
void CScriptSpecialFunction::ThinkPlayerInArea(float, CStateManager &)
{
}
bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& stateMgr) const
{
#ifndef NDEBUG
return true;
#else
return g_GameState->SystemOptions().GetCinematicState(stateMgr.GetWorld()->IGetWorldAssetId(), GetEditorId());
#endif
}
void CScriptSpecialFunction::DeleteEmitter(const CSfxHandle& handle)
{
if (handle)
CSfxManager::RemoveEmitter(handle);
}
u32 CScriptSpecialFunction::GetSpecialEnding(const CStateManager& mgr) const
{
const u32 rate = (mgr.GetPlayerState()->CalculateItemCollectionRate() * 100) / mgr.GetPlayerState()->GetPickupTotal();
if (rate < 75)
return 0;
else if (rate < 100)
return 1;
return 2;
}
CScriptSpecialFunction::SRingController::SRingController(TUniqueId uid, float f, bool b)
: x0_id(uid)
, x4_(f)
, x8_(b)
{
}
}

View File

@ -54,11 +54,17 @@ public:
enum class ESpinnerControllerMode
{
Zero,
One,
};
struct SRingController
{
SRingController(TUniqueId, float, bool);
TUniqueId x0_id;
float x4_;
bool x8_;
zeus::CVector3f xc_;
SRingController(TUniqueId uid, float f, bool b);
};
private:
@ -77,14 +83,12 @@ private:
s16 x170_;
s16 x172_;
s16 x174_;
u32 x178_ = 0;
CSfxHandle x178_sfxHandle;
u32 x17c_;
float x180_ = 0.f;
std::vector<float> x184_;
float x194_ = 0.f;
u32 x19c_ = 0;
u32 x1a0_ = 0;
u32 x1a4_ = 0;
std::vector<SRingController> x198_ringControllers;
u32 x1a8_ = 2;
zeus::CVector3f x1ac_ = zeus::CVector3f::skZero;
bool x1b8_ = true;
@ -97,17 +101,20 @@ private:
struct
{
bool x1e4_24_ : 1;
bool x1e4_25_ : 1;
bool x1e4_25_spinnerCanMove : 1;
bool x1e4_26_ : 1;
bool x1e4_27_ : 1;
bool x1e4_28_frustumEntered : 1;
bool x1e4_29_frustumExited : 1;
bool x1e4_30_ : 1;
bool x1e4_31_ : 1;
bool x1e5_24_doSave : 1;
bool x1e5_25_ : 1;
bool x1e5_26_ : 1;
bool x1e5_26_displayBillboard : 1;
};
u32 x1e4_dummy = 0;
};
bool x1f0_ = false;
TLockedToken<CTexture> x1e8_; // Used to be optional
public:
CScriptSpecialFunction(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, ESpecialFunction,
std::string_view, float, float, float, float, const zeus::CVector3f&, const zeus::CColor&,
@ -129,11 +136,18 @@ public:
void ThinkPlayerFollowLocator(float, CStateManager&);
void ThinkSpinnerController(float, CStateManager&, ESpinnerControllerMode);
void ThinkObjectFollowLocator(float, CStateManager&);
void ThinkObjectFollowObject(float, CStateManager&);
void ThinkChaffTarget(float, CStateManager&);
void ThinkActorScale(float, CStateManager&);
void ThinkSaveStation(float, CStateManager&);
void ThinkRainSimulator(float, CStateManager&);
void ThinkAreaDamage(float, CStateManager&);
void ThinkPlayerInArea(float, CStateManager&);
bool ShouldSkipCinematic(CStateManager& stateMgr) const;
void DeleteEmitter(const CSfxHandle& handle);
u32 GetSpecialEnding(const CStateManager&) const;
};
}

View File

@ -211,7 +211,7 @@ CWorld::~CWorld()
CScriptRoomAcoustics::DisableAuxCallbacks();
}
CAssetId CWorld::IGetWorldAssetId() const { return x8_mlvlId; }
CAssetId CWorld::IGetWorldAssetId() const { return GetWorldAssetId(); }
CAssetId CWorld::IGetStringTableAssetId() const { return xc_strgId; }

View File

@ -209,6 +209,7 @@ public:
bool HasGlobalSound(u16 id) const;
void AddGlobalSound(const CSfxHandle& hnd);
EEnvFxType GetNeededEnvFx() const { return xc4_neededFx; }
CAssetId GetWorldAssetId() const { return x8_mlvlId; }
bool AreSkyNeedsMet() const;
};