diff --git a/binaries/data/mods/public/simulation/templates/special/flare_target_marker.xml b/binaries/data/mods/public/simulation/templates/special/flare_target_marker.xml index f19048b2c4..3e5e6fb99b 100644 --- a/binaries/data/mods/public/simulation/templates/special/flare_target_marker.xml +++ b/binaries/data/mods/public/simulation/templates/special/flare_target_marker.xml @@ -3,6 +3,7 @@ true false + 1.0 6 10000 0 diff --git a/binaries/data/mods/public/simulation/templates/special/target_marker.xml b/binaries/data/mods/public/simulation/templates/special/target_marker.xml index 6605738ffc..242183d282 100644 --- a/binaries/data/mods/public/simulation/templates/special/target_marker.xml +++ b/binaries/data/mods/public/simulation/templates/special/target_marker.xml @@ -3,6 +3,7 @@ true false + 1.0 0.5 10000 0 diff --git a/binaries/data/mods/public/simulation/templates/template_rubble.xml b/binaries/data/mods/public/simulation/templates/template_rubble.xml index 2b28d3de9e..36d0714a2e 100644 --- a/binaries/data/mods/public/simulation/templates/template_rubble.xml +++ b/binaries/data/mods/public/simulation/templates/template_rubble.xml @@ -3,6 +3,7 @@ false false + 0.25 15.0 0.2 0 diff --git a/binaries/data/mods/public/simulation/templates/template_structure.xml b/binaries/data/mods/public/simulation/templates/template_structure.xml index 94b1633189..29f8ef36c5 100644 --- a/binaries/data/mods/public/simulation/templates/template_structure.xml +++ b/binaries/data/mods/public/simulation/templates/template_structure.xml @@ -24,6 +24,7 @@ false false + 1.0 0.0 3.0 9.8 diff --git a/binaries/data/mods/public/simulation/templates/template_unit.xml b/binaries/data/mods/public/simulation/templates/template_unit.xml index e819518061..9cf95fd6e6 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit.xml @@ -14,6 +14,7 @@ false false + 0.01 30.0 0.01 0.0 diff --git a/binaries/data/mods/public/simulation/templates/template_unit_ship.xml b/binaries/data/mods/public/simulation/templates/template_unit_ship.xml index 4af44185f3..fe4ababdc0 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_ship.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_ship.xml @@ -2,6 +2,7 @@ true + 1.0 0.0 0.5 7.0 diff --git a/binaries/data/mods/public/simulation/templates/template_unit_siege.xml b/binaries/data/mods/public/simulation/templates/template_unit_siege.xml index bff74e2008..9b8b4b4437 100644 --- a/binaries/data/mods/public/simulation/templates/template_unit_siege.xml +++ b/binaries/data/mods/public/simulation/templates/template_unit_siege.xml @@ -5,6 +5,7 @@ 0.0 + 1.0 0.0 2.0 diff --git a/source/simulation2/components/CCmpDecay.cpp b/source/simulation2/components/CCmpDecay.cpp index 2eccd139c0..acc5c05050 100644 --- a/source/simulation2/components/CCmpDecay.cpp +++ b/source/simulation2/components/CCmpDecay.cpp @@ -36,6 +36,8 @@ #include #include +#include +#include #include /** @@ -65,6 +67,13 @@ public: bool m_Active; bool m_ShipSink; + bool m_Stochastic; + + std::optional m_Generator; + std::negative_binomial_distribution<> m_Distribution{ 6, 0.032 }; + std::geometric_distribution<>::result_type m_NextSink; + + float m_SinkProb; float m_DelayTime; float m_SinkRate; float m_SinkAccel; @@ -88,6 +97,9 @@ public: "" "" "" + "" + "" + "" "" "" "" @@ -103,6 +115,7 @@ public: { m_Active = paramNode.GetChild("Active").ToBool(); m_ShipSink = paramNode.GetChild("SinkingAnim").ToBool(); + m_SinkProb = paramNode.GetChild("SinkProb").ToFixed().ToFloat(); m_DelayTime = paramNode.GetChild("DelayTime").ToFixed().ToFloat(); m_SinkRate = paramNode.GetChild("SinkRate").ToFixed().ToFloat(); m_SinkAccel = paramNode.GetChild("SinkAccel").ToFixed().ToFloat(); @@ -110,6 +123,11 @@ public: m_CurrentTime = 0.f; m_TotalSinkDepth = -1.f; + m_SinkProb < 1.f ? m_Stochastic = true : m_Stochastic = false; + + std::negative_binomial_distribution::param_type new_params(6, m_SinkProb*4); + m_Distribution.param(new_params); + // Detect unsafe misconfiguration if (m_Active && !ENTITY_IS_LOCAL(GetEntityId())) { @@ -175,6 +193,13 @@ public: CFixedVector3D pos = cmpPosition->GetPosition(); + //Use the entities position upon decay start to vary the pseudorandom seed. + if (!m_Generator.has_value()) + { + m_Generator.emplace(pos.X.ToInt_RoundToNearest() * pos.Z.ToInt_RoundToNearest()); + m_NextSink = m_Distribution(m_Generator.value()); + } + CmpPtr cmpTerrain(GetSystemEntity()); if (cmpTerrain) { @@ -199,27 +224,32 @@ public: if (m_CurrentTime >= m_DelayTime) { - float t = m_CurrentTime - m_DelayTime; - float depth = (m_SinkRate * t) + (m_SinkAccel * t * t); - - if (m_ShipSink) + //If the entity should sink stochastically, use the negative binomial distribution to see if it should sink each frame. + if ((m_Stochastic && (m_NextSink-- == 0)) || !m_Stochastic) { - // exponential sinking with tilting - float tilt_time = t > 5.f ? 5.f : t; - float tiltSink = tilt_time * tilt_time / 5.f; - entity_pos_t RotX = entity_pos_t::FromFloat(((m_InitialXRotation.ToFloat() * (5.f - tiltSink)) + (m_SinkingAngleX * tiltSink)) / 5.f); - entity_pos_t RotZ = entity_pos_t::FromFloat(((m_InitialZRotation.ToFloat() * (3.f - tilt_time)) + (m_SinkingAngleZ * tilt_time)) / 3.f); - cmpPosition->SetXZRotation(RotX,RotZ); + m_NextSink = m_Distribution(m_Generator.value()); + float t = m_CurrentTime - m_DelayTime; + float depth = (m_SinkRate * t) + (m_SinkAccel * t * t); - depth = m_SinkRate * (exp(t - 1.f) - 0.54881163609f) + (m_SinkAccel * exp(t - 4.f) - 0.01831563888f); - if (depth < 0.f) - depth = 0.f; + if (m_ShipSink) + { + // exponential sinking with tilting + float tilt_time = t > 5.f ? 5.f : t; + float tiltSink = tilt_time * tilt_time / 5.f; + entity_pos_t RotX = entity_pos_t::FromFloat(((m_InitialXRotation.ToFloat() * (5.f - tiltSink)) + (m_SinkingAngleX * tiltSink)) / 5.f); + entity_pos_t RotZ = entity_pos_t::FromFloat(((m_InitialZRotation.ToFloat() * (3.f - tilt_time)) + (m_SinkingAngleZ * tilt_time)) / 3.f); + cmpPosition->SetXZRotation(RotX,RotZ); + + depth = m_SinkRate * (exp(t - 1.f) - 0.54881163609f) + (m_SinkAccel * exp(t - 4.f) - 0.01831563888f); + if (depth < 0.f) + depth = 0.f; + } + + cmpPosition->SetHeightOffset(entity_pos_t::FromFloat(-depth)); + + if (depth > m_TotalSinkDepth) + GetSimContext().GetComponentManager().DestroyComponentsSoon(GetEntityId()); } - - cmpPosition->SetHeightOffset(entity_pos_t::FromFloat(-depth)); - - if (depth > m_TotalSinkDepth) - GetSimContext().GetComponentManager().DestroyComponentsSoon(GetEntityId()); } break;