From 29489f0b14c73f07db9b4a1008056a21ce16e52f Mon Sep 17 00:00:00 2001 From: Jaxe <42095078+Jaxe-Dev@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:44:10 +0800 Subject: [PATCH] v2.7 - Better memory handling for long-term play - Minor fixes --- .editorconfig | 14 ++++ .gitattributes | 3 + .gitignore | 2 + README.md | 4 +- source/Access/Reflection.cs | 14 ++++ ...erface_MapInterfaceOnGUI_BeforeMainTabs.cs | 6 +- ...aySettings_DoPlaySettingsGlobalControls.cs | 12 +-- source/{Patch => Access}/Verse_PlayLog_Add.cs | 4 +- ...file_MemoryUtility_ClearAllMapsAndWorld.cs | 2 +- source/Bubbles.csproj | 42 +++++----- source/Configuration/Listing_Settings.cs | 14 ++-- source/Configuration/Setting.cs | 17 ++-- source/Configuration/SettingsEditor.cs | 12 +-- source/Core/Bubble.cs | 84 +++++++++---------- source/Core/Bubbler.cs | 46 +++++----- source/Core/Compatibility.cs | 12 +-- source/Mod.cs | 8 +- source/Settings.cs | 64 +++++++------- source/release.targets | 73 +++++++--------- 19 files changed, 232 insertions(+), 201 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 source/Access/Reflection.cs rename source/{Patch => Access}/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs (78%) rename source/{Patch => Access}/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs (60%) rename source/{Patch => Access}/Verse_PlayLog_Add.cs (81%) rename source/{Patch => Access}/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs (91%) diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..94562df --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.sln] +indent_style = tab + +[*.{md,mdx}] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c7c9086 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto +*.sln text eol=crlf +*.csproj text eol=crlf diff --git a/.gitignore b/.gitignore index 9b665f2..cb54d64 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ _* *.user *.pdb !/.gitignore +!/.gitattributes +!/.editorconfig !/*.md !/*.sln !/source/ diff --git a/README.md b/README.md index 0b77b62..6da2bfb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Interaction Bubbles -![Mod Version](https://img.shields.io/badge/Mod_Version-2.6-blue) +![Mod Version](https://img.shields.io/badge/Mod_Version-2.7-blue) ![RimWorld Version](https://img.shields.io/badge/Built_for_RimWorld-1.4-blue) -![Harmony Version](https://img.shields.io/badge/Powered_by_Harmony-2.2-blue)\ +![Harmony Version](https://img.shields.io/badge/Powered_by_Harmony-2.2.2-blue)\ [![Steam Subscribers](https://img.shields.io/steam/downloads/1516158345?color=blue&label=Steam%20Downloads&logo=Steam)](https://steamcommunity.com/sharedfiles/filedetails/?id=1516158345) [![GitHub Downloads](https://img.shields.io/github/downloads/Jaxe-Dev/Bubbles/total?color=blue&label=GitHub%20Downloads&logo=GitHub)](https://github.com/Jaxe-Dev/Bubbles) diff --git a/source/Access/Reflection.cs b/source/Access/Reflection.cs new file mode 100644 index 0000000..c899681 --- /dev/null +++ b/source/Access/Reflection.cs @@ -0,0 +1,14 @@ +using System.Reflection; +using HarmonyLib; +using Verse; + +namespace Bubbles.Access +{ + public static class Reflection + { + public static readonly FieldInfo Verse_PlayLogEntry_Interaction_Initiator = AccessTools.Field(typeof(PlayLogEntry_Interaction), "initiator"); + public static readonly FieldInfo Verse_PlayLogEntry_Interaction_Recipient = AccessTools.Field(typeof(PlayLogEntry_Interaction), "recipient"); + + public static readonly FieldInfo Verse_CameraDriver_RootSize = AccessTools.Field(typeof(CameraDriver), "rootSize"); + } +} diff --git a/source/Patch/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs b/source/Access/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs similarity index 78% rename from source/Patch/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs rename to source/Access/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs index aad86e1..4413300 100644 --- a/source/Patch/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs +++ b/source/Access/RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs.cs @@ -1,9 +1,9 @@ -using System; +using System; using Bubbles.Core; using HarmonyLib; using RimWorld; -namespace Bubbles.Patch +namespace Bubbles.Access { [HarmonyPatch(typeof(MapInterface), nameof(MapInterface.MapInterfaceOnGUI_BeforeMainTabs))] public static class RimWorld_MapInterface_MapInterfaceOnGUI_BeforeMainTabs @@ -13,7 +13,7 @@ private static void Postfix() try { Bubbler.Draw(); } catch (Exception exception) { - Mod.Error($"Deactivated because draw failed with error: [{exception.Source}: {exception.Message}]\n\nStacktrace:\n{exception.StackTrace}"); + Mod.Error($"Deactivated because draw failed with error: [{exception.Source}: {exception.Message}]\n\nTrace:\n{exception.StackTrace}"); Settings.Activated = false; } } diff --git a/source/Patch/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs b/source/Access/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs similarity index 60% rename from source/Patch/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs rename to source/Access/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs index 5676d3a..291ddf9 100644 --- a/source/Patch/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs +++ b/source/Access/RimWorld_PlaySettings_DoPlaySettingsGlobalControls.cs @@ -1,24 +1,26 @@ -using Bubbles.Configuration; +using Bubbles.Configuration; using Bubbles.Core; using HarmonyLib; using RimWorld; using UnityEngine; using Verse; -namespace Bubbles.Patch +namespace Bubbles.Access { [HarmonyPatch(typeof(PlaySettings), nameof(PlaySettings.DoPlaySettingsGlobalControls))] public static class RimWorld_PlaySettings_DoPlaySettingsGlobalControls { - private static void Postfix(WidgetRow row, bool worldView) + private static void Postfix(WidgetRow? row, bool worldView) { - if (worldView || row == null) { return; } + if (worldView || row is null) { return; } var activated = Settings.Activated; row.ToggleableIcon(ref activated, Textures.Icon, "Bubbles.Toggle".Translate(), SoundDefOf.Mouseover_ButtonToggle); - if (activated != Settings.Activated && Event.current.shift) { SettingsEditor.ShowWindow(); } + if (activated != Settings.Activated && Event.current!.shift) { SettingsEditor.ShowWindow(); } else { Settings.Activated = activated; } + + if (!Settings.Activated) { Bubbler.Clear(); } } } } diff --git a/source/Patch/Verse_PlayLog_Add.cs b/source/Access/Verse_PlayLog_Add.cs similarity index 81% rename from source/Patch/Verse_PlayLog_Add.cs rename to source/Access/Verse_PlayLog_Add.cs index 9c72f8f..a794927 100644 --- a/source/Patch/Verse_PlayLog_Add.cs +++ b/source/Access/Verse_PlayLog_Add.cs @@ -1,8 +1,8 @@ -using Bubbles.Core; +using Bubbles.Core; using HarmonyLib; using Verse; -namespace Bubbles.Patch +namespace Bubbles.Access { [HarmonyPatch(typeof(PlayLog), nameof(PlayLog.Add))] public static class Verse_PlayLog_Add diff --git a/source/Patch/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs b/source/Access/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs similarity index 91% rename from source/Patch/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs rename to source/Access/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs index c5a5d1a..dfcc61b 100644 --- a/source/Patch/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs +++ b/source/Access/Verse_Profile_MemoryUtility_ClearAllMapsAndWorld.cs @@ -2,7 +2,7 @@ using HarmonyLib; using Verse.Profile; -namespace Bubbles.Patch +namespace Bubbles.Access { [HarmonyPatch(typeof(MemoryUtility), nameof(MemoryUtility.ClearAllMapsAndWorld))] public static class Verse_Profile_MemoryUtility_ClearAllMapsAndWorld diff --git a/source/Bubbles.csproj b/source/Bubbles.csproj index 91f6276..850c9a9 100644 --- a/source/Bubbles.csproj +++ b/source/Bubbles.csproj @@ -22,15 +22,12 @@ prompt 4 false + latest + enable - - ..\packages\Lib.Harmony.2.2.2\lib\net472\0Harmony.dll - False - False - Assembly-CSharp.dll False @@ -51,12 +48,18 @@ UnityEngine.TextRenderingModule.dll False + + ..\packages\Lib.Harmony.2.2.2\lib\net472\0Harmony.dll + False + False + + @@ -69,23 +72,24 @@ - - - - + + + + - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/source/Configuration/Listing_Settings.cs b/source/Configuration/Listing_Settings.cs index f549861..8929398 100644 --- a/source/Configuration/Listing_Settings.cs +++ b/source/Configuration/Listing_Settings.cs @@ -1,4 +1,4 @@ -using System.Globalization; +using System.Globalization; using UnityEngine; using Verse; @@ -24,7 +24,7 @@ public void EndScrollView(ref Rect viewRect) viewRect.height = CurHeight; } - public void SliderLabeled(string label, ref float value, float min, float max, float roundTo = -1f, string display = null) + public void SliderLabeled(string label, ref float value, float min, float max, float roundTo = -1f, string? display = null) { var rect = GetRect(Text.LineHeight); @@ -39,14 +39,14 @@ public void SliderLabeled(string label, ref float value, float min, float max, f if (roundTo > 0f) { value = Mathf.Round(value / roundTo) * roundTo; } } - public void SliderLabeled(string label, ref int value, int min, int max, int roundTo = -1, string display = null) + public void SliderLabeled(string label, ref int value, int min, int max, int roundTo = -1, string? display = null) { var floatValue = (float)value; SliderLabeled(label, ref floatValue, min, max, roundTo, display); value = (int)floatValue; } - public void ColorEntry(string label, ref string buffer, ref Color original) + public void ColorEntry(string label, ref string? buffer, ref Color original) { var rect = GetRect(Text.LineHeight); var rectLeft = rect.LeftHalf().Rounded(); @@ -58,12 +58,10 @@ public void ColorEntry(string label, ref string buffer, ref Color original) Widgets.DrawBoxSolid(rectPreview, original); Widgets.DrawBox(rectPreview); - if (buffer == null) { buffer = ColorUtility.ToHtmlStringRGB(original); } - - buffer = (rect.height <= 30f ? Widgets.TextField(rectEntry, buffer) : Widgets.TextArea(rectEntry, buffer)).ToUpper(); + buffer = Widgets.TextField(rectEntry, buffer ?? ColorUtility.ToHtmlStringRGB(original)); var color = original; - var valid = buffer.Length == 6 && ColorUtility.TryParseHtmlString("#" + buffer, out color); + var valid = buffer!.Length is 6 && ColorUtility.TryParseHtmlString("#" + buffer, out color); if (!valid) { diff --git a/source/Configuration/Setting.cs b/source/Configuration/Setting.cs index 53ea0c7..3604e58 100644 --- a/source/Configuration/Setting.cs +++ b/source/Configuration/Setting.cs @@ -1,35 +1,34 @@ -using UnityEngine; +using UnityEngine; using Verse; namespace Bubbles.Configuration { public abstract class Setting { - protected readonly string Id; - protected Setting(string id) => Id = id; - public abstract void ToDefault(); public abstract void Scribe(); + protected readonly string Id; + protected Setting(string id) => Id = id; } public class Setting : Setting where T : struct { - public readonly T Default; + private readonly T _default; public T Value; public Setting(string id, T defaultValue) : base(id) { - Default = defaultValue; + _default = defaultValue; Value = defaultValue; } - public override void ToDefault() => Value = Default; + public override void ToDefault() => Value = _default; public override void Scribe() { - if ((Value is float floatValue && Default is float floatDefault && Mathf.Approximately(floatValue, floatDefault)) || (Value is Color colorValue && Default is Color colorDefault && colorValue.IndistinguishableFromFast(colorDefault))) { Value = Default; } + if ((Value is float floatValue && _default is float floatDefault && Mathf.Approximately(floatValue, floatDefault)) || (Value is Color colorValue && _default is Color colorDefault && colorValue.IndistinguishableFromFast(colorDefault))) { Value = _default; } - Scribe_Values.Look(ref Value, Id, Default); + Scribe_Values.Look(ref Value, Id, _default); } } } diff --git a/source/Configuration/SettingsEditor.cs b/source/Configuration/SettingsEditor.cs index 8f533d3..ad9a20c 100644 --- a/source/Configuration/SettingsEditor.cs +++ b/source/Configuration/SettingsEditor.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Bubbles.Core; using UnityEngine; using Verse; @@ -7,7 +7,7 @@ namespace Bubbles.Configuration { public static class SettingsEditor { - private static string[] _colorBuffer = new string[4]; + private static string?[] _colorBuffer = new string[4]; private static Vector2 _scrollPosition = Vector2.zero; private static Rect _viewRect; @@ -70,11 +70,11 @@ private static void Reset() Settings.Reset(); } - public static void ShowWindow() => Find.WindowStack.Add(new Dialog()); + public static void ShowWindow() => Find.WindowStack!.Add(new Dialog()); - private class Dialog : Window + private sealed class Dialog : Window { - public override Vector2 InitialSize => new Vector2(600f, 600f); + public override Vector2 InitialSize => new(600f, 600f); public Dialog() { @@ -89,7 +89,7 @@ public Dialog() public override void DoWindowContents(Rect rect) { rect.yMax -= 60f; - DrawSettings(rect.ContractedBy(8f, 0f)); + DrawSettings(rect); } public override void PostClose() diff --git a/source/Core/Bubble.cs b/source/Core/Bubble.cs index cc0605b..7ddfc8b 100644 --- a/source/Core/Bubble.cs +++ b/source/Core/Bubble.cs @@ -1,4 +1,4 @@ -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; using UnityEngine; using Verse; @@ -6,22 +6,22 @@ namespace Bubbles.Core { public class Bubble { - private static readonly Regex RemoveColorTag = new Regex("<\\/?color[^>]*>"); - private static readonly GUIContent Content = new GUIContent(); + private static readonly Regex RemoveColorTag = new("<\\/?color[^>]*>"); + private static readonly GUIContent Content = new(); public PlayLogEntry_Interaction Entry { get; } private readonly Pawn _pawn; - private string _text; - public string Text => _text ?? (_text = GetText()); + private string? _text; + private string Text => _text ??= GetText(); - private GUIStyle _style; - private GUIStyle Style => _style ?? (_style = new GUIStyle(Verse.Text.CurFontStyle) + private GUIStyle? _style; + private GUIStyle Style => _style ??= new GUIStyle(Verse.Text.CurFontStyle) { alignment = TextAnchor.MiddleCenter, clipping = TextClipping.Clip - }); + }; public int Height { get; private set; } public int Width { get; private set; } @@ -32,6 +32,35 @@ public Bubble(Pawn pawn, PlayLogEntry_Interaction entry) _pawn = pawn; } + private static Color GetBackground(bool isSelected) => isSelected ? Settings.SelectedBackground.Value : Settings.Background.Value; + private static Color GetForeground(bool isSelected) => isSelected ? Settings.SelectedForeground.Value : Settings.Foreground.Value; + + private static void DrawAtlas(Rect rect, Texture2D atlas) + { + rect.xMin = Widgets.AdjustCoordToUIScalingFloor(rect.xMin); + rect.yMin = Widgets.AdjustCoordToUIScalingFloor(rect.yMin); + rect.xMax = Widgets.AdjustCoordToUIScalingCeil(rect.xMax); + rect.yMax = Widgets.AdjustCoordToUIScalingCeil(rect.yMax); + + var scale = Mathf.RoundToInt(Mathf.Min(atlas.width * 0.25f, rect.height * 0.25f, rect.width * 0.25f)); + + Compatibility.BeginGroupHandler(null, rect); + + Widgets.DrawTexturePart(new Rect(0.0f, 0.0f, scale, scale), new Rect(0.0f, 0.0f, 0.25f, 0.25f), atlas); + Widgets.DrawTexturePart(new Rect(rect.width - scale, 0.0f, scale, scale), new Rect(0.75f, 0.0f, 0.25f, 0.25f), atlas); + Widgets.DrawTexturePart(new Rect(0.0f, rect.height - scale, scale, scale), new Rect(0.0f, 0.75f, 0.25f, 0.25f), atlas); + + Widgets.DrawTexturePart(new Rect(rect.width - scale, rect.height - scale, scale, scale), new Rect(0.75f, 0.75f, 0.25f, 0.25f), atlas); + Widgets.DrawTexturePart(new Rect(scale, scale, rect.width - (scale * 2f), rect.height - (scale * 2f)), new Rect(0.25f, 0.25f, 0.5f, 0.5f), atlas); + Widgets.DrawTexturePart(new Rect(scale, 0.0f, rect.width - (scale * 2f), scale), new Rect(0.25f, 0.0f, 0.5f, 0.25f), atlas); + + Widgets.DrawTexturePart(new Rect(scale, rect.height - scale, rect.width - (scale * 2f), scale), new Rect(0.25f, 0.75f, 0.5f, 0.25f), atlas); + Widgets.DrawTexturePart(new Rect(0.0f, scale, scale, rect.height - (scale * 2f)), new Rect(0.0f, 0.25f, 0.25f, 0.5f), atlas); + Widgets.DrawTexturePart(new Rect(rect.width - scale, scale, scale, rect.height - (scale * 2f)), new Rect(0.75f, 0.25f, 0.25f, 0.5f), atlas); + + Compatibility.EndGroupHandler(null); + } + public bool Draw(Vector2 pos, bool isSelected, float scale) { ScaleFont(ref scale); @@ -41,12 +70,12 @@ public bool Draw(Vector2 pos, bool isSelected, float scale) var posX = pos.x; var posY = pos.y; - if (Settings.OffsetDirection.Value.IsHorizontal) { posY -= Height / 2f; } - else { posX -= Width / 2f; } + if (Settings.OffsetDirection.Value.IsHorizontal) { posY -= Height * 0.5f; } + else { posX -= Width * 0.5f; } var rect = new Rect(Mathf.Ceil(posX), Mathf.Ceil(posY), Width, Height).RoundedCeil(); - var fade = Event.current.shift && Mouse.IsOver(rect) ? Settings.OpacityStart.Value : Mathf.Min(GetFade(), Mouse.IsOver(rect) ? Settings.OpacityHover.Value : 1f); + var fade = Event.current!.shift && Mouse.IsOver(rect) ? Settings.OpacityStart.Value : Mathf.Min(GetFade(), Mouse.IsOver(rect) ? Settings.OpacityHover.Value : 1f); if (fade <= 0f) { return false; } var background = GetBackground(isSelected).ToTransparent(fade); @@ -89,12 +118,12 @@ private void ScaleDimensions(float scale) private string GetText() { var text = Entry.ToGameStringFromPOV(_pawn); - return Settings.DoTextColors.Value ? text : RemoveColorTag.Replace(text, ""); + return Settings.DoTextColors.Value ? text : RemoveColorTag.Replace(text, string.Empty); } private float GetFade() { - var elasped = Find.TickManager.TicksAbs - Entry.Tick - Settings.FadeStart.Value; + var elasped = Find.TickManager!.TicksAbs - Entry.Tick - Settings.FadeStart.Value; if (elasped <= 0) { return Settings.OpacityStart.Value; } if (elasped > Settings.FadeLength.Value) { return 0f; } @@ -103,35 +132,6 @@ private float GetFade() return fade; } - private static Color GetBackground(bool isSelected) => isSelected ? Settings.SelectedBackground.Value : Settings.Background.Value; - private static Color GetForeground(bool isSelected) => isSelected ? Settings.SelectedForeground.Value : Settings.Foreground.Value; - - private static void DrawAtlas(Rect rect, Texture2D atlas) - { - rect.xMin = Widgets.AdjustCoordToUIScalingFloor(rect.xMin); - rect.yMin = Widgets.AdjustCoordToUIScalingFloor(rect.yMin); - rect.xMax = Widgets.AdjustCoordToUIScalingCeil(rect.xMax); - rect.yMax = Widgets.AdjustCoordToUIScalingCeil(rect.yMax); - - var scale = Mathf.RoundToInt(Mathf.Min(atlas.width * 0.25f, rect.height / 4f, rect.width / 4f)); - - Compatibility.BeginGroupHandler(null, rect); - - Widgets.DrawTexturePart(new Rect(0.0f, 0.0f, scale, scale), new Rect(0.0f, 0.0f, 0.25f, 0.25f), atlas); - Widgets.DrawTexturePart(new Rect(rect.width - scale, 0.0f, scale, scale), new Rect(0.75f, 0.0f, 0.25f, 0.25f), atlas); - Widgets.DrawTexturePart(new Rect(0.0f, rect.height - scale, scale, scale), new Rect(0.0f, 0.75f, 0.25f, 0.25f), atlas); - - Widgets.DrawTexturePart(new Rect(rect.width - scale, rect.height - scale, scale, scale), new Rect(0.75f, 0.75f, 0.25f, 0.25f), atlas); - Widgets.DrawTexturePart(new Rect(scale, scale, rect.width - (scale * 2f), rect.height - (scale * 2f)), new Rect(0.25f, 0.25f, 0.5f, 0.5f), atlas); - Widgets.DrawTexturePart(new Rect(scale, 0.0f, rect.width - (scale * 2f), scale), new Rect(0.25f, 0.0f, 0.5f, 0.25f), atlas); - - Widgets.DrawTexturePart(new Rect(scale, rect.height - scale, rect.width - (scale * 2f), scale), new Rect(0.25f, 0.75f, 0.5f, 0.25f), atlas); - Widgets.DrawTexturePart(new Rect(0.0f, scale, scale, rect.height - (scale * 2f)), new Rect(0.0f, 0.25f, 0.25f, 0.5f), atlas); - Widgets.DrawTexturePart(new Rect(rect.width - scale, scale, scale, rect.height - (scale * 2f)), new Rect(0.75f, 0.25f, 0.25f, 0.5f), atlas); - - Compatibility.EndGroupHandler(null); - } - public void Rebuild() => _text = null; } } diff --git a/source/Core/Bubbler.cs b/source/Core/Bubbler.cs index 33666d2..64fb517 100644 --- a/source/Core/Bubbler.cs +++ b/source/Core/Bubbler.cs @@ -1,5 +1,6 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; +using Bubbles.Access; using HarmonyLib; using RimWorld.Planet; using UnityEngine; @@ -11,69 +12,72 @@ public static class Bubbler { private const float LabelPositionOffset = -0.6f; - private static readonly Dictionary> Dictionary = new Dictionary>(); + private static readonly Dictionary> Dictionary = new(); + + private static bool ShouldShow() => Settings.Activated && !WorldRendererUtility.WorldRenderedNow && (Settings.AutoHideSpeed.Value is Settings.AutoHideSpeedDisabled || (int)Find.TickManager!.CurTimeSpeed < Settings.AutoHideSpeed.Value); public static void Add(LogEntry entry) { - if (!GetApplicable() || !(entry is PlayLogEntry_Interaction interaction)) { return; } + if (!ShouldShow() || entry is not PlayLogEntry_Interaction interaction) { return; } + + var initiator = (Pawn?)Reflection.Verse_PlayLogEntry_Interaction_Initiator.GetValue(interaction); + var recipient = (Pawn?)Reflection.Verse_PlayLogEntry_Interaction_Recipient.GetValue(interaction); - var initiator = Traverse.Create(interaction).Field("initiator").Value; - var recipient = Traverse.Create(interaction).Field("recipient").Value; - if (initiator == null || initiator.Map != Find.CurrentMap) { return; } + if (initiator is null || initiator.Map != Find.CurrentMap) { return; } if (!Settings.DoNonPlayer.Value && (!initiator.Faction?.IsPlayer ?? true)) { return; } - if (!Settings.DoAnimals.Value && ((initiator?.RaceProps?.Animal ?? false) || (recipient?.RaceProps?.Animal ?? false))) { return; } + if (!Settings.DoAnimals.Value && ((initiator.RaceProps?.Animal ?? false) || (recipient?.RaceProps?.Animal ?? false))) { return; } if (!Settings.DoDrafted.Value && ((initiator.drafter?.Drafted ?? false) || (recipient?.drafter?.Drafted ?? false))) { return; } if (!Dictionary.ContainsKey(initiator)) { Dictionary[initiator] = new List(); } - Dictionary[initiator].Add(new Bubble(initiator, interaction)); + Dictionary[initiator]!.Add(new Bubble(initiator, interaction)); } private static void Remove(Pawn pawn, Bubble bubble) { - Dictionary[pawn].Remove(bubble); - if (Dictionary[pawn].Count == 0) { Dictionary.Remove(pawn); } + Dictionary[pawn]!.Remove(bubble); + if (Dictionary[pawn]!.Count is 0) { Dictionary.Remove(pawn); } } public static void Draw() { - if (!GetApplicable()) { return; } - var altitude = GetAltitude(); if (altitude <= 0 || altitude > Settings.AltitudeMax.Value) { return; } var scale = Settings.AltitudeBase.Value / altitude; if (scale > Settings.ScaleMax.Value) { scale = Settings.ScaleMax.Value; } - var selected = Find.Selector.SingleSelectedObject as Pawn; + var selected = Find.Selector!.SingleSelectedObject as Pawn; - foreach (var pawn in Dictionary.Keys.OrderBy(pawn => pawn == selected).ThenBy(pawn => pawn.Position.y).ToArray()) { DrawBubble(pawn, pawn == selected, scale); } + foreach (var pawn in Dictionary.Keys.OrderBy(pawn => pawn == selected).ThenBy(static pawn => pawn.Position.y).ToArray()) { DrawBubble(pawn, pawn == selected, scale); } } private static void DrawBubble(Pawn pawn, bool isSelected, float scale) { - if (!pawn.Spawned || pawn.Map != Find.CurrentMap || pawn.Map.fogGrid.IsFogged(pawn.Position)) { return; } + if (!pawn.Spawned || pawn.Map != Find.CurrentMap || pawn.Map!.fogGrid!.IsFogged(pawn.Position)) { return; } var pos = GenMapUI.LabelDrawPosFor(pawn, LabelPositionOffset); var offset = Settings.OffsetStart.Value; var count = 0; - foreach (var bubble in Dictionary[pawn].OrderByDescending(b => b.Entry.Tick).ToArray()) + foreach (var bubble in Dictionary[pawn].OrderByDescending(static bubble => bubble.Entry.Tick).ToArray()) { if (count > Settings.PawnMax.Value) { return; } - if (!bubble.Draw(pos + GetOffset(offset), isSelected, scale)) { Remove(pawn, bubble); } + if (!bubble.Draw(pos + GetOffset(offset), isSelected, scale)) + { + Remove(pawn, bubble); + if (Dictionary[pawn].NullOrEmpty()) { Dictionary.Remove(pawn); } + } offset += (Settings.OffsetDirection.Value.IsHorizontal ? bubble.Width : bubble.Height) + Settings.OffsetSpacing.Value; count++; } } - private static bool GetApplicable() => Settings.Activated && !WorldRendererUtility.WorldRenderedNow && (Settings.AutoHideSpeed.Value == Settings.AutoHideSpeedDisabled || (int)Find.TickManager.CurTimeSpeed < Settings.AutoHideSpeed.Value); - private static float GetAltitude() { - var altitude = Mathf.Max(1f, Traverse.Create(Find.CameraDriver).Field("rootSize").Value); + var altitude = Mathf.Max(1f, (float)Reflection.Verse_CameraDriver_RootSize.GetValue(Find.CameraDriver)); Compatibility.Apply(ref altitude); return altitude; @@ -85,7 +89,7 @@ private static Vector2 GetOffset(float offset) return new Vector2(offset * direction.x, offset * direction.y); } - public static void Rebuild() => Dictionary.Values.Do(list => list.Do(bubble => bubble.Rebuild())); + public static void Rebuild() => Dictionary.Values.Do(static list => list.Do(static bubble => bubble.Rebuild())); public static void Clear() => Dictionary.Clear(); } diff --git a/source/Core/Compatibility.cs b/source/Core/Compatibility.cs index 6c66ddd..9f0268a 100644 --- a/source/Core/Compatibility.cs +++ b/source/Core/Compatibility.cs @@ -1,4 +1,4 @@ -using System; +using System; using HarmonyLib; using UnityEngine; using Verse; @@ -7,12 +7,12 @@ namespace Bubbles.Core { internal static class Compatibility { - private static readonly bool CameraPlusLoaded = ModsConfig.IsActive("brrainz.cameraplus"); - public static readonly FastInvokeHandler BeginGroupHandler = MethodInvoker.GetHandler(typeof(Widgets).GetMethod("BeginGroup", new[] { typeof(Rect) }) ?? typeof(GUI).GetMethod(nameof(GUI.BeginGroup), new[] { typeof(Rect) })); public static readonly FastInvokeHandler EndGroupHandler = MethodInvoker.GetHandler(typeof(Widgets).GetMethod("EndGroup", new Type[] { }) ?? typeof(GUI).GetMethod(nameof(GUI.EndGroup), new Type[] { })); - private static FastInvokeHandler _cameraPlusLerpRootSize; + private static readonly bool CameraPlusLoaded = ModsConfig.IsActive("brrainz.cameraplus"); + + private static FastInvokeHandler? _cameraPlusLerpRootSize; public static void Apply(ref float altitude) => ApplyCameraPlus(ref altitude); @@ -20,9 +20,9 @@ private static void ApplyCameraPlus(ref float scale) { if (!CameraPlusLoaded) { return; } - if (_cameraPlusLerpRootSize == null) { _cameraPlusLerpRootSize = MethodInvoker.GetHandler(AccessTools.Method("CameraPlus.Tools:LerpRootSize")); } + _cameraPlusLerpRootSize ??= MethodInvoker.GetHandler(AccessTools.Method("CameraPlus.Tools:LerpRootSize")); - scale = (float)_cameraPlusLerpRootSize(null, scale); + scale = (float)_cameraPlusLerpRootSize!(null, scale); } } } diff --git a/source/Mod.cs b/source/Mod.cs index 2e4469a..b2a99ee 100644 --- a/source/Mod.cs +++ b/source/Mod.cs @@ -5,20 +5,20 @@ namespace Bubbles { - public class Mod : Verse.Mod + public sealed class Mod : Verse.Mod { public const string Id = "Bubbles"; public const string Name = "Interaction Bubbles"; - public const string Version = "2.6"; + public const string Version = "2.7"; - public static Mod Instance; + public static Mod Instance = null!; public Mod(ModContentPack content) : base(content) { Instance = this; var settings = GetSettings(); - settings.CheckResetRequired(); + settings!.CheckResetRequired(); new Harmony(Id).PatchAll(); diff --git a/source/Settings.cs b/source/Settings.cs index 49d1d58..eecccdf 100644 --- a/source/Settings.cs +++ b/source/Settings.cs @@ -12,47 +12,51 @@ public class Settings : ModSettings { public const int AutoHideSpeedDisabled = 1; - private static readonly string[] SameConfigVersions = { }; + private static readonly string[] SameConfigVersions = + { + "2.6", + "2.7" + }; private static bool _resetRequired; public static bool Activated = true; - public static readonly Setting AutoHideSpeed = new Setting(nameof(AutoHideSpeed), AutoHideSpeedDisabled); + public static readonly Setting AutoHideSpeed = new(nameof(AutoHideSpeed), AutoHideSpeedDisabled); - public static readonly Setting DoNonPlayer = new Setting(nameof(DoNonPlayer), true); - public static readonly Setting DoAnimals = new Setting(nameof(DoAnimals), true); - public static readonly Setting DoDrafted = new Setting(nameof(DoDrafted), false); - public static readonly Setting DoTextColors = new Setting(nameof(DoTextColors), false); + public static readonly Setting DoNonPlayer = new(nameof(DoNonPlayer), true); + public static readonly Setting DoAnimals = new(nameof(DoAnimals), true); + public static readonly Setting DoDrafted = new(nameof(DoDrafted), false); + public static readonly Setting DoTextColors = new(nameof(DoTextColors), false); - public static readonly Setting AltitudeBase = new Setting(nameof(AltitudeBase), 11); - public static readonly Setting AltitudeMax = new Setting(nameof(AltitudeMax), 40); - public static readonly Setting ScaleMax = new Setting(nameof(ScaleMax), 1.25f); - public static readonly Setting PawnMax = new Setting(nameof(PawnMax), 3); + public static readonly Setting AltitudeBase = new(nameof(AltitudeBase), 11); + public static readonly Setting AltitudeMax = new(nameof(AltitudeMax), 40); + public static readonly Setting ScaleMax = new(nameof(ScaleMax), 1.25f); + public static readonly Setting PawnMax = new(nameof(PawnMax), 3); - public static readonly Setting FontSize = new Setting(nameof(FontSize), 12); - public static readonly Setting PaddingX = new Setting(nameof(PaddingX), 7); - public static readonly Setting PaddingY = new Setting(nameof(PaddingY), 5); - public static readonly Setting WidthMax = new Setting(nameof(WidthMax), 256); + public static readonly Setting FontSize = new(nameof(FontSize), 12); + public static readonly Setting PaddingX = new(nameof(PaddingX), 7); + public static readonly Setting PaddingY = new(nameof(PaddingY), 5); + public static readonly Setting WidthMax = new(nameof(WidthMax), 256); - public static readonly Setting OffsetSpacing = new Setting(nameof(OffsetSpacing), 2); - public static readonly Setting OffsetStart = new Setting(nameof(OffsetStart), 14); - public static readonly Setting OffsetDirection = new Setting(nameof(OffsetDirection), Rot4.North); + public static readonly Setting OffsetSpacing = new(nameof(OffsetSpacing), 2); + public static readonly Setting OffsetStart = new(nameof(OffsetStart), 14); + public static readonly Setting OffsetDirection = new(nameof(OffsetDirection), Rot4.North); - public static readonly Setting OpacityStart = new Setting(nameof(OpacityStart), 0.9f); - public static readonly Setting OpacityHover = new Setting(nameof(OpacityHover), 0.2f); + public static readonly Setting OpacityStart = new(nameof(OpacityStart), 0.9f); + public static readonly Setting OpacityHover = new(nameof(OpacityHover), 0.2f); - public static readonly Setting FadeStart = new Setting(nameof(FadeStart), 500); - public static readonly Setting FadeLength = new Setting(nameof(FadeLength), 100); + public static readonly Setting FadeStart = new(nameof(FadeStart), 500); + public static readonly Setting FadeLength = new(nameof(FadeLength), 100); - public static readonly Setting Background = new Setting(nameof(Background), Color.white); - public static readonly Setting Foreground = new Setting(nameof(Foreground), Color.black); - public static readonly Setting SelectedBackground = new Setting(nameof(SelectedBackground), new Color(1f, 1f, 0.75f)); - public static readonly Setting SelectedForeground = new Setting(nameof(SelectedForeground), Color.black); + public static readonly Setting Background = new(nameof(Background), Color.white); + public static readonly Setting Foreground = new(nameof(Foreground), Color.black); + public static readonly Setting SelectedBackground = new(nameof(SelectedBackground), new Color(1f, 1f, 0.75f)); + public static readonly Setting SelectedForeground = new(nameof(SelectedForeground), Color.black); - private static IEnumerable AllSettings => typeof(Settings).GetFields().Select(field => field.GetValue(null) as Setting).Where(setting => setting != null); + private static IEnumerable AllSettings => typeof(Settings).GetFields().Select(static field => field.GetValue(null) as Setting).Where(static setting => setting is not null)!; - public static void Reset() => AllSettings.Do(setting => setting.ToDefault()); + public static void Reset() => AllSettings.Do(static setting => setting.ToDefault()); public void CheckResetRequired() { @@ -68,15 +72,15 @@ public override void ExposeData() { if (_resetRequired) { return; } - var version = Scribe.mode == LoadSaveMode.Saving ? Bubbles.Mod.Version : null; + var version = Scribe.mode is LoadSaveMode.Saving ? Bubbles.Mod.Version : null; Scribe_Values.Look(ref version, "Version"); - if (Scribe.mode == LoadSaveMode.LoadingVars && (version == null || (version != Bubbles.Mod.Version && !SameConfigVersions.Contains(Regex.Match(version, "^\\d+\\.\\d+").Value)))) + if (Scribe.mode is LoadSaveMode.LoadingVars && (version is null || (version is not Bubbles.Mod.Version && !SameConfigVersions.Contains(Regex.Match(version, "^\\d+\\.\\d+").Value)))) { _resetRequired = true; return; } - AllSettings.Do(setting => setting.Scribe()); + AllSettings.Do(static setting => setting.Scribe()); } } } diff --git a/source/release.targets b/source/release.targets index 06ef5e9..aff1fd1 100644 --- a/source/release.targets +++ b/source/release.targets @@ -1,84 +1,71 @@ - + - - - - - - - - - - '%(Identity)', '|')"; - this.GameVersion = Regex.Match(paths, "Assembly-CSharp, Version=(\\d+\\.\\d+)").Groups[1].Value; - this.HarmonyVersion = Regex.Match(paths, "0Harmony, Version=(\\d+\\.\\d+)").Groups[1].Value; - ]]> - - - - + + - - - + + + + - + - + - - - + + + + - - - + + $(ProjectDir)-\ $(SolutionDir)build\$(AssemblyName)\ $(SolutionDir)releases\ + - - - - + + + + + + + + + + + + + +