64 lines
2.6 KiB
C
64 lines
2.6 KiB
C
// Vanilla named settlements supply exclusion areas; no original mission location system.
|
|
// Shared town/village exclusion for mortar impacts, roadblocks and mine sites.
|
|
// Fixed distance from mapped settlement centres, independent of mission
|
|
// activation radii. Scattered buildings and props are not settlements.
|
|
class ERR_SettlementSafety
|
|
{
|
|
static const float RADIUS = 200;
|
|
string SettlementReason;
|
|
protected vector m_SafeImpact;
|
|
protected bool m_SettlementNear;
|
|
protected vector m_LastSettlementImpact;
|
|
protected float m_LastSettlementCheck = -1;
|
|
protected bool m_LastSettlementClear;
|
|
|
|
bool OutsideSettlements(vector impact)
|
|
{
|
|
float now = GetGame().GetWorld().GetWorldTime();
|
|
if (m_LastSettlementCheck >= 0 && now >= m_LastSettlementCheck && now - m_LastSettlementCheck < 1000 && vector.DistanceXZ(impact, m_LastSettlementImpact) == 0)
|
|
return m_LastSettlementClear;
|
|
m_LastSettlementCheck = now;
|
|
m_LastSettlementImpact = impact;
|
|
m_LastSettlementClear = false;
|
|
m_SafeImpact = impact;
|
|
m_SettlementNear = false;
|
|
SettlementReason = "clear";
|
|
// Also cover named native map settlements, independent of whether the
|
|
// mission placed a garrison marker there. Generic building entities also
|
|
// include deer stands, bridge pillars, rubble and electrical cabinets.
|
|
// Broad vertical bounds keep the 200m distance horizontal on hills.
|
|
GetGame().GetWorld().QueryEntitiesByAABB(impact - Vector(RADIUS, 5000, RADIUS), impact + Vector(RADIUS, 5000, RADIUS), CheckSettlement, FilterSettlement, EQueryEntitiesFlags.ALL);
|
|
m_LastSettlementClear = !m_SettlementNear;
|
|
return m_LastSettlementClear;
|
|
}
|
|
|
|
protected bool FilterSettlement(IEntity entity)
|
|
{
|
|
return entity && entity.FindComponent(MapDescriptorComponent);
|
|
}
|
|
|
|
protected bool CheckSettlement(IEntity entity)
|
|
{
|
|
float radius;
|
|
MapDescriptorComponent descriptor = MapDescriptorComponent.Cast(entity.FindComponent(MapDescriptorComponent));
|
|
if (descriptor)
|
|
{
|
|
int type = descriptor.GetBaseType();
|
|
if (type == EMapDescriptorType.MDT_NAME_CITY)
|
|
radius = RADIUS;
|
|
else if (type == EMapDescriptorType.MDT_NAME_TOWN)
|
|
radius = RADIUS;
|
|
else if (type == EMapDescriptorType.MDT_NAME_VILLAGE || type == EMapDescriptorType.MDT_NAME_SETTLEMENT)
|
|
radius = RADIUS;
|
|
}
|
|
if (radius > 0 && vector.DistanceXZ(m_SafeImpact, entity.GetOrigin()) <= radius)
|
|
{
|
|
m_SettlementNear = true;
|
|
SettlementReason = string.Format("named map settlement entity=%1 position=%2 distance=%3m exclusion=%4m", entity, entity.GetOrigin(), vector.DistanceXZ(m_SafeImpact, entity.GetOrigin()), radius);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
}
|