diff --git a/Runtime/World/CScriptSpecialFunction.cpp b/Runtime/World/CScriptSpecialFunction.cpp index a0d36b848..e74e4c639 100644 --- a/Runtime/World/CScriptSpecialFunction.cpp +++ b/Runtime/World/CScriptSpecialFunction.cpp @@ -375,19 +375,29 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } break; } - case ESpecialFunction::RumbleEffect: - if (msg == EScriptObjectMessage::Action) { - const s32 rumbFx = s32(x100_float2); - - // Retro originally did not check the upper bounds, this could potentially cause a crash - // with some runtimes, so let's make sure we're not out of bounds in either direction. - if (rumbFx < 0 || rumbFx >= 6) { - break; + case ESpecialFunction::RumbleEffect: { + if (msg != EScriptObjectMessage::Action) { + break; + } + int rumbFxIdx = int(x100_float2); + if (rumbFxIdx < 0 || rumbFxIdx >= fxTranslation.size()) { + break; + } + ERumbleFxId rumbFx = fxTranslation[rumbFxIdx]; + uint param3 = x104_float3; + if ((param3 & 1) != 0) { + mgr.GetRumbleManager().Rumble(mgr, rumbFx, 1.f, ERumblePriority::One); + } else { + zeus::CVector3f pos = GetTranslation(); + if ((param3 & 2) != 0) { + if (const CActor* act = TCastToConstPtr(mgr.GetObjectById(uid))) { + pos = act->GetTranslation(); + } } - - mgr.GetRumbleManager().Rumble(mgr, fxTranslation[rumbFx], 1.f, ERumblePriority::One); + mgr.GetRumbleManager().Rumble(mgr, pos, rumbFx, xfc_float1, ERumblePriority::One); } break; + } case ESpecialFunction::InventoryActivator: { if (msg == EScriptObjectMessage::Action && mgr.GetPlayerState()->HasPowerUp(x1c4_item)) { SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); @@ -506,11 +516,12 @@ void CScriptSpecialFunction::PreRender(CStateManager&, const zeus::CFrustum& fru if (x1e4_30_ == val) { return; } - if (!val) { - x1e4_29_frustumExited = true; - } else { + if (val) { x1e4_28_frustumEntered = true; + } else { + x1e4_29_frustumExited = true; } + x1e4_30_ = val; } void CScriptSpecialFunction::AddToRenderer(const zeus::CFrustum&, CStateManager& mgr) { @@ -525,7 +536,7 @@ void CScriptSpecialFunction::AddToRenderer(const zeus::CFrustum&, CStateManager& void CScriptSpecialFunction::Render(CStateManager& mgr) { if (xe8_function == ESpecialFunction::FogVolume) { - const float z = mgr.IntegrateVisorFog(xfc_float1 * std::sin(CGraphics::GetSecondsMod900())); + const float z = mgr.IntegrateVisorFog(xfc_float1 * std::sin(CGraphics::GetSecondsMod900() * x100_float2)); if (z > 0.f) { zeus::CVector3f max = GetTranslation() + x10c_vector3f; max.z() += z; @@ -634,6 +645,10 @@ void CScriptSpecialFunction::ThinkPlayerFollowLocator(float, CStateManager& mgr) const auto search = mgr.GetIdListForScript(conn.x8_objId); for (auto it = search.first; it != search.second; ++it) { if (const TCastToConstPtr act = mgr.GetObjectById(it->second)) { + if (!act->GetModelData() || !act->GetModelData()->HasAnimData()) { + continue; + } + const zeus::CTransform xf = act->GetTransform() * act->GetLocatorTransform(xec_locatorName); CPlayer& pl = mgr.GetPlayer(); pl.SetTransform(xf); @@ -832,10 +847,9 @@ void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr) } void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) { - const zeus::CAABox box(5.f - GetTranslation(), 5.f + GetTranslation()); + const zeus::CAABox box(GetTranslation() - 5.f, GetTranslation() + 5.f); EntityList nearList; mgr.BuildNearList(nearList, box, CMaterialFilter::MakeInclude({EMaterialTypes::Projectile}), nullptr); - auto& filter = mgr.GetCameraFilterPass(7); for (const auto& uid : nearList) { if (const TCastToPtr proj = mgr.ObjectById(uid)) { @@ -843,6 +857,9 @@ void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) { proj->Set3d0_26(true); if (mgr.GetPlayer().GetAreaIdAlways() == GetAreaIdAlways()) { mgr.GetPlayer().SetHudDisable(x100_float2, 0.5f, 2.5f); + x194_ = xfc_float1; + + auto& filter = mgr.GetCameraFilterPass(7); filter.SetFilter(EFilterType::Blend, EFilterShape::Fullscreen, 0.f, zeus::skWhite, CAssetId()); filter.DisableFilter(0.1f); } @@ -859,7 +876,7 @@ void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) { mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), intfMag, .5f); - if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan) { + if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Thermal) { mgr.GetPlayer().AddOrbitDisableSource(mgr, GetUniqueId()); } else { mgr.GetPlayer().RemoveOrbitDisableSource(GetUniqueId()); @@ -906,7 +923,7 @@ void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr) { } void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) { - if ((float(mgr.GetInputFrameIdx()) / 3600.f) < 0.5f) { + if ((static_cast< float >(mgr.GetInputFrameIdx() % 3600)) / 3600.f < 0.5f) { SendScriptMsgs(EScriptObjectState::MaxReached, mgr, EScriptObjectMessage::None); } else { SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); @@ -975,23 +992,27 @@ bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& stateMgr) const return g_GameState->SystemOptions().GetCinematicState(stateMgr.GetWorld()->IGetWorldAssetId(), GetEditorId()); } -void CScriptSpecialFunction::DeleteEmitter(const CSfxHandle& handle) { +void CScriptSpecialFunction::DeleteEmitter(CSfxHandle& handle) { if (!handle) { return; } CSfxManager::RemoveEmitter(handle); + handle = CSfxHandle(); } u32 CScriptSpecialFunction::GetSpecialEnding(const CStateManager& mgr) const { - const u32 rate = (mgr.GetPlayerState()->CalculateItemCollectionRate() * 100) / mgr.GetPlayerState()->GetPickupTotal(); + const int rate = (mgr.GetPlayerState()->CalculateItemCollectionRate() * 100) / mgr.GetPlayerState()->GetPickupTotal(); + int result; if (rate < 75) { - return 0; + result = 0; + } else { + result = 2; + if (rate < 100) { + result = 1; + } } - if (rate < 100) { - return 1; - } - return 2; + return result; } void CScriptSpecialFunction::AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, const zeus::CVector3f& pos, diff --git a/Runtime/World/CScriptSpecialFunction.hpp b/Runtime/World/CScriptSpecialFunction.hpp index 167883062..d848fe9a6 100644 --- a/Runtime/World/CScriptSpecialFunction.hpp +++ b/Runtime/World/CScriptSpecialFunction.hpp @@ -141,7 +141,7 @@ public: bool ShouldSkipCinematic(CStateManager& stateMgr) const; - void DeleteEmitter(const CSfxHandle& handle); + void DeleteEmitter(CSfxHandle& handle); u32 GetSpecialEnding(const CStateManager&) const; void AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, const zeus::CVector3f& pos, float vol); };