modded class ERR_BodyRecovery
{
 bool ERR_TestBorrow(vector position, SCR_AIGroup expected, float now)
 {
  int waves = m_Waves;
  ERR_BodyRecoveryJob job = new ERR_BodyRecoveryJob(); job.Id = 999; job.Position = position;
  bool result = SpawnTeam(job, now);
  return result && job.Team == expected && job.Prepared && job.State == 1 && m_Waves == waves;
 }
}
modded class ERR_EngineerMine
{
 protected bool m_ERRCleared;
 protected bool ERR_MoveTestFriend(IEntity entity)
 {
  ChimeraCharacter character=ChimeraCharacter.Cast(entity);
  if(!character || entity==m_Actor || ERR_Actors.Player(entity))return true;
  vector transform[4];character.GetWorldTransform(transform);transform[3]=ERR_Actors.Ground(m_Rally+Vector(0,0,100));character.Teleport(transform);
  return true;
 }
 void ERR_ClearTestFriends()
 {
  if(m_State!=3 || m_ERRCleared)return;
  m_ERRCleared=true;
  GetGame().GetWorld().QueryEntitiesBySphere(m_Position,25,ERR_MoveTestFriend,queryFlags:EQueryEntitiesFlags.ALL);
 }
 bool ERR_TestArmed() { return m_Trigger && m_Trigger.IsActivated(); }
 string ERR_TestProgress() { return string.Format("stage=%1 stopped=%2 owned=%3 quiet=%4 actor=%5 mine=%6 site=%7",m_State,m_Stopped,Owned(),Quiet(),m_Actor.GetOrigin(),m_Mine.GetOrigin(),m_Position)+string.Format(" placed=%1 friendNear=%2",Placed(),m_FriendlyNear); }
}
modded class ERR_HQ
{
 bool ERR_TestRecovery(float now)
 {
  IndexRadios();
  foreach (ERR_HQUnit unit : m_Units)
  {
   if (!unit.Eligible(m_Mode) || !unit.StatusSampler.Bound() || !unit.Radio || unit.Assignment || unit.PendingOrder || unit.Downlink || Fighting(unit)) continue;
   if (!m_Network.Route(unit.Radio, true)) continue;
   ERR_HQStatusReport status = new ERR_HQStatusReport(); status.SourceId = unit.ForceSourceId;status.MessageId=m_Journal.Message();status.Position=unit.Group.GetOrigin();status.Strength=unit.StatusSampler.InitialStrength();status.Count=m_Mode.ForceLiving(unit.Group);status.Fit=status.Count;status.ObservedAt=now;
   if (!m_Watch.Ingest(status,now)) continue;
   bool guard=unit.HomeGuard;unit.HomeGuard=false;
   bool result=m_Recovery.ERR_TestBorrow(status.Position,unit.Group,now);
   unit.ReservedForSupport=false;unit.HomeGuard=guard;
   return result;
  }
  return false;
 }
 ERR_EngineerMine ERR_TestMine(float now)
 {
  m_Equipment.Tick(now); m_Journal.Flush();
  foreach (ERR_HQUnit original : m_Units)
  {
   if (original.ForceSourceId.Contains("prison")) continue;
   if (!original.Eligible(m_Mode) || !original.StatusSampler.Bound() || Fighting(original)) continue;
   vector rally=original.Group.GetOrigin();
   bool carried;
   array<AIAgent> agents={};original.Group.GetAgents(agents);
   foreach (AIAgent agent:agents)
   {
    IEntity actor=agent.GetControlledEntity(); if(!actor) continue;
    SCR_InventoryStorageManagerComponent inventory=SCR_InventoryStorageManagerComponent.Cast(actor.FindComponent(SCR_InventoryStorageManagerComponent));
    if(!inventory) continue;
    array<IEntity> items={};ERR_Inventory.Items(inventory,items);
    foreach(IEntity item:items) if(item && item.GetPrefabData() && item.GetPrefabData().GetPrefabName()==ERR_EnemyLoadoutCatalog.MINE) carried=true;
   }
   if(!carried) continue;
   vector site;
   if(!ERR_EngineerMineSite.Select(rally,site))
   {
    bool clear;
    for(int direction=0;direction<8;direction++)
    {
     float angle=direction*Math.PI2/8;
     site=ERR_Actors.Ground(rally+Vector(Math.Cos(angle)*35,0,Math.Sin(angle)*35));
     if(!ERR_HQRoadIntercept.Standable(site))continue;
     bool nearFriend;
     foreach(AIAgent neighbour:agents) if(neighbour.GetControlledEntity() && vector.DistanceXZ(neighbour.GetControlledEntity().GetOrigin(),site)<25)nearFriend=true;
     if(nearFriend)continue;
     clear=true;break;
    }
    if(!clear)continue;
   }
   if (!m_ERRFixtureRoadGroups.Contains(original.Group))
   {
    AIWaypoint post = AIWaypoint.Cast(ERR_Actors.Spawn(ERR_Resources.DefendWaypoint(),rally));
    if(!post)continue;
    post.SetCompletionRadius(70); original.Group.AddWaypointAt(post,0);
    m_ERRFixtureRoadGroups.Insert(original.Group);
    original.Group.SetPermanentLOD(0);
    foreach(AIAgent heldBefore:agents){heldBefore.SetPermanentLOD(0);heldBefore.ActivateAI();}
    continue;
   }
   ERR_HQUnit unit=new ERR_HQUnit();unit.Group=original.Group;unit.Utility=original.Utility;unit.StatusSampler=original.StatusSampler;unit.ForceSourceId=original.ForceSourceId;
   unit.Task=new ERR_HQTask();unit.Task.RoadIntercept=true;unit.Task.Role=ERR_HQPursuitRole.INTERCEPT;unit.Task.Destination=rally;unit.Task.QueuedAt=now;unit.Task.ExpiresAt=now+180000;
   unit.Assignment=new ERR_HQReport();unit.Assignment.MessageId=777;unit.Assignment.ObservedAt=now;unit.Assignment.Position=rally;
   array<IEntity> attempted={};ERR_EngineerMine mine=new ERR_EngineerMine(attempted);
   if(!mine.Begin(m_Mode,unit,unit.Task,site,now)) continue;
   // Keep this arranged unit alive; production owns the actual movement/item.
   m_ERRFixtureUnit=unit; m_ERRFixtureAttempts=attempted;
   original.ReservedForSupport=true;
   original.Group.SetPermanentLOD(0);
   foreach(AIAgent held:agents) {held.SetPermanentLOD(0);held.ActivateAI();}
   return mine;
  }
  return null;
 }
 protected ref array<SCR_AIGroup> m_ERRFixtureRoadGroups = {};
 protected ref ERR_HQUnit m_ERRFixtureUnit;
 protected ref array<IEntity> m_ERRFixtureAttempts;
}
modded class ArmaReforgerScripted
{
 protected float m_ERRFixStart=-1,m_ERRFixNext;
 protected bool m_ERRFixBorrowed,m_ERRFixDone;
 protected ref ERR_EngineerMine m_ERRFixMine;
 override void OnUpdate(BaseWorld world,float timeslice)
 {
  super.OnUpdate(world,timeslice);
  ERR_GameMode mode=ERR_GameMode.Get();
  if(m_ERRFixDone || !world || !Replication.IsServer() || !mode || !mode.Active())return;
  float now=world.GetWorldTime();
  if(m_ERRFixStart<0) m_ERRFixStart=now;
  if(!m_ERRFixBorrowed && now-m_ERRFixStart>10000)
  {
   m_ERRFixBorrowed=ERR_HQ.Get().ERR_TestRecovery(now);
   if(m_ERRFixBorrowed)Print("ERR FIX PASS: existing native idle infantry selected for body search without new spawn");
  }
  if(!m_ERRFixMine && m_ERRFixBorrowed)m_ERRFixMine=ERR_HQ.Get().ERR_TestMine(now);
  if(m_ERRFixMine)
  {
   m_ERRFixMine.ERR_ClearTestFriends();
   m_ERRFixMine.Tick(now); ERR_HQ.Get().Journal().Flush();
   if(now>=m_ERRFixNext){m_ERRFixNext=now+10000;Print("ERR FIX MINE: "+m_ERRFixMine.ERR_TestProgress());}
   if(m_ERRFixMine.Finished())
   {
    if(m_ERRFixMine.ERR_TestArmed())Print("ERR FIX PASS: native soldier walked, removed carried mine, withdrew and armed it");
    else Print("ERR FIX FAIL: physical mine job stopped before arming",LogLevel.ERROR);
    m_ERRFixDone=true;Print("ERR FIX COMPLETE");
   }
  }
  if(now-m_ERRFixStart>210000){Print("ERR FIX FAIL: fixture deadline",LogLevel.ERROR);m_ERRFixDone=true;Print("ERR FIX COMPLETE");}
 }
}
