Add manual radar ping, blip refresh/fade, and resolution statue barrier

- Manual hider ping on "E": server-authoritative RequestManualPing gated to
  Seek + living hider; shared EmitRadarPings path so interval and manual pings
  produce identical blips. Ping key read client-side in GameModeManager, role-
  gated and excluded in FreeCam (E is fly-up there).
- Radar refreshes an existing blip for the same transform target instead of
  duplicating it (lifetime resets to the configured value) via RadarTarget.Refresh.
- Blips fade in/out independently of the disc fade: per-blip MoveTowards factor
  multiplied on top of the radar fade, refresh-safe, with separate in/out speeds.
- Resolution countdown waits for conversion statues to load: generalized the
  match-start loading barrier (RunReadinessBarrier over _barrierTargets, hold
  phase carried in MsgBeginLoad) and run it a second time over statue IDs before
  starting the real resolveDuration. Only holds for Conversion with real statues.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-06 13:59:28 +02:00
1 parent 8f31c07bef
commit bfcd84afe4
4 files changed
+199 -64

No files matched your search

@@ -42,6 +42,16 @@ public class GameModeManager : MonoBehaviour
[Tooltip("Mode active at startup (0 = Player Control).")]
public int startModeIndex = 0;
[Header("Hider radar ping")]
[Tooltip("Key a HIDER presses to manually ping itself on every hunter's radar during Seek - the same blip " +
"as the periodic sweep, on demand. Ignored for hunters, outside Seek, and in Free Cam (whose fly " +
"controls already use this key).")]
#if ENABLE_INPUT_SYSTEM
public Key pingKey = Key.E;
#else
public KeyCode pingKey = KeyCode.E;
#endif
[Header("Player collision")]
[Tooltip("ON = players physically block each other (default). OFF = the local player passes through every " +
"other player - their CharacterController stops colliding with other players' body colliders. " +
@@ -76,6 +86,7 @@ public class GameModeManager : MonoBehaviour
private bool _paused;
private int _resumeIndex = -1;
private bool _loadFrozen; // true while the pre-match Loading barrier is holding the local player still
private PlayerRole? _localRole; // bound local avatar's role (null = pre-spawn / spectator / unscoped lobby)
// Player-collision reconciler state (see ReconcilePlayerCollision). Non-serialized: reset each play session.
private bool _playerCollisionDirty = true; // force a re-apply (startup, toggle flip, inspector edit)
@@ -180,6 +191,7 @@ public class GameModeManager : MonoBehaviour
{
player = null;
painter = null;
_localRole = null; // spectator / released: no hider ping
PainterChanged?.Invoke(null);
}
@@ -237,9 +249,15 @@ public class GameModeManager : MonoBehaviour
// Lobby avatar -> full set; match variant -> its role's modes. Scope is baked per prefab
// variant, so it follows the spawned avatar with no replicated-phase timing race.
if (setup && setup.ScopedModes)
{
_localRole = setup.Role;
BuildModes(setup.Role);
}
else
{
_localRole = null; // unscoped lobby avatar: no hider ping
BuildModes(null);
}
// Index 0 is each set's intended start mode.
SwitchTo(0);
@@ -394,6 +412,13 @@ public class GameModeManager : MonoBehaviour
SwitchTo(next);
}
// A hider manually pings itself onto every hunter's radar (same blip as the periodic sweep), on demand.
// Excluded in Free Cam whose fly controls already use this key; the phase/role gate lives in MatchManager
// (RequestManualPing no-ops outside Seek / for a found hider), so a stray press is harmless.
if (_localRole == PlayerRole.Hider && !(ActiveMode is FreeCamMode) &&
InputUtil.GameplayKeyPressed(pingKey) && MatchManager.Instance)
MatchManager.Instance.RequestManualPing();
ActiveMode?.Tick();
}