// 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");
 }
}
