Files
EscapistsReintroduced/docs/evidence/object-guards-2026-10-06/native-probe.c.txt
T
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

143 lines
6.2 KiB
Plaintext

class ERR_ObjectProbeScanner
{
protected int m_ObjectProbeCount;
protected int m_ObjectProbeElevated;
ref array<IEntity> m_ObjectProbeCandidates = {};
protected bool ObjectProbeFilter(IEntity entity)
{
if (!entity || Vehicle.Cast(entity) || ChimeraCharacter.Cast(entity)) return false;
string prefab;
if (entity.GetPrefabData()) prefab = entity.GetPrefabData().GetPrefabName();
MapDescriptorComponent descriptor = MapDescriptorComponent.Cast(entity.FindComponent(MapDescriptorComponent));
int type = -1; if (descriptor) type = descriptor.GetBaseType();
return ERR_ObjectGuardRules.Structure(prefab, type);
}
protected bool ObjectProbeRemember(IEntity entity)
{
m_ObjectProbeCandidates.Insert(entity);
return m_ObjectProbeCandidates.Count() < 80;
}
void Run(BaseWorld world)
{
world.QueryEntitiesByAABB("0 -1000 0", "14000 1000 14000", ObjectProbeRemember, ObjectProbeFilter, EQueryEntitiesFlags.ALL);
PrintFormat("ERR OBJECT PROBE candidates=%1", m_ObjectProbeCandidates.Count());
foreach (IEntity entity : m_ObjectProbeCandidates)
{
ERR_ObjectGuardPlacement posts = new ERR_ObjectGuardPlacement(); posts.Reset();
array<vector> players = {entity.GetOrigin() + "1200 0 0"};
vector point; bool found = posts.Find(entity, players, 0, point);
float height; if (found) height = point[1] - world.GetSurfaceY(point[0], point[2]);
string prefab; if (entity.GetPrefabData()) prefab = entity.GetPrefabData().GetPrefabName();
PrintFormat("ERR OBJECT PROBE structure=%1 origin=%2 found=%3 point=%4 aboveGround=%5", prefab, entity.GetOrigin(), found, point, height);
if (found && height > 2) m_ObjectProbeElevated++;
m_ObjectProbeCount++;
}
PrintFormat("ERR OBJECT GEOMETRY COMPLETE: tested=%1 elevated=%2", m_ObjectProbeCount, m_ObjectProbeElevated);
ERR_HQ hq = ERR_HQ.Cast(ERR_GameMode.Get().Command());
foreach (IEntity candidate : m_ObjectProbeCandidates)
{
string name; if (candidate.GetPrefabData()) name = candidate.GetPrefabData().GetPrefabName();
if (!name.Contains("LightTower_01")) continue;
hq.ObjectProbeStart(candidate, m_ObjectProbeCandidates); break;
}
}
}
modded class SCR_ChimeraAIAgent
{
void ObjectProbeRelease() { ERR_PrisonPhaseChanged(ERR_Phase.PRISON, ERR_Phase.RADIO_SEARCH); SetPermanentLOD(0); ActivateAI(); }
}
modded class ERR_ObjectGarrisons
{
protected ref array<vector> m_ProbeObservers = {};
protected ref array<vector> m_ProbeStarts = {};
override protected void Players(out array<vector> positions)
{
if (m_ProbeObservers.IsEmpty()) { super.Players(positions); return; }
positions.Copy(m_ProbeObservers);
}
void ObjectProbeSetup(IEntity first, array<IEntity> nearby)
{
ConfigureCount(8); Remember(first);
foreach (IEntity other : nearby) if (vector.DistanceXZ(first.GetOrigin(), other.GetOrigin()) < 120) Remember(other);
m_ProbeObservers.Insert(first.GetOrigin() + "1200 0 0");
PrintFormat("ERR OBJECT SETUP sites=%1 groups=%2 structures=%3", m_Sites.Count(), m_Towns.Count(), m_Sites[0].Structures.Count());
}
override void ObjectProbeSpawn(float now)
{
foreach (ERR_TownGarrison entry : m_Towns) Attempt(entry, m_ProbeObservers, now);
}
override void ObjectProbeInspect(bool release)
{
int total, fixed, radios, elevated;
foreach (ERR_TownGarrison entry : m_Towns)
{
if (!entry.Admitted) { PrintFormat("ERR OBJECT WAIT id=%1", entry.Id); continue; }
array<AIAgent> agents = {}; entry.Group.GetAgents(agents);
foreach (AIAgent agent : agents)
{
IEntity actor = agent.GetControlledEntity(); if (!actor) continue;
vector point = actor.GetOrigin();
float height = point[1] - GetGame().GetWorld().GetSurfaceY(point[0], point[2]);
int radio = ERR_HQRadio.Capability(actor);
bool alive = ERR_Actors.Alive(actor);
PrintFormat("ERR OBJECT ACTOR id=%1 fixed=%2 alive=%3 radio=%4 height=%5 point=%6", entry.Id, entry.FixedGuard, alive, radio, height, point);
total++; if (entry.FixedGuard) fixed++; if (radio > 0) radios++; if (height > 2) elevated++;
SCR_ChimeraAIAgent soldier = SCR_ChimeraAIAgent.Cast(agent);
if (release && soldier) soldier.ObjectProbeRelease();
}
}
PrintFormat("ERR OBJECT COUNTS total=%1 fixed=%2 radios=%3 elevated=%4 release=%5", total, fixed, radios, elevated, release);
}
}
modded class ERR_TownGarrisons
{
void ObjectProbeStart(IEntity first, array<IEntity> nearby)
{
m_Objects = new ERR_ObjectGarrisons(m_Mode); m_Objects.ObjectProbeSetup(first, nearby);
}
void ObjectProbeSpawn(float now) { if (m_Objects) m_Objects.ObjectProbeSpawn(now); }
void ObjectProbeInspect(bool release) { if (m_Objects) m_Objects.ObjectProbeInspect(release); }
}
modded class ERR_HQ
{
void ObjectProbeStart(IEntity first, array<IEntity> nearby) { m_Towns.ObjectProbeStart(first, nearby); }
void ObjectProbeSpawn(float now) { m_Towns.ObjectProbeSpawn(now); m_Equipment.Tick(now); }
void ObjectProbeInspect(bool release)
{
m_Towns.ObjectProbeInspect(release);
foreach (ERR_HQUnit unit : m_Units)
if (unit.ForceSourceId.StartsWith("object-")) PrintFormat("ERR OBJECT HQ id=%1 fixed=%2 reserved=%3 eligible=%4", unit.ForceSourceId, unit.HomeGuard, unit.ReservedForSupport, unit.Eligible(m_Mode));
}
}
modded class ArmaReforgerScripted
{
protected int m_ObjectProbePhase;
protected float m_ObjectProbeStarted;
protected float m_ObjectProbeNext;
override void OnUpdate(BaseWorld world, float timeslice)
{
super.OnUpdate(world, timeslice);
ERR_GameMode mode = ERR_GameMode.Get();
if (!mode || mode.Phase() < ERR_Phase.PRISON || m_ObjectProbePhase == 3) return;
float now = world.GetWorldTime(); if (now < m_ObjectProbeNext) return; m_ObjectProbeNext = now + 1000;
ERR_HQ hq = ERR_HQ.Cast(mode.Command());
if (m_ObjectProbePhase == 0)
{
ERR_ObjectProbeScanner scanner = new ERR_ObjectProbeScanner(); scanner.Run(world);
m_ObjectProbePhase = 1; m_ObjectProbeStarted = now; return;
}
if (m_ObjectProbePhase == 1)
{
hq.ObjectProbeSpawn(now);
if (now - m_ObjectProbeStarted < 12000) return;
hq.ObjectProbeInspect(true); m_ObjectProbePhase = 2; return;
}
hq.ObjectProbeSpawn(now);
if (now - m_ObjectProbeStarted < 45000) return;
hq.ObjectProbeInspect(false); m_ObjectProbePhase = 3;
Print("ERR OBJECT PROBE COMPLETE: native spawn / HQ role / 30-second post observation");
}
}