Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
61 lines
3.4 KiB
Plaintext
61 lines
3.4 KiB
Plaintext
// Private observer fixture; all traffic placement, driving and retirement are production.
|
|
modded class ERR_CivilianTraffic
|
|
{
|
|
protected IEntity m_ERRObserver;
|
|
protected bool m_ERRLeave, m_ERRReady, m_ERRMoved;
|
|
protected float m_ERRStarted=-1, m_ERRNext, m_ERRLog;
|
|
protected override bool Observers(array<vector> positions, array<IEntity> actors)
|
|
{
|
|
positions.Clear();actors.Clear();if(m_ERRLeave)return true;
|
|
if(!m_ERRObserver)m_ERRObserver=ERR_Actors.Spawn(DriverPrefab(),ERR_Actors.Ground("9322.19 0 4823.22"));
|
|
if(!m_ERRObserver)return false;
|
|
positions.Insert(m_ERRObserver.GetOrigin());actors.Insert(m_ERRObserver);return true;
|
|
}
|
|
bool ERR_Probe(float now)
|
|
{
|
|
if(m_ERRStarted<0)m_ERRStarted=now;
|
|
if(now<m_ERRNext)return false;m_ERRNext=now+1000;
|
|
if(now>=m_ERRLog){m_ERRLog=now+30000;PrintFormat("ERR TRAFFIC PROGRESS: cars=%1 spawned=%2",m_Cars.Count(),m_Serial);}
|
|
foreach(ERR_CivilianCar traffic:m_Cars)
|
|
{
|
|
if(!traffic.Ready || traffic.Released || !traffic.Car || !traffic.Driver)continue;
|
|
if(traffic.Group.GetFaction().GetFactionKey()!="CIV" || traffic.Seat.GetOccupant()!=traffic.Driver)continue;
|
|
if(m_Mode.EnemyFaction().IsFactionEnemy(traffic.Group.GetFaction()) || traffic.Group.GetFaction().IsFactionEnemy(m_Mode.EnemyFaction())){Print("ERR TRAFFIC FAIL: hostile civilian relation",LogLevel.ERROR);return true;}
|
|
BaseWeaponManagerComponent inventory=BaseWeaponManagerComponent.Cast(traffic.Driver.FindComponent(BaseWeaponManagerComponent));
|
|
array<IEntity> weapons={};if(inventory)inventory.GetWeaponsList(weapons);
|
|
if(!inventory || !weapons.IsEmpty()){Print("ERR TRAFFIC FAIL: unarmed driver check",LogLevel.ERROR);return true;}
|
|
if(!m_ERRReady)
|
|
{
|
|
if(vector.DistanceXZ(traffic.Route[0],m_ERRObserver.GetOrigin())<1000){Print("ERR TRAFFIC FAIL: close spawn",LogLevel.ERROR);return true;}
|
|
SCR_GarbageSystem garbage=SCR_GarbageSystem.GetByEntityWorld(traffic.Car);
|
|
if(!garbage || garbage.Insert(traffic.Car,1) || garbage.Insert(traffic.Driver,1)){Print("ERR TRAFFIC FAIL: managed entities not protected from native garbage",LogLevel.ERROR);return true;}
|
|
Print("ERR TRAFFIC PASS: native garbage collector refuses managed car and driver");
|
|
m_ERRReady=true;Print("ERR TRAFFIC PASS: native civilian car/driver, neutral and unarmed; hidden start beyond 1 km");
|
|
}
|
|
if(!m_ERRMoved && vector.DistanceXZ(traffic.Route[0],traffic.Car.GetOrigin())>25)
|
|
{
|
|
m_ERRMoved=true;m_ERRLeave=true;
|
|
Print("ERR TRAFFIC PASS: civilian drives more than 25 m natively along fixed road route");
|
|
Print("ERR TRAFFIC FIXTURE: observer leaves; wait for production cleanup grace");
|
|
}
|
|
}
|
|
if(m_ERRMoved && m_Cars.IsEmpty())
|
|
{
|
|
Stop();Print("ERR TRAFFIC PASS: all unclaimed traffic retired after observer departure and production grace");return true;
|
|
}
|
|
if(now-m_ERRStarted>240000){PrintFormat("ERR TRAFFIC FAIL: deadline cars=%1 spawned=%2",m_Cars.Count(),m_Serial);return true;}
|
|
return false;
|
|
}
|
|
}
|
|
modded class ArmaReforgerScripted
|
|
{
|
|
protected bool m_ERRTrafficDone;
|
|
override void OnUpdate(BaseWorld world,float timeslice)
|
|
{
|
|
super.OnUpdate(world,timeslice);ERR_GameMode mode=ERR_GameMode.Get();
|
|
if(m_ERRTrafficDone || !world || !Replication.IsServer() || !mode || !mode.Active())return;
|
|
if(mode.Phase()==ERR_Phase.PRISON)mode.Transition(ERR_Phase.RADIO_SEARCH);
|
|
if(mode.CivilianTraffic() && mode.CivilianTraffic().ERR_Probe(world.GetWorldTime())){m_ERRTrafficDone=true;Print("ERR TRAFFIC COMPLETE");}
|
|
}
|
|
}
|