Harden participant and map ownership and validate bounded physical flight
This commit is contained in:
@@ -31,6 +31,7 @@ class ERRM_SharedMapComponent : SCR_MapGadgetComponent
|
||||
protected Widget m_ESMRootWidget;
|
||||
protected RTTextureWidget m_ESMRenderTarget;
|
||||
protected SCR_MapEntity m_ESMMapEntity;
|
||||
protected ref MapConfiguration m_ESMMapConfig;
|
||||
protected IEntity m_ESMCharacterOwner;
|
||||
protected bool m_bESMInHand;
|
||||
protected bool m_bESMOwnsMapRenderer;
|
||||
@@ -107,12 +108,21 @@ class ERRM_SharedMapComponent : SCR_MapGadgetComponent
|
||||
MapConfiguration mapConfig = m_ESMMapEntity.SetupMapConfig(EMapEntityMode.PLAIN, MAP_CONFIG, m_ESMRootWidget);
|
||||
if (!mapConfig)
|
||||
{
|
||||
ReleaseMapCapture();
|
||||
CompleteMapModeSwitch();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ESMMapEntity.OpenMap(mapConfig);
|
||||
m_ESMMapConfig = mapConfig;
|
||||
m_bESMOwnsMapRenderer = true;
|
||||
m_ESMMapEntity.OpenMap(mapConfig);
|
||||
if (!OwnsMapCapture())
|
||||
{
|
||||
ReleaseMapCapture();
|
||||
if (m_bESMInHand && GetGame())
|
||||
GetGame().GetCallqueue().CallLater(TryCaptureMapSurface, MAP_RETRY_DELAY_MS, false);
|
||||
return;
|
||||
}
|
||||
RestoreCharacterCamera();
|
||||
|
||||
GetGame().GetCallqueue().CallLater(CenterMapOnHolder, MAP_SETUP_DELAY_MS, false);
|
||||
@@ -121,7 +131,7 @@ class ERRM_SharedMapComponent : SCR_MapGadgetComponent
|
||||
|
||||
protected void CenterMapOnHolder()
|
||||
{
|
||||
if (!m_bESMOwnsMapRenderer || !m_ESMMapEntity || !m_ESMCharacterOwner)
|
||||
if (!OwnsMapCapture() || !m_ESMCharacterOwner)
|
||||
return;
|
||||
|
||||
ERRM_SharedMapComponentClass data = ERRM_SharedMapComponentClass.Cast(GetComponentData(GetOwner()));
|
||||
@@ -136,19 +146,41 @@ class ERRM_SharedMapComponent : SCR_MapGadgetComponent
|
||||
{
|
||||
if (!m_bESMOwnsMapRenderer)
|
||||
return;
|
||||
if (!OwnsMapCapture())
|
||||
{
|
||||
ReleaseMapCapture();
|
||||
// A native UI replaced this capture. Do not close, pan, fade or
|
||||
// focus that UI; use the existing retry path after it closes.
|
||||
if (m_bESMInHand && GetGame())
|
||||
GetGame().GetCallqueue().CallLater(TryCaptureMapSurface, MAP_RETRY_DELAY_MS, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Freeze the last rendered frame before closing the auxiliary map.
|
||||
// Leaving the widget enabled would redraw the closed map as an empty
|
||||
// texture and make the physical map appear to vanish.
|
||||
ReleaseMapCapture();
|
||||
CompleteMapModeSwitch();
|
||||
}
|
||||
|
||||
protected bool OwnsMapCapture()
|
||||
{
|
||||
if (!GetGame() || !m_bESMOwnsMapRenderer || !m_ESMMapEntity || !m_ESMMapConfig || !m_ESMRootWidget)
|
||||
return false;
|
||||
if (SCR_MapEntity.GetMapInstance() != m_ESMMapEntity || !m_ESMMapEntity.IsOpen())
|
||||
return false;
|
||||
// Vanilla reuses the same config object for equal map modes and changes
|
||||
// RootWidgetRef, so pointer identity alone cannot establish ownership.
|
||||
return m_ESMMapEntity.GetMapConfig() == m_ESMMapConfig && m_ESMMapConfig.RootWidgetRef == m_ESMRootWidget;
|
||||
}
|
||||
|
||||
protected void ReleaseMapCapture()
|
||||
{
|
||||
bool ownsRenderer = OwnsMapCapture();
|
||||
// Freeze our own target even on interruption or foreign replacement.
|
||||
if (m_ESMRenderTarget)
|
||||
m_ESMRenderTarget.SetEnabled(false);
|
||||
|
||||
if (m_ESMMapEntity && m_ESMMapEntity.IsOpen())
|
||||
m_ESMMapEntity.CloseMap();
|
||||
|
||||
m_bESMOwnsMapRenderer = false;
|
||||
RestoreCharacterCamera();
|
||||
CompleteMapModeSwitch();
|
||||
m_ESMMapConfig = null;
|
||||
if (ownsRenderer)
|
||||
m_ESMMapEntity.CloseMap(); // vanilla also restores its character camera
|
||||
}
|
||||
|
||||
protected void CompleteMapModeSwitch()
|
||||
@@ -163,21 +195,20 @@ class ERRM_SharedMapComponent : SCR_MapGadgetComponent
|
||||
protected void StopMapCapture()
|
||||
{
|
||||
m_bESMInHand = false;
|
||||
GetGame().GetCallqueue().Remove(TryCaptureMapSurface);
|
||||
GetGame().GetCallqueue().Remove(CenterMapOnHolder);
|
||||
GetGame().GetCallqueue().Remove(FinishMapCapture);
|
||||
|
||||
if (m_bESMOwnsMapRenderer && m_ESMMapEntity && m_ESMMapEntity.IsOpen())
|
||||
m_ESMMapEntity.CloseMap();
|
||||
|
||||
m_bESMOwnsMapRenderer = false;
|
||||
if (GetGame())
|
||||
{
|
||||
GetGame().GetCallqueue().Remove(TryCaptureMapSurface);
|
||||
GetGame().GetCallqueue().Remove(CenterMapOnHolder);
|
||||
GetGame().GetCallqueue().Remove(FinishMapCapture);
|
||||
}
|
||||
ReleaseMapCapture();
|
||||
m_ESMCharacterOwner = null;
|
||||
RestoreCharacterCamera();
|
||||
m_ESMMapEntity = null;
|
||||
}
|
||||
|
||||
protected void RestoreCharacterCamera()
|
||||
{
|
||||
if (!GetGame()) return;
|
||||
if (!OwnsMapCapture()) return;
|
||||
PlayerController playerController = GetGame().GetPlayerController();
|
||||
if (playerController)
|
||||
playerController.SetCharacterCameraRenderActive(true);
|
||||
|
||||
Reference in New Issue
Block a user