Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
61 lines
3.7 KiB
Diff
61 lines
3.7 KiB
Diff
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c
|
|
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeCrashStartProbe.c
|
|
@@ -3,6 +3,28 @@
|
|
// actor relocation, damage or inventory creation in this probe.
|
|
class ERR_NativeCrashStartProbe
|
|
{
|
|
+ protected static SCR_AIGroup s_ClueGroup;
|
|
+ protected static ref array<SCR_ChimeraAIAgent> s_ClueAgents = {};
|
|
+ protected static ref array<IEntity> s_ClueBodies = {};
|
|
+ static bool NearbyEnemies(ERR_GameMode mode, IEntity player)
|
|
+ {
|
|
+ ERR_SiteRuntime clue = mode.Sites().Find("everon-supply-1");
|
|
+ if (!clue || clue.Group != s_ClueGroup || !s_ClueGroup || s_ClueAgents.IsEmpty() || s_ClueAgents.Count() != s_ClueBodies.Count()) return false;
|
|
+ array<AIAgent> current = {}; s_ClueGroup.GetAgents(current);
|
|
+ int nearby, active;
|
|
+ for (int index = 0; index < s_ClueAgents.Count(); index++)
|
|
+ {
|
|
+ SCR_ChimeraAIAgent agent = s_ClueAgents[index]; IEntity actor = s_ClueBodies[index];
|
|
+ if (!agent || !actor || agent.GetControlledEntity() != actor || !current.Contains(agent) || !ERR_Actors.CanFight(actor) || ERR_Actors.Player(actor)) continue;
|
|
+ if (vector.DistanceXZ(actor.GetOrigin(), player.GetOrigin()) > 100) continue;
|
|
+ nearby++;
|
|
+ bool awake = agent.IsAIActivated();
|
|
+ PrintFormat("ERR CRASH NEARBY AI: index=%1 active=%2 lod=%3 permanentLod=%4 prisonHeld=%5", index, awake, agent.GetLOD(), agent.GetPermanentLOD(), agent.ERR_PrisonHeldForTest());
|
|
+ if (awake && !agent.ERR_PrisonHeldForTest()) active++;
|
|
+ }
|
|
+ PrintFormat("ERR CRASH NEARBY AI TOTAL: retained=%1 nearby=%2 active=%3; ordinary native activation after scripted cache approach, no activation override", s_ClueAgents.Count(), nearby, active);
|
|
+ return active > 0;
|
|
+ }
|
|
protected static bool Check(bool condition, string message)
|
|
{
|
|
if (condition) { Print("ERR SMOKE PASS: crash start " + message); return true; }
|
|
@@ -24,6 +46,18 @@
|
|
static bool Run(ERR_GameMode mode, IEntity player)
|
|
{
|
|
if (!Check(mode && mode.StartMode() == 1 && mode.Phase() == ERR_Phase.RADIO_SEARCH, "frozen choice enters radio search directly")) return false;
|
|
+ s_ClueAgents.Clear(); s_ClueBodies.Clear(); s_ClueGroup = null;
|
|
+ ERR_SiteRuntime clue = mode.Sites().Find("everon-supply-1");
|
|
+ if (!Check(clue && clue.Group, "retains original clue defenders before approach")) return false;
|
|
+ s_ClueGroup = clue.Group;
|
|
+ array<AIAgent> guards = {}; s_ClueGroup.GetAgents(guards);
|
|
+ if (guards.IsEmpty() || guards.Count() > 16) return false;
|
|
+ foreach (AIAgent guard : guards)
|
|
+ {
|
|
+ SCR_ChimeraAIAgent original = SCR_ChimeraAIAgent.Cast(guard);
|
|
+ if (!original || !original.GetControlledEntity()) return false;
|
|
+ s_ClueAgents.Insert(original); s_ClueBodies.Insert(original.GetControlledEntity());
|
|
+ }
|
|
ERR_PlayerLife life = mode.Players().CurrentActor(player);
|
|
CompartmentAccessComponent access = CompartmentAccessComponent.Cast(player.FindComponent(CompartmentAccessComponent));
|
|
if (!Check(life && life.UsedLife && access && !access.IsInCompartment() && ERR_Actors.CanFight(player), "ordinary canonical one-life survivor starts conscious on foot")) return false;
|
|
--- a/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
|
+++ b/addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeSmoke.c
|
|
@@ -985,6 +985,7 @@
|
|
}
|
|
else if (m_ERRSmokeStep == 3)
|
|
{
|
|
+ if (m_ERRTestCrashStart && !ERR_Check(ERR_NativeCrashStartProbe.NearbyEnemies(this, m_ERRSmokePlayer), "an original nearby clue defender has native AI active after crash-route approach")) return;
|
|
if (!ERR_CheckRouteExtras(now)) return;
|
|
if (!ERR_Check(m_ERRSmokeRadio.Knowledge() == 2, "carried intel identifies radio through intel service")) return;
|
|
if (!ERR_Check(!TuneRadio(m_ERRSmokePlayer, m_ERRSmokeRadio), "radio rejects distant player")) return;
|