mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
Fully fix memory leak from settings UI + fix UI reload breaking it
This commit is contained in:
1 parent
07296ed616
commit
52132e18f8
22 files changed
+160
-84
No files matched your search
@@ -207,6 +207,7 @@ public class Main : BasePlugin
|
||||
public static ConfigEntry<bool> ButtonCooldownInDecimalUnder10s { get; private set; }
|
||||
public static ConfigEntry<bool> CancelPetAnimation { get; private set; }
|
||||
public static ConfigEntry<bool> TryFixStuttering { get; private set; }
|
||||
public static ConfigEntry<bool> ShowClientControlGUI { get; private set; }
|
||||
public static ConfigEntry<float> UIScaleFactor { get; private set; }
|
||||
|
||||
// Preset Name Options
|
||||
@@ -300,6 +301,7 @@ public class Main : BasePlugin
|
||||
ButtonCooldownInDecimalUnder10s = Config.Bind("Client Options", "ButtonCooldownInDecimalUnder10s", false);
|
||||
CancelPetAnimation = Config.Bind("Client Options", "CancelPetAnimation", true);
|
||||
TryFixStuttering = Config.Bind("Client Options", "TryFixStuttering", true);
|
||||
ShowClientControlGUI = Config.Bind("Client Options", "ShowClientControlGUI", true);
|
||||
UIScaleFactor = Config.Bind("Client Options", "UIScaleFactor", 1f);
|
||||
|
||||
AddComponent<ClientControlGUI>();
|
||||
|
||||
@@ -25,7 +25,7 @@ public class ClientOptionItem
|
||||
|
||||
ToggleButtonBehaviour mouseMoveToggle = optionsMenuBehaviour.DisableMouseMovement;
|
||||
|
||||
if (CustomBackground == null)
|
||||
if (!CustomBackground)
|
||||
{
|
||||
CustomBackground = Object.Instantiate(optionsMenuBehaviour.Background, optionsMenuBehaviour.transform);
|
||||
CustomBackground.name = "CustomBackground";
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace EHR.Modules.Extensions;
|
||||
public sealed class CountdownTimer : IDisposable
|
||||
{
|
||||
private readonly float _durationSeconds;
|
||||
private readonly Stopwatch _stopwatch;
|
||||
private Coroutine _coroutine;
|
||||
private bool _completed;
|
||||
|
||||
@@ -27,7 +26,7 @@ public sealed class CountdownTimer : IDisposable
|
||||
throw new ArgumentOutOfRangeException(nameof(durationSeconds));
|
||||
|
||||
_durationSeconds = durationSeconds;
|
||||
_stopwatch = new Stopwatch();
|
||||
Stopwatch = new Stopwatch();
|
||||
|
||||
_cancelOnMeeting = cancelOnMeeting;
|
||||
_cancelOnGameEnd = cancelOnGameEnd;
|
||||
@@ -57,12 +56,12 @@ public sealed class CountdownTimer : IDisposable
|
||||
if (_completed)
|
||||
return TimeSpan.Zero;
|
||||
|
||||
TimeSpan remaining = TimeSpan.FromSeconds(_durationSeconds) - _stopwatch.Elapsed;
|
||||
TimeSpan remaining = TimeSpan.FromSeconds(_durationSeconds) - Stopwatch.Elapsed;
|
||||
return remaining >= TimeSpan.Zero ? remaining : TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public Stopwatch Stopwatch => _stopwatch;
|
||||
public Stopwatch Stopwatch { get; }
|
||||
|
||||
public void Start()
|
||||
{
|
||||
@@ -70,7 +69,7 @@ public sealed class CountdownTimer : IDisposable
|
||||
return;
|
||||
|
||||
_completed = false;
|
||||
_stopwatch.Restart();
|
||||
Stopwatch.Restart();
|
||||
_coroutine = Main.Instance.StartCoroutine(_hasTickEvent ? Run() : RunWithoutTicks());
|
||||
}
|
||||
|
||||
@@ -84,7 +83,7 @@ public sealed class CountdownTimer : IDisposable
|
||||
{
|
||||
int lastRemaining = (int)Math.Ceiling(Remaining.TotalSeconds);
|
||||
|
||||
while (_stopwatch.Elapsed.TotalSeconds < _durationSeconds)
|
||||
while (Stopwatch.Elapsed.TotalSeconds < _durationSeconds)
|
||||
{
|
||||
int remaining = (int)Math.Ceiling(Remaining.TotalSeconds);
|
||||
|
||||
@@ -101,7 +100,7 @@ public sealed class CountdownTimer : IDisposable
|
||||
if (remaining > 1)
|
||||
yield return new WaitForSecondsRealtime(1f);
|
||||
else
|
||||
yield return new WaitForSecondsRealtime((float)(_durationSeconds - _stopwatch.Elapsed.TotalSeconds));
|
||||
yield return new WaitForSecondsRealtime((float)(_durationSeconds - Stopwatch.Elapsed.TotalSeconds));
|
||||
}
|
||||
|
||||
Complete();
|
||||
@@ -119,7 +118,7 @@ public sealed class CountdownTimer : IDisposable
|
||||
return;
|
||||
|
||||
_completed = true;
|
||||
_stopwatch.Stop();
|
||||
Stopwatch.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -146,7 +145,7 @@ public sealed class CountdownTimer : IDisposable
|
||||
_coroutine = null;
|
||||
}
|
||||
|
||||
_stopwatch.Stop();
|
||||
Stopwatch.Stop();
|
||||
OnElapsed = null;
|
||||
OnTick = null;
|
||||
OnCanceled = null;
|
||||
|
||||
@@ -1200,6 +1200,34 @@ public static class GuessManager
|
||||
public static void Postfix()
|
||||
{
|
||||
Object.Destroy(TextTemplate.gameObject);
|
||||
if (GuesserUI) Object.Destroy(GuesserUI);
|
||||
|
||||
foreach (List<Transform> roleButtonsValue in RoleButtons.Values)
|
||||
{
|
||||
foreach (Transform transform in roleButtonsValue)
|
||||
{
|
||||
if (transform.gameObject)
|
||||
Object.Destroy(transform.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (SpriteRenderer spriteRenderer in RoleSelectButtons.Values)
|
||||
{
|
||||
if (spriteRenderer.gameObject)
|
||||
Object.Destroy(spriteRenderer.gameObject);
|
||||
}
|
||||
|
||||
foreach (SpriteRenderer spriteRenderer in PageButtons)
|
||||
{
|
||||
if (spriteRenderer.gameObject)
|
||||
Object.Destroy(spriteRenderer.gameObject);
|
||||
}
|
||||
|
||||
TextTemplate = null;
|
||||
GuesserUI = null;
|
||||
RoleButtons.Clear();
|
||||
RoleSelectButtons.Clear();
|
||||
PageButtons.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
-32
@@ -30,6 +30,7 @@ public static class ModUpdater
|
||||
public static string DownloadUrl;
|
||||
private static GenericPopup InfoPopup;
|
||||
private static GenericPopup InfoPopupV2;
|
||||
private static readonly HttpClient HttpClient = new();
|
||||
|
||||
[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
|
||||
[HarmonyPrefix]
|
||||
@@ -75,8 +76,7 @@ public static class ModUpdater
|
||||
public static string Get(string url)
|
||||
{
|
||||
string result;
|
||||
HttpClient req = new();
|
||||
HttpResponseMessage res = req.GetAsync(url).Result;
|
||||
HttpResponseMessage res = HttpClient.GetAsync(url).Result;
|
||||
Stream stream = res.Content.ReadAsStreamAsync().Result;
|
||||
|
||||
try
|
||||
@@ -227,9 +227,7 @@ public static class ModUpdater
|
||||
// Delete the temporary file if it exists
|
||||
if (File.Exists(savePath)) File.Delete(savePath);
|
||||
|
||||
HttpResponseMessage response;
|
||||
|
||||
using (HttpClient client = new()) response = await client.GetAsync(url);
|
||||
HttpResponseMessage response = await HttpClient.GetAsync(url);
|
||||
|
||||
if (response is not { IsSuccessStatusCode: true }) throw new($"File retrieval failed with status code: {response.StatusCode}");
|
||||
|
||||
@@ -266,9 +264,7 @@ public static class ModUpdater
|
||||
// Delete the temporary file if it exists
|
||||
if (File.Exists(savePath)) File.Delete(savePath);
|
||||
|
||||
HttpResponseMessage response;
|
||||
|
||||
using (HttpClient client = new()) response = await client.GetAsync(url);
|
||||
HttpResponseMessage response = await HttpClient.GetAsync(url);
|
||||
|
||||
if (response is not { IsSuccessStatusCode: true }) throw new($"File retrieval failed with status code: {response.StatusCode}");
|
||||
|
||||
@@ -302,41 +298,44 @@ public static class ModUpdater
|
||||
|
||||
public static void ShowPopup(string message, StringNames buttonText, bool showButton = false, bool buttonIsExit = true)
|
||||
{
|
||||
if (InfoPopup == null) return;
|
||||
if (!InfoPopup) return;
|
||||
|
||||
InfoPopup.Show(message);
|
||||
Transform button = InfoPopup.transform.FindChild("ExitGame");
|
||||
|
||||
if (button != null)
|
||||
if (button)
|
||||
{
|
||||
button.gameObject.SetActive(showButton);
|
||||
button.GetChild(0).GetComponent<TextTranslatorTMP>().TargetText = buttonText;
|
||||
button.GetChild(0).GetComponent<TextTranslatorTMP>().ResetText();
|
||||
button.GetComponent<PassiveButton>().OnClick = new();
|
||||
var textTranslatorTMP = button.GetChild(0).GetComponent<TextTranslatorTMP>();
|
||||
textTranslatorTMP.TargetText = buttonText;
|
||||
textTranslatorTMP.ResetText();
|
||||
var passiveButton = button.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
|
||||
if (buttonIsExit)
|
||||
button.GetComponent<PassiveButton>().OnClick.AddListener((Action)Application.Quit);
|
||||
passiveButton.OnClick.AddListener((Action)Application.Quit);
|
||||
else
|
||||
button.GetComponent<PassiveButton>().OnClick.AddListener((Action)(() => InfoPopup.Close()));
|
||||
passiveButton.OnClick.AddListener((Action)(() => InfoPopup.Close()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowPopupWithTwoButtons(string message, string firstButtonText, string secondButtonText = "", Action onClickOnFirstButton = null, Action onClickOnSecondButton = null)
|
||||
{
|
||||
if (InfoPopupV2 != null)
|
||||
if (InfoPopupV2)
|
||||
{
|
||||
var templateExitGame = InfoPopupV2.transform.FindChild("ExitGame");
|
||||
if (templateExitGame == null) return;
|
||||
if (!templateExitGame) return;
|
||||
|
||||
var background = InfoPopupV2.transform.FindChild("Background");
|
||||
if (background == null) return;
|
||||
if (!background) return;
|
||||
background.localScale *= 2f;
|
||||
|
||||
InfoPopupV2.Show(message);
|
||||
templateExitGame.gameObject.SetActive(false);
|
||||
var firstButton = Object.Instantiate(templateExitGame, InfoPopupV2.transform);
|
||||
var secondButton = Object.Instantiate(templateExitGame, InfoPopupV2.transform);
|
||||
if (firstButton != null)
|
||||
|
||||
if (firstButton)
|
||||
{
|
||||
firstButton.gameObject.SetActive(true);
|
||||
firstButton.name = "FirstButton";
|
||||
@@ -344,17 +343,20 @@ public static class ModUpdater
|
||||
firstButton.transform.localPosition = new Vector3(firstButtonTransform.localPosition.x - 1f, firstButtonTransform.localPosition.y - 0.7f, firstButtonTransform.localPosition.z);
|
||||
firstButton.transform.localScale *= 1.2f;
|
||||
var firstButtonGetChild = firstButton.GetChild(0);
|
||||
firstButtonGetChild.GetComponent<TextTranslatorTMP>().TargetText = StringNames.Cancel;
|
||||
firstButtonGetChild.GetComponent<TextTranslatorTMP>().ResetText();
|
||||
firstButtonGetChild.GetComponent<TextTranslatorTMP>().DestroyTranslator();
|
||||
var textTranslatorTMP = firstButtonGetChild.GetComponent<TextTranslatorTMP>();
|
||||
textTranslatorTMP.TargetText = StringNames.Cancel;
|
||||
textTranslatorTMP.ResetText();
|
||||
textTranslatorTMP.DestroyTranslator();
|
||||
firstButtonGetChild.GetComponent<TextMeshPro>().text = firstButtonText;
|
||||
firstButtonGetChild.GetComponent<TMP_Text>().text = firstButtonText;
|
||||
firstButton.GetComponent<PassiveButton>().OnClick = new();
|
||||
var passiveButton = firstButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
if (onClickOnFirstButton != null)
|
||||
firstButton.GetComponent<PassiveButton>().OnClick.AddListener((UnityAction)(() => { onClickOnFirstButton(); InfoPopupV2.Close();}));
|
||||
else firstButton.GetComponent<PassiveButton>().OnClick.AddListener((UnityAction)(() => InfoPopupV2.Close()));
|
||||
passiveButton.OnClick.AddListener((UnityAction)(() => { onClickOnFirstButton(); InfoPopupV2.Close();}));
|
||||
else passiveButton.OnClick.AddListener((UnityAction)(() => InfoPopupV2.Close()));
|
||||
}
|
||||
if (secondButton != null)
|
||||
|
||||
if (secondButton)
|
||||
{
|
||||
secondButton.gameObject.SetActive(true);
|
||||
secondButton.name = "SecondButton";
|
||||
@@ -362,18 +364,21 @@ public static class ModUpdater
|
||||
secondButton.transform.localPosition = new Vector3(secondButtonTransform.localPosition.x + 1f, secondButtonTransform.localPosition.y - 0.7f, secondButtonTransform.localPosition.z);
|
||||
secondButton.transform.localScale *= 1.2f;
|
||||
var secondButtonGetChild = secondButton.GetChild(0);
|
||||
secondButtonGetChild.GetComponent<TextTranslatorTMP>().TargetText = StringNames.Cancel;
|
||||
secondButtonGetChild.GetComponent<TextTranslatorTMP>().ResetText();
|
||||
var textTranslatorTMP = secondButtonGetChild.GetComponent<TextTranslatorTMP>();
|
||||
textTranslatorTMP.TargetText = StringNames.Cancel;
|
||||
textTranslatorTMP.ResetText();
|
||||
if (!string.IsNullOrWhiteSpace(secondButtonText))
|
||||
{
|
||||
secondButtonGetChild.GetComponent<TextTranslatorTMP>().DestroyTranslator();
|
||||
textTranslatorTMP.DestroyTranslator();
|
||||
secondButtonGetChild.GetComponent<TextMeshPro>().text = secondButtonText;
|
||||
secondButtonGetChild.GetComponent<TMP_Text>().text = secondButtonText;
|
||||
}
|
||||
secondButton.GetComponent<PassiveButton>().OnClick = new();
|
||||
|
||||
var passiveButton = secondButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
if (onClickOnSecondButton != null)
|
||||
secondButton.GetComponent<PassiveButton>().OnClick.AddListener((UnityAction)(() => { onClickOnSecondButton(); InfoPopupV2.Close(); }));
|
||||
else secondButton.GetComponent<PassiveButton>().OnClick.AddListener((UnityAction)(() => InfoPopupV2.Close()));
|
||||
passiveButton.OnClick.AddListener((UnityAction)(() => { onClickOnSecondButton(); InfoPopupV2.Close(); }));
|
||||
else passiveButton.OnClick.AddListener((UnityAction)(() => InfoPopupV2.Close()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +98,6 @@ public static class OnlinePresetsManager
|
||||
TextMeshPro plusText = row.PlusBtn.GetComponentInChildren<TextMeshPro>();
|
||||
plusText.DestroyTranslator();
|
||||
plusText.text = "ⓘ";
|
||||
row.PlusBtn.transform.localPosition += new Vector3(1.8f, 0f, 0f);
|
||||
row.PlusBtn.OnClick = new();
|
||||
row.PlusBtn.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
|
||||
@@ -65,7 +65,8 @@ public abstract class OptionItem
|
||||
private bool IsHidden { get; set; }
|
||||
public bool IsText { get; protected set; }
|
||||
|
||||
public TextOptionItem Header { get; set; } = null;
|
||||
public TextOptionItem Header { get; set; }
|
||||
public BaseGameSetting CachedSetting { get; set; }
|
||||
|
||||
public Dictionary<string, string> ReplacementDictionary
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ public static class OptionsMenuBehaviourStartPatch
|
||||
private static ClientOptionItem ButtonCooldownInDecimalUnder10s;
|
||||
private static ClientOptionItem CancelPetAnimation;
|
||||
private static ClientOptionItem TryFixStuttering;
|
||||
private static ClientOptionItem ShowClientControlGUI;
|
||||
#if DEBUG
|
||||
private static ClientOptionItem GodMode;
|
||||
#endif
|
||||
@@ -256,6 +257,24 @@ public static class OptionsMenuBehaviourStartPatch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowClientControlGUI == null || !ShowClientControlGUI.ToggleButton)
|
||||
{
|
||||
ShowClientControlGUI = ClientOptionItem.Create("ShowClientControlGUI", Main.ShowClientControlGUI, __instance, ShowClientControlGUIButtonToggle);
|
||||
|
||||
static void ShowClientControlGUIButtonToggle()
|
||||
{
|
||||
switch (Main.ShowClientControlGUI.Value)
|
||||
{
|
||||
case true when !ClientControlGUI.Instance:
|
||||
Main.Instance.AddComponent<ClientControlGUI>();
|
||||
break;
|
||||
case false when ClientControlGUI.Instance:
|
||||
Object.Destroy(ClientControlGUI.Instance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if ((GodMode == null || GodMode.ToggleButton == null) && DebugModeManager.AmDebugger)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace EHR;
|
||||
public static class ModGameOptionsMenu
|
||||
{
|
||||
public static int TabIndex;
|
||||
public static readonly List<BaseGameSetting> BaseGameSettingCache = new();
|
||||
public static readonly List<Coroutine> RunningMainCoroutines = new();
|
||||
public static readonly Dictionary<OptionBehaviour, int> OptionList = new();
|
||||
public static readonly Dictionary<int, OptionBehaviour> BehaviourList = new();
|
||||
public static readonly Dictionary<int, CategoryHeaderMasked> CategoryHeaderList = new();
|
||||
@@ -46,7 +46,7 @@ public static class ModGameOptionsMenu
|
||||
foreach (var btn in ui.GetComponentsInChildren<PassiveButton>(true))
|
||||
btn.OnClick.RemoveAllListeners();
|
||||
|
||||
Object.Destroy(ui);
|
||||
Object.DestroyImmediate(ui);
|
||||
}
|
||||
SpawnedUI.Clear();
|
||||
|
||||
@@ -64,7 +64,7 @@ public static class ModGameOptionsMenu
|
||||
kv.Key.SetClickMask(null);
|
||||
if (kv.Key.TryGetComponent<PassiveButton>(out var btn))
|
||||
btn.OnClick.RemoveAllListeners();
|
||||
Object.Destroy(kv.Key.gameObject);
|
||||
Object.DestroyImmediate(kv.Key.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public static class ModGameOptionsMenu
|
||||
kv.Value.SetClickMask(null);
|
||||
if (kv.Value.TryGetComponent<PassiveButton>(out var btn))
|
||||
btn.OnClick.RemoveAllListeners();
|
||||
Object.Destroy(kv.Value.gameObject);
|
||||
Object.DestroyImmediate(kv.Value.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,18 +86,20 @@ public static class ModGameOptionsMenu
|
||||
{
|
||||
if (kv.Value.TryGetComponent<PassiveButton>(out var btn))
|
||||
btn.OnClick.RemoveAllListeners();
|
||||
Object.Destroy(kv.Value.gameObject);
|
||||
Object.DestroyImmediate(kv.Value.gameObject);
|
||||
}
|
||||
}
|
||||
foreach (var setting in BaseGameSettingCache)
|
||||
|
||||
foreach (var co in RunningMainCoroutines)
|
||||
{
|
||||
if (setting) Object.Destroy(setting);
|
||||
if (co != null)
|
||||
Main.Instance.StopCoroutine(co);
|
||||
}
|
||||
|
||||
OptionList.Clear();
|
||||
BehaviourList.Clear();
|
||||
CategoryHeaderList.Clear();
|
||||
BaseGameSettingCache.Clear();
|
||||
RunningMainCoroutines.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,8 +291,6 @@ public static class GameOptionsMenuPatch
|
||||
|
||||
foreach (UiElement x in __instance.scrollBar.GetComponentsInChildren<UiElement>())
|
||||
__instance.ControllerSelectable.Add(x);
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
float CalculateScrollBarYBoundsMax()
|
||||
@@ -468,6 +468,8 @@ public static class GameOptionsMenuPatch
|
||||
}
|
||||
public static BaseGameSetting GetSetting(OptionItem item)
|
||||
{
|
||||
if (item.CachedSetting) return item.CachedSetting;
|
||||
|
||||
BaseGameSetting baseGameSetting;
|
||||
|
||||
switch (item)
|
||||
@@ -525,7 +527,7 @@ public static class GameOptionsMenuPatch
|
||||
if (baseGameSetting)
|
||||
{
|
||||
baseGameSetting.Title = StringNames.Accept;
|
||||
ModGameOptionsMenu.BaseGameSettingCache.Add(baseGameSetting);
|
||||
item.CachedSetting = baseGameSetting;
|
||||
}
|
||||
return baseGameSetting;
|
||||
}
|
||||
@@ -878,7 +880,11 @@ public static class StringOptionPatch
|
||||
long now = Utils.TimeStamp;
|
||||
bool startCoRoutine = now > HelpShowEndTS;
|
||||
HelpShowEndTS = now + 15;
|
||||
if (startCoRoutine) Main.Instance.StartCoroutine(CoRoutine());
|
||||
if (startCoRoutine)
|
||||
{
|
||||
var co = Main.Instance.StartCoroutine(CoRoutine());
|
||||
ModGameOptionsMenu.RunningMainCoroutines.Add(co);
|
||||
}
|
||||
|
||||
IEnumerator CoRoutine()
|
||||
{
|
||||
@@ -1077,14 +1083,14 @@ public static class GameSettingMenuPatch
|
||||
private static float VanillaKillCooldownOnOpen = 1;
|
||||
private static float ModdedKillCooldownOnOpen = 1;
|
||||
|
||||
public static void DestroySetting()
|
||||
private static void DestroySetting()
|
||||
{
|
||||
foreach (var button in ModSettingsButtons.Values)
|
||||
{
|
||||
if (button)
|
||||
{
|
||||
button.OnClick.RemoveAllListeners();
|
||||
Object.Destroy(button.gameObject);
|
||||
Object.DestroyImmediate(button.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1101,7 +1107,7 @@ public static class GameSettingMenuPatch
|
||||
if (child.TryGetComponent<PassiveButton>(out var btn))
|
||||
btn.OnClick.RemoveAllListeners();
|
||||
|
||||
Object.Destroy(child.gameObject);
|
||||
Object.DestroyImmediate(child.gameObject);
|
||||
}
|
||||
tab.Children.Clear();
|
||||
}
|
||||
@@ -1109,7 +1115,7 @@ public static class GameSettingMenuPatch
|
||||
}
|
||||
|
||||
foreach (var gmButton in GMButtons)
|
||||
if (gmButton) Object.Destroy(gmButton);
|
||||
if (gmButton) Object.DestroyImmediate(gmButton);
|
||||
|
||||
ModSettingsButtons.Clear();
|
||||
ModSettingsTabs.Clear();
|
||||
@@ -1499,7 +1505,7 @@ public static class GameSettingMenuPatch
|
||||
|
||||
if (!OnlinePresetsManager.PresetsLoaded && tabGroup == TabGroup.PresetExplorer)
|
||||
{
|
||||
Main.Instance.StartCoroutine(
|
||||
var co = Main.Instance.StartCoroutine(
|
||||
OnlinePresetsManager.FetchPresetList(list =>
|
||||
{
|
||||
OnlinePresetsManager.CachedPresets = list;
|
||||
@@ -1507,6 +1513,7 @@ public static class GameSettingMenuPatch
|
||||
GameOptionsMenuPatch.ReloadUI();
|
||||
})
|
||||
);
|
||||
ModGameOptionsMenu.RunningMainCoroutines.Add(co);
|
||||
}
|
||||
|
||||
if ((previewOnly && Controller.currentTouchType == Controller.TouchType.Joystick) || !previewOnly)
|
||||
@@ -1678,5 +1685,4 @@ public static class RpcSyncSettingsPatch
|
||||
{
|
||||
OptionItem.SyncAllOptions();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,6 +28,20 @@ public static class LobbyViewSettingsPanePatch
|
||||
private static readonly HashSet<CustomRoles> RoleEnabledList = [];
|
||||
private static StringNames VanillaSettingsTabName => StringNames.OverviewCategory;
|
||||
private static StringNames VanillaRolesTabName => StringNames.RolesCategory;
|
||||
|
||||
// Storing Unity objects in static variables prevents GC from collecting them
|
||||
// (and everything inside them, like event listeners)
|
||||
// even if the object was destroyed
|
||||
// This method doesn't check object lifetime because it's called when a game starts,
|
||||
// and these are guaranteed to be destroyed by then
|
||||
public static void ClearReferences()
|
||||
{
|
||||
RoleListCoroutine = null;
|
||||
OptionsCoroutine = null;
|
||||
ShowOnlyEnabledRolesButton = null;
|
||||
TabButtons.Clear();
|
||||
AllTabButtons.Clear();
|
||||
}
|
||||
|
||||
[HarmonyPatch(nameof(LobbyViewSettingsPane.Awake))]
|
||||
[HarmonyPostfix]
|
||||
@@ -293,7 +307,7 @@ public static class LobbyViewSettingsPanePatch
|
||||
rightPassiveButton.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
LastGameModeSelected++;
|
||||
CustomGameMode[] enumGameModes = Enum.GetValues<CustomGameMode>().Without(CustomGameMode.All).ToArray();
|
||||
CustomGameMode[] enumGameModes = Enum.GetValues<CustomGameMode>()[..^1];
|
||||
if ((int)LastGameModeSelected > enumGameModes.Length)
|
||||
LastGameModeSelected = CustomGameMode.Standard;
|
||||
__instance.ChangeTab(VanillaSettingsTabName);
|
||||
@@ -313,7 +327,7 @@ public static class LobbyViewSettingsPanePatch
|
||||
leftButtonPassiveButton.OnClick.AddListener((UnityAction)(() =>
|
||||
{
|
||||
LastGameModeSelected--;
|
||||
CustomGameMode[] enumGameModes = Enum.GetValues<CustomGameMode>().Without(CustomGameMode.All).ToArray();
|
||||
CustomGameMode[] enumGameModes = Enum.GetValues<CustomGameMode>()[..^1];
|
||||
if ((int)LastGameModeSelected < 0x01)
|
||||
LastGameModeSelected = (CustomGameMode)enumGameModes.Length;
|
||||
__instance.ChangeTab(VanillaSettingsTabName);
|
||||
@@ -722,7 +736,7 @@ public static class LobbyViewSettingsPanePatch
|
||||
private static void DrawRoles(LobbyViewSettingsPane viewSettings, TabGroup tabName)
|
||||
{
|
||||
var yPos = 1.3f;
|
||||
var xPos = -6.53f;
|
||||
const float xPos = -6.53f;
|
||||
float xPosOpt;
|
||||
var index = 0;
|
||||
RoleEnabledList.Clear();
|
||||
@@ -828,7 +842,7 @@ public static class LobbyViewSettingsPanePatch
|
||||
// Roles
|
||||
if (allCustomRoles.FindFirst(x => x.ToString() == realName, out CustomRoles role))
|
||||
{
|
||||
if (role == default(CustomRoles) || role is CustomRoles.CovenLeader) continue;
|
||||
if (role is default(CustomRoles) or CustomRoles.CovenLeader) continue;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -911,9 +925,7 @@ public static class LobbyViewSettingsPanePatch
|
||||
viewSettings.settingsInfo.Add(viewSettingsInfoPanelRoleVariant.gameObject);
|
||||
yPos -= 0.65f;
|
||||
}
|
||||
else if (LastGameModeSelected == CustomGameMode.HideAndSeek && role is CustomRoles.Seeker or CustomRoles.Hider)
|
||||
RoleEnabledList.Add(role);
|
||||
else if (!enabledOrNotCollapsed && enabled && !roleDisabled)
|
||||
else if (LastGameModeSelected == CustomGameMode.HideAndSeek && role is CustomRoles.Seeker or CustomRoles.Hider || !enabledOrNotCollapsed && enabled && !roleDisabled)
|
||||
RoleEnabledList.Add(role);
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
@@ -922,8 +934,8 @@ public static class LobbyViewSettingsPanePatch
|
||||
{
|
||||
// Skip all role settings
|
||||
if (option.Parent != null && allCustomRoles.Any(x => x.ToString() == option.Parent?.Name)) continue;
|
||||
else if (option.Parent?.Parent != null && allCustomRoles.Any(x => x.ToString() == option.Parent?.Parent?.Name)) continue;
|
||||
else if (option.Parent?.Parent?.Parent != null && allCustomRoles.Any(x => x.ToString() == option.Parent?.Parent?.Parent.Name)) continue;
|
||||
if (option.Parent?.Parent != null && allCustomRoles.Any(x => x.ToString() == option.Parent?.Parent?.Name)) continue;
|
||||
if (option.Parent?.Parent?.Parent != null && allCustomRoles.Any(x => x.ToString() == option.Parent?.Parent?.Parent.Name)) continue;
|
||||
|
||||
ViewSettingsInfoPanel viewSettingsInfoPanel = Object.Instantiate(viewSettings.infoPanelOrigin, Vector3.zero, Quaternion.identity, viewSettings.settingsContainer);
|
||||
viewSettingsInfoPanel.name = option.Name;
|
||||
@@ -986,6 +998,7 @@ public static class LobbyViewSettingsPanePatch
|
||||
|
||||
if (RoleEnabledList.Count <= 0) yield break;
|
||||
yield return CoShowRoleSettings().WrapToIl2Cpp();
|
||||
yield break;
|
||||
|
||||
IEnumerator CoShowRoleSettings()
|
||||
{
|
||||
@@ -1001,8 +1014,8 @@ public static class LobbyViewSettingsPanePatch
|
||||
|
||||
float leftY = startY;
|
||||
float rightY = startY;
|
||||
float leftX = -5.8f;
|
||||
var rightX = 0.15f;
|
||||
const float leftX = -5.8f;
|
||||
const float rightX = 0.15f;
|
||||
|
||||
foreach (CustomRoles role in RoleEnabledList)
|
||||
{
|
||||
|
||||
@@ -185,7 +185,7 @@ public static class MainMenuManagerPatch
|
||||
{
|
||||
GameOptionsManager.Instance.Initialize();
|
||||
|
||||
if (GameOptionsManager.Instance.normalGameHostOptions.MapId is 3 or > 5)
|
||||
if (GameOptionsManager.Instance.normalGameHostOptions.MapId == 3 || (GameOptionsManager.Instance.normalGameHostOptions.MapId > 5 && !SubmergedCompatibility.Loaded))
|
||||
{
|
||||
GameOptionsManager.Instance.normalGameHostOptions.MapId = 0;
|
||||
GameOptionsManager.Instance.SaveNormalHostOptions();
|
||||
|
||||
@@ -280,6 +280,8 @@ internal static class ChangeRoleSettings
|
||||
ChatCommands.LastSpectators.UnionWith(ChatCommands.Spectators);
|
||||
|
||||
RPCHandlerPatch.RemoveExpiredWhiteList();
|
||||
|
||||
LobbyViewSettingsPanePatch.ClearReferences();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -10589,6 +10589,7 @@
|
||||
"ButtonCooldownInDecimalUnder10s": "Button Cooldown in Decimal Under 10s",
|
||||
"CancelPetAnimation": "Fully Cancel Self Pet Animation As Host",
|
||||
"TryFixStuttering": "Try to Fix Stuttering",
|
||||
"ShowClientControlGUI": "Show Client Control GUI",
|
||||
"GM": "Game Master",
|
||||
"GMInfo": "Spectate the chaos!",
|
||||
"GMInfoLong": "(Other):\\nThe Game Master is an observer role. Their presence does not affect the game; all players know who the Game Master is. The Game Master role will be assigned to the Host/Spectators, who will automatically become a ghost at the start of the game.",
|
||||
|
||||
@@ -81,7 +81,7 @@ public class Imitator : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates.ToArray())
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || pc.IsAlive()) continue;
|
||||
if (!pc || pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -418,7 +418,7 @@ public class Inspector : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates)
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -267,7 +267,7 @@ public class Judge : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates)
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -135,7 +135,7 @@ public class Retributionist : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates.ToArray())
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -281,7 +281,7 @@ public class Swapper : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates)
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -295,7 +295,7 @@ public class Councillor : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates.ToArray())
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -204,7 +204,7 @@ internal class Nemesis : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates.ToArray())
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class Ventriloquist : RoleBase
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates.ToArray())
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
if (!pc || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
|
||||
@@ -105,8 +105,9 @@ public class Starspawn : RoleBase
|
||||
|
||||
private static void CreateStarspawnButton(MeetingHud __instance)
|
||||
{
|
||||
if (GameObject.Find("StarspawnButton") != null) Object.Destroy(GameObject.Find("StarspawnButton").gameObject);
|
||||
if (PlayerControl.LocalPlayer == null || !PlayerControl.LocalPlayer.IsAlive()) return;
|
||||
GameObject existingButton = GameObject.Find("StarspawnButton");
|
||||
if (existingButton) Object.Destroy(existingButton.gameObject);
|
||||
if (!PlayerControl.LocalPlayer || !PlayerControl.LocalPlayer.IsAlive()) return;
|
||||
|
||||
GameObject parent = GameObject.Find("Main Camera").transform.Find("Hud").Find("ChatUi").Find("ChatScreenRoot").Find("ChatScreenContainer").gameObject;
|
||||
GameObject template = __instance.transform.Find("MeetingContents").Find("ButtonStuff").Find("button_skipVoting").gameObject;
|
||||
|
||||
Reference in new issue
Block a user