// Private fixture forces the observed opening-plan failure; production owns all
// fallback placement, real vehicle/crew spawning, registration and routing.
modded class ERR_HunterOpeningPlan
{
 override void Step(array<IEntity> players)
 {
  if (m_Done) return;
  m_Scanned = 64; m_Done = true;
  Print("ERR HUNT FIXTURE: opening exhausted with no three-way layout");
 }
}
modded class ERR_HunterService
{
 protected ref array<vector> m_ERRStarts = {};
 bool ERR_CheckPhysicalHunters()
 {
  if (m_Hunters.Count() != 3) return false;
  int ready; bool moved;
  foreach (ERR_HunterVehicle unit : m_Hunters)
  {
   if (!unit.Registered || unit.Released || !unit.CrewValid(m_Mode) || VehicleRadioCapability(unit.Driver) != 2) return false;
   ready++;
  }
  if (m_ERRStarts.IsEmpty())
  {
   foreach (ERR_HunterVehicle first : m_Hunters) m_ERRStarts.Insert(first.Entity.GetOrigin());
   Print("ERR HUNT PASS: three independent fallback UAZs physically spawned, crewed, registered and radio-equipped on Nogova");
  }
  for (int i=0; i<m_Hunters.Count(); i++)
  {
   ERR_HunterVehicle hunter=m_Hunters[i];
   float distance=vector.DistanceXZ(m_ERRStarts[i],hunter.Entity.GetOrigin());
   if(distance>25 && hunter.Waypoint)
   {
    PrintFormat("ERR HUNT PASS: fallback patrol drives natively; hunter=%1 distance=%2 waypoint=%3",i,distance,hunter.Waypoint.GetOrigin());
    return true;
   }
  }
  return false;
 }
}
modded class ArmaReforgerScripted
{
 protected float m_ERRHuntStart=-1, m_ERRHuntNext;
 protected bool m_ERRHuntDone, m_ERRHunterPassed, m_ERRFlankPassed, m_ERRContact;
 protected ERR_SupplyConvoyTask m_ERRConvoy;
 override void OnUpdate(BaseWorld world,float timeslice)
 {
  super.OnUpdate(world,timeslice);
  ERR_GameMode mode=ERR_GameMode.Get();
  if(m_ERRHuntDone || !world || !Replication.IsServer() || !mode || !mode.Active())return;
  float now=world.GetWorldTime();
  if(m_ERRHuntStart<0) {m_ERRHuntStart=now;mode.Transition(ERR_Phase.RADIO_SEARCH);}
  if(now<m_ERRHuntNext)return;m_ERRHuntNext=now+1000;
  ERR_HQ hq=ERR_HQ.Get();if(!hq || !hq.Hunters())return;
  // Playerless fixture: normal mission deliberately skips tactical Tick without players.
  hq.Tick(now);
  if(!m_ERRHunterPassed && hq.Hunters().ERR_CheckPhysicalHunters()) m_ERRHunterPassed=true;
  if(!m_ERRConvoy && hq.Convoys().Count()>0) m_ERRConvoy=ERR_SupplyConvoyTask.Cast(hq.Convoys().At(0));
  if(m_ERRConvoy && m_ERRConvoy.Tactics && !m_ERRContact)
  {
   m_ERRContact=true;
   vector contact=m_ERRConvoy.Vehicles[2].Entity.GetOrigin()+"0 0 200";
   m_ERRConvoy.Tactics.Report(contact,now,now);
   Print("ERR HUNT FIXTURE: one synthetic convoy contact; no claim of organic perception");
  }
  if(m_ERRContact && !m_ERRFlankPassed)
  {
   bool ready=true;
   foreach(ERR_SupplyTeam team:m_ERRConvoy.Teams)
    if(!team.SearchPlanned || !team.Aboard(m_ERRConvoy.Vehicles[2].Entity,false) || team.Released)ready=false;
   if(ready){m_ERRFlankPassed=true;Print("ERR HUNT PASS: both real convoy infantry teams dismounted with native flank/search orders");}
  }
  if(m_ERRHunterPassed && m_ERRFlankPassed){m_ERRHuntDone=true;Print("ERR HUNT COMPLETE");}
  if(now-m_ERRHuntStart>210000) {m_ERRHuntDone=true;Print("ERR HUNT FAIL: fixture deadline",LogLevel.ERROR);Print("ERR HUNT COMPLETE");}
 }
}
