fix(world): remove non-retail portal exit fade
This commit is contained in:
parent
842bd89c16
commit
dded9e6b17
21 changed files with 919 additions and 347 deletions
|
|
@ -23,7 +23,7 @@ public enum TeleportEntryKind { Portal, Login, Death, Logout }
|
|||
public enum TeleportAnimEvent
|
||||
{
|
||||
PlayEnterSound, // Begin(): sound_ui_enter_portal
|
||||
EnterTunnel, // Off/WorldFade* -> Tunnel: world is now hidden
|
||||
EnterTunnel, // First tunnel-family frame: portal viewport replaces world
|
||||
Place, // Tunnel -> TunnelContinue: world loaded; place the player
|
||||
PlayExitSound, // TunnelFadeOut -> WorldFadeIn: sound_ui_exit_portal
|
||||
FireLoginComplete, // WorldFadeIn -> Off: send GameAction 0xA1
|
||||
|
|
@ -32,7 +32,7 @@ public enum TeleportAnimEvent
|
|||
/// <summary>Immutable per-frame snapshot from the sequencer.</summary>
|
||||
public readonly record struct TeleportAnimSnapshot(
|
||||
TeleportAnimState State,
|
||||
float FadeAlpha, // 0 = clear world, 1 = full black
|
||||
float ViewPlaneBlend, // 0 = game view distance, 1 = transition distance
|
||||
bool ShowTunnel, // true during TunnelFadeIn..TunnelFadeOut
|
||||
bool ShowPleaseWait); // true during TunnelContinue only
|
||||
|
||||
|
|
@ -82,6 +82,21 @@ public sealed class TeleportAnimSequencer
|
|||
_enterTunnelPending = _state == TeleportAnimState.Tunnel; // true for Portal/Login/Death
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancel the current transition and discard every pending edge event.
|
||||
/// Session teardown and a replacement teleport both require a clean
|
||||
/// lifetime; no event from the abandoned transition may reach the next
|
||||
/// session or destination.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
_state = TeleportAnimState.Off;
|
||||
_elapsed = 0f;
|
||||
_continueElapsed = 0f;
|
||||
_enterSoundPending = false;
|
||||
_enterTunnelPending = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Advance the machine by <paramref name="dt"/> seconds.
|
||||
/// <paramref name="worldReady"/> = destination collision landblock is resident.
|
||||
|
|
@ -104,12 +119,14 @@ public sealed class TeleportAnimSequencer
|
|||
{
|
||||
case TeleportAnimState.WorldFadeOut:
|
||||
if (_elapsed >= FadeTime)
|
||||
Advance(TeleportAnimState.TunnelFadeIn, enterTunnel: false);
|
||||
// UseTime's viewport-visibility block precedes this state
|
||||
// transition, so retail shows portal space on the next tick.
|
||||
Advance(TeleportAnimState.TunnelFadeIn, enterTunnel: true);
|
||||
break;
|
||||
|
||||
case TeleportAnimState.TunnelFadeIn:
|
||||
if (_elapsed >= FadeTime)
|
||||
Advance(TeleportAnimState.Tunnel, enterTunnel: true);
|
||||
Advance(TeleportAnimState.Tunnel, enterTunnel: false);
|
||||
break;
|
||||
|
||||
case TeleportAnimState.Tunnel:
|
||||
|
|
@ -171,13 +188,13 @@ public sealed class TeleportAnimSequencer
|
|||
|
||||
private TeleportAnimSnapshot BuildSnapshot()
|
||||
{
|
||||
float alpha = ComputeFadeAlpha(_state, _elapsed);
|
||||
float viewBlend = ComputeViewPlaneBlend(_state, _elapsed);
|
||||
bool showTunnel = _state is TeleportAnimState.TunnelFadeIn
|
||||
or TeleportAnimState.Tunnel
|
||||
or TeleportAnimState.TunnelContinue
|
||||
or TeleportAnimState.TunnelFadeOut;
|
||||
bool pleaseWait = _state == TeleportAnimState.TunnelContinue;
|
||||
return new TeleportAnimSnapshot(_state, alpha, showTunnel, pleaseWait);
|
||||
return new TeleportAnimSnapshot(_state, viewBlend, showTunnel, pleaseWait);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -193,21 +210,26 @@ public sealed class TeleportAnimSequencer
|
|||
return RetailAnimationLevels[-negativeIndex];
|
||||
}
|
||||
|
||||
private static float ComputeFadeAlpha(TeleportAnimState state, float elapsed)
|
||||
/// <summary>
|
||||
/// Retail's four states named <c>*Fade*</c> do not drive an alpha cover.
|
||||
/// <c>gmSmartBoxUI::UseTime</c> (0x004D7133-0x004D725F) uses this eased
|
||||
/// level only to interpolate SmartBox's view-plane distance.
|
||||
/// </summary>
|
||||
private static float ComputeViewPlaneBlend(TeleportAnimState state, float elapsed)
|
||||
{
|
||||
float t = Math.Clamp(elapsed / FadeTime, 0f, 1f);
|
||||
float level = GetRetailAnimationLevel(t) / 1024f;
|
||||
return state switch
|
||||
{
|
||||
// Fading TO black (alpha 0→1):
|
||||
// Normal game view distance -> transition distance.
|
||||
TeleportAnimState.WorldFadeOut => level,
|
||||
TeleportAnimState.TunnelFadeIn => 1f - level, // tunnel fades IN: overlay goes clear
|
||||
// Full black / fully clear inside tunnel states:
|
||||
TeleportAnimState.Tunnel => 0f, // world hidden, overlay not needed
|
||||
TeleportAnimState.TunnelFadeOut => level,
|
||||
// Transition distance -> normal game view distance.
|
||||
TeleportAnimState.TunnelFadeIn => 1f - level,
|
||||
TeleportAnimState.WorldFadeIn => 1f - level,
|
||||
// Stable viewport states use the ordinary game projection.
|
||||
TeleportAnimState.Tunnel => 0f,
|
||||
TeleportAnimState.TunnelContinue => 0f,
|
||||
// Fading back out of tunnel:
|
||||
TeleportAnimState.TunnelFadeOut => level, // tunnel fades out: overlay goes black
|
||||
TeleportAnimState.WorldFadeIn => 1f - level, // world fades in: overlay clears
|
||||
_ => 0f,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue