diff --git a/Assets/Scripts/BuildInfo.cs b/Assets/Scripts/BuildInfo.cs index 9043282f54..8fd02be07f 100644 --- a/Assets/Scripts/BuildInfo.cs +++ b/Assets/Scripts/BuildInfo.cs @@ -1 +1 @@ -public static class BuildInfo{public static string BUILD_TIME = "12/31/2023 4:26:34 AM";} +public static class BuildInfo{public static string BUILD_TIME = "1/2/2024 2:12:46 AM";} diff --git a/Assets/Scripts/Entity/EntityMover.cs b/Assets/Scripts/Entity/EntityMover.cs index 49384c1701..f0b13b16bf 100644 --- a/Assets/Scripts/Entity/EntityMover.cs +++ b/Assets/Scripts/Entity/EntityMover.cs @@ -44,6 +44,7 @@ public Vector2 Position { [SerializeField] private bool bounceOnImpacts; //---Private Variables + private Vector2 previousInternalPosition; private Vector2 previousRenderPosition; private PropertyReader internalPositionPropertyReader; @@ -79,9 +80,18 @@ public unsafe override void Render() { if (Freeze) { newPosition = Position; } else if (TryGetSnapshotsBuffers(out var from, out var to, out float alpha)) { + // Snapshot interpolation with no smoothing: + Vector2 fromVector; + Vector2 toVector; - (Vector2 fromVector, Vector2 toVector) = internalPositionPropertyReader.Read(from, to); + if (ForceSnapshotInterpolation) { + fromVector = previousInternalPosition; + toVector = Position; + previousInternalPosition = Position; + } else { + (fromVector, toVector) = internalPositionPropertyReader.Read(from, to); + } if (interpolationTeleportDistance > 0 && Utils.WrappedDistance(fromVector, toVector) > interpolationTeleportDistance) { // Teleport over large distances @@ -94,7 +104,6 @@ public unsafe override void Render() { } } else { // Fallback interpolation with some smoothing: - if (interpolationTeleportDistance > 0 && Utils.WrappedDistance(previousRenderPosition, Position) > interpolationTeleportDistance) { // Teleport over large distances newPosition = Utils.WrapWorldLocation(Position); diff --git a/Assets/Scripts/Entity/World Elements/GenericMover.cs b/Assets/Scripts/Entity/World Elements/GenericMover.cs index cb70008625..ad561b6677 100644 --- a/Assets/Scripts/Entity/World Elements/GenericMover.cs +++ b/Assets/Scripts/Entity/World Elements/GenericMover.cs @@ -4,7 +4,7 @@ using NSMB.Game; //[OrderBefore(typeof(EntityMover))] -public class GenericMover : NetworkBehaviour, IBeforeTick, IWaitForGameStart { +public class GenericMover : NetworkBehaviour, IBeforeTick, IWaitForGameStart, IWaitForGameEnd { //---Networked Variables [Networked] private Vector3 Origin { get; set; } @@ -61,10 +61,14 @@ public override void FixedUpdateNetwork() { SetPosition(transform, Origin, Runner.SimulationTime - GameManager.Instance.GameStartTime); } - public void Execute() { + void IWaitForGameStart.Execute() { Enabled = true; } + void IWaitForGameEnd.Execute() { + Enabled = false; + } + private void SetPosition(Transform target, Vector3 origin, float secondsElapsed) { if (!target) { target = transform; diff --git a/Assets/Scripts/Entity/World Elements/IWaitForGameEnd.cs b/Assets/Scripts/Entity/World Elements/IWaitForGameEnd.cs new file mode 100644 index 0000000000..14ef157c81 --- /dev/null +++ b/Assets/Scripts/Entity/World Elements/IWaitForGameEnd.cs @@ -0,0 +1,35 @@ +using Fusion; + +public interface IWaitForGameEnd { + + public virtual FunctionTarget Target => FunctionTarget.All; + + void AttemptExecute(NetworkObject obj) { + switch (Target) { + case FunctionTarget.All: { + Execute(); + break; + } + case FunctionTarget.ServerHostOnly: { + if (obj.Runner.IsServer) { + Execute(); + } + + break; + } + case FunctionTarget.ObjectOwnerOnly: { + if (obj.HasInputAuthority) { + Execute(); + } + + break; + } + } + } + + void Execute(); + + public enum FunctionTarget { + All, ServerHostOnly, ObjectOwnerOnly + } +} diff --git a/Assets/Scripts/Entity/World Elements/IWaitForGameEnd.cs.meta b/Assets/Scripts/Entity/World Elements/IWaitForGameEnd.cs.meta new file mode 100644 index 0000000000..a3b0450971 --- /dev/null +++ b/Assets/Scripts/Entity/World Elements/IWaitForGameEnd.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fb54e2ac78114574cb5c9d3a0f03f805 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/IWaitForGameStart.cs b/Assets/Scripts/Entity/World Elements/IWaitForGameStart.cs similarity index 100% rename from Assets/Scripts/IWaitForGameStart.cs rename to Assets/Scripts/Entity/World Elements/IWaitForGameStart.cs diff --git a/Assets/Scripts/IWaitForGameStart.cs.meta b/Assets/Scripts/Entity/World Elements/IWaitForGameStart.cs.meta similarity index 100% rename from Assets/Scripts/IWaitForGameStart.cs.meta rename to Assets/Scripts/Entity/World Elements/IWaitForGameStart.cs.meta diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index b603e60969..4bfea5c514 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -684,6 +684,11 @@ private IEnumerator EndGame(int winningTeam) { PlaySounds = false; endSoundPlayed = true; + // End "WaitForGameEnd" objects + foreach (var wfge in FindObjectsByType(FindObjectsSortMode.None).Where(nb => nb is IWaitForGameEnd)) { + ((IWaitForGameEnd) wfge).AttemptExecute(wfge.Object); + } + ForceUnpause(); musicManager.Stop(); diff --git a/Assets/Scripts/Networking/Fusion/NetworkHandler.cs b/Assets/Scripts/Networking/Fusion/NetworkHandler.cs index 031dfe64ac..56320a0684 100644 --- a/Assets/Scripts/Networking/Fusion/NetworkHandler.cs +++ b/Assets/Scripts/Networking/Fusion/NetworkHandler.cs @@ -453,17 +453,19 @@ public static async Task ConnectToRegion(string region = "") { object communicator = cloudServices.GetType().GetProperty("Communicator", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).GetValue(cloudServices); object client = communicator.GetType().GetProperty("Client", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).GetValue(communicator); object regionHandler = client.GetType().GetField("RegionHandler", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).GetValue(client); - IList regions = (IList) regionHandler.GetType().GetProperty("EnabledRegions", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).GetValue(regionHandler); - - var codeField = regions[0].GetType().GetProperty("Code", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); - var pingField = regions[0].GetType().GetProperty("Ping", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); - foreach (object item in regions) { - string code = (string) codeField.GetValue(item); - int ping = (int) pingField.GetValue(item); - RegionPings[code] = ping; - } + if (regionHandler != null) { + IList regions = (IList) regionHandler.GetType().GetProperty("EnabledRegions", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).GetValue(regionHandler); + + var codeField = regions[0].GetType().GetProperty("Code", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); + var pingField = regions[0].GetType().GetProperty("Ping", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); + foreach (object item in regions) { + string code = (string) codeField.GetValue(item); + int ping = (int) pingField.GetValue(item); + RegionPings[code] = ping; + } - OnRegionPingsUpdated?.Invoke(); + OnRegionPingsUpdated?.Invoke(); + } } catch (Exception e) { Debug.LogError(e); } diff --git a/Assets/Scripts/UI/Menu/Chat/MainMenuChat.cs b/Assets/Scripts/UI/Menu/Chat/MainMenuChat.cs index 6308b73092..672768fbd0 100644 --- a/Assets/Scripts/UI/Menu/Chat/MainMenuChat.cs +++ b/Assets/Scripts/UI/Menu/Chat/MainMenuChat.cs @@ -40,16 +40,19 @@ public void UpdatePlayerColors() { } public void SetTypingIndicator(PlayerRef player) { - if (!MainMenuManager.Instance) + if (!MainMenuManager.Instance) { return; + } PlayerData data; - if ((data = player.GetPlayerData(NetworkHandler.Runner)) && data.IsMuted) + if ((data = player.GetPlayerData(NetworkHandler.Runner)) && data.IsMuted) { return; + } PlayerListEntry ple = MainMenuManager.Instance.playerList.GetPlayerListEntry(player); - if (ple) + if (ple) { ple.typingCounter = 4; + } } public void SendChat() { @@ -61,8 +64,9 @@ public void SendChat() { } string text = chatbox.text.Replace("\n", " ").Trim(); - if (string.IsNullOrWhiteSpace(text)) + if (string.IsNullOrWhiteSpace(text)) { return; + } if (text.StartsWith('/')) { ChatManager.Instance.AddSystemMessage("ui.inroom.chat.command"); @@ -73,8 +77,9 @@ public void SendChat() { } public void ClearChat() { - foreach (ChatMessage message in chatMessages) + foreach (ChatMessage message in chatMessages) { Destroy(message.gameObject); + } chatMessages.Clear(); } @@ -94,18 +99,21 @@ public void OnChatMessage(ChatMessage.ChatMessageData data) { } public void OnTextboxChanged() { - if (!MainMenuManager.Instance) + if (!MainMenuManager.Instance) { return; + } int size = chatbox.text.Length; - if (size == previousTextLength) + if (size == previousTextLength) { return; + } previousTextLength = size; PlayerListEntry ple = MainMenuManager.Instance.playerList.GetPlayerListEntry(NetworkHandler.Runner.LocalPlayer); - if (!ple || ple.typingCounter > 2) + if (!ple || ple.typingCounter > 2) { return; + } SessionData.Instance.Rpc_UpdateTypingCounter(); } diff --git a/Assets/Scripts/UI/Menu/MainMenuManager.cs b/Assets/Scripts/UI/Menu/MainMenuManager.cs index d98157cc1d..11d70e1b40 100644 --- a/Assets/Scripts/UI/Menu/MainMenuManager.cs +++ b/Assets/Scripts/UI/Menu/MainMenuManager.cs @@ -498,19 +498,7 @@ public void UpdateStartGameButton() { } public bool IsRoomConfigurationValid() { - List nonSpectators = Runner.ActivePlayers.Select(p => p.GetPlayerData(Runner)).Where(pd => !pd.IsManualSpectator).ToList(); - bool validRoomConfig = true; - - int realPlayers = nonSpectators.Count(); - validRoomConfig &= realPlayers >= 1; - - // Only do team checks if there's more than one player - if (SessionData.Instance && SessionData.Instance.Teams && realPlayers > 1) { - int teams = nonSpectators.Select(pd => pd.Team).Distinct().Count(); - validRoomConfig &= teams > 1; - } - - return validRoomConfig; + return Runner.ActivePlayers.Select(p => p.GetPlayerData(Runner)).Where(pd => !pd.IsManualSpectator).Count() >= 1; } public void Kick(PlayerData target) { diff --git a/Assets/Scripts/UI/Menu/PlayerListHandler.cs b/Assets/Scripts/UI/Menu/PlayerListHandler.cs index bc826015dc..1da7ef90b5 100644 --- a/Assets/Scripts/UI/Menu/PlayerListHandler.cs +++ b/Assets/Scripts/UI/Menu/PlayerListHandler.cs @@ -18,11 +18,13 @@ public class PlayerListHandler : MonoBehaviour { private NetworkRunner Runner => NetworkHandler.Instance.runner; public void OnEnable() { - if (!NetworkHandler.Instance.runner) + if (!NetworkHandler.Instance || !Runner) { return; + } - if (NetworkHandler.Instance.runner.SessionInfo.IsValid) + if (NetworkHandler.Instance.runner.SessionInfo.IsValid) { PopulatePlayerEntries(true); + } NetworkHandler.OnPlayerJoined += OnPlayerJoined; NetworkHandler.OnPlayerLeft += OnPlayerLeft; @@ -39,8 +41,9 @@ public void PopulatePlayerEntries(bool addSelf) { RemoveAllPlayerEntries(); try { foreach (PlayerRef player in Runner.ActivePlayers) { - if (addSelf || Runner.LocalPlayer != player) + if (addSelf || Runner.LocalPlayer != player) { AddPlayerEntry(player); + } } } catch { @@ -49,8 +52,9 @@ public void PopulatePlayerEntries(bool addSelf) { public void AddPlayerEntry(PlayerRef player) { PlayerData data = player.GetPlayerData(Runner); - if (!data || !template) + if (!data || !template) { return; + } if (!playerListEntries.ContainsKey(player)) { GameObject go = Instantiate(template, contentPane.transform); @@ -71,8 +75,9 @@ public void RemoveAllPlayerEntries() { } public void RemovePlayerEntry(PlayerRef player) { - if (!playerListEntries.ContainsKey(player)) + if (!playerListEntries.ContainsKey(player)) { return; + } Destroy(playerListEntries[player].gameObject); playerListEntries.Remove(player); @@ -80,11 +85,13 @@ public void RemovePlayerEntry(PlayerRef player) { } public void UpdateAllPlayerEntries() { - foreach (PlayerRef player in Runner.ActivePlayers) + foreach (PlayerRef player in Runner.ActivePlayers) { UpdatePlayerEntry(player, false); + } - if (MainMenuManager.Instance) + if (MainMenuManager.Instance) { MainMenuManager.Instance.chat.UpdatePlayerColors(); + } } public void UpdatePlayerEntry(PlayerRef player, bool updateChat = true) { @@ -96,23 +103,26 @@ public void UpdatePlayerEntry(PlayerRef player, bool updateChat = true) { playerListEntries[player].UpdateText(); ReorderEntries(); - if (updateChat && MainMenuManager.Instance) + if (updateChat && MainMenuManager.Instance) { MainMenuManager.Instance.chat.UpdatePlayerColors(); + } } public void ReorderEntries() { foreach (PlayerRef player in Runner.ActivePlayers.OrderByDescending(pr => pr.GetPlayerData(NetworkHandler.Runner).JoinTick)) { - if (!playerListEntries.ContainsKey(player)) + if (!playerListEntries.ContainsKey(player)) { continue; + } playerListEntries[player].transform.SetAsFirstSibling(); } } public PlayerListEntry GetPlayerListEntry(PlayerRef player) { - if (playerListEntries.ContainsKey(player)) + if (playerListEntries.ContainsKey(player)) { return playerListEntries[player]; + } return null; }