Files
EscapistsReintroduced/addons/ai/Scripts/Game/ERR/ERR_SettlementSafety.c
T

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;
}
}