Skip to content

Commit

Permalink
Fix getting stuck in cinematic bugs
Browse files Browse the repository at this point in the history
Also skip intro by default for creative
  • Loading branch information
Jannify committed Feb 8, 2024
1 parent 82671c4 commit 742d7a8
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 16 deletions.
18 changes: 15 additions & 3 deletions NitroxClient/GameLogic/PlayerLogic/PlayerCinematics.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using NitroxClient.Communication.Abstract;
using System.Collections.Generic;
using NitroxClient.Communication.Abstract;
using NitroxModel.DataStructures;
using NitroxModel.DataStructures.GameLogic;
using NitroxModel.Packets;
Expand All @@ -10,6 +11,11 @@ public class PlayerCinematics
private readonly IPacketSender packetSender;
private readonly LocalPlayer localPlayer;

/// <summary>
/// Some cinematics should not be played. Example the intro as it's completely handled by a dedicated system.
/// </summary>
private readonly HashSet<string> blacklistedKeys = ["escapepod_intro"];

public PlayerCinematics(IPacketSender packetSender, LocalPlayer localPlayer)
{
this.packetSender = packetSender;
Expand All @@ -18,12 +24,18 @@ public PlayerCinematics(IPacketSender packetSender, LocalPlayer localPlayer)

public void StartCinematicMode(ushort playerId, NitroxId controllerID, int controllerNameHash, string key)
{
packetSender.Send(new PlayerCinematicControllerCall(playerId, controllerID, controllerNameHash, key, true));
if (!blacklistedKeys.Contains(key))
{
packetSender.Send(new PlayerCinematicControllerCall(playerId, controllerID, controllerNameHash, key, true));
}
}

public void EndCinematicMode(ushort playerId, NitroxId controllerID, int controllerNameHash, string key)
{
packetSender.Send(new PlayerCinematicControllerCall(playerId, controllerID, controllerNameHash, key, false));
if (!blacklistedKeys.Contains(key))
{
packetSender.Send(new PlayerCinematicControllerCall(playerId, controllerID, controllerNameHash, key, false));
}
}

public void SetLocalIntroCinematicMode(IntroCinematicMode introCinematicMode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ private GameObject CreateNewEscapePod(EscapePodWorldEntity escapePodEntity)
// TODO: When we want to implement multiple escape pods, instantiate the prefab. Backlog task: #1945
// This will require some work as instantiating the prefab as-is will not make it visible.
//GameObject escapePod = Object.Instantiate(EscapePod.main.gameObject);

GameObject escapePod = EscapePod.main.gameObject;
UnityEngine.Component.DestroyImmediate(escapePod.GetComponent<NitroxEntity>()); // if template has a pre-existing NitroxEntity, remove.
NitroxEntity.SetNewId(escapePod, escapePodEntity.Id);
Expand All @@ -69,13 +69,6 @@ private GameObject CreateNewEscapePod(EscapePodWorldEntity escapePodEntity)

FixStartMethods(escapePod);

// Start() isn't executed for the EscapePod, why? Idk, maybe because it's a scene...
MultiplayerCinematicReference reference = escapePod.AddComponent<MultiplayerCinematicReference>();
foreach (PlayerCinematicController controller in escapePod.GetComponentsInChildren<PlayerCinematicController>())
{
reference.AddController(controller);
}

return escapePod;
}

Expand All @@ -84,15 +77,21 @@ private GameObject CreateNewEscapePod(EscapePodWorldEntity escapePodEntity)
/// </summary>
private static void FixStartMethods(GameObject escapePod)
{
foreach (FMOD_CustomEmitter customEmitter in escapePod.GetComponentsInChildren<FMOD_CustomEmitter>())
foreach (FMOD_CustomEmitter customEmitter in escapePod.GetComponentsInChildren<FMOD_CustomEmitter>(true))
{
customEmitter.Start();
}

foreach (FMOD_StudioEventEmitter studioEventEmitter in escapePod.GetComponentsInChildren<FMOD_StudioEventEmitter>())
foreach (FMOD_StudioEventEmitter studioEventEmitter in escapePod.GetComponentsInChildren<FMOD_StudioEventEmitter>(true))
{
studioEventEmitter.Start();
}

MultiplayerCinematicReference reference = escapePod.AddComponent<MultiplayerCinematicReference>();
foreach (PlayerCinematicController controller in escapePod.GetComponentsInChildren<PlayerCinematicController>(true))
{
reference.AddController(controller);
}
}

public bool SpawnsOwnChildren()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;
using NitroxClient.GameLogic;
using NitroxClient.Unity.Helper;
using NitroxModel.DataStructures.GameLogic;
using UnityEngine;

namespace NitroxClient.MonoBehaviours.CinematicController;
Expand All @@ -10,8 +11,18 @@ public class MultiplayerCinematicReference : MonoBehaviour
{
private readonly Dictionary<string, Dictionary<int, MultiplayerCinematicController>> controllerByKey = new();

private bool isEscapePod;

private void Start()
{
// TODO: Currently only single EscapePod is supported, therefor EscapePod.main. Can probably be removed after we use one pod per intro sequence
isEscapePod = gameObject == EscapePod.main.gameObject;
}

public void CallStartCinematicMode(string key, int identifier, RemotePlayer player)
{
if(isEscapePod && this.Resolve<LocalPlayer>().IntroCinematicMode is IntroCinematicMode.PLAYING or IntroCinematicMode.SINGLEPLAYER) return;

if (!controllerByKey.TryGetValue(key, out Dictionary<int, MultiplayerCinematicController> controllers))
{
throw new KeyNotFoundException($"There was no entry for the key {key} at {gameObject.GetFullHierarchyPath()}");
Expand All @@ -27,6 +38,8 @@ public void CallStartCinematicMode(string key, int identifier, RemotePlayer play

public void CallCinematicModeEnd(string key, int identifier, RemotePlayer player)
{
if(isEscapePod && this.Resolve<LocalPlayer>().IntroCinematicMode is IntroCinematicMode.PLAYING or IntroCinematicMode.SINGLEPLAYER) return;

if (!controllerByKey.TryGetValue(key, out Dictionary<int, MultiplayerCinematicController> controllers))
{
throw new KeyNotFoundException($"There was no entry for the key {key} at {gameObject.GetFullHierarchyPath()}");
Expand All @@ -44,7 +57,6 @@ public void CallCinematicModeEnd(string key, int identifier, RemotePlayer player

public void AddController(PlayerCinematicController playerController)
{

MultiplayerCinematicController[] allControllers = controllerByKey.SelectMany(n => n.Value.Select(x => x.Value)).ToArray();

if (!controllerByKey.TryGetValue(playerController.playerViewAnimationName, out Dictionary<int, MultiplayerCinematicController> controllers))
Expand Down
1 change: 1 addition & 0 deletions NitroxModel/DataStructures/GameLogic/IntroCinematicMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public enum IntroCinematicMode : byte
LOADING,
WAITING,
START,
PLAYING,
SINGLEPLAYER,
COMPLETED
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ private static float GetSkipTime()
private static bool IsRemoteCinematicReady(uGUI_SceneIntro uGuiSceneIntro)
{
if (callbackRun) return true;
if (GameModeUtils.currentGameMode.HasFlag(GameModeOption.Creative)) uGuiSceneIntro.Stop(true); // Stopping intro if Creative like in normal SN

if (Resolve<LocalPlayer>().IntroCinematicMode == IntroCinematicMode.COMPLETED)
{
Expand Down Expand Up @@ -120,6 +121,7 @@ private static bool IsRemoteCinematicReady(uGUI_SceneIntro uGuiSceneIntro)
{
partner = firstWaitingRemotePlayer;
EnqueueStartCinematic(uGuiSceneIntro);
Resolve<PlayerCinematics>().SetLocalIntroCinematicMode(IntroCinematicMode.PLAYING);
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public SetIntroCinematicModeProcessor(PlayerManager playerManager)
{
this.playerManager = playerManager;
}

public override void Process(SetIntroCinematicMode packet, Player player)
{
if (packet.PlayerId != player.Id)
Expand All @@ -31,8 +32,8 @@ public override void Process(SetIntroCinematicMode packet, Player player)
Log.Info($"Starting IntroCinematic for {allWaitingPlayers[0].PlayerContext.PlayerName} and {allWaitingPlayers[1].PlayerContext.PlayerName}");

allWaitingPlayers[0].PlayerContext.IntroCinematicMode = allWaitingPlayers[1].PlayerContext.IntroCinematicMode = IntroCinematicMode.START;
allWaitingPlayers[0].SendPacket(new SetIntroCinematicMode(allWaitingPlayers[1].Id, IntroCinematicMode.START));
allWaitingPlayers[1].SendPacket(new SetIntroCinematicMode(allWaitingPlayers[0].Id, IntroCinematicMode.START));
playerManager.SendPacketToAllPlayers(new SetIntroCinematicMode(allWaitingPlayers[0].Id, IntroCinematicMode.START));
playerManager.SendPacketToAllPlayers(new SetIntroCinematicMode(allWaitingPlayers[1].Id, IntroCinematicMode.START));
}
}
}

0 comments on commit 742d7a8

Please sign in to comment.