mirror of https://github.com/AxioDL/metaforce.git
Initial CScriptSpecialFunction implementations
This commit is contained in:
parent
d2c2af326d
commit
259a2d431c
|
@ -28,6 +28,7 @@ public:
|
|||
bool IsWorldVisible(TAreaId) const;
|
||||
bool IsAreaVisible(TAreaId) const;
|
||||
bool IsAnythingSet() const;
|
||||
void SetMapStationUsed(bool val) { x38_mapStationUsed = val; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue