Add the conversion match mode
Introduce a second match mode alongside Classic. In Conversion mode hiders are invisible to each other (and to hunters during Hide), and a hunter hit converts the hider into a full hunter in place instead of sending them to the spectator freecam. The mode is replicated to all clients through the existing phase named-message byte; visibility is computed locally per client per mode. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f46e6258d
commit
f485d1676b
2 files changed
+113
-28
No files matched your search
@@ -86,7 +86,12 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
|
||||
if (IsOwner)
|
||||
{
|
||||
PlaceAtSpawn();
|
||||
// A Conversion-mode tag respawns the hider as this Hunter variant mid-Seek; keep the server-set
|
||||
// position (it converts where it was tagged) by skipping the spawn-area/ring placement. Match-start
|
||||
// variants spawn while the sub-phase is still None, so they DO place; end-match lobby avatars spawn
|
||||
// after the sub-phase is cleared, so they place too. Only an in-place conversion lands here mid-Seek.
|
||||
if (!SpawnedMidSeek())
|
||||
PlaceAtSpawn();
|
||||
|
||||
var manager = FindFirstObjectByType<GameModeManager>(FindObjectsInactive.Include);
|
||||
if (manager)
|
||||
@@ -168,9 +173,10 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
private void Update() => UpdateVisibility();
|
||||
|
||||
// Per-client visibility: each machine decides whether to render THIS avatar's body from the LOCAL
|
||||
// viewer's perspective. A found hider is hidden for everyone; during HIDE, hiders are hidden on hunter
|
||||
// clients only (the spec - hunters can't see hiders yet). The local owner's own body is left alone unless
|
||||
// found, so this never fights the FirstPersonController's own-body self-hide.
|
||||
// viewer's perspective (hunter bodies are always visible; only hider bodies are ever hidden). A found
|
||||
// hider (Classic) is hidden for everyone. Otherwise it depends on the match MODE - see ComputeVisible.
|
||||
// The local owner's own body is left alone unless found, so this never fights the FirstPersonController's
|
||||
// own-body self-hide.
|
||||
private void UpdateVisibility()
|
||||
{
|
||||
bool found = _isFound.Value;
|
||||
@@ -187,20 +193,46 @@ public class NetworkPlayerSetup : NetworkBehaviour
|
||||
_visibilityApplied = true;
|
||||
}
|
||||
|
||||
// Decides whether THIS avatar's body is rendered for the local viewer. Hunters and non-match avatars are
|
||||
// always visible; a Classic-found hider is always hidden; Resolution reveals everyone. The rest is the
|
||||
// hider-visibility matrix per mode:
|
||||
// Classic - Hide: hidden from hunters only (hiders still see each other); Seek: visible to all.
|
||||
// Conversion - Hide: hidden from EVERYONE (hiders don't see each other either); Seek: only hunters see
|
||||
// hiders (so they can shoot them; hiders stay blind to each other).
|
||||
private bool ComputeVisible(bool found)
|
||||
{
|
||||
if (found) return false;
|
||||
if (found) return false; // Classic: a found hider is out of play, hidden for all
|
||||
|
||||
var match = MatchManager.Instance;
|
||||
if (match && match.MatchActive
|
||||
&& match.LocalSubPhase == MatchManager.MatchSubPhase.Hide
|
||||
&& role == PlayerRole.Hider
|
||||
&& LocalViewerIsHunter())
|
||||
return false;
|
||||
if (!match || !match.MatchActive) return true; // lobby / no match -> everything visible
|
||||
if (role != PlayerRole.Hider) return true; // hunters are always visible
|
||||
|
||||
var phase = match.LocalSubPhase;
|
||||
if (phase == MatchManager.MatchSubPhase.Resolution) return true; // all revealed at the end
|
||||
|
||||
if (match.LocalMatchMode == MatchManager.MatchMode.Conversion)
|
||||
{
|
||||
// Hiders are hidden from each other the whole match; only hunters get to see them, and only
|
||||
// during Seek (so the hide phase truly hides them from everyone but themselves).
|
||||
if (phase == MatchManager.MatchSubPhase.Hide) return false;
|
||||
if (phase == MatchManager.MatchSubPhase.Seek) return LocalViewerIsHunter();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Classic: hiders are hidden from hunters during Hide only; visible to everyone otherwise.
|
||||
if (phase == MatchManager.MatchSubPhase.Hide && LocalViewerIsHunter()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// True if this avatar is spawning during the SEEK sub-phase - i.e. a Conversion-mode tag respawning a
|
||||
// hider as the Hunter variant in place. Match-start and end-match respawns never happen during Seek
|
||||
// (start spawns before Hide, end spawns after the phase is cleared), so this uniquely flags a conversion.
|
||||
private static bool SpawnedMidSeek()
|
||||
{
|
||||
var match = MatchManager.Instance;
|
||||
return match && match.LocalSubPhase == MatchManager.MatchSubPhase.Seek;
|
||||
}
|
||||
|
||||
// True if THIS machine's local player is a Hunter role variant (so it must not see hiders during hide).
|
||||
private static bool LocalViewerIsHunter()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user