Files
EscapistsReintroduced/tests/test_mortar_station.py
T
jakub 1b1a8b5173 Add mission customization, HQ support and aggression-driven AI
Integrate faction and random settings menus, generated objectives, scouts, convoys, air support, mortar stations and body-intel recovery. Add identified-body aggression, finite hunter UAZ deployment, dedicated objective defence and maximum AI skill with separate reduced aim accuracy. Include policy tests, native probes, evidence and documentation.
2026-09-23 15:07:14 +02:00

36 lines
2.3 KiB
Python

"""Run actual station scope predicates; native boarding/movement is tested separately."""
from policy_harness import ROOT, body, run
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_MortarStation.c'
s='\n'.join(body(p,name) for name in ('bool Holds(', 'bool HoldsSeat(', 'bool HoldsPosition('))
s=(s.replace('IEntity actor','IEntity* actor').replace('IEntity vehicle','IEntity* vehicle')
.replace('m_Battery.', 'm_Battery->').replace('Replication.', 'Replication::')
.replace('ERR_HQ.', 'ERR_HQ::').replace('ERR_Actors.', 'ERR_Actors::')
.replace('CompartmentAccessComponent.', 'CompartmentAccessComponent::'))
run(r'''
#include <cassert>
struct IEntity {bool player=false, fighting=true; int group=1; IEntity* vehicle=nullptr;};
struct Battery {int Group=1; IEntity* Gun=nullptr;};
namespace Replication {bool server=true;bool IsServer(){return server;}}
namespace ERR_HQ {bool active=true;bool MissionActive(){return active;}}
namespace ERR_Actors {bool Player(IEntity* a){return a->player;}int Group(IEntity* a){return a->group;}bool CanFight(IEntity* a){return a&&a->fighting;}}
namespace CompartmentAccessComponent {IEntity* GetVehicleIn(IEntity* a){return a->vehicle;}}
struct Station {Battery* m_Battery;IEntity* m_Gunner=nullptr;bool m_Stopped=false,intact=true;bool GunIntact(){return intact;}
''' + s + r'''
};
int main(){
IEntity gun,other,actor;Battery b;b.Gun=&gun;Station s{&b};actor.vehicle=&gun;
assert(s.Holds(&actor)&&s.HoldsPosition(&actor)&&s.HoldsSeat(&actor,&gun));
assert(!s.HoldsSeat(&actor,&other));actor.vehicle=nullptr;assert(!s.HoldsSeat(&actor,&gun));
s.m_Gunner=&actor;assert(s.Holds(&actor)&&!s.HoldsPosition(&actor)); // gunner may walk to board
s.m_Gunner=nullptr;actor.fighting=false;assert(!s.HoldsPosition(&actor));actor.fighting=true;
actor.player=true;assert(!s.Holds(&actor));actor.player=false;
actor.group=2;assert(!s.Holds(&actor));actor.group=1;
s.intact=false;assert(!s.Holds(&actor)&&!s.HoldsPosition(&actor));s.intact=true;
s.m_Stopped=true;assert(!s.Holds(&actor));s.m_Stopped=false;
Replication::server=false;assert(!s.Holds(&actor));Replication::server=true;
ERR_HQ::active=false;assert(!s.Holds(&actor));ERR_HQ::active=true;
assert(!s.Holds(nullptr));
}
''')
print('PASS: mortar duty scope excludes players, other crews, stopped/client/inactive states; only destruction releases an active assignment, while the gunner may approach the gun')