Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
--- a/addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c
|
||||
@@ -4,6 +4,10 @@
|
||||
modded class SCR_ChimeraAIAgent
|
||||
{
|
||||
protected ERR_GameMode m_ERRPrisonMode;
|
||||
+#ifdef WORKBENCH
|
||||
+ // Observe only this mission hold; native distance LOD may independently deactivate AI.
|
||||
+ bool ERR_PrisonHeldForTest() { return m_ERRPrisonMode != null; }
|
||||
+#endif
|
||||
|
||||
void ERR_HoldForPrison()
|
||||
{
|
||||
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
||||
@@ -541,6 +541,29 @@
|
||||
PrintFormat("ERR PRISON AI: checked=%1 active=%2", checked, active);
|
||||
return checked > 0;
|
||||
}
|
||||
+ protected bool ERR_CrashPrisonHoldReleased()
|
||||
+ {
|
||||
+ if (!Forces() || Forces().Count() > 256) return false;
|
||||
+ int checked, held, active, dormant;
|
||||
+ for (int i = 0; i < Forces().Count(); i++)
|
||||
+ {
|
||||
+ ERR_ForceRecord record = Forces().At(i);
|
||||
+ if (!record || !record.Group) continue;
|
||||
+ array<AIAgent> agents = {};
|
||||
+ record.Group.GetAgents(agents);
|
||||
+ if (agents.Count() > 128) return false;
|
||||
+ foreach (AIAgent original : agents)
|
||||
+ {
|
||||
+ SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(original);
|
||||
+ if (!agent || !agent.GetControlledEntity()) return false;
|
||||
+ checked++;
|
||||
+ if (agent.ERR_PrisonHeldForTest()) held++;
|
||||
+ if (agent.IsAIActivated()) active++; else dormant++;
|
||||
+ }
|
||||
+ }
|
||||
+ PrintFormat("ERR CRASH PRISON HOLD: checked=%1 held=%2 active=%3 dormant=%4; native activation is independent", checked, held, active, dormant);
|
||||
+ return checked > 0 && held == 0;
|
||||
+ }
|
||||
protected void ERR_EndScreenshot() { System.MakeScreenshot("$logs:err-result"); }
|
||||
protected void ERR_BeginProtectedDeathProbe(float now)
|
||||
{
|
||||
@@ -906,7 +929,7 @@
|
||||
}
|
||||
if (m_ERRTestCrashStart)
|
||||
{
|
||||
- if (!ERR_Check(!m_ERRCrashEnteredPrison && ERR_PrisonAIState(true), "crash start never enters prison and existing enemies are active")) return;
|
||||
+ if (!ERR_Check(!m_ERRCrashEnteredPrison && ERR_CrashPrisonHoldReleased(), "crash start never enters prison and existing enemies have no prison hold")) return;
|
||||
if (!ERR_NativeCrashStartProbe.Run(this, m_ERRSmokePlayer)) { m_ERRSmokeDone = true; GetGame().GetCallqueue().Remove(ERR_SmokeTick); return; }
|
||||
}
|
||||
else
|
||||
--- a/tests/test_prison_ai.py
|
||||
+++ b/tests/test_prison_ai.py
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Run the production prison hold/release callbacks with engine boundaries stubbed."""
|
||||
from policy_harness import ROOT, body, run
|
||||
-source = ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c'
|
||||
+from pathlib import Path
|
||||
+import os
|
||||
+source = Path(os.environ.get('ERR_PRISON_AI_SOURCE', ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_PrisonAI.c'))
|
||||
def cpp(signature):
|
||||
s=body(source,signature).replace('protected ','')
|
||||
for ns in ('Replication','SCR_Global','ERR_GameMode','ERR_Phase','ERR_Actors','SCR_FactionManager'):
|
||||
@@ -32,16 +34,17 @@
|
||||
struct Agent {ERR_GameMode* m_ERRPrisonMode=nullptr;Actor* actor=nullptr;bool pending=false,active=true;int starts=0;
|
||||
Actor* GetControlledEntity(){return actor;}bool IsPlayerPending_S(){return pending;}
|
||||
void DeactivateAI(){active=false;}void ActivateAI(){active=true;starts++;}
|
||||
-'''+cpp('void ERR_HoldForPrison(')+cpp('protected void ERR_PrisonUnsubscribe(')+cpp('protected void ERR_PrisonPhaseChanged(')+cpp('protected void ERR_PrisonStopped(')+r'''
|
||||
+'''+cpp('bool ERR_PrisonHeldForTest(')+cpp('void ERR_HoldForPrison(')+cpp('protected void ERR_PrisonUnsubscribe(')+cpp('protected void ERR_PrisonPhaseChanged(')+cpp('protected void ERR_PrisonStopped(')+r'''
|
||||
};
|
||||
int main(){
|
||||
for(int phase=0;phase<=1;phase++){
|
||||
ERR_GameMode mode;mode.phase=phase;ERR_GameMode::current=&mode;Actor actor;Agent a;a.actor=&actor;
|
||||
- a.ERR_HoldForPrison();assert(!a.active&&mode.phases.callbacks.size()==1&&mode.stops.callbacks.size()==1);
|
||||
+ a.ERR_HoldForPrison();assert(a.ERR_PrisonHeldForTest());assert(!a.active&&mode.phases.callbacks.size()==1&&mode.stops.callbacks.size()==1);
|
||||
a.active=true;a.ERR_HoldForPrison();assert(!a.active&&mode.phases.inserted==1);
|
||||
a.ERR_PrisonPhaseChanged(0,1);assert(!a.active&&a.m_ERRPrisonMode==&mode);
|
||||
- mode.phase=2;a.ERR_PrisonPhaseChanged(1,2);assert(a.active&&a.starts==1&&!a.m_ERRPrisonMode&&mode.phases.callbacks.empty()&&mode.stops.callbacks.empty());
|
||||
+ mode.phase=2;a.ERR_PrisonPhaseChanged(phase,2);assert(a.active&&a.starts==1&&!a.m_ERRPrisonMode&&mode.phases.callbacks.empty()&&mode.stops.callbacks.empty());
|
||||
a.ERR_HoldForPrison();assert(a.active&&mode.phases.inserted==1);
|
||||
+ assert(!a.ERR_PrisonHeldForTest());a.DeactivateAI();assert(!a.active&&!a.ERR_PrisonHeldForTest());
|
||||
}
|
||||
for(int fault=0;fault<8;fault++){
|
||||
ERR_GameMode mode;ERR_GameMode::current=&mode;Actor actor;Agent a;a.actor=&actor;
|
||||
Reference in New Issue
Block a user