Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
141 lines
5.1 KiB
Plaintext
141 lines
5.1 KiB
Plaintext
// Vanilla caches are tied to the original game mode. Release its exact
|
|
// components before takeover. Some vanilla destructors unconditionally clear
|
|
// their static cache later; resolve those getters from the current takeover
|
|
// owner so delayed destruction cannot invalidate the replacement.
|
|
modded class SCR_ArsenalManagerComponent
|
|
{
|
|
static void ERR_ReleaseTerrainSingleton(SCR_ArsenalManagerComponent expected)
|
|
{
|
|
if (s_Instance == expected) s_Instance = null;
|
|
}
|
|
}
|
|
|
|
modded class SCR_GroupsManagerComponent
|
|
{
|
|
static void ERR_ReleaseTerrainSingleton(SCR_GroupsManagerComponent expected)
|
|
{
|
|
if (s_Instance == expected) s_Instance = null;
|
|
}
|
|
}
|
|
|
|
modded class SCR_SupportStationManagerComponent
|
|
{
|
|
static void ERR_ReleaseTerrainSingleton(SCR_SupportStationManagerComponent expected)
|
|
{
|
|
if (s_Instance == expected) s_Instance = null;
|
|
}
|
|
}
|
|
|
|
modded class SCR_TaskFinishHistoryManagerComponent
|
|
{
|
|
static void ERR_ReleaseTerrainSingleton(SCR_TaskFinishHistoryManagerComponent expected)
|
|
{
|
|
if (s_Instance == expected) s_Instance = null;
|
|
}
|
|
override static SCR_TaskFinishHistoryManagerComponent GetInstance()
|
|
{
|
|
ERR_TerrainTakeoverMode mode;
|
|
if (GetGame()) mode = ERR_TerrainTakeoverMode.Cast(GetGame().GetGameMode());
|
|
if (mode) return SCR_TaskFinishHistoryManagerComponent.Cast(mode.FindComponent(SCR_TaskFinishHistoryManagerComponent));
|
|
return super.GetInstance();
|
|
}
|
|
}
|
|
|
|
modded class SCR_TaskManagerUIComponent
|
|
{
|
|
static void ERR_ReleaseTerrainSingleton(SCR_TaskManagerUIComponent expected)
|
|
{
|
|
if (s_Instance == expected) s_Instance = null;
|
|
}
|
|
override static SCR_TaskManagerUIComponent GetInstance()
|
|
{
|
|
ERR_TerrainTakeoverMode mode;
|
|
if (GetGame()) mode = ERR_TerrainTakeoverMode.Cast(GetGame().GetGameMode());
|
|
if (mode) return SCR_TaskManagerUIComponent.Cast(mode.FindComponent(SCR_TaskManagerUIComponent));
|
|
return super.GetInstance();
|
|
}
|
|
}
|
|
|
|
modded class SCR_TextsTaskManagerComponent
|
|
{
|
|
static void ERR_ReleaseTerrainSingleton(SCR_TextsTaskManagerComponent expected)
|
|
{
|
|
if (s_Instance == expected) s_Instance = null;
|
|
}
|
|
override static SCR_TextsTaskManagerComponent GetInstance()
|
|
{
|
|
ERR_TerrainTakeoverMode mode;
|
|
if (GetGame()) mode = ERR_TerrainTakeoverMode.Cast(GetGame().GetGameMode());
|
|
if (mode) return SCR_TextsTaskManagerComponent.Cast(mode.FindComponent(SCR_TextsTaskManagerComponent));
|
|
return super.GetInstance();
|
|
}
|
|
}
|
|
|
|
modded class SCR_MapMarkerManagerComponent
|
|
{
|
|
override static SCR_MapMarkerManagerComponent GetInstance()
|
|
{
|
|
ERR_TerrainTakeoverMode mode;
|
|
if (GetGame()) mode = ERR_TerrainTakeoverMode.Cast(GetGame().GetGameMode());
|
|
if (mode) return SCR_MapMarkerManagerComponent.Cast(mode.FindComponent(SCR_MapMarkerManagerComponent));
|
|
return super.GetInstance();
|
|
}
|
|
}
|
|
|
|
modded class SCR_RespawnSystemComponent
|
|
{
|
|
override static SCR_RespawnSystemComponent GetInstance()
|
|
{
|
|
ERR_TerrainTakeoverMode mode;
|
|
if (GetGame()) mode = ERR_TerrainTakeoverMode.Cast(GetGame().GetGameMode());
|
|
if (mode) return SCR_RespawnSystemComponent.Cast(mode.FindComponent(SCR_RespawnSystemComponent));
|
|
return super.GetInstance();
|
|
}
|
|
}
|
|
|
|
// Standalone global nodes otherwise have no delivery-order relationship. During
|
|
// a connected restart a faction delegate can arrive before its new mode and
|
|
// faction manager. Express that dependency to replication before publishing the
|
|
// newly spawned hierarchy, rather than relying on an arbitrary frame delay.
|
|
class ERR_TerrainTakeoverReplication
|
|
{
|
|
static void CollectDelegates(SCR_DelegateFactionManagerComponent manager, array<IEntity> entities)
|
|
{
|
|
if (!manager) return;
|
|
map<Faction, SCR_EditableFactionComponent> delegates = new map<Faction, SCR_EditableFactionComponent>();
|
|
manager.GetFactionDelegates(delegates);
|
|
for (int i = 0; i < delegates.Count(); i++)
|
|
{
|
|
SCR_EditableFactionComponent delegate = delegates.GetElement(i);
|
|
if (delegate && delegate.GetOwner() && !entities.Contains(delegate.GetOwner())) entities.Insert(delegate.GetOwner());
|
|
}
|
|
}
|
|
protected static bool Parent(IEntity entity, IEntity parent)
|
|
{
|
|
RplComponent childRpl = SCR_EntityHelper.GetEntityRplComponent(entity);
|
|
RplComponent parentRpl = SCR_EntityHelper.GetEntityRplComponent(parent);
|
|
if (!childRpl || !parentRpl) return false;
|
|
RplNode childNode = childRpl.GetNode();
|
|
RplNode parentNode = parentRpl.GetNode();
|
|
if (!childNode || !parentNode || childNode == parentNode) return false;
|
|
if (childNode.GetParent() != parentNode) childNode.SetParent(parentNode);
|
|
return childNode.GetParent() == parentNode;
|
|
}
|
|
static bool Link(ERR_GameMode mode)
|
|
{
|
|
IEntity factions = GetGame().GetFactionManager();
|
|
if (!factions || !Parent(factions, mode)) return false;
|
|
if (!Parent(GetGame().GetLoadoutManager(), mode) || !Parent(GetGame().GetChat(), mode)) return false;
|
|
SCR_DelegateFactionManagerComponent manager = SCR_DelegateFactionManagerComponent.GetInstance();
|
|
if (!manager) return false;
|
|
map<Faction, SCR_EditableFactionComponent> delegates = new map<Faction, SCR_EditableFactionComponent>();
|
|
manager.GetFactionDelegates(delegates);
|
|
for (int i = 0; i < delegates.Count(); i++)
|
|
{
|
|
SCR_EditableFactionComponent delegate = delegates.GetElement(i);
|
|
if (!delegate || !Parent(delegate.GetOwner(), factions)) return false;
|
|
}
|
|
return !delegates.IsEmpty();
|
|
}
|
|
}
|