// Private native fixture: sentinel events exercise real invokers without fake players. [BaseContainerProps(configRoot: true)] modded class SCR_EditorManagerCore { protected int m_ERRProbeEvents; protected bool m_ERRProbeComplete; protected override void OnPlayerRegistered(int playerID) { if (playerID == -919) { m_ERRProbeEvents++; return; } super.OnPlayerRegistered(playerID); } protected override void OnPlayerDisconnected(int playerID) { if (playerID == -919) { m_ERRProbeEvents++; return; } super.OnPlayerDisconnected(playerID); } [Friend(SCR_ReconnectComponent)] protected override void OnPlayerSpawn(int playerID, IEntity controlledEntity) { if (playerID == -919) { m_ERRProbeEvents++; return; } super.OnPlayerSpawn(playerID, controlledEntity); } protected override void OnPlayerKilled(notnull SCR_InstigatorContextData instigatorContextData) { if (instigatorContextData.GetVictimPlayerID() == -919) { m_ERRProbeEvents++; return; } super.OnPlayerKilled(instigatorContextData); } protected override void OnPlayerDeleted(int playerID, IEntity player) { if (playerID == -919) { m_ERRProbeEvents++; return; } super.OnPlayerDeleted(playerID, player); } protected override void OnPlayerRoleChange(int playerId, EPlayerRole roleFlags) { if (playerId == -919) { m_ERRProbeEvents++; return; } super.OnPlayerRoleChange(playerId, roleFlags); } protected void ERR_ProbeEvents(SCR_BaseGameMode mode, int expected, string label) { m_ERRProbeEvents = 0; mode.GetOnPlayerRegistered().Invoke(-919); mode.GetOnPostCompPlayerDisconnected().Invoke(-919, 0, 0); mode.GetOnPlayerSpawned().Invoke(-919, null); mode.GetOnPlayerKilled().Invoke(new SCR_InstigatorContextData(-919, null, null, Instigator.CreateInstigatorGM(), true)); mode.GetOnPlayerDeleted().Invoke(-919, null); mode.GetOnPlayerRoleChange().Invoke(-919, 0); if (m_ERRProbeEvents == expected) Print("ERR EDITOR PASS: " + label); else PrintFormat("ERR EDITOR FAIL: %1 expected=%2 actual=%3", label, expected, m_ERRProbeEvents); } override void ERR_SetTerrainModeEvents(SCR_BaseGameMode mode, bool attach) { super.ERR_SetTerrainModeEvents(mode, attach); if (attach) GetGame().GetCallqueue().CallLater(ERR_ProbeAttached, 1000, false, mode); } protected void ERR_ProbeAttached(SCR_BaseGameMode mode) { if (m_ERRProbeComplete) return; m_ERRProbeComplete = true; Print("ERR EDITOR PASS: automatic Nogova takeover calls editor handover"); // Keep fake player events away from unrelated game systems. Only this private // playerless fixture clears listeners, then tests the actual production bind. mode.GetOnPlayerRegistered().Clear(); mode.GetOnPostCompPlayerDisconnected().Clear(); mode.GetOnPlayerSpawned().Clear(); mode.GetOnPlayerKilled().Clear(); mode.GetOnPlayerDeleted().Clear(); mode.GetOnPlayerRoleChange().Clear(); super.ERR_SetTerrainModeEvents(mode, true); ERR_ProbeEvents(mode, 6, "all six native editor event subscriptions deliver"); super.ERR_SetTerrainModeEvents(mode, true); ERR_ProbeEvents(mode, 6, "repeat attach does not duplicate editor listeners"); super.ERR_SetTerrainModeEvents(mode, false); ERR_ProbeEvents(mode, 0, "replacement can detach for lifecycle cleanup"); super.ERR_SetTerrainModeEvents(mode, true); ERR_ProbeEvents(mode, 6, "reattach restores normal editor lifecycle"); Print("ERR EDITOR COMPLETE"); } }