Files
EscapistsReintroduced/docs/evidence/server-lifecycle-fixes-2026-10-07/ERR_ItemStationLifecycle.c.txt
T
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

58 lines
2.5 KiB
Plaintext

// A support station's cleanup must not require a still-living item catalog.
// Remember the subscriptions made by successful native initialization, rather
// than rerunning startup validation after that catalog has been destroyed.
modded class SCR_BaseItemSupportStationComponent
{
protected bool m_ERRItemStationScoped;
protected bool m_ERRItemStationInitializing;
protected bool m_ERRItemStationInitialized;
protected bool m_ERRItemStationDeleted;
protected SCR_ResourceComponent m_ERRItemStationResource;
protected SCR_SupportStationManagerComponent m_ERRItemStationManager;
override void OnPostInit(IEntity owner)
{
m_ERRItemStationScoped = !SCR_Global.IsEditMode() && (ERR_GameMode.Get() || ERR_TerrainTakeoverSettings.Enabled());
super.OnPostInit(owner);
}
protected override void DelayedInit(IEntity owner)
{
if (m_ERRItemStationDeleted) return;
// A preloader/preview is not a playable world. Its transient equipment may
// be created before any game mode/catalog exists and immediately discarded.
if (m_ERRItemStationScoped && owner && GetGame() && owner.GetWorld() != GetGame().GetWorld() && !SCR_EntityCatalogManagerComponent.GetInstance()) return;
m_ERRItemStationInitializing = m_ERRItemStationScoped;
super.DelayedInit(owner);
m_ERRItemStationInitializing = false;
if (m_ERRItemStationInitialized && UsesRange()) m_ERRItemStationManager = SCR_SupportStationManagerComponent.GetInstance();
}
protected override void AddRemoveOnDamageStateChanged(IEntity owner, bool subscribe)
{
super.AddRemoveOnDamageStateChanged(owner, subscribe);
// This hook is reached only after the complete native virtual validation.
if (!subscribe || !m_ERRItemStationInitializing) return;
m_ERRItemStationInitialized = true;
if (m_ResourceConsumer || m_ResourceGenerator) m_ERRItemStationResource = GetResourceComponent();
}
override void OnDelete(IEntity owner)
{
if (!m_ERRItemStationScoped || SCR_Global.IsEditMode())
{
super.OnDelete(owner);
return;
}
if (m_ERRItemStationDeleted) return;
m_ERRItemStationDeleted = true;
if (GetGame()) GetGame().GetCallqueue().Remove(DelayedInit);
if (m_ERRItemStationInitialized)
{
AddRemoveOnDamageStateChanged(owner, false);
// Use the managers this station joined, never a new round's singleton.
if (m_ERRItemStationManager) m_ERRItemStationManager.RemoveSupportStation(this);
if (m_ERRItemStationResource) m_ERRItemStationResource.TEMP_GetOnInteractorReplicated().Remove(TEMP_OnInteractorReplicated);
}
m_ERRItemStationManager = null;
m_ERRItemStationResource = null;
}
}