Index: binaries/data/config/default.cfg =================================================================== --- binaries/data/config/default.cfg +++ binaries/data/config/default.cfg @@ -61,6 +61,8 @@ ; if false, actors won't be rendered but anything entity will be. renderactors = true +maxragdolls = -1 ; When enabled, limits the number of corpses to the number specified. + watereffects=true ; When disabled, force usage of the fixed pipeline water. This is faster, but really, really ugly. waterfancyeffects = false waterrealdepth = true Index: binaries/data/mods/public/gui/options/options.json =================================================================== --- binaries/data/mods/public/gui/options/options.json +++ binaries/data/mods/public/gui/options/options.json @@ -592,6 +592,14 @@ "tooltip": "Units and Structures can be part of multiple control groups. This is useful to keep control groups for distinct armies and a control group for the entire army simultaneously." } ] + }, + { + "type": "number", + "label": "Number of ragdolls", + "tooltip": "To save CPU workload, limits the number of corpses to display -1 is unlimited.", + "config": "maxragdolls", + "min": -1, + "max": 200 } ] } Index: binaries/data/mods/public/simulation/components/Health.js =================================================================== --- binaries/data/mods/public/simulation/components/Health.js +++ binaries/data/mods/public/simulation/components/Health.js @@ -323,7 +323,13 @@ if (resource) entCorpse = Engine.AddEntity("resource|" + templateName); else + { + let cmpUnitRenderer = Engine.QueryInterface(SYSTEM_ENTITY, IID_UnitRenderer); + if(!cmpUnitRenderer || !cmpUnitRenderer.CanAddRagDoll()) + return; + entCorpse = Engine.AddLocalEntity("corpse|" + templateName); + } // Copy various parameters so it looks just like us. let cmpPositionCorpse = Engine.QueryInterface(entCorpse, IID_Position); Index: binaries/data/mods/public/simulation/templates/template_unit.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit.xml +++ binaries/data/mods/public/simulation/templates/template_unit.xml @@ -19,6 +19,7 @@ false + false 30.0 0.01 Index: source/renderer/RenderingOptions.h =================================================================== --- source/renderer/RenderingOptions.h +++ source/renderer/RenderingOptions.h @@ -99,7 +99,7 @@ OPTION(PostProc, bool); OPTION(DisplayFrustum, bool); OPTION(DisplayShadowsFrustum, bool); - + OPTION(MaxRagDolls, int); OPTION(RenderActors, bool); #undef OPTION_DEFAULT_SETTER Index: source/renderer/RenderingOptions.cpp =================================================================== --- source/renderer/RenderingOptions.cpp +++ source/renderer/RenderingOptions.cpp @@ -110,7 +110,7 @@ CFG_GET_VAL("forcealphatest", m_ForceAlphaTest); CFG_GET_VAL("gpuskinning", m_GPUSkinning); - + CFG_GET_VAL("maxragdolls", m_MaxRagDolls); CFG_GET_VAL("renderactors", m_RenderActors); } Index: source/simulation2/components/CCmpDecay.cpp =================================================================== --- source/simulation2/components/CCmpDecay.cpp +++ source/simulation2/components/CCmpDecay.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,6 +24,7 @@ #include "ICmpPosition.h" #include "ICmpTerrain.h" +#include "ICmpUnitRenderer.h" #include "ICmpVisual.h" #include "ps/Profile.h" @@ -55,6 +56,7 @@ bool m_Active; bool m_ShipSink; + bool m_CreatesCorpse; float m_DelayTime; float m_SinkRate; float m_SinkAccel; @@ -75,6 +77,11 @@ "" "" "" + "" + "" + "" + "" + "" "" "" "" @@ -93,6 +100,7 @@ { m_Active = paramNode.GetChild("Active").ToBool(); m_ShipSink = paramNode.GetChild("SinkingAnim").ToBool(); + m_CreatesCorpse = paramNode.GetChild("CreatesCorpse").IsOk(); m_DelayTime = paramNode.GetChild("DelayTime").ToFixed().ToFloat(); m_SinkRate = paramNode.GetChild("SinkRate").ToFixed().ToFloat(); m_SinkAccel = paramNode.GetChild("SinkAccel").ToFixed().ToFloat(); @@ -109,10 +117,26 @@ if (m_Active) GetSimContext().GetComponentManager().DynamicSubscriptionNonsync(MT_Interpolate, this, true); + + if (m_Active && m_CreatesCorpse) + { + CmpPtr cmpUnitRenderer(GetSystemEntity()); + if (cmpUnitRenderer) + { + cmpUnitRenderer->AddRagDoll(); + } + } } virtual void Deinit() { + if (m_Active && m_CreatesCorpse) + { + CmpPtr cmpUnitRenderer(GetSystemEntity()); + if (cmpUnitRenderer) + cmpUnitRenderer->RemoveRagDoll(); + } + } virtual void Serialize(ISerializer& UNUSED(serialize)) Index: source/simulation2/components/CCmpUnitRenderer.cpp =================================================================== --- source/simulation2/components/CCmpUnitRenderer.cpp +++ source/simulation2/components/CCmpUnitRenderer.cpp @@ -119,6 +119,7 @@ std::vector m_UnitTagsFree; int m_FrameNumber; + int m_RagDollCount; float m_FrameOffset; bool m_EnableDebugOverlays; @@ -189,6 +190,22 @@ return &m_Units[tag.n - 1]; } + virtual void AddRagDoll() + { + ++m_RagDollCount; + + } + virtual void RemoveRagDoll() + { + --m_RagDollCount; + } + + virtual bool CanAddRagDoll() + { + int maxCorpses = g_RenderingOptions.GetMaxRagDolls(); + return maxCorpses != -1 && m_RagDollCount < maxCorpses; + } + virtual tag_t AddUnit(CEntityHandle entity, CUnit* actor, const CBoundingSphere& boundsApprox, int flags) { ENSURE(actor != NULL); Index: source/simulation2/components/ICmpUnitRenderer.h =================================================================== --- source/simulation2/components/ICmpUnitRenderer.h +++ source/simulation2/components/ICmpUnitRenderer.h @@ -49,7 +49,9 @@ virtual tag_t AddUnit(CEntityHandle entity, CUnit* unit, const CBoundingSphere& boundsApprox, int flags) = 0; virtual void RemoveUnit(tag_t tag) = 0; - + virtual void AddRagDoll() = 0; + virtual void RemoveRagDoll() = 0; + virtual bool CanAddRagDoll() = 0; virtual void UpdateUnit(tag_t tag, CUnit* unit, const CBoundingSphere& boundsApprox) = 0; virtual void UpdateUnitPos(tag_t tag, bool inWorld, const CVector3D& pos0, const CVector3D& pos1) = 0; Index: source/simulation2/components/ICmpUnitRenderer.cpp =================================================================== --- source/simulation2/components/ICmpUnitRenderer.cpp +++ source/simulation2/components/ICmpUnitRenderer.cpp @@ -22,5 +22,8 @@ #include "simulation2/system/InterfaceScripted.h" BEGIN_INTERFACE_WRAPPER(UnitRenderer) -DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitRenderer, SetDebugOverlay, bool) + DEFINE_INTERFACE_METHOD_1("SetDebugOverlay", void, ICmpUnitRenderer, SetDebugOverlay, bool) + DEFINE_INTERFACE_METHOD_0("AddRagDoll", void, ICmpUnitRenderer, AddRagDoll) + DEFINE_INTERFACE_METHOD_0("RemoveRagDoll", void, ICmpUnitRenderer, RemoveRagDoll) + DEFINE_INTERFACE_METHOD_0("CanAddRagDoll", bool, ICmpUnitRenderer, CanAddRagDoll) END_INTERFACE_WRAPPER(UnitRenderer)