Index: binaries/data/mods/public/simulation/templates/structures/palisades_gate.xml =================================================================== --- binaries/data/mods/public/simulation/templates/structures/palisades_gate.xml +++ binaries/data/mods/public/simulation/templates/structures/palisades_gate.xml @@ -11,7 +11,7 @@ 7 - 20 + 2 0.5 Index: binaries/data/mods/public/simulation/templates/template_structure_defensive_wall_gate.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_structure_defensive_wall_gate.xml +++ binaries/data/mods/public/simulation/templates/template_structure_defensive_wall_gate.xml @@ -10,7 +10,7 @@ - 20 + 2 2500 Index: source/simulation2/components/CCmpRangeManager.cpp =================================================================== --- source/simulation2/components/CCmpRangeManager.cpp +++ source/simulation2/components/CCmpRangeManager.cpp @@ -1213,12 +1213,13 @@ if (!InParabolicRange( CFixedVector3D(it->second.x, secondPosition.Y, it->second.z) - pos3d, - q.maxRange)) + q.maxRange + fixed::FromInt(it->second.size))) continue; if (!q.minRange.IsZero()) { - int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange); + // Subtract 1 since we round up from the real size and we prefer returning too many entities. + int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange + fixed::FromInt(it->second.size - 1)); if (distVsMin < 0) continue; } @@ -1243,13 +1244,15 @@ continue; // Restrict based on precise distance - int distVsMax = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.maxRange); + // Account for entity size assuming nearest-distance possible. + int distVsMax = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.maxRange + fixed::FromInt(it->second.size)); if (distVsMax > 0) continue; if (!q.minRange.IsZero()) { - int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange); + // Subtract 1 since we round up from the real size and we prefer returning too many entities. + int distVsMin = (CFixedVector2D(it->second.x, it->second.z) - pos).CompareLength(q.minRange + fixed::FromInt(it->second.size - 1)); if (distVsMin < 0) continue; } @@ -1380,6 +1383,18 @@ q.maxRange = maxRange; q.elevationBonus = entity_pos_t::Zero(); + if (q.source.GetId() != INVALID_ENTITY) + { + EntityMap::const_iterator it = m_EntityData.find(q.source.GetId()); + ENSURE(it != m_EntityData.end()); + if (q.maxRange != entity_pos_t::FromInt(-1)) + q.maxRange += fixed::FromInt(it->second.size); + + // It's fine if this goes negative. + if (q.minRange > entity_pos_t::Zero()) + q.minRange -= fixed::FromInt(it->second.size); + } + q.ownersMask = 0; for (size_t i = 0; i < owners.size(); ++i) q.ownersMask |= CalcOwnerMask(owners[i]); Index: source/simulation2/components/ICmpRangeManager.h =================================================================== --- source/simulation2/components/ICmpRangeManager.h +++ source/simulation2/components/ICmpRangeManager.h @@ -73,7 +73,7 @@ * * In most cases the users are event-based and want notifications when something * has entered or left the range, and the query can be set up once and rarely changed. - * These queries have to be fast. It's fine to approximate an entity as a point. + * These queries have to be fast. Entities are approximated as circles. * * Current design: *