diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 46a473c7b..4574fbbb4 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -402,6 +402,7 @@ public: void SetInMapScreen(bool b) { xf94_27_inMapScreen = b; } bool GetInMapScreen() const { return xf94_27_inMapScreen; } bool IsFullThreat() const { return xf94_30_fullThreat; } + void SetIsFullThreat(bool v) { xf94_30_fullThreat = v; } const std::shared_ptr& GetPlayerState() const {return x8b8_playerState;} CRandom16* GetActiveRandom() {return x900_activeRandom;} diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index 6c0e84d71..4a94a0ad1 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -830,4 +830,10 @@ bool CCameraManager::HasCameraHint(CStateManager& mgr) const } bool CCameraManager::IsInterpolationCameraActive() const { return x88_interpCamera->GetActive(); } + +void CCameraManager::SetFogDensity(float fogDensityTarget, float fogDensitySpeed) +{ + x9c_fogDensityFactorTarget = fogDensityTarget; + x98_fogDensitySpeed = (x9c_fogDensityFactorTarget >= x94_fogDensityFactor ? fogDensitySpeed : -fogDensitySpeed); +} } diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp index 84a54f7c7..dbb5af48e 100644 --- a/Runtime/Camera/CCameraManager.hpp +++ b/Runtime/Camera/CCameraManager.hpp @@ -136,6 +136,7 @@ public: void UpdateListener(CStateManager& mgr); float CalculateFogDensity(CStateManager&, const CScriptWater*); + void SetFogDensity(float, float); void ProcessInput(const CFinalInput& input, CStateManager& stateMgr); diff --git a/Runtime/Character/CAnimTreeTweenBase.cpp b/Runtime/Character/CAnimTreeTweenBase.cpp index 719d6c3ef..d11df2781 100644 --- a/Runtime/Character/CAnimTreeTweenBase.cpp +++ b/Runtime/Character/CAnimTreeTweenBase.cpp @@ -35,7 +35,10 @@ void CAnimTreeTweenBase::VGetSegStatementSet(const CSegIdList& list, CSegStateme else if (sStack > 3) { auto& n = w > 0.5f ? x18_b : x14_a; - n->GetBestUnblendedChild()->VGetSegStatementSet(list, setOut); + auto ptr = n->GetBestUnblendedChild(); + if (!ptr) + ptr = n; + ptr->VGetSegStatementSet(list, setOut); } else { diff --git a/Runtime/Character/CBoneTracking.cpp b/Runtime/Character/CBoneTracking.cpp index 79b01235f..0a3da4a9b 100644 --- a/Runtime/Character/CBoneTracking.cpp +++ b/Runtime/Character/CBoneTracking.cpp @@ -26,17 +26,20 @@ void CBoneTracking::Update(float dt) void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, const zeus::CTransform& xf, const zeus::CVector3f& vec, const CBodyController& bodyController) { - TCastToPtr patterned = bodyController.GetOwner(); - bool r31 = false; - if (bodyController.GetBodyStateInfo().ApplyHeadTracking() && patterned && patterned->ApplyBoneTracking()) - r31 = true; + TCastToPtr patterned = bodyController.GetOwner(); - PreRender(mgr, animData, xf, vec, r31); + PreRender(mgr, animData, xf, vec, + (bodyController.GetBodyStateInfo().ApplyHeadTracking() && patterned && patterned->ApplyBoneTracking())); } void CBoneTracking::PreRender(const CStateManager& mgr, CAnimData& animData, const zeus::CTransform& xf, const zeus::CVector3f& vec, bool b) { + if (x14_segId == 0) + return; + + + x18_time = 0.f; } void CBoneTracking::SetActive(bool) diff --git a/Runtime/MP1/World/CBurrower.cpp b/Runtime/MP1/World/CBurrower.cpp index ebd272241..de3d9c9dc 100644 --- a/Runtime/MP1/World/CBurrower.cpp +++ b/Runtime/MP1/World/CBurrower.cpp @@ -1,4 +1,5 @@ #include "CBurrower.hpp" +#include "CStateManager.hpp" namespace urde::MP1 { @@ -11,4 +12,17 @@ CBurrower::CBurrower(TUniqueId uid, std::string_view name, const CEntityInfo& in { } + +void CBurrower::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) +{ + CPatterned::AcceptScriptMsg(msg, uid, mgr); + if (msg == EScriptObjectMessage::Registered) + x450_bodyController->Activate(mgr); + else if (msg == EScriptObjectMessage::InitializedInArea) + { + + } + else if (msg == EScriptObjectMessage::InvulnDamage) + x6a4_ = 1.f; +} } \ No newline at end of file diff --git a/Runtime/MP1/World/CBurrower.hpp b/Runtime/MP1/World/CBurrower.hpp index 482d36f05..cdad65507 100644 --- a/Runtime/MP1/World/CBurrower.hpp +++ b/Runtime/MP1/World/CBurrower.hpp @@ -7,11 +7,13 @@ namespace urde::MP1 class CBurrower : public CPatterned { - + float x6a4_ = 0.f; public: DEFINE_PATTERNED(Burrower) CBurrower(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&, const CPatternedInfo&, const CActorParameters&, CAssetId, CAssetId, CAssetId, const CDamageInfo&, CAssetId, u32, CAssetId); + + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); }; } diff --git a/Runtime/MP1/World/CNewIntroBoss.cpp b/Runtime/MP1/World/CNewIntroBoss.cpp index 8bd5ddbe3..48a49ca5e 100644 --- a/Runtime/MP1/World/CNewIntroBoss.cpp +++ b/Runtime/MP1/World/CNewIntroBoss.cpp @@ -78,6 +78,7 @@ void CNewIntroBoss::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSt RemoveMaterial(EMaterialTypes::Solid, mgr); RemoveMaterial(EMaterialTypes::Target, mgr); RemoveMaterial(EMaterialTypes::Orbit, mgr); + RemoveMaterial(EMaterialTypes::Occluder, mgr); x450_bodyController->Activate(mgr); if (x5d4_stage1Projectile == kInvalidUniqueId) diff --git a/Runtime/World/CScriptSpecialFunction.cpp b/Runtime/World/CScriptSpecialFunction.cpp index f1fcfeb14..1172ec2e2 100644 --- a/Runtime/World/CScriptSpecialFunction.cpp +++ b/Runtime/World/CScriptSpecialFunction.cpp @@ -1,14 +1,18 @@ #include "CScriptSpecialFunction.hpp" -#include "Character/CModelData.hpp" -#include "CActorParameters.hpp" #include "Audio/CSfxManager.hpp" -#include "TCastTo.hpp" +#include "Camera/CCameraManager.hpp" +#include "Character/CModelData.hpp" +#include "Graphics/CTexture.hpp" +#include "World/CActorParameters.hpp" +#include "World/CPlayer.hpp" #include "GameGlobalObjects.hpp" #include "CMemoryCardSys.hpp" #include "CGameState.hpp" +#include "CSimplePool.hpp" #include "CStateManager.hpp" #include "IMain.hpp" -#include "CPlayer.hpp" +#include "TCastTo.hpp" + #include "hecl/CVarManager.hpp" namespace urde @@ -18,7 +22,7 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n const zeus::CTransform& xf, ESpecialFunction func, std::string_view lcName, float f1, float f2, float f3, float f4, const zeus::CVector3f& vec, const zeus::CColor& col, bool active, - const CDamageInfo& dInfo, s32 aId1, s32 aId2, CAssetId aId3, + const CDamageInfo& dInfo, s32 aId1, s32 aId2, CPlayerState::EItemType itemType, s16 sId1, s16 sId2, s16 sId3) : CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(), CActorParameters::None(), kInvalidUniqueId) @@ -36,7 +40,7 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n , x174_(CSfxManager::TranslateSFXID(sId3)) , x1bc_areaSaveId(aId1) , x1c0_layerIdx(aId2) -, x1c4_(aId3) +, x1c4_item(itemType) { x1e4_26_ = true; if (xe8_function == ESpecialFunction::HUDTarget) @@ -77,13 +81,11 @@ void CScriptSpecialFunction::Think(float dt, CStateManager& mgr) case ESpecialFunction::PlayerInAreaRelay: ThinkPlayerInArea(dt, mgr); break; case ESpecialFunction::Billboard: { -#if 0 - if (x1f0_ && x1e8_->x10_ && x1e5_26_) + if (x1e8_ && x1e5_26_displayBillboard) { SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None); - x1e5_26_ = false; + x1e5_26_displayBillboard = false; } -#endif break; } default: break; @@ -276,7 +278,6 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } //std::sort(x198_ringControllers.begin(), x198_ringControllers.end()); - /* TODO: Finish */ } break; } @@ -390,6 +391,109 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId mgr.GetRumbleManager().Rumble(mgr, fxTranslation[rumbFx], 1.f, ERumblePriority::One); } break; + case ESpecialFunction::InventoryActivator: + { + if (msg == EScriptObjectMessage::Action && mgr.GetPlayerState()->HasPowerUp(x1c4_item)) + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + break; + } + case ESpecialFunction::FusionRelay: + { + if (msg == EScriptObjectMessage::Action && mgr.GetPlayerState()->IsFusionEnabled()) + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + break; + } + case ESpecialFunction::AreaDamage: + { + if ((msg == EScriptObjectMessage::Deleted || msg == EScriptObjectMessage::Deactivate) && x1e4_31_) + { + x1e4_31_ = false; + mgr.GetPlayer().DecrementPhazon(); + mgr.SetIsFullThreat(false); + } + break; + } + case ESpecialFunction::DropBomb: + { + if (msg == EScriptObjectMessage::Action) + { + if (xfc_ >= 1.f) + mgr.GetPlayer().GetPlayerGun()->DropBomb(CPlayerGun::EBWeapon::PowerBomb, mgr); + else + mgr.GetPlayer().GetPlayerGun()->DropBomb(CPlayerGun::EBWeapon::Bomb, mgr); + } + break; + } + case ESpecialFunction::RedundantHintSystem: + { + CHintOptions& hintOptions = g_GameState->HintOptions(); + if (msg == EScriptObjectMessage::Action) + hintOptions.ActivateContinueDelayHintTimer(xec_locatorName.c_str()); + else if (msg == EScriptObjectMessage::Increment) + hintOptions.ActivateImmediateHintTimer(xec_locatorName.c_str()); + else if (msg == EScriptObjectMessage::Decrement) + hintOptions.DelayHint(xec_locatorName.c_str()); + break; + } + case ESpecialFunction::Billboard: + { + if (msg == EScriptObjectMessage::Increment) + { + const SObjectTag* objectTag = g_ResFactory->GetResourceIdByName(xec_locatorName); + CAssetId assetId = objectTag ? objectTag->id : CAssetId(); + + mgr.SetPendingOnScreenTex(assetId, {x104_, x108_}, {xfc_, x100_}); + if (objectTag) + { + x1e8_ = g_SimplePool->GetObj(*objectTag); + x1e5_26_displayBillboard = true; + } + } + else if (msg == EScriptObjectMessage::Decrement) + { + mgr.SetPendingOnScreenTex({}, {x104_, x108_}, {xfc_, x100_}); + if (x1e8_) + x1e8_ = TLockedToken(); + x1e5_26_displayBillboard = false; + } + break; + } + case ESpecialFunction::PlayerInAreaRelay: + { + if ((msg == EScriptObjectMessage::Action || msg == EScriptObjectMessage::SetToZero) && + GetAreaIdAlways() == mgr.GetPlayer().GetAreaIdAlways()) + { + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + } + break; + } + case ESpecialFunction::HUDTarget: + { + if (msg == EScriptObjectMessage::Increment) + AddMaterial(EMaterialTypes::Target, EMaterialTypes::RadarObject, mgr); + else if (msg == EScriptObjectMessage::Decrement) + RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::RadarObject, mgr); + break; + } + case ESpecialFunction::FogFader: + { + if (msg == EScriptObjectMessage::Increment) + mgr.GetCameraManager()->SetFogDensity(x100_, xfc_); + else if (msg == EScriptObjectMessage::Decrement) + mgr.GetCameraManager()->SetFogDensity(x100_, 1.f); + break; + } + case ESpecialFunction::EnterLogbook: + { + if (msg == EScriptObjectMessage::Action) + mgr.DeferStateTransition(EStateManagerTransition::LogBook); + break; + } + case ESpecialFunction::Ending: + { + if (msg == EScriptObjectMessage::Action && GetSpecialEnding(mgr) == u32(xfc_)) + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + } default: break; } @@ -496,9 +600,12 @@ void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr) } } -void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager &) +void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) { - + if ((float(mgr.GetInputFrameIdx()) / 3600.f) < 0.5f) + SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None); + else + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); } void CScriptSpecialFunction::ThinkAreaDamage(float, CStateManager &) @@ -506,9 +613,21 @@ void CScriptSpecialFunction::ThinkAreaDamage(float, CStateManager &) } -void CScriptSpecialFunction::ThinkPlayerInArea(float, CStateManager &) +void CScriptSpecialFunction::ThinkPlayerInArea(float dt, CStateManager& mgr) { + if (mgr.GetPlayer().GetAreaIdAlways() == GetAreaIdAlways()) + { + if (x1e5_25_playerInArea) + return; + x1e5_25_playerInArea = true; + SendScriptMsgs(EScriptObjectState::Entered, mgr, EScriptObjectMessage::None); + } + else if (x1e5_25_playerInArea) + { + x1e5_25_playerInArea = false; + SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None); + } } bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& stateMgr) const diff --git a/Runtime/World/CScriptSpecialFunction.hpp b/Runtime/World/CScriptSpecialFunction.hpp index 71a73bf99..67fcd3563 100644 --- a/Runtime/World/CScriptSpecialFunction.hpp +++ b/Runtime/World/CScriptSpecialFunction.hpp @@ -93,7 +93,7 @@ private: bool x1b8_ = true; s32 x1bc_areaSaveId; s32 x1c0_layerIdx; - CAssetId x1c4_; + CPlayerState::EItemType x1c4_item; std::experimental::optional x1c8_; union { @@ -108,7 +108,7 @@ private: bool x1e4_30_ : 1; bool x1e4_31_ : 1; bool x1e5_24_doSave : 1; - bool x1e5_25_ : 1; + bool x1e5_25_playerInArea : 1; bool x1e5_26_displayBillboard : 1; }; u32 x1e4_dummy = 0; @@ -117,7 +117,7 @@ private: 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&, - bool, const CDamageInfo&, s32, s32, CAssetId, s16, s16, s16); + bool, const CDamageInfo&, s32, s32, CPlayerState::EItemType, s16, s16, s16); void Accept(IVisitor& visitor); void Think(float, CStateManager &); diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 0d8667d05..9f77cd519 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -1861,7 +1861,7 @@ CEntity* ScriptLoader::LoadSpecialFunction(CStateManager& mgr, CInputStream& in, float f3 = in.readFloatBig(); u32 w2 = in.readUint32Big(); u32 w3 = in.readUint32Big(); - u32 w4 = in.readUint32Big(); + CPlayerState::EItemType w4 = CPlayerState::EItemType(in.readUint32Big()); bool active1 = in.readBool(); float f4 = in.readFloatBig(); s16 w5 = in.readUint32Big() & 0xFFFF; @@ -2681,7 +2681,7 @@ CEntity* ScriptLoader::LoadFogVolume(CStateManager& mgr, CInputStream& in, int p return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, ConvertEditorEulerToTransform4f(center, {}), CScriptSpecialFunction::ESpecialFunction::FogVolume, "", flickerSpeed, f2, 0.f, - 0.f, volume, fogColor, active, CDamageInfo(), -1, -1, CAssetId(), + 0.f, volume, fogColor, active, CDamageInfo(), -1, -1, CPlayerState::EItemType::Invalid, -1, -1, -1); } @@ -2767,7 +2767,7 @@ CEntity* ScriptLoader::LoadRadialDamage(CStateManager& mgr, CInputStream& in, in return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, xf, CScriptSpecialFunction::ESpecialFunction::RadialDamage, "", radius, 0.f, 0.f, 0.f, zeus::CVector3f::skZero, zeus::CColor::skBlack, active, dInfo, -1, -1, - -1, -1, -1, -1); + CPlayerState::EItemType::Invalid, -1, -1, -1); } CEntity* ScriptLoader::LoadCameraPitchVolume(CStateManager& mgr, CInputStream& in, int propCount, @@ -2800,7 +2800,7 @@ CEntity* ScriptLoader::LoadEnvFxDensityController(CStateManager& mgr, CInputStre return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, zeus::CTransform::Identity(), CScriptSpecialFunction::ESpecialFunction::EnvFxDensityController, "", density, w1, 0.f, 0.f, zeus::CVector3f::skZero, zeus::CColor::skBlack, active, CDamageInfo(), - -1, -1, CAssetId(), -1, -1, -1); + -1, -1, CPlayerState::EItemType::Invalid, -1, -1, -1); } CEntity* ScriptLoader::LoadMagdolite(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) @@ -3089,7 +3089,7 @@ CEntity* ScriptLoader::LoadRumbleEffect(CStateManager& mgr, CInputStream& in, in return new CScriptSpecialFunction( mgr.AllocateUniqueId(), name, info, ConvertEditorEulerToTransform4f(zeus::CVector3f::skZero, position), CScriptSpecialFunction::ESpecialFunction::RumbleEffect, "", f1, w1, pFlags, 0.f, zeus::CVector3f::skZero, - zeus::CColor::skBlack, active, {}, {}, {}, {}, -1, -1, -1); + zeus::CColor::skBlack, active, {}, {}, {}, CPlayerState::EItemType::Invalid, -1, -1, -1); } CEntity* ScriptLoader::LoadAmbientAI(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)