// Private encounter: four protected US AI stand-ins for escapees, three real
// production hunter crews. Arrangement is synthetic; sensing/radio/combat are native.
modded class ERR_HunterService
{
 vector m_ERRSceneCenter;
 protected bool m_ERRSceneStarted;
 protected float m_ERRSceneAt, m_ERRSceneLog;
 protected SCR_AIGroup m_ERRSceneEscapers;
 protected SCR_ManualCamera m_ERRSceneCamera;
 protected float m_ERRCapture;
 bool ERR_Scene(float now)
 {
  ERR_HQ hq=ERR_HQ.Cast(m_Mode.Command());
  if(!m_ERRSceneStarted)
  {
   m_ERRSceneStarted=true;m_ERRSceneAt=now;m_NextSpawn=now+1000000;
   vector angles;
   if(!ERR_SupplyConvoySystem.ApproachDirected("9322 0 4823",m_ERRSceneCenter,angles,300)) {Print("ERR SCENE FAIL: target road");return true;}
   m_ERRSceneCenter=ERR_Actors.Ground(m_ERRSceneCenter+"35 0 0");
   m_ERRSceneEscapers=SCR_AIGroup.Cast(ERR_Actors.Spawn("{84E5BBAB25EA23E5}Prefabs/Groups/BLUFOR/Group_US_FireTeam.et",m_ERRSceneCenter));
   if(m_ERRSceneEscapers){m_ERRSceneEscapers.SetPermanentLOD(0);m_ERRSceneEscapers.ActivateAI();AIWaypoint hold=AIWaypoint.Cast(ERR_Actors.Spawn(ERR_Resources.DefendWaypoint(),m_ERRSceneCenter));if(hold)m_ERRSceneEscapers.AddWaypoint(hold);}
   array<vector> starts={}; ERR_ConvoyPlacement placement=new ERR_ConvoyPlacement();
   for(int i=0;i<64 && m_Hunters.Count()<3;i++)
   {
    float bearing=(i*17)*Math.DEG2RAD;
    vector position,heading;
    if(!ERR_SupplyConvoySystem.ApproachDirected(m_ERRSceneCenter+Vector(Math.Sin(bearing)*(400+(i/16)*150),0,Math.Cos(bearing)*(400+(i/16)*150)),position,heading,150))continue;
    if(vector.DistanceXZ(position,m_ERRSceneCenter)<300 || !ERR_SupplyConvoyRules.Separated(position,starts,70) || !placement.Clear(position,heading[0]))continue;
    if(SpawnHunter(hq,now,position,heading,"controlled-scene"))starts.Insert(position);
   }
   PrintFormat("ERR SCENE START: center=%1 uazs=%2",m_ERRSceneCenter,m_Hunters.Count());
  }
  if(m_ERRSceneEscapers)
  {
   array<AIAgent> escaped={};m_ERRSceneEscapers.GetAgents(escaped);
   foreach(AIAgent a:escaped)if(a && a.GetControlledEntity())
   {
    a.SetPermanentLOD(0);a.ActivateAI();
    DamageManagerComponent d=DamageManagerComponent.Cast(a.GetControlledEntity().FindComponent(DamageManagerComponent));if(d)d.EnableDamageHandling(false);
   }
  }
  foreach(ERR_HunterVehicle unit:m_Hunters)
  {
   if(unit.Registered && !unit.DeliveredContact && !unit.Waypoint && !unit.CombatHeld && unit.NextOrder<1000000)
   {
    unit.NextOrder=1000000;
    unit.Waypoint=AIWaypoint.Cast(ERR_Actors.Spawn(ERR_Resources.MoveWaypoint(),m_ERRSceneCenter));
    if(unit.Waypoint){unit.Waypoint.SetCompletionRadius(80);unit.Group.AddWaypoint(unit.Waypoint);}
   }
   foreach(IEntity member:unit.Members)
   {DamageManagerComponent md=DamageManagerComponent.Cast(member.FindComponent(DamageManagerComponent));if(md)md.EnableDamageHandling(false);}
  }
  if(!System.IsConsoleApp())
  {
   if(!m_ERRSceneCamera)m_ERRSceneCamera=SCR_ManualCamera.Cast(ERR_Actors.Spawn("{EB1210AAE1BB8F54}Prefabs/ERR/SpectatorCamera.et",m_ERRSceneCenter+"0 210 -270"));
   if(m_ERRSceneCamera)GetGame().GetCameraManager().SetCamera(m_ERRSceneCamera);
   SCR_RespawnSystemComponent respawn=SCR_RespawnSystemComponent.GetInstance();if(respawn){respawn.ERR_KeepSpawnSceneLoading(false);respawn.DestroyLoadingPlaceholder();}
   if(now>=m_ERRCapture && now-m_ERRSceneAt>15000){m_ERRCapture=now+30000;System.MakeScreenshot("$logs:uaz-scene-"+Math.Floor((now-m_ERRSceneAt)/1000).ToString());}
  }
  if(now>=m_ERRSceneLog)
  {
   m_ERRSceneLog=now+5000; if(!System.IsConsoleApp())PrintFormat("ERR SCENE CAMERA: current=%1 pos=%2",GetGame().GetCameraManager().CurrentCamera(),m_ERRSceneCamera.GetOrigin());
   array<ref ERR_HQReport> contacts={};hq.SupportContacts(contacts,now);
   foreach(ERR_HQReport r:contacts){ERR_HQBelief b=hq.Memory().Get(r.Target);if(b)PrintFormat("ERR SCENE BELIEF: pos=%1 age=%2 actionable=%3",b.PredictedPosition,(now-b.ObservedAt)/1000,b.Actionable());}
   foreach(ERR_HunterVehicle u:m_Hunters)
   {
    vector destination;if(u.Waypoint)destination=u.Waypoint.GetOrigin();
    PrintFormat("ERR SCENE CAR: t=%1 id=%2 pos=%3 order=%4 combat=%5 released=%6",(now-m_ERRSceneAt)/1000,u.Source,u.Entity.GetOrigin(),destination,u.CombatHeld,u.Released);
    ERR_HQMountedAmmoSnapshot ammo=ERR_HQMountedAmmoSampler.Inspect(u.Entity); if(ammo)PrintFormat("ERR SCENE AMMO: t=%1 id=%2 rounds=%3 chambers=%4 complete=%5",(now-m_ERRSceneAt)/1000,u.Source,ammo.Rounds,ammo.Chambers,ammo.Complete);
    PrintFormat("ERR SCENE ELIGIBLE: id=%1 crew=%2 registered=%3",u.Source,u.CrewValid(m_Mode),u.Registered);
    if(u.Group.GetGroupUtilityComponent())u.Group.GetGroupUtilityComponent().ERR_SceneSight();
    int memberIndex;
    foreach(IEntity soldier:u.Members){if(soldier)PrintFormat("ERR SCENE MAN: t=%1 id=%2 man=%3 pos=%4 mounted=%5 alive=%6",(now-m_ERRSceneAt)/1000,u.Source,memberIndex,soldier.GetOrigin(),CompartmentAccessComponent.GetVehicleIn(soldier)!=null,ERR_Actors.CanFight(soldier));memberIndex++;}
   }
  }
  return now-m_ERRSceneAt>330000;
 }
}
modded class ArmaReforgerScripted
{
 protected bool m_ERRSceneDone;
 protected float m_ERRSceneNext;
 override void OnUpdate(BaseWorld world,float timeslice)
 {
  super.OnUpdate(world,timeslice);ERR_GameMode mode=ERR_GameMode.Get();
  if(world && !System.IsConsoleApp())
  {
   vector view[4]; vector aim="9606.07 112.977 4826.07"; vector eye=aim+"0 100 -150";
   vector dir=aim-eye;dir.Normalize();Math3D.DirectionAndUpMatrix(dir,"0 1 0",view);view[3]=eye;
   world.SetCameraEx(0,view);
  }
  if(m_ERRSceneDone || !world || !Replication.IsServer() || !mode || !mode.Active())return;
  float now=world.GetWorldTime();if(now<m_ERRSceneNext)return;m_ERRSceneNext=now+1000;
  if(mode.Phase()==ERR_Phase.PRISON)mode.Transition(ERR_Phase.RADIO_SEARCH);
  ERR_HQ hq=ERR_HQ.Get();if(!hq || !hq.Hunters())return;
  if(hq.Hunters().ERR_Scene(now)){m_ERRSceneDone=true;Print("ERR SCENE COMPLETE");return;}
  hq.Tick(now);
 }
}
modded class SCR_AIGroupUtilityComponent
{
 void ERR_SceneSight()
 {
  foreach(SCR_AIInfoComponent info:m_aInfoComponents)
  {
   if(!info || !info.m_Perception)continue;
   array<BaseTarget> targets={};info.m_Perception.GetTargetsList(targets,ETargetCategory.ENEMY);
   foreach(BaseTarget target:targets)
    if(target)PrintFormat("ERR SCENE SIGHT: owner=%1 age=%2 trace=%3 exposure=%4 target=%5",info.GetOwner(),target.GetTimeSinceSeen(),target.GetTraceFraction(),target.GetExposure(),target.GetTargetEntity());
  }
 }
}
[BaseContainerProps(), SCR_BaseManualCameraComponentTitle()]
modded class ERR_FollowSurvivorCameraComponent
{
 override void EOnCameraFrame(SCR_ManualCameraParam param)
 {
  ERR_HQ hq=ERR_HQ.Get();if(!hq || !hq.Hunters())return;
  vector aim=hq.Hunters().m_ERRSceneCenter;
  vector position=aim+"0 160 -140";
  vector direction=aim-position;direction.Normalize();
  Math3D.DirectionAndUpMatrix(direction,"0 1 0",param.transform);
  param.transform[3]=position;param.isDirty=true;
 }
}
