42 lines
3.7 KiB
Python
42 lines
3.7 KiB
Python
"""Run production horn limits and the control hook with engine boundaries doubled."""
|
|
from policy_harness import ROOT, body, run
|
|
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_AIDriverHorn.c'
|
|
policy=body(p,'class ERR_AIDriverHornLimit').replace('protected ','').replace('class ERR_AIDriverHornLimit','struct ERR_AIDriverHornLimit')+';'
|
|
hook=body(p,'protected override void OnApplyControls(')
|
|
for a,b in [('protected override ','') ,('IEntity owner','Actor* owner'),('super.OnApplyControls(owner, timeSlice);','nativeCalls++;'),('Replication.IsServer()','authority'),('ERR_Actors.Player(owner)','owner->player'),('ERR_GameMode mode = ERR_GameMode.Get();','Mode* mode = currentMode;'),('IEntity vehicle = CompartmentAccessComponent.GetVehicleIn(owner);','Vehicle* vehicle = owner->vehicle;'),('vehicle.FindComponent(AICarMovementComponent)','vehicle->road'),('BaseVehicleControllerComponent controls = BaseVehicleControllerComponent.Cast(vehicle.FindComponent(BaseVehicleControllerComponent));','Controls* controls = vehicle->controls;'),('controls.GetPilotCompartmentSlot()','controls->seat'),('controls->seat.GetOccupant()','controls->seat->occupant'),('CharacterInputContext input = GetInputContext();','Input* input = inputs;'),('mode.Active()','mode->active'),('input.','input->'),('m_ERRHornLimit.Allow','m_ERRHornLimit->Allow'),('System.GetTickCount()','now')]: hook=hook.replace(a,b)
|
|
run(r'''
|
|
#include <cassert>
|
|
'''+policy+r'''
|
|
struct Input {int horn=1,writes=0;int GetVehicleHorn(){return horn;}void SetVehicleHorn(int v){writes++;horn=v;}};
|
|
struct Actor;struct Seat {Actor* occupant=nullptr;};struct Controls {Seat* seat=nullptr;};
|
|
struct Vehicle {bool road=true;Controls* controls=nullptr;};struct Actor {bool player=false;Vehicle* vehicle=nullptr;};
|
|
struct Mode {bool active=true;};
|
|
struct Controller {bool authority=true;int now=0,nativeCalls=0;Mode mode;Mode* currentMode=&mode;Input input;Input* inputs=&input;ERR_AIDriverHornLimit* m_ERRHornLimit=nullptr;
|
|
~Controller(){delete m_ERRHornLimit;}
|
|
'''+hook+r'''
|
|
};
|
|
int main(){
|
|
ERR_AIDriverHornLimit continuous;int allowed=0;
|
|
for(int t=0;t<90000;t+=10)if(continuous.Allow(true,t))allowed++;
|
|
assert(allowed==150); // three half-second beeps over 90 seconds, even held forever
|
|
ERR_AIDriverHornLimit tapped;
|
|
assert(tapped.Allow(true,0));assert(!tapped.Allow(false,100));
|
|
for(int t=200;t<30000;t+=100)assert(!tapped.Allow(t%200==0,t));
|
|
assert(tapped.Allow(true,30000));assert(!tapped.Allow(true,30500));
|
|
assert(!tapped.Allow(true,100));assert(!tapped.Allow(true,30099));assert(tapped.Allow(true,30100));
|
|
Controller c;Actor driver,passenger;Seat seat{&driver};Controls controls{&seat};Vehicle car{true,&controls};driver.vehicle=&car;passenger.vehicle=&car;
|
|
c.OnApplyControls(&driver,.02f);assert(c.input.horn==1&&c.nativeCalls==1);
|
|
c.now=500;c.OnApplyControls(&driver,.02f);assert(c.input.horn==0);
|
|
c.now=1000;c.input.horn=1;c.OnApplyControls(&driver,.02f);assert(c.input.horn==0);
|
|
// Player control, passengers, aircraft, replicas and unrelated scenarios are untouched.
|
|
driver.player=true;c.input.horn=1;c.OnApplyControls(&driver,.02f);assert(c.input.horn==1);
|
|
driver.player=false;c.OnApplyControls(&passenger,.02f);assert(c.input.horn==1);
|
|
car.road=false;c.OnApplyControls(&driver,.02f);assert(c.input.horn==1);car.road=true;
|
|
c.authority=false;c.OnApplyControls(&driver,.02f);assert(c.input.horn==1);c.authority=true;
|
|
c.currentMode=nullptr;c.OnApplyControls(&driver,.02f);assert(c.input.horn==1);c.currentMode=&c.mode;
|
|
c.mode.active=false;c.OnApplyControls(&driver,.02f);assert(c.input.horn==0);
|
|
c.inputs=nullptr;c.OnApplyControls(&driver,.02f);c.OnApplyControls(nullptr,.02f);
|
|
}
|
|
''')
|
|
print('PASS: held/tapped AI horn limits, half-second pulses, 30-second cooldown, clock reset, player/passenger/aircraft/replica exclusion and ended mission cleanup')
|