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.
This commit is contained in:
@@ -128,3 +128,48 @@ int main(){int faction,group,foreign;Usage usage;Actor gun{&faction,&group};gun.
|
||||
}
|
||||
''')
|
||||
print('PASS: actual native-gun ownership gate rejects player/foreign/replaced/dead occupant, faction change, missing seat and missing registry')
|
||||
|
||||
# Exercise the production between-trip target selector with four batteries.
|
||||
select = body(p, 'protected void SelectBattery(')
|
||||
select = select.replace('protected ', '').replace('ERR_MortarLogisticsRules.', 'Rules::').replace('vector.DistanceXZ', 'Distance')
|
||||
select = select.replace('array<ref ERR_MortarBattery> batteries = {};', 'Array<Battery*> batteries;').replace('ERR_MortarBattery selected;', 'Battery* selected=nullptr;')
|
||||
select = select.replace('foreach (ERR_MortarBattery candidate : batteries)', 'for (Battery* candidate : batteries)').replace('float.MAX', '999999')
|
||||
select = select.replace('m_HQ.Mortars().Batteries(batteries)', 'system.Batteries(batteries)')
|
||||
for name in ('m_Battery', 'candidate', 'selected', 'm_Cache'):
|
||||
select = select.replace(name+'.', name+'->')
|
||||
run(r'''
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
using std::abs;
|
||||
struct Battery { bool StartupActivated=true, stopped=false, operational=true; int shells=0, Gun=1, Group=1; float Position=0;
|
||||
bool Stopped(){return stopped;} bool Operational(){return operational;} int CountShells(){return shells;} };
|
||||
template<class T> struct Array:std::vector<T>{using std::vector<T>::operator=;void Clear(){this->clear();}};
|
||||
struct System {Array<Battery*> all; void Batteries(Array<Battery*>& out){out=all;}};
|
||||
struct Cache {float GetOrigin(){return 0;}};
|
||||
float Distance(float a,float b){return abs(a-b);}
|
||||
namespace Rules {bool Need(int n){return n>=0&&n<=6;}}
|
||||
struct Courier {int m_State=1;bool m_Report=false,m_Move=false,m_Order=false; Battery* m_Battery=nullptr;
|
||||
int m_OriginalGun=0,m_OriginalBatteryGroup=0;Array<int> m_BatteryMembers;float m_NextReport=99;
|
||||
Cache cache;Cache* m_Cache=&cache;System system;
|
||||
bool TargetAvailable(){return m_Battery&&m_Battery->StartupActivated&&!m_Battery->Stopped()&&m_Battery->Operational();}
|
||||
''' + select + r'''
|
||||
};
|
||||
int main(){
|
||||
Battery a,b,c,d;a.Position=200;b.Position=100;c.Position=300;d.Position=400;
|
||||
Courier s;s.system.all={&a,&b,&c,&d};s.SelectBattery();assert(s.m_Battery==&b);
|
||||
// Keep an active low-ammo recipient; a new nearer request cannot retarget it.
|
||||
a.Position=1;s.SelectBattery();assert(s.m_Battery==&b);
|
||||
// Once replenished, choose another depleted battery and reset only binding.
|
||||
b.shells=12;s.m_BatteryMembers={9};s.SelectBattery();assert(s.m_Battery==&a&&s.m_BatteryMembers.empty()&&s.m_NextReport==0);
|
||||
a.operational=false;s.SelectBattery();assert(s.m_Battery==&c);
|
||||
c.stopped=true;d.StartupActivated=false;s.SelectBattery();assert(s.m_Battery==&c);
|
||||
d.StartupActivated=true;
|
||||
for(int gate=0;gate<4;gate++){
|
||||
s.m_State=gate==0?3:1;s.m_Report=gate==1;s.m_Move=gate==2;s.m_Order=gate==3;
|
||||
s.SelectBattery();assert(s.m_Battery==&c);
|
||||
}
|
||||
s.m_Order=false;s.SelectBattery();assert(s.m_Battery==&d);
|
||||
}
|
||||
''')
|
||||
print('PASS: four-battery courier selection preserves pending trip/report/transfer identity, skips unavailable crews, and selects the next depleted battery without new stock')
|
||||
|
||||
Reference in New Issue
Block a user