Reduce redundant AI equipment, radio and observation checks
continuous-integration/drone/push Build is passing

Preserve live ownership and detection rules while skipping redundant work. Record published Workshop version 0.0.150 and add operation-count regressions.
This commit is contained in:
2026-11-09 17:05:25 +01:00
parent 47cd4fa2bc
commit 4b737c825f
12 changed files with 335 additions and 18 deletions
@@ -36,7 +36,11 @@ modded class SCR_AICombatComponent
void ERR_RefreshEnemySkill()
{
if (!m_ERRSkillMode || !ERR_EnemyEquipmentRules.Eligible(m_ERRSkillMode, m_ERRSkillGroup, GetOwner())) return;
EAISkill skill = ERR_EnemyGunnerSkill.Profile(m_ERRRequestedSkill, ERR_EnemyGunnerSkill.OriginalGunner(m_ERRSkillMode, m_ERRSkillGroup, GetOwner()));
bool originalGunner;
// A maximum floor already determines the profile; preserve the lower-floor path.
if (ERR_EnemyEquipmentRules.Floor(m_ERRRequestedSkill) < EAISkill.CYLON)
originalGunner = ERR_EnemyGunnerSkill.OriginalGunner(m_ERRSkillMode, m_ERRSkillGroup, GetOwner());
EAISkill skill = ERR_EnemyGunnerSkill.Profile(m_ERRRequestedSkill, originalGunner);
if (GetAISkill() != skill) super.SetAISkill(skill);
}
void ERR_ReleaseEnemySkill(ERR_GameMode mode)
@@ -50,7 +54,10 @@ modded class SCR_AICombatComponent
if (m_ERRSkillMode && ERR_EnemyEquipmentRules.Eligible(m_ERRSkillMode, m_ERRSkillGroup, GetOwner()))
{
m_ERRRequestedSkill = skill;
skill = ERR_EnemyGunnerSkill.Profile(skill, ERR_EnemyGunnerSkill.OriginalGunner(m_ERRSkillMode, m_ERRSkillGroup, GetOwner()));
bool originalGunner;
if (ERR_EnemyEquipmentRules.Floor(skill) < EAISkill.CYLON)
originalGunner = ERR_EnemyGunnerSkill.OriginalGunner(m_ERRSkillMode, m_ERRSkillGroup, GetOwner());
skill = ERR_EnemyGunnerSkill.Profile(skill, originalGunner);
}
super.SetAISkill(skill);
}
@@ -184,7 +191,8 @@ class ERR_EnemyEquipment
if (!ERR_EnemyEquipmentRules.Owned(m_Mode, entry.Group, entry.Actor)) { entry.Stop(m_Mode); continue; }
// Incapacitation suspends work on the existing entry; it must not permanently
// remove the skill binding or recreate completed equipment grants on recovery.
if (!ERR_EnemyEquipmentRules.Eligible(m_Mode, entry.Group, entry.Actor)) continue;
// Owned was checked immediately above; only the consciousness gate remains.
if (!ERR_Actors.CanFight(entry.Actor)) continue;
// Combat may arrive after the group's initial membership notification.
if (!entry.Combat && entry.SkillChecks < 5)
{
@@ -127,6 +127,8 @@ class ERR_HQBodyObserver
vector observerPosition = observer.GetOrigin();
vector delta = bodyPosition - observerPosition;
float distance = delta.Length();
// No facing can admit an invalid or distant body; avoid native transform work.
if (!ERR_HQBodyRules.InView(distance, 1)) return false;
delta[1] = 0;
vector transform[4]; observer.GetWorldTransform(transform);
vector forward = transform[2]; forward[1] = 0;
@@ -162,7 +164,8 @@ class ERR_HQBodyObserver
report = null;
if (!Replication.IsServer() || !ERR_HQMemoryRules.Finite(now) || now < m_Now || now < 0) return false;
TickBudget(now);
if (!OwnedPhysical(group) || group.GetPlayerCount(true) > 0 || m_Bodies.IsEmpty()) return false;
// Refresh death candidates first, then skip ownership lookups if none exist.
if (m_Bodies.IsEmpty() || !OwnedPhysical(group) || group.GetPlayerCount(true) > 0) return false;
ERR_HQBodyScan state;
foreach (ERR_HQBodyScan scan : m_Groups) if (scan.Group == group) state = scan;
if (!state) return false;
@@ -17,11 +17,13 @@ class ERR_HQRadio
InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(character.FindComponent(InventoryStorageManagerComponent));
if (!inventory)
return 0;
array<IEntity> items = {};
inventory.GetItems(items);
int result;
ERR_HQ hq = ERR_HQ.Get();
if (hq && hq.Hunters()) result = hq.Hunters().VehicleRadioCapability(character);
// A live physical vehicle manpack already supplies the maximum capability.
if (result == 2) return 2;
array<IEntity> items = {};
inventory.GetItems(items);
foreach (IEntity item : items)
{
if (!item || !item.FindComponent(BaseRadioComponent))
@@ -88,7 +88,8 @@ class ERR_KnownMines
protected bool Collect(IEntity actor)
{
if (m_Near.Count() >= 128) return false;
if (FriendlyActor(actor) && !m_Near.Contains(actor)) m_Near.Insert(actor);
// Reject props cheaply; overlapping queries need not reclassify accepted soldiers.
if (ChimeraCharacter.Cast(actor) && !m_Near.Contains(actor) && FriendlyActor(actor)) m_Near.Insert(actor);
return true;
}
protected ERR_KnownMine Blocking(vector start, vector goal, float radius)