diff --git a/Gamemodes/HotPotato.cs b/Gamemodes/HotPotato.cs index 8ec09071c..b0cf6aa45 100644 --- a/Gamemodes/HotPotato.cs +++ b/Gamemodes/HotPotato.cs @@ -162,7 +162,7 @@ internal static class HotPotato if (HotPotatoState.TimeLeft <= 0) { holder.Suicide(); - RecordDeath(HotPotatoState.HolderID, (HotPotatoState.RoundNum - 1) * GetKillInterval()); + RecordDeath(HotPotatoState.HolderID, Options.IntegrateNaturalDisasters.GetBool() ? (int)(Utils.TimeStamp - IntroCutsceneDestroyPatch.IntroDestroyTS - NaturalDisasters.FixedUpdatePatch.WaitTime) : (HotPotatoState.RoundNum - 1) * GetKillInterval()); PassHotPotato(); if (holder.AmOwner) diff --git a/Gamemodes/RoomRush.cs b/Gamemodes/RoomRush.cs index 5762a46af..f512d0765 100644 --- a/Gamemodes/RoomRush.cs +++ b/Gamemodes/RoomRush.cs @@ -870,6 +870,8 @@ public static class RoomRush case MapNames.Airship: time += previous switch { + SystemTypes.MeetingRoom => 5, + SystemTypes.Electrical => 4, SystemTypes.Engine => 3, SystemTypes.MainHall => 2, _ => 0 diff --git a/Main.cs b/Main.cs index d85a24ae3..5e8e9e681 100644 --- a/Main.cs +++ b/Main.cs @@ -53,8 +53,8 @@ public class Main : BaseUnityPlugin private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d"; private const string DebugKeySalt = "59687b"; public const string PluginGuid = "com.gurge44.endlesshostroles"; - public const string PluginVersion = "8.0.1"; - public const string PluginDisplayVersion = "8.0.1"; + public const string PluginVersion = "8.0.2"; + public const string PluginDisplayVersion = "8.0.2"; public const int TestBuildNumber = 0; // 0 = Release public const string NeutralColor = "#ffab1b"; diff --git a/Modules/AmciRegistration.cs b/Modules/AmciRegistration.cs index b987e5033..64db8995f 100644 --- a/Modules/AmciRegistration.cs +++ b/Modules/AmciRegistration.cs @@ -25,7 +25,7 @@ public static class AmciRegistration /// /// Writes EHR's GUID into the game's mod registration slot so the matchmaker /// can filter lobby searches to EHR lobbies only. - /// Call once from . + /// Call once when the mod loads. /// The base game code does the rest. /// public static void Apply() @@ -34,6 +34,15 @@ public static class AmciRegistration Logger.Info($"AMCI mod GUID registered: {ModGuidString}", nameof(AmciRegistration)); } + /// + /// Reverts the AMCI mod GUID registration when the mod is unloaded. + /// + public static void Revert() + { + CurrentModRegistration.ModRegistrationGuidString = string.Empty; + Logger.Info("AMCI mod GUID removed", nameof(AmciRegistration)); + } + // Fixes not being able to host local games when the mod GUID is registered [HarmonyPatch(typeof(CurrentModRegistration), nameof(CurrentModRegistration.TryGetModRegistrationGuid))] public static class TryGetModRegistrationGuidPatch diff --git a/Modules/ClientControlGUI.cs b/Modules/ClientControlGUI.cs index fc4d5108f..ab199059c 100644 --- a/Modules/ClientControlGUI.cs +++ b/Modules/ClientControlGUI.cs @@ -552,68 +552,67 @@ public class ClientControlGUI : MonoBehaviour bool canToggleHud = Main.IntroDestroyed && !inMeeting && !ExileController.Instance && !ReportDeadBodyPatch.MeetingStarted; if (canZoom || canNoClip || canToggleHud) - { Section(ref y, "Camera"); - if (canZoom) + if (canZoom) + { + // Sync slider to actual camera value so external changes (scroll wheel, touch pinch) are reflected + if (_cam) _zoomValue = _cam.orthographicSize; + + float newZoom = Slider(ref y, $"Zoom {_zoomValue:F1}x", _zoomValue, 3.0f, 18.0f, w); + if (Mathf.Abs(newZoom - _zoomValue) > 0.01f) { - // Sync slider to actual camera value so external changes (scroll wheel, touch pinch) are reflected - if (_cam) _zoomValue = _cam.orthographicSize; - - float newZoom = Slider(ref y, $"Zoom {_zoomValue:F1}x", _zoomValue, 3.0f, 18.0f, w); - if (Mathf.Abs(newZoom - _zoomValue) > 0.01f) - { - _zoomValue = newZoom; - Zoom.SetZoomSize(reset: false); - if (_cam) _cam.orthographicSize = _zoomValue; - if (HudManager.InstanceExists) HudManager.Instance.UICamera.orthographicSize = _zoomValue; - } - - if (GUI.Button(new Rect(0, y, w, ButtonHeight), "Reset Zoom", _sAction)) - { - Zoom.SetZoomSize(reset: true); - _zoomValue = 3.0f; - } - y += ButtonHeight + Padding * 0.7f; + _zoomValue = newZoom; + Zoom.SetZoomSize(reset: false); + if (_cam) _cam.orthographicSize = _zoomValue; + if (HudManager.InstanceExists) HudManager.Instance.UICamera.orthographicSize = _zoomValue; } - else if (!Mathf.Approximately(_zoomValue, 3.0f)) + + if (GUI.Button(new Rect(0, y, w, ButtonHeight), "Reset Zoom", _sAction)) { Zoom.SetZoomSize(reset: true); _zoomValue = 3.0f; } - - if (canNoClip) - { - // Reads live state every frame for correct label/colour; lambda also reads it on click to avoid stale values - bool noclipOn = ControllerManagerUpdatePatch.NoClipEnabled; - Btn(ref y, noclipOn ? "Noclip: ON" : "Noclip: OFF", noclipOn ? _sHost : _sAction, () => - { - ControllerManagerUpdatePatch.NoClipEnabled = !ControllerManagerUpdatePatch.NoClipEnabled; - if (OperatingSystem.IsAndroid()) PlayerControl.LocalPlayer.Collider.offset = ControllerManagerUpdatePatch.NoClipEnabled ? new Vector2(0f, 127f) : new Vector2(0f, -0.3636f); - }); - } - else if (ControllerManagerUpdatePatch.NoClipEnabled && OperatingSystem.IsAndroid() && PlayerControl.LocalPlayer) - { - PlayerControl.LocalPlayer.Collider.offset = new Vector2(0f, -0.3636f); - ControllerManagerUpdatePatch.NoClipEnabled = false; - } - - if (canToggleHud) - { - Btn(ref y, HudHidden ? "Show HUD" : "Hide HUD", HudHidden ? _sHost : _sAction, () => - { - HudHidden = !HudHidden; - if (HudManager.InstanceExists) - HudManager.Instance.gameObject.SetActive(!HudHidden); - }); - } - else if (HudHidden) - { - HudHidden = false; - if (HudManager.InstanceExists) - HudManager.Instance.gameObject.SetActive(true); - } + y += ButtonHeight + Padding * 0.7f; } + else if (!Mathf.Approximately(_zoomValue, 3.0f)) + { + Zoom.SetZoomSize(reset: true); + _zoomValue = 3.0f; + } + + if (canNoClip) + { + // Reads live state every frame for correct label/colour; lambda also reads it on click to avoid stale values + bool noclipOn = ControllerManagerUpdatePatch.NoClipEnabled; + Btn(ref y, noclipOn ? "Noclip: ON" : "Noclip: OFF", noclipOn ? _sHost : _sAction, () => + { + ControllerManagerUpdatePatch.NoClipEnabled = !ControllerManagerUpdatePatch.NoClipEnabled; + if (OperatingSystem.IsAndroid()) PlayerControl.LocalPlayer.Collider.offset = ControllerManagerUpdatePatch.NoClipEnabled ? new Vector2(0f, 127f) : new Vector2(0f, -0.3636f); + }); + } + else if (ControllerManagerUpdatePatch.NoClipEnabled && OperatingSystem.IsAndroid() && PlayerControl.LocalPlayer) + { + PlayerControl.LocalPlayer.Collider.offset = new Vector2(0f, -0.3636f); + ControllerManagerUpdatePatch.NoClipEnabled = false; + } + + if (canToggleHud) + { + Btn(ref y, HudHidden ? "Show HUD" : "Hide HUD", HudHidden ? _sHost : _sAction, () => + { + HudHidden = !HudHidden; + if (HudManager.InstanceExists) + HudManager.Instance.gameObject.SetActive(!HudHidden); + }); + } + else if (HudHidden) + { + HudHidden = false; + if (HudManager.InstanceExists) + HudManager.Instance.gameObject.SetActive(true); + } + Section(ref y, "Utilities"); diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index a36990d90..747ea98a9 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -1507,9 +1507,7 @@ internal static class ExtendedPlayerControl try { - var queue = player.NetTransform.incomingPosQueue; - - if (queue.Count > 0 && player.NetTransform.isActiveAndEnabled && !player.NetTransform.isPaused) + if (player.NetTransform.incomingPosQueue.Count > 0 && player.NetTransform.isActiveAndEnabled && !player.NetTransform.isPaused) return CustomNetworkTransformHelper.CurrentPosition[player.PlayerId]; } catch (Exception e) { ThrowException(e); } diff --git a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs index cab2da8e8..8d3f01743 100644 --- a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs +++ b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs @@ -605,6 +605,9 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS break; } } + + if (Options.IntegrateNaturalDisasters.GetBool() && Options.CurrentGameMode != CustomGameMode.NaturalDisasters) + NaturalDisasters.ApplyGameOptions(opt, player.PlayerId); switch (player.GetCustomRoleTypes()) { diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 5134ddf3e..d971176d4 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -2767,6 +2767,21 @@ public static class Utils catch (Exception e) { ThrowException(e); } } + public static bool ChatDuringGame() + { + return Options.CurrentGameMode switch + { + CustomGameMode.SoloPVP => SoloPVP.SoloPVP_ChatDuringGame.GetBool(), + CustomGameMode.FFA => FreeForAll.FFAChatDuringGame.GetBool(), + CustomGameMode.Mingle => Mingle.ChatDuringGameOption.GetBool(), + CustomGameMode.Quiz => Quiz.Chat, + CustomGameMode.HideAndSeek => CustomHnS.Chat, + CustomGameMode.NaturalDisasters => NaturalDisasters.Chat, + CustomGameMode.Standard => Options.ChatDuringGame.GetBool(), + _ => false + }; + } + public static string BuildSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false) { BuildSBSuffix.Clear().Append("<#ffffff>"); @@ -3112,7 +3127,7 @@ public static class Utils SelfSuffix.Append($"\n\n<#ffffff>{GetString($"GameModeTutorial.{Options.CurrentGameMode}")}\n"); } - bool noRoleText = GameStates.IsLobby || Options.CurrentGameMode is CustomGameMode.CaptureTheFlag or CustomGameMode.NaturalDisasters or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz or CustomGameMode.TheMindGame or CustomGameMode.BedWars or CustomGameMode.Deathrace or CustomGameMode.Mingle or CustomGameMode.Snowdown or CustomGameMode.DoomTag; + bool noRoleText = GameStates.IsLobby || ChatDuringGame() || Options.CurrentGameMode is CustomGameMode.CaptureTheFlag or CustomGameMode.NaturalDisasters or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz or CustomGameMode.TheMindGame or CustomGameMode.BedWars or CustomGameMode.Deathrace or CustomGameMode.Mingle or CustomGameMode.Snowdown or CustomGameMode.DoomTag; // Combine the seer's job title and SelfTaskText with the seer's player name and SelfMark string selfRoleName = noRoleText ? string.Empty : $"{seer.GetDisplayRoleName()}{selfTaskText}"; @@ -3469,7 +3484,8 @@ public static class Utils var targetDeathReason = string.Empty; string newLineBeforeSuffix = !(Options.CurrentGameMode == CustomGameMode.BedWars && GameStates.InGame) ? "\r\n" : " - "; - if (seer.KnowDeathReason(target) && !GameStates.IsLobby) targetDeathReason = $"{newLineBeforeSuffix}({CustomRoles.Doctor.ColoredTextByRole(GetVitalText(target.PlayerId))})"; + noRoleText = GameStates.IsLobby || ChatDuringGame() || Options.CurrentGameMode is CustomGameMode.CaptureTheFlag or CustomGameMode.NaturalDisasters or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz or CustomGameMode.TheMindGame or CustomGameMode.BedWars or CustomGameMode.Deathrace or CustomGameMode.Mingle or CustomGameMode.Snowdown or CustomGameMode.DoomTag; + if (seer.KnowDeathReason(target) && !GameStates.IsLobby && !noRoleText) targetDeathReason = $"{newLineBeforeSuffix}({CustomRoles.Doctor.ColoredTextByRole(GetVitalText(target.PlayerId))})"; // Devourer if (Devourer.HideNameOfConsumedPlayer.GetBool() && !GameStates.IsLobby && !camouflageIsForMeeting) diff --git a/Patches/ClientOptionsPatch.cs b/Patches/ClientOptionsPatch.cs index 45655f50b..1d86f48e9 100644 --- a/Patches/ClientOptionsPatch.cs +++ b/Patches/ClientOptionsPatch.cs @@ -2,6 +2,7 @@ using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; +using EHR.Modules; using HarmonyLib; using UnityEngine; @@ -127,6 +128,7 @@ public static class OptionsMenuBehaviourStartPatch { if (ClientControlGUI.Instance) Object.Destroy(ClientControlGUI.Instance); MainMenuManagerPatch.ShowRightPanelImmediately(); + AmciRegistration.Revert(); Main.Instance.Harmony.UnpatchSelf(); #if IL2CPP diff --git a/Patches/GameOptionsPatch.cs b/Patches/GameOptionsPatch.cs index 8cc1d8585..2edd6114e 100644 --- a/Patches/GameOptionsPatch.cs +++ b/Patches/GameOptionsPatch.cs @@ -1,4 +1,5 @@ using AmongUs.GameOptions; +using EHR.Modules; using HarmonyLib; namespace EHR.Patches; @@ -33,6 +34,7 @@ internal static class SwitchGameModePatch } Zoom.SetZoomSize(reset: true); + AmciRegistration.Revert(); Main.Instance.Harmony.UnpatchSelf(); #if IL2CPP Main.Instance.Unload(); diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index d910f6d88..d92bf0e09 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -1070,6 +1070,12 @@ internal static class BeginCrewmatePatch } } + if (Options.IntegrateNaturalDisasters.GetBool() && Options.CurrentGameMode is not CustomGameMode.NaturalDisasters and not CustomGameMode.Standard) + { + __instance.ImpostorText.gameObject.SetActive(true); + __instance.ImpostorText.text = $"+ {Utils.ColorString(Main.GameModeColors[CustomGameMode.NaturalDisasters], GetString("NDPlayer"))}"; + } + return; AudioClip GetAudioClipFromCustomRoleType() => @@ -1255,18 +1261,8 @@ internal static class IntroCutsceneDestroyPatch } } - switch (Options.CurrentGameMode) - { - case CustomGameMode.SoloPVP when SoloPVP.SoloPVP_ChatDuringGame.GetBool(): - case CustomGameMode.FFA when FreeForAll.FFAChatDuringGame.GetBool(): - case CustomGameMode.Mingle when Mingle.ChatDuringGameOption.GetBool(): - case CustomGameMode.Quiz when Quiz.Chat: - case CustomGameMode.HideAndSeek when CustomHnS.Chat: - case CustomGameMode.NaturalDisasters when NaturalDisasters.Chat: - case CustomGameMode.Standard when Options.ChatDuringGame.GetBool(): - LateTask.New(() => Main.AllAlivePlayerControlsToList.SetChatVisible(true), 4f); - break; - } + if (Utils.ChatDuringGame()) + LateTask.New(() => Main.AllAlivePlayerControlsToList.SetChatVisible(true), 4f); // LateTask.New(() => Main.EnumeratePlayerControls().Do(pc ⇒ pc.RpcSetRoleDesync(RoleTypes.Shapeshifter, -3)), 2f, "SetImpostorForServer"); diff --git a/Patches/MatchInfoGuidePatch.cs b/Patches/MatchInfoGuidePatch.cs index d6a288f46..4a5fb0e12 100644 --- a/Patches/MatchInfoGuidePatch.cs +++ b/Patches/MatchInfoGuidePatch.cs @@ -29,6 +29,7 @@ public static class MatchInfoGuidePatch __instance.matchInfoSettingsMaskArea.material.SetInt(PlayerMaterial.MaskLayer, 50); __instance.CreatePlayerEntries(); ReColorTabButtons(__instance); + SetAlternativeText(__instance); return false; } @@ -149,4 +150,12 @@ public static class MatchInfoGuidePatch } } } + + private static void SetAlternativeText(MatchInfoGuide __instance) + { + CustomGameMode currentGameMode = Options.CurrentGameMode; + var tmp = __instance.rolesEnabledMessage.GetComponent(); + tmp.DestroyTranslator(); + tmp.text = currentGameMode == CustomGameMode.Standard ? TranslationController.Instance.GetString(StringNames.MatchInfoGuideNoRolesMessage) : Translator.GetString(Main.HasPlayedGM.ContainsKey(currentGameMode) ? $"GameModeTutorial.{currentGameMode}" : $"ModeDescribe.{currentGameMode}"); + } } \ No newline at end of file diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index 8fab6b04f..bee1ca538 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -1439,10 +1439,6 @@ internal static class MeetingHudOnDestroyPatch } if (Main.LIMap) Main.Instance.StartCoroutine(WaitForExileFinish()); - - GC.Collect(); - Resources.UnloadUnusedAssets(); - GC.Collect(); return; IEnumerator WaitForExileFinish() diff --git a/Patches/OutroPatch.cs b/Patches/OutroPatch.cs index 46b2ffbf7..e20c8d758 100644 --- a/Patches/OutroPatch.cs +++ b/Patches/OutroPatch.cs @@ -800,13 +800,6 @@ internal static class SetEverythingUpPatch yield return null; } } - - yield return null; - - GC.Collect(); - yield return null; - Resources.UnloadUnusedAssets(); - GC.Collect(); } static string GetAdditionalWinnerRoleName(string role) diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 3311dd590..8aef0a274 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -1657,7 +1657,7 @@ internal static class FixedUpdatePatch if (self) { - if (NumSnapToCallsThisRound > 80) + if (NumSnapToCallsThisRound > 80 && !lowLoad) NumSnapToCallsThisRound = 80; Zoom.OnFixedUpdate(); @@ -2207,7 +2207,8 @@ internal static class FixedUpdatePatch string suffix = Suffix.ToString().Trim(); string newLineBeforeSuffix = !(Options.CurrentGameMode == CustomGameMode.BedWars && !self && GameStates.InGame) ? "\n" : " - "; - string deathReason = !seer.IsAlive() && seer.KnowDeathReason(target) ? $"{newLineBeforeSuffix}『{CustomRoles.Doctor.ColoredTextByRole(GetVitalText(target.PlayerId))}』" : string.Empty; + bool noRoleText = GameStates.IsLobby || ChatDuringGame() || Options.CurrentGameMode is CustomGameMode.CaptureTheFlag or CustomGameMode.NaturalDisasters or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz or CustomGameMode.TheMindGame or CustomGameMode.BedWars or CustomGameMode.Deathrace or CustomGameMode.Mingle or CustomGameMode.Snowdown or CustomGameMode.DoomTag; + string deathReason = !seer.IsAlive() && seer.KnowDeathReason(target) && !noRoleText ? $"{newLineBeforeSuffix}『{CustomRoles.Doctor.ColoredTextByRole(GetVitalText(target.PlayerId))}』" : string.Empty; target.cosmetics.nameText.text = $"{roleText}{realName}{deathReason}{Mark}{newLineBeforeSuffix}{suffix}";