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:
2026-09-23 15:07:14 +02:00
parent 04bd19327b
commit 1b1a8b5173
242 changed files with 12153 additions and 875 deletions
+7 -7
View File
@@ -44,7 +44,7 @@ struct SCR_AIGroup {
struct Settings {int oneIn=15;int Get(std::string key){assert(key=="stingerChanceOneIn");return oneIn;}};
struct ERR_GameMode {
static inline ERR_GameMode* current=nullptr;bool active=true;struct Settings values;
static ERR_GameMode* Get(){return current;}bool Active(){return active;}int EnemyFaction(){return 1;}
static ERR_GameMode* Get(){return current;}bool Active(){return active;}int EnemyFaction(){return 1;}bool IsMissionEnemy(int f){return f==1;}
struct Settings* Settings(){return &values;}
};
namespace Math {int draw=0,calls=0;int RandomInt(int lo,int hi){assert(lo==0&&hi>0);calls++;return draw;}}
@@ -70,7 +70,7 @@ struct NativeCombat {
namespace ERR_EnemyGunnerSkill {
bool CapturedGroup(ERR_GameMode*,SCR_AIGroup*){return false;}
bool OriginalGunner(ERR_GameMode*,SCR_AIGroup*,IEntity*){return false;}
EAISkill Profile(EAISkill requested,bool){return requested<EAISkill::EXPERT?EAISkill::EXPERT:requested;}
EAISkill Profile(EAISkill requested,bool){return EAISkill::CYLON;}
}
struct ERR_EnemyOptics{int stops=0;void Stop(){stops++;}};
''' + code + r'''
@@ -121,9 +121,9 @@ int main(){
soldier.combat.ERR_BindEnemySkill(&mode,&soldier.group);assert(soldier.combat.GetAISkill()==EAISkill::REGULAR);
Replication::server=true;SCR_Global::editor=false;mode.active=true;ERR_GameMode::current=&mode;
}
Soldier skill;skill.combat.ERR_BindEnemySkill(&mode,&skill.group);assert(skill.combat.GetAISkill()==EAISkill::EXPERT);
skill.combat.SetAISkill(EAISkill::ROOKIE);assert(skill.combat.GetAISkill()==EAISkill::EXPERT);
skill.combat.ResetAISkill();assert(skill.combat.GetAISkill()==EAISkill::EXPERT);
Soldier skill;skill.combat.ERR_BindEnemySkill(&mode,&skill.group);assert(skill.combat.GetAISkill()==EAISkill::CYLON);
skill.combat.SetAISkill(EAISkill::ROOKIE);assert(skill.combat.GetAISkill()==EAISkill::CYLON);
skill.combat.ResetAISkill();assert(skill.combat.GetAISkill()==EAISkill::CYLON);
skill.combat.SetAISkill(EAISkill::CYLON);assert(skill.combat.GetAISkill()==EAISkill::CYLON);
skill.combat.ERR_BindEnemySkill(&mode,&skill.group);skill.combat.ERR_ReleaseEnemySkill(&mode);assert(skill.combat.GetAISkill()==EAISkill::REGULAR);
skill.combat.SetAISkill(EAISkill::ROOKIE);assert(skill.combat.GetAISkill()==EAISkill::ROOKIE);
@@ -187,7 +187,7 @@ int main(){
service.Stop();service.RegisterGroup(&group);service.Tick(50000);assert(service.m_Groups.Count()==0&&service.m_Stopped);
ERR_EnemyEquipment delayed(&mode);SCR_AIGroup late;delayed.RegisterGroup(&late);delayed.Tick(3000);late.agents.Insert(&agent);delayed.Tick(6000);assert(delayed.m_Entries.Count()==1);
ERR_EnemyEquipment expired(&mode);SCR_AIGroup empty;expired.RegisterGroup(&empty);for(int i=1;i<=6;i++){expired.Tick(i*3000);}empty.agents.Insert(&agent);expired.Tick(21000);assert(expired.m_Entries.Count()==0);
ERR_EnemyEquipment bounded(&mode);for(int i=0;i<140;i++){bounded.RegisterGroup(new SCR_AIGroup());}assert(bounded.m_Groups.Count()==128);
ERR_EnemyEquipment bounded(&mode);for(int i=0;i<270;i++){bounded.RegisterGroup(new SCR_AIGroup());}assert(bounded.m_Groups.Count()==256);
ERR_EnemyEquipment incomplete(&mode);SCR_AIGroup unresolved;IEntity body;AIAgent bodyAgent;bodyAgent.actor=&body;unresolved.agents.Insert(&bodyAgent);incomplete.RegisterGroup(&unresolved);
for(int i=1;i<=12;i++){incomplete.Tick(i*3000);}assert(incomplete.m_Entries.Count()==1&&incomplete.m_Entries[0]->SkillChecks==5);
auto incompleteOptics=incomplete.m_Entries[0]->Optics;int checksBeforeStop=incompleteOptics->checks;
@@ -199,4 +199,4 @@ int main(){
capturedBody.eligible=true;capture.Tick(9000);assert(capturedOptics->checks==1);
}
''')
print('PASS: actual equipment coordinator registration dedupe, startup delay, five member scans, finite component retries, unregister/stop terminal behavior and 128-group bound')
print('PASS: actual equipment coordinator registration dedupe, startup delay, five member scans, finite component retries, unregister/stop terminal behavior and 256-group bound')