Add anger-scaled Sarka hunter waves every ten minutes

This commit is contained in:
2026-10-16 16:36:38 +02:00
parent ae9aaafaae
commit a66aca35bf
14 changed files with 332 additions and 20 deletions
+14 -2
View File
@@ -2,6 +2,7 @@
import re
from policy_harness import ROOT,body,run
p=ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HunterService.c'
sarka_rules=body(p.parent/'ERR_HunterSarkaRules.c','static bool Seats(')
bike_rules=body(p.parent/'ERR_OptionalMotorbikes.c','static bool Seats(')
rules=body(p,'static bool Transport(')+body(p,'static bool Seats(')
s=body(p,'override protected bool FillCrew(').replace('override protected ','')
@@ -13,7 +14,7 @@ for typ in ['ERR_ConvoyVehicle','ERR_HunterVehicle','BaseCompartmentSlot','AIGro
for obj in ['unit','seat','hunter','m_Mode']:
s=s.replace(obj+'.',obj+'->')
s=s.replace('unit->Seats[i].','unit->Seats[i]->')
for cls in ['ERR_EnemyMedicalCatalog','ERR_EnemyLoadoutCatalog','ERR_ConvoyRules','ERR_HunterFleetRules','ERR_MotorbikeRules','ERR_ConvoyResources','ERR_HQ','ECompartmentType','string']:
for cls in ['ERR_EnemyMedicalCatalog','ERR_EnemyLoadoutCatalog','ERR_ConvoyRules','ERR_HunterFleetRules','ERR_MotorbikeRules','ERR_SarkaRules','ERR_ConvoyResources','ERR_HQ','ECompartmentType','string']:
s=s.replace(cls+'.',cls+'::')
run(r'''
#include <cassert>
@@ -25,6 +26,9 @@ template<class T>struct Array:std::vector<T>{using std::vector<T>::operator=;voi
struct ERR_HunterFleetRules{
'''+rules+r'''
};
struct ERR_SarkaRules{
'''+sarka_rules+r'''
};
struct ERR_MotorbikeRules{
'''+bike_rules+r'''
};
@@ -33,7 +37,7 @@ struct IEntity{int prefab;};struct AIGroup{};
struct BaseCompartmentSlot{int type;bool available=true,fail=false;IEntity*occupant=nullptr;bool IsCompartmentAccessible(){return available;}IEntity*GetOccupant(){return occupant;}int GetType(){return type;}
IEntity*SpawnCharacterInCompartment(int prefab,AIGroup*&,int){if(fail)return nullptr;occupant=new IEntity{prefab};return occupant;}};
struct Vehicle{Array<BaseCompartmentSlot*> seats;};
struct ERR_ConvoyVehicle{Vehicle*Entity;AIGroup*Group;bool TroopTransport=false;bool Motorbike=false;Array<BaseCompartmentSlot*>Seats;Array<IEntity*>Members;IEntity*Driver=nullptr;};using ERR_HunterVehicle=ERR_ConvoyVehicle;
struct ERR_ConvoyVehicle{Vehicle*Entity;AIGroup*Group;bool TroopTransport=false;bool Motorbike=false;bool Sarka=false;Array<BaseCompartmentSlot*>Seats;Array<IEntity*>Members;IEntity*Driver=nullptr;};using ERR_HunterVehicle=ERR_ConvoyVehicle;
struct Mode{int owned=0;void Own(IEntity*){owned++;}};
namespace ERR_EnemyMedicalCatalog{int Crew(Mode*,bool medic){return medic?2:1;}}
namespace ERR_EnemyLoadoutCatalog{bool Available(int p){return p>0;}}
@@ -58,6 +62,14 @@ int main(){
BaseCompartmentSlot driver{ECompartmentType::PILOT},passenger{ECompartmentType::CARGO};vehicle.seats={};vehicle.seats.Insert(&driver);vehicle.seats.Insert(&passenger);
assert(service.FillCrew(&bike)&&bike.Members.Count()==2&&bike.Driver==driver.occupant);
assert(driver.occupant->prefab==1&&passenger.occupant->prefab==2);}
for(int passengers=2;passengers<=4;passengers++){
Mode mode;Service service{&mode};Vehicle vehicle;AIGroup group;ERR_HunterVehicle car{&vehicle,&group};car.Sarka=true;car.TroopTransport=true;
BaseCompartmentSlot driver{ECompartmentType::PILOT},cargo[4];vehicle.seats.Insert(&driver);
for(int i=0;i<passengers;i++){cargo[i].type=ECompartmentType::CARGO;vehicle.seats.Insert(&cargo[i]);}
assert(service.FillCrew(&car)==(passengers==3));
if(passengers==3){assert(car.Members.Count()==4&&car.Driver==driver.occupant);int medics=0;for(auto member:car.Members)if(member->prefab==2)medics++;assert(medics==1);}
else assert(mode.owned==0);
}
assert(!ERR_HunterFleetRules::Seats(true,1,0,13,14)); // no silent population shrink
assert(!ERR_HunterFleetRules::Seats(false,1,0,14,15)); // transport cannot pass as armed UAZ
assert(!ERR_HunterFleetRules::Seats(true,2,0,14,16));