diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DieModule.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DieModule.h index c3a28c08d92..49fda2e8bf7 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DieModule.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DieModule.h @@ -54,6 +54,8 @@ class DieMuxData // does NOT inherit from ModuleData. VeterancyLevelFlags m_veterancyLevels; ObjectStatusMaskType m_exemptStatus; ///< die module is ignored if any of these status bits are set ObjectStatusMaskType m_requiredStatus; ///< die module is ignored if any of these status bits are clear + Real m_minWaterDepth; + Real m_maxWaterDepth; DieMuxData(); static const FieldParse* getFieldParse(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Die/DieModule.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Die/DieModule.cpp index 397893dc675..c353a11f50c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Die/DieModule.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Die/DieModule.cpp @@ -37,6 +37,8 @@ #include "GameLogic/GameLogic.h" #include "GameLogic/Module/DieModule.h" #include "GameLogic/Object.h" +#include + @@ -50,6 +52,8 @@ DieMuxData::DieMuxData() { if (TheGlobalData) { m_deathTypes &= ~TheGlobalData->m_defaultExcludedDeathTypes; } + m_minWaterDepth = 0.0f; + m_maxWaterDepth = std::numeric_limits::infinity(); } //------------------------------------------------------------------------------------------------- @@ -61,7 +65,9 @@ const FieldParse* DieMuxData::getFieldParse() { "VeterancyLevels", INI::parseVeterancyLevelFlags, nullptr, offsetof( DieMuxData, m_veterancyLevels ) }, { "ExemptStatus", ObjectStatusMaskType::parseFromINI, nullptr, offsetof( DieMuxData, m_exemptStatus ) }, { "RequiredStatus", ObjectStatusMaskType::parseFromINI, nullptr, offsetof( DieMuxData, m_requiredStatus ) }, - { nullptr, nullptr, nullptr, 0 } + { "MinWaterDepth", INI::parseReal, nullptr, offsetof(DieMuxData, m_minWaterDepth )}, + { "MaxWaterDepth", INI::parseReal, nullptr, offsetof(DieMuxData, m_maxWaterDepth )}, + { nullptr, nullptr, nullptr, 0 } }; return dataFieldParse; } @@ -86,6 +92,27 @@ Bool DieMuxData::isDieApplicable(const Object* obj, const DamageInfo *damageInfo if( m_requiredStatus.any() && !obj->getStatusBits().testForAll( m_requiredStatus ) ) return false; + if ((m_minWaterDepth > 0.0f || m_maxWaterDepth < std::numeric_limits::infinity()) && obj != nullptr) { + + // if on bride and we need water -> not applicable + if (obj->getLayer() > LAYER_GROUND && m_minWaterDepth > 0.0f) { + return false; + } + + // Water level restriction + const Coord3D* pos = obj->getPosition(); + Real waterZ{ 0 }, terrainZ{ 0 }; + + if (TheTerrainLogic->isUnderwater(pos->x, pos->y, &waterZ, &terrainZ)) { + Real depth = waterZ - terrainZ; + return depth >= m_minWaterDepth && depth < m_maxWaterDepth; + } + else { + // we are over land + if (m_minWaterDepth > 0.0f) return false; + } + } + return true; }