From f25a6c8c84ddeb20876370a37e5c1ae6135f0089 Mon Sep 17 00:00:00 2001 From: Andreas Pardeike Date: Mon, 18 Oct 2021 00:04:59 +0200 Subject: [PATCH] v2.2.1 has rewritten logic for dots and labels and works correctly with vanilla animal name settings --- 1.3/Assemblies/CameraPlus.dll | Bin 59904 -> 62976 bytes About/Manifest.xml | 2 +- Source/CameraDelegates.cs | 39 ++++++ Source/CameraPlus.csproj | 30 ++--- Source/Extensions.cs | 43 +++++++ Source/Main.cs | 118 ++++++------------ Source/ReversePatches.cs | 49 ++++++++ Source/Tools.cs | 224 +++++++++++++--------------------- 8 files changed, 274 insertions(+), 231 deletions(-) create mode 100644 Source/CameraDelegates.cs create mode 100644 Source/Extensions.cs create mode 100644 Source/ReversePatches.cs diff --git a/1.3/Assemblies/CameraPlus.dll b/1.3/Assemblies/CameraPlus.dll index fd43d35d2691a5658a6a6d1cf6fe9b2d67d86d15..85cb8a1a2b56baf44b38c3785aaffd12b932b037 100644 GIT binary patch literal 62976 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 literal 59904 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 diff --git a/About/Manifest.xml b/About/Manifest.xml index 1b594bf..adf2c20 100644 --- a/About/Manifest.xml +++ b/About/Manifest.xml @@ -1,7 +1,7 @@  net.pardeike.rimworld.mod.cameraplus - 2.2.0.0 + 2.2.1.0
  • 1.0.0
  • 1.1.0
  • diff --git a/Source/CameraDelegates.cs b/Source/CameraDelegates.cs new file mode 100644 index 0000000..54ecc58 --- /dev/null +++ b/Source/CameraDelegates.cs @@ -0,0 +1,39 @@ +using HarmonyLib; +using System; +using System.Linq.Expressions; +using System.Reflection; +using UnityEngine; +using Verse; + +namespace CameraPlus +{ + class CameraDelegates + { + public Func GetCameraColors = null; + public Func GetCameraMarkers = null; + + static MethodInfo GetMethod(Pawn pawn, string name) + { + return pawn.GetType().Assembly + .GetType("CameraPlusSupport.Methods", false)? + .GetMethod(name, AccessTools.all); + } + + public CameraDelegates(Pawn pawn) + { + var m_GetCameraColors = GetMethod(pawn, "GetCameraPlusColors"); + if (m_GetCameraColors != null) + { + var funcType = Expression.GetFuncType(new[] { typeof(Pawn), typeof(Color[]) }); + GetCameraColors = (Func)Delegate.CreateDelegate(funcType, m_GetCameraColors); + } + + var m_GetCameraTextures = GetMethod(pawn, "GetCameraPlusMarkers"); + if (m_GetCameraTextures != null) + { + var funcType = Expression.GetFuncType(new[] { typeof(Pawn), typeof(Texture2D[]) }); + GetCameraMarkers = (Func)Delegate.CreateDelegate(funcType, m_GetCameraTextures); + } + } + } +} diff --git a/Source/CameraPlus.csproj b/Source/CameraPlus.csproj index 2fb2c46..73936da 100644 --- a/Source/CameraPlus.csproj +++ b/Source/CameraPlus.csproj @@ -1,4 +1,4 @@ - + {AC5EE7A1-16EA-498D-B21A-83ACF78F0E5A} @@ -10,7 +10,7 @@ ..\1.3\Assemblies\ true false - 2.2.0.0 + 2.2.1.0 Copyright Andreas Pardeike @@ -30,9 +30,9 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -67,15 +67,17 @@ - echo Postprocessing -where ModBuilder 2> nul | find /i "ModBuilder.exe" -if not errorlevel 1 ( - ModBuilder AssemblyVersion -file "$(MSBuildProjectDirectory)\$(OutputPath)$(AssemblyName).dll" -save "$(MSBuildProjectName)-version" - ModBuilder XMLPut -file "$(MSBuildProjectDirectory)\..\About\Manifest.xml" -xpath /Manifest/version -value "{{$(MSBuildProjectName)-version}}" -) -if defined INSTALL_MOD ( - "%INSTALL_MOD%" "$(Configuration)" "$(MSBuildProjectDirectory)\..\" "$(MSBuildProjectName)" "1.1 1.2 1.3 About Assemblies Languages Textures" "LoadFolders.xml" -) + + echo Postprocessing + where ModBuilder 2> nul | find /i "ModBuilder.exe" + if not errorlevel 1 ( + ModBuilder AssemblyVersion -file "$(MSBuildProjectDirectory)\$(OutputPath)$(AssemblyName).dll" -save "$(MSBuildProjectName)-version" + ModBuilder XMLPut -file "$(MSBuildProjectDirectory)\..\About\Manifest.xml" -xpath /Manifest/version -value "{{$(MSBuildProjectName)-version}}" + ) + if defined INSTALL_MOD ( + "%INSTALL_MOD%" "$(Configuration)" "$(MSBuildProjectDirectory)\..\" "$(MSBuildProjectName)" "1.1 1.2 1.3 About Assemblies Languages Textures" "LoadFolders.xml" + ) + Brrainz Andreas Pardeike @@ -84,4 +86,4 @@ if defined INSTALL_MOD ( Camera+ - \ No newline at end of file + diff --git a/Source/Extensions.cs b/Source/Extensions.cs new file mode 100644 index 0000000..9966172 --- /dev/null +++ b/Source/Extensions.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; +using Verse; + +namespace CameraPlus +{ + static class Extensions + { + public static void Slider(this Listing_Standard list, ref int value, int min, int max, Func label) + { + float f = value; + var h = HorizontalSlider(list.GetRect(22f), ref f, min, max, label == null ? null : label(), 1f); + value = (int)f; + list.Gap(h); + } + + public static void Slider(this Listing_Standard list, ref float value, float min, float max, Func label, float roundTo = -1f) + { + var rect = list.GetRect(22f); + var h = HorizontalSlider(rect, ref value, min, max, label == null ? null : label(), roundTo); + list.Gap(h); + } + + public static float HorizontalSlider(Rect rect, ref float value, float leftValue, float rightValue, string label = null, float roundTo = -1f) + { + if (label != null) + { + var anchor = Text.Anchor; + var font = Text.Font; + Text.Font = GameFont.Tiny; + Text.Anchor = TextAnchor.UpperLeft; + Widgets.Label(rect, label); + Text.Anchor = anchor; + Text.Font = font; + rect.y += 18f; + } + value = GUI.HorizontalSlider(rect, value, leftValue, rightValue); + if (roundTo > 0f) + value = Mathf.RoundToInt(value / roundTo) * roundTo; + return 4f + label != null ? 18f : 0f; + } + } +} diff --git a/Source/Main.cs b/Source/Main.cs index 6617bc5..7b2ddf5 100644 --- a/Source/Main.cs +++ b/Source/Main.cs @@ -145,19 +145,10 @@ static bool Prefix(Pawn ___pawn) if (CameraPlusMain.skipCustomRendering) return true; - var cameraDelegate = Tools.GetCachedCameraDelegate(___pawn); - if (cameraDelegate.GetCameraColors == null) - { - if (CameraPlusMain.Settings.customNameStyle == LabelStyle.HideAnimals) - return true; - } - - if (Tools.PawnHasNoLabel(___pawn)) - return true; - - return Tools.ShouldShowBody(___pawn); + return Tools.ShouldShowDot(___pawn) == false; } + [HarmonyPriority(10000)] static void Postfix(Pawn ___pawn) { if (CameraPlusMain.Settings.hideNamesWhenZoomedOut && CameraPlusMain.Settings.customNameStyle != LabelStyle.HideAnimals) @@ -168,18 +159,19 @@ static void Postfix(Pawn ___pawn) [HarmonyPatch(typeof(PawnUIOverlay), nameof(PawnUIOverlay.DrawPawnGUIOverlay))] static class PawnUIOverlay_DrawPawnGUIOverlay_Patch { - static AnimalNameDisplayMode AnimalNameMode() - { - if (CameraPlusMain.Settings.includeNotTamedAnimals) - return AnimalNameDisplayMode.TameAll; - return Prefs.AnimalNameMode; - } - + // fake everything being humanlike so Prefs.AnimalNameMode is ignored (we handle it ourselves) public static IEnumerable Transpiler(IEnumerable instructions) { - var from = AccessTools.PropertyGetter(typeof(Prefs), nameof(Prefs.AnimalNameMode)); - var into = SymbolExtensions.GetMethodInfo(() => AnimalNameMode()); - return Transpilers.MethodReplacer(instructions, from, into); + var mHumanlike = AccessTools.PropertyGetter(typeof(RaceProperties), nameof(RaceProperties.Humanlike)); + foreach (var code in instructions) + { + yield return code; + if (code.Calls(mHumanlike)) + { + yield return new CodeInstruction(OpCodes.Pop); + yield return new CodeInstruction(OpCodes.Ldc_I4_1); + } + } } [HarmonyPriority(10000)] @@ -188,9 +180,6 @@ public static bool Prefix(Pawn ___pawn) if (CameraPlusMain.skipCustomRendering) return true; - if (CameraPlusMain.Settings.includeNotTamedAnimals == false) - return true; - if (!___pawn.Spawned || ___pawn.Map.fogGrid.IsFogged(___pawn.Position)) return true; if (___pawn.RaceProps.Humanlike) @@ -198,63 +187,23 @@ public static bool Prefix(Pawn ___pawn) if (___pawn.Name != null) return true; - return GenMapUI_DrawPawnLabel_Patch.HandlePawn(___pawn); - } - } - - [HarmonyPatch(typeof(GenMapUI), nameof(GenMapUI.DrawPawnLabel))] - [HarmonyPatch(new Type[] { typeof(Pawn), typeof(Vector2), typeof(float), typeof(float), typeof(Dictionary), typeof(GameFont), typeof(bool), typeof(bool) })] - [StaticConstructorOnStartup] - static class GenMapUI_DrawPawnLabel_Patch - { - static readonly Texture2D downedTexture = ContentFinder.Get("DownedMarker", true); - static readonly Texture2D draftedTexture = ContentFinder.Get("DraftedMarker", true); - static readonly Color downedColor = new Color(0.9f, 0f, 0f); - static readonly Color draftedColor = new Color(0f, 0.5f, 0f); - - public static bool HandlePawn(Pawn pawn) - { - Tools.ShouldShowLabel(pawn.DrawPos, true, out var showLabel, out var showDot); - if (showLabel) - return true; - if (showDot == false) - return false; - - var useMarkers = Tools.GetMarkerColors(pawn, out var innerColor, out var outerColor); + var useMarkers = Tools.GetMarkerColors(___pawn, out var innerColor, out var outerColor); if (useMarkers == false) return true; // use label - _ = Tools.GetMarkerTextures(pawn, out var innerTexture, out var outerTexture); - - var pos = pawn.DrawPos; - var v1 = (pos - new Vector3(0.75f, 0f, 0.75f)).MapToUIPosition().Rounded(); - var v2 = (pos + new Vector3(0.75f, 0f, 0.75f)).MapToUIPosition().Rounded(); - var markerRect = new Rect(v1, v2 - v1); - - // draw outer marker - GUI.color = outerColor; - GUI.DrawTexture(markerRect, outerTexture, ScaleMode.ScaleToFit, true); - - // draw inner marker - GUI.color = innerColor; - GUI.DrawTexture(markerRect, innerTexture, ScaleMode.ScaleToFit, true); - - // draw extra marker - if (pawn.Downed) + if (Tools.ShouldShowDot(___pawn)) { - GUI.color = downedColor; - GUI.DrawTexture(markerRect, downedTexture, ScaleMode.ScaleToFit, true); - } - else if (pawn.Drafted) - { - GUI.color = draftedColor; - GUI.DrawTexture(markerRect, draftedTexture, ScaleMode.ScaleToFit, true); + Tools.DrawDot(___pawn, innerColor, outerColor); + return false; } - - // skip label - return false; + return Tools.CorrectLabelRendering(___pawn); } + } + [HarmonyPatch(typeof(GenMapUI), nameof(GenMapUI.DrawPawnLabel))] + [HarmonyPatch(new Type[] { typeof(Pawn), typeof(Vector2), typeof(float), typeof(float), typeof(Dictionary), typeof(GameFont), typeof(bool), typeof(bool) })] + static class GenMapUI_DrawPawnLabel_Patch + { [HarmonyPriority(10000)] public static bool Prefix(Pawn pawn, float truncateToWidth) { @@ -262,9 +211,23 @@ public static bool Prefix(Pawn pawn, float truncateToWidth) return true; if (truncateToWidth != 9999f) - return true; // use label + return true; + + if (Tools.ShouldShowDot(pawn)) + { + var useMarkers = Tools.GetMarkerColors(pawn, out var innerColor, out var outerColor); + if (useMarkers == false) + return Tools.CorrectLabelRendering(pawn); + + Tools.DrawDot(pawn, innerColor, outerColor); + return false; + } + + // we fake "show all" so we need to skip if original could would not render labels + if (ReversePatches.PerformsDrawPawnGUIOverlay(pawn.Drawer.ui) == false) + return false; - return HandlePawn(pawn); + return Tools.ShouldShowLabel(pawn); } } @@ -290,8 +253,7 @@ public static bool Prefix(Vector2 screenPos) if (CameraPlusMain.skipCustomRendering) return true; - Tools.ShouldShowLabel(screenPos, false, out var showLabel, out _); - return showLabel; + return Tools.ShouldShowLabel(null, screenPos); } // we replace the first "GameFont.Tiny" with "GetAdaptedGameFont()" diff --git a/Source/ReversePatches.cs b/Source/ReversePatches.cs new file mode 100644 index 0000000..57014ca --- /dev/null +++ b/Source/ReversePatches.cs @@ -0,0 +1,49 @@ +using HarmonyLib; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using Verse; + +namespace CameraPlus +{ + [HarmonyPatch] + static class ReversePatches + { + // mostly copied from the logic in the beginning od PawnUIOverlay.DrawPawnGUIOverlay + // + [HarmonyReversePatch(HarmonyReversePatchType.Original)] + [HarmonyPatch(typeof(PawnUIOverlay), nameof(PawnUIOverlay.DrawPawnGUIOverlay))] + public static bool PerformsDrawPawnGUIOverlay(PawnUIOverlay me) + { + static IEnumerable Transpiler(IEnumerable instructions) + { + var mLabelDrawPosFor = SymbolExtensions.GetMethodInfo(() => GenMapUI.LabelDrawPosFor(null, 0f)); + + var list = instructions.ToList(); + var idx = list.FirstIndexOf(code => code.Calls(mLabelDrawPosFor)); + if (idx < 3 || idx >= list.Count) throw new AmbiguousMatchException("Cannot find GenMapUI.LabelDrawPosFor in PawnUIOverlay.DrawPawnGUIOverlay"); + idx -= 3; + var endLabels = list[idx].labels; + list.RemoveRange(idx, list.Count - idx); + + foreach (var code in list) + { + if (code.opcode == OpCodes.Ret) + { + var labels = code.labels; + yield return new CodeInstruction(OpCodes.Ldc_I4_0) { labels = labels }; + yield return new CodeInstruction(OpCodes.Ret); + } + else + yield return code; + } + yield return new CodeInstruction(OpCodes.Ldc_I4_1) { labels = endLabels }; + yield return new CodeInstruction(OpCodes.Ret); + } + + _ = Transpiler(default); + try { _ = me; return default; } finally { } + } + } +} diff --git a/Source/Tools.cs b/Source/Tools.cs index 81070ee..70a8f01 100644 --- a/Source/Tools.cs +++ b/Source/Tools.cs @@ -1,96 +1,103 @@ -using HarmonyLib; -using RimWorld; +using RimWorld; using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; -using System.Reflection; using UnityEngine; using Verse; namespace CameraPlus { - class CameraDelegates + public enum LabelMode { - public Func GetCameraColors = null; - public Func GetCameraMarkers = null; + hide, + show, + dot + } - static MethodInfo GetMethod(Pawn pawn, string name) - { - return pawn.GetType().Assembly - .GetType("CameraPlusSupport.Methods", false)? - .GetMethod(name, AccessTools.all); - } + [StaticConstructorOnStartup] + class Tools : CameraPlusSettings + { + static readonly Texture2D innerColonistTexture = ContentFinder.Get("InnerColonistMarker", true); + static readonly Texture2D outerColonistTexture = ContentFinder.Get("OuterColonistMarker", true); + static readonly Texture2D innerAnimalTexture = ContentFinder.Get("InnerAnimalMarker", true); + static readonly Texture2D outerAnimalTexture = ContentFinder.Get("OuterAnimalMarker", true); - public CameraDelegates(Pawn pawn) + static readonly Texture2D downedTexture = ContentFinder.Get("DownedMarker", true); + static readonly Texture2D draftedTexture = ContentFinder.Get("DraftedMarker", true); + static readonly Color downedColor = new Color(0.9f, 0f, 0f); + static readonly Color draftedColor = new Color(0f, 0.5f, 0f); + + public static bool ShouldShowDot(Pawn pawn) { - var m_GetCameraColors = GetMethod(pawn, "GetCameraPlusColors"); - if (m_GetCameraColors != null) - { - var funcType = Expression.GetFuncType(new[] { typeof(Pawn), typeof(Color[]) }); - GetCameraColors = (Func)Delegate.CreateDelegate(funcType, m_GetCameraColors); - } + if (CameraPlusMain.Settings.hideNamesWhenZoomedOut == false) + return false; - var m_GetCameraTextures = GetMethod(pawn, "GetCameraPlusMarkers"); - if (m_GetCameraTextures != null) - { - var funcType = Expression.GetFuncType(new[] { typeof(Pawn), typeof(Texture2D[]) }); - GetCameraMarkers = (Func)Delegate.CreateDelegate(funcType, m_GetCameraTextures); - } - } - } + if (CameraPlusMain.Settings.customNameStyle == LabelStyle.HideAnimals && pawn.RaceProps.Animal) + return false; - static class Extensions - { - public static void Slider(this Listing_Standard list, ref int value, int min, int max, Func label) - { - float f = value; - var h = HorizontalSlider(list.GetRect(22f), ref f, min, max, label == null ? null : label(), 1f); - value = (int)f; - list.Gap(h); + if (MouseDistanceSquared(pawn.DrawPos, true) <= 2.25f && CameraPlusMain.Settings.mouseOverShowsLabels) + return false; + + var len = UI.CurUICellSize(); + var isSmall = len <= CameraPlusMain.Settings.dotSize; + var tamedAnimal = pawn.RaceProps.Animal && pawn.Name != null; + return isSmall && (CameraPlusMain.Settings.includeNotTamedAnimals || pawn.RaceProps.Animal == false || tamedAnimal); } - public static void Slider(this Listing_Standard list, ref float value, float min, float max, Func label, float roundTo = -1f) + public static bool ShouldShowLabel(Thing thing, Vector2 screenPos = default) { - var rect = list.GetRect(22f); - var h = HorizontalSlider(rect, ref value, min, max, label == null ? null : label(), roundTo); - list.Gap(h); + if (CameraPlusMain.Settings.hideNamesWhenZoomedOut == false) + return true; + + var isPawn = thing is Pawn; + + if (MouseDistanceSquared(thing?.DrawPos ?? screenPos, isPawn) <= 2.25f && CameraPlusMain.Settings.mouseOverShowsLabels) + return true; + + var len = UI.CurUICellSize(); + + var lower = isPawn ? CameraPlusMain.Settings.hidePawnLabelBelow : CameraPlusMain.Settings.hideThingLabelBelow; + if (len <= lower) + return false; + + if (isPawn && CameraPlusMain.Settings.customNameStyle == LabelStyle.HideAnimals && (thing as Pawn).RaceProps.Animal) + return true; + + if (isPawn && len <= CameraPlusMain.Settings.dotSize) + return false; + + return true; } - public static float HorizontalSlider(Rect rect, ref float value, float leftValue, float rightValue, string label = null, float roundTo = -1f) + public static void DrawDot(Pawn pawn, Color innerColor, Color outerColor) { - if (label != null) + _ = GetMarkerTextures(pawn, out var innerTexture, out var outerTexture); + + var pos = pawn.DrawPos; + var v1 = (pos - new Vector3(0.75f, 0f, 0.75f)).MapToUIPosition().Rounded(); + var v2 = (pos + new Vector3(0.75f, 0f, 0.75f)).MapToUIPosition().Rounded(); + var markerRect = new Rect(v1, v2 - v1); + + // draw outer marker + GUI.color = outerColor; + GUI.DrawTexture(markerRect, outerTexture, ScaleMode.ScaleToFit, true); + + // draw inner marker + GUI.color = innerColor; + GUI.DrawTexture(markerRect, innerTexture, ScaleMode.ScaleToFit, true); + + // draw extra marker + if (pawn.Downed) + { + GUI.color = downedColor; + GUI.DrawTexture(markerRect, downedTexture, ScaleMode.ScaleToFit, true); + } + else if (pawn.Drafted) { - var anchor = Text.Anchor; - var font = Text.Font; - Text.Font = GameFont.Tiny; - Text.Anchor = TextAnchor.UpperLeft; - Widgets.Label(rect, label); - Text.Anchor = anchor; - Text.Font = font; - rect.y += 18f; + GUI.color = draftedColor; + GUI.DrawTexture(markerRect, draftedTexture, ScaleMode.ScaleToFit, true); } - value = GUI.HorizontalSlider(rect, value, leftValue, rightValue); - if (roundTo > 0f) - value = Mathf.RoundToInt(value / roundTo) * roundTo; - return 4f + label != null ? 18f : 0f; } - } - - public enum LabelMode - { - hide, - show, - dot - } - - [StaticConstructorOnStartup] - class Tools : CameraPlusSettings - { - static readonly Texture2D innerColonistTexture = ContentFinder.Get("InnerColonistMarker", true); - static readonly Texture2D outerColonistTexture = ContentFinder.Get("OuterColonistMarker", true); - static readonly Texture2D innerAnimalTexture = ContentFinder.Get("InnerAnimalMarker", true); - static readonly Texture2D outerAnimalTexture = ContentFinder.Get("OuterAnimalMarker", true); static readonly Dictionary cachedMainColors = new Dictionary(); public static Color? GetMainColor(Pawn pawn) @@ -142,34 +149,6 @@ class Tools : CameraPlusSettings return color; } - // shameless copy of vanilla - public static bool PawnHasNoLabel(Pawn pawn) - { - if (!pawn.Spawned || pawn.Map.fogGrid.IsFogged(pawn.Position)) - return true; - if (!pawn.RaceProps.Humanlike) - { - if (CameraPlusMain.Settings.includeNotTamedAnimals) - return false; - - var animalNameMode = Prefs.AnimalNameMode; - if (animalNameMode == AnimalNameDisplayMode.None) - return true; - if (animalNameMode != AnimalNameDisplayMode.TameAll) - { - if (animalNameMode == AnimalNameDisplayMode.TameNamed) - { - if (pawn.Name == null || pawn.Name.Numerical) - return true; - } - } - else if (pawn.Name == null) - return true; - } - - return false; - } - public static float MouseDistanceSquared(Vector3 pos, bool mapCoordinates) { var mouse = UI.MouseMapPosition(); @@ -189,43 +168,6 @@ public static float MouseDistanceSquared(Vector3 pos, bool mapCoordinates) return delta / len / len; } - public static bool ShouldShowBody(Pawn pawn) - { - if (CameraPlusMain.Settings.hideNamesWhenZoomedOut == false || MouseDistanceSquared(pawn.DrawPos, true) <= 2.25f) - return true; - - return (UI.CurUICellSize() > CameraPlusMain.Settings.dotSize); - } - - public static void ShouldShowLabel(Vector3 location, bool isPawn, out bool showLabel, out bool showDot) - { - showLabel = true; - showDot = false; - - if (CameraPlusMain.Settings.hideNamesWhenZoomedOut == false) - return; - - if (MouseDistanceSquared(location, isPawn) <= 2.25f && CameraPlusMain.Settings.mouseOverShowsLabels) - return; - - var len = UI.CurUICellSize(); - - if (isPawn && len <= CameraPlusMain.Settings.dotSize) - { - showLabel = false; - showDot = true; - return; - } - - var lower = isPawn ? CameraPlusMain.Settings.hidePawnLabelBelow : CameraPlusMain.Settings.hideThingLabelBelow; - if (len <= lower) - { - showLabel = false; - showDot = false; - return; - } - } - static readonly Dictionary cachedCameraDelegates = new Dictionary(); public static CameraDelegates GetCachedCameraDelegate(Pawn pawn) { @@ -238,6 +180,12 @@ public static CameraDelegates GetCachedCameraDelegate(Pawn pawn) return result; } + public static bool CorrectLabelRendering(Pawn pawn) + { + // we fake "show all" so we need to skip if original could would not render labels + return ReversePatches.PerformsDrawPawnGUIOverlay(pawn.Drawer.ui) == false; + } + // returning true will prefer markers over labels static readonly Color dangerousAnimalColor = new Color(0.62f, 0f, 0.05f); public static bool GetMarkerColors(Pawn pawn, out Color innerColor, out Color outerColor) @@ -257,9 +205,9 @@ public static bool GetMarkerColors(Pawn pawn, out Color innerColor, out Color ou return true; } - var isAnimal = pawn.RaceProps.Animal; - var showAnimals = CameraPlusMain.Settings.customNameStyle != LabelStyle.HideAnimals; - if (isAnimal && showAnimals == false) + var isAnimal = pawn.RaceProps.Animal && pawn.Name != null; + var hideAnimalMarkers = CameraPlusMain.Settings.customNameStyle == LabelStyle.HideAnimals; + if (isAnimal && hideAnimalMarkers) { innerColor = default; outerColor = default;