modded class ERR_GameMode { void ERR_GameMode(IEntitySource src, IEntity parent) { if (!GetGame() || Replication.IsServer()) return; GetGame().ERR_ClientConstructorDrain(this); } } modded class ArmaReforgerScripted { protected ref array m_ERRClientOldManagers = {}; bool m_ERRClientDetected; protected SCR_EntityCatalogManagerComponent m_ERROldCatalog; void ERR_ClientCaptureOriginal(SCR_BaseGameMode mode) { if (Replication.IsServer() || ERR_GameMode.Cast(mode)) return; m_ERROldCatalog = SCR_EntityCatalogManagerComponent.GetInstance(); m_ERRClientOldManagers = {mode, GetLoadoutManager(), GetFactionManager(), GetPerceptionManager(), GetChat()}; ChimeraWorld chimera = ChimeraWorld.CastFrom(GetWorld()); if (chimera) m_ERRClientOldManagers.Insert(chimera.GetRadioManager()); PrintFormat("ERR CONSTRUCTOR: retained original managers=%1", m_ERRClientOldManagers.Count()); } void ERR_ClientConstructorDrain(ERR_GameMode incoming) { if (m_ERRClientOldManagers.IsEmpty()) return; m_ERRClientDetected = true; SCR_BaseGameMode mode = SCR_BaseGameMode.Cast(m_ERRClientOldManagers[0]); PrintFormat("ERR CONSTRUCTOR: drain retained mode=%1 incoming=%2", mode, incoming); if (mode) mode.OnGameEnd(); if (m_DataCollectorComponent && m_DataCollectorComponent.GetOwner() == mode) m_DataCollectorComponent = null; SCR_EntityCatalogManagerComponent.ERR_ReleaseClientCatalog(m_ERROldCatalog); m_DataCollectorComponent = null; foreach (IEntity manager : m_ERRClientOldManagers) if (manager && manager != incoming) delete manager; m_ERRClientOldManagers.Clear(); PrintFormat("ERR CONSTRUCTOR: drained native mode=%1 factions=%2 loadouts=%3", GetGameMode(), GetFactionManager(), GetLoadoutManager()); } } modded class SCR_EntityCatalogManagerComponent { static void ERR_ReleaseClientCatalog(SCR_EntityCatalogManagerComponent expected) { if (s_Instance == expected) s_Instance = null; } protected bool m_ERRWaitingForFaction; void ERR_CompleteFactionInit() { if (!m_ERRWaitingForFaction || !GetGame().GetFactionManager()) return; m_ERRWaitingForFaction = false; ClearEventMask(GetOwner(), EntityEvent.FRAME); super.EOnInit(GetOwner()); Print("ERR CONSTRUCTOR: catalog completed during faction initialization"); } override void EOnInit(IEntity owner) { if (!Replication.IsServer() && ERR_GameMode.Cast(owner) && !GetGame().GetFactionManager()) { m_ERRWaitingForFaction = true; SetEventMask(owner, EntityEvent.FRAME); return; } super.EOnInit(owner); } override void EOnFrame(IEntity owner, float timeSlice) { if (!m_ERRWaitingForFaction || !GetGame().GetFactionManager()) return; m_ERRWaitingForFaction = false; ClearEventMask(owner, EntityEvent.FRAME); super.EOnInit(owner); Print("ERR CONSTRUCTOR: catalog initialized after factions"); } } modded class SCR_DelegateFactionManagerComponent { override void OnFactionsInit(array factions) { if (!Replication.IsServer() && GetGame().m_ERRClientDetected) { SCR_EntityCatalogManagerComponent catalog = SCR_EntityCatalogManagerComponent.GetInstance(); if (catalog) catalog.ERR_CompleteFactionInit(); return; } super.OnFactionsInit(factions); } } modded class SCR_EditableFactionComponent { override bool RplSave(ScriptBitWriter writer) { writer.WriteInt(m_iFactionIndex); return super.RplSave(writer); } override bool RplLoad(ScriptBitReader reader) { int initialIndex; reader.ReadInt(initialIndex); if (GetGame().m_ERRClientDetected && !m_ScrFaction) { PrintFormat("ERR CONSTRUCTOR: delegate RplLoad wireIndex=%1", initialIndex); SetFactionIndexBroadcast(initialIndex); } return super.RplLoad(reader); } } modded class SCR_BaseGameMode { override void EOnInit(IEntity owner) { super.EOnInit(owner); GetGame().ERR_ClientCaptureOriginal(this); } }