// Owner-authorized startup optics adaptation; provenance belongs in equipment migration docs. // Native attachment storage owns fitting/replication; no loose optics or replacement grants. class ERR_EnemyOpticsInspection { int Remaining = 128; bool Complete = true; bool Visit(IEntity entity, int depth = 0) { if (!entity) return false; if (depth > 4 || Remaining <= 0) { Complete = false; return false; } Remaining--; if (entity.FindComponent(SCR_2DOpticsComponent) || entity.FindComponent(SCR_2DPIPSightsComponent) || entity.FindComponent(SCR_PIPSightsComponent)) return true; IEntity child = entity.GetChildren(); while (child) { if (Visit(child, depth + 1)) return true; if (!Complete) return false; child = child.GetSibling(); } return false; } bool Inspect(BaseWeaponComponent weapon) { if (!weapon) { Complete = false; return false; } if (Visit(weapon.GetOwner())) return true; BaseSightsComponent sights = weapon.GetAttachedSights(); if (sights && Visit(sights.GetOwner())) return true; array slots = {}; weapon.GetAttachments(slots); if (slots.Count() > 16) { Complete = false; return false; } foreach (AttachmentSlotComponent slot : slots) { if (slot && Visit(slot.GetAttachedEntity())) return true; if (!Complete) return false; } return false; } } class ERR_EnemyOpticsJob { IEntity Rifle; bool Submitted; bool Terminal; bool Confirmed; int Attempt = -1; ref array Rejected = {}; ref ERR_EnemyEquipmentCallback Operation; string Reason; } class ERR_EnemyOptics { protected IEntity m_Actor; protected SCR_AIGroup m_Group; protected ref array m_Jobs = {}; protected int m_Checks; protected bool m_Captured; protected bool m_Stopped; void ERR_EnemyOptics(IEntity actor, SCR_AIGroup group) { m_Actor = actor; m_Group = group; } static bool EligibleWeapon(EWeaponType type) { return type == EWeaponType.WT_SNIPERRIFLE || type == EWeaponType.WT_RIFLE || type == EWeaponType.WT_MACHINEGUN; } static void Candidates(out array result) { result = { "{C850A33226B8F9C1}Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1.et", "{D2018EDB1BBF4C88}Prefabs/Weapons/Attachments/Optics/Optic_ARTII/Optic_ARTII.et", "{A1D5833FF10C6503}Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1M2.et", "{695AAA77F84EB238}Prefabs/Weapons/Attachments/Optics/1p21/Optic_1P21.et", "{333A794F0B55C019}Prefabs/Weapons/Attachments/Optics/m8541/Optic_M8541.et", "{BD496EE1B40DC510}Prefabs/Weapons/Attachments/Optics/Optic_4x20/Optic_4x20.et", "{8D4BAA235F7EDBEA}Prefabs/Weapons/Attachments/Optics/1p78/Optic_1P78.et" }; } protected void Finish(ERR_EnemyOpticsJob job, string reason) { if (job.Terminal) return; job.Terminal = true; job.Reason = reason; ERR_HQ.Event("OPTICS", reason); } protected void Fit(ERR_GameMode mode, ERR_EnemyOpticsJob job, InventoryStorageManagerComponent inventory) { if (job.Terminal) return; // Re-read the canonical actor and native weapon roster before every grant. if (!ERR_EnemyEquipmentRules.Eligible(mode, m_Group, m_Actor)) { Finish(job, "startup optics cancelled: actor ownership changed"); return; } BaseWeaponManagerComponent manager = BaseWeaponManagerComponent.Cast(m_Actor.FindComponent(BaseWeaponManagerComponent)); array current = {}; if (manager) manager.GetWeaponsList(current); if (!job.Rifle || !current.Contains(job.Rifle)) { Finish(job, "startup rifle left original actor; no replacement"); return; } BaseWeaponComponent weapon = BaseWeaponComponent.Cast(job.Rifle.FindComponent(BaseWeaponComponent)); if (!weapon || !EligibleWeapon(weapon.GetWeaponType())) { Finish(job, "original weapon no longer eligible"); return; } ERR_EnemyOpticsInspection inspection = new ERR_EnemyOpticsInspection(); if (inspection.Inspect(weapon)) { job.Confirmed = true; Finish(job, "physical magnified optic preserved/confirmed"); return; } // Callback success is terminal even if someone removes the optic before our next observation. if (job.Submitted && job.Operation && job.Operation.Finished && job.Operation.Succeeded) { Finish(job, "native optic insertion completed; no replenishment"); return; } if (m_Checks >= 5) { if (job.Submitted && (!job.Operation || !job.Operation.Finished)) Finish(job, "startup optics deadline; unresolved insertion remains quarantined"); else Finish(job, "startup optics deadline; compatible magnified optic not confirmed"); return; } if (job.Submitted) { if (!job.Operation || !job.Operation.Finished) return; job.Rejected.Insert(job.Attempt); job.Submitted = false; } if (!inspection.Complete) { job.Reason = "existing optics inspection incomplete; no grant"; return; } WeaponAttachmentsStorageComponent storage = WeaponAttachmentsStorageComponent.Cast(job.Rifle.FindComponent(WeaponAttachmentsStorageComponent)); if (!storage || storage.GetSlotsCount() > 16) return; array candidates = {}; Candidates(candidates); array remaining = {0, 1, 2, 3, 4, 5, 6}; while (!remaining.IsEmpty()) { int draw = Math.RandomInt(0, remaining.Count()); int index = remaining[draw]; remaining.Remove(draw); ResourceName prefab = candidates[index]; for (int slotIndex = 0; slotIndex < storage.GetSlotsCount(); slotIndex++) { InventoryStorageSlot slot = storage.GetSlot(slotIndex); int attempt = index * 16 + slotIndex; if (!slot || slot.GetAttachedEntity() || job.Rejected.Contains(attempt)) continue; if (!inventory.CanInsertResourceInStorage(prefab, storage, slotIndex)) continue; job.Attempt = attempt; job.Operation = new ERR_EnemyEquipmentCallback(); job.Submitted = true; bool accepted = inventory.TrySpawnPrefabToStorage(prefab, storage, slotIndex, EStoragePurpose.PURPOSE_ANY, job.Operation); // A synchronous success is authoritative even if the return value is inconsistent. if (!accepted && !(job.Operation.Finished && job.Operation.Succeeded)) { job.Rejected.Insert(attempt); job.Submitted = false; } return; // At most one native submission per original rifle per startup check. } } } bool Check(ERR_GameMode mode) { if (m_Stopped) return true; if (!ERR_EnemyEquipmentRules.Eligible(mode, m_Group, m_Actor)) { Stop(); return true; } m_Checks++; BaseWeaponManagerComponent manager = BaseWeaponManagerComponent.Cast(m_Actor.FindComponent(BaseWeaponManagerComponent)); InventoryStorageManagerComponent inventory = InventoryStorageManagerComponent.Cast(m_Actor.FindComponent(InventoryStorageManagerComponent)); if (!manager || !inventory) { if (m_Checks >= 5) Stop(); return m_Stopped; } if (!m_Captured) { array current = {}; manager.GetWeaponsList(current); if (current.Count() > 8) { Stop(); return true; } array seen = {}; foreach (IEntity rifle : current) { if (!rifle || rifle == m_Actor || seen.Contains(rifle)) continue; seen.Insert(rifle); BaseWeaponComponent weapon = BaseWeaponComponent.Cast(rifle.FindComponent(BaseWeaponComponent)); if (!weapon || !EligibleWeapon(weapon.GetWeaponType())) continue; ERR_EnemyOpticsJob job = new ERR_EnemyOpticsJob(); job.Rifle = rifle; m_Jobs.Insert(job); } m_Captured = !m_Jobs.IsEmpty(); } bool complete = m_Captured; foreach (ERR_EnemyOpticsJob job : m_Jobs) { Fit(mode, job, inventory); if (!job.Terminal) complete = false; } if (complete || m_Checks >= 5) Stop(); return m_Stopped; } void Stop() { m_Stopped = true; foreach (ERR_EnemyOpticsJob job : m_Jobs) job.Terminal = true; // Keep exact-weapon tombstones/callbacks. Accepted native inserts cannot be cancelled here. } }