Skip to content

Commit

Permalink
v2.2.1 has rewritten logic for dots and labels and works correctly wi…
Browse files Browse the repository at this point in the history
…th vanilla animal name settings
  • Loading branch information
pardeike committed Oct 17, 2021
1 parent 03f6818 commit f25a6c8
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 231 deletions.
Binary file modified 1.3/Assemblies/CameraPlus.dll
Binary file not shown.
2 changes: 1 addition & 1 deletion About/Manifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Manifest>
<identifier>net.pardeike.rimworld.mod.cameraplus</identifier>
<version>2.2.0.0</version>
<version>2.2.1.0</version>
<targetVersions>
<li>1.0.0</li>
<li>1.1.0</li>
Expand Down
39 changes: 39 additions & 0 deletions Source/CameraDelegates.cs
Original file line number Diff line number Diff line change
@@ -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<Pawn, Color[]> GetCameraColors = null;
public Func<Pawn, Texture2D[]> 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<Pawn, Color[]>)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<Pawn, Texture2D[]>)Delegate.CreateDelegate(funcType, m_GetCameraTextures);
}
}
}
}
30 changes: 16 additions & 14 deletions Source/CameraPlus.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ProjectGuid>{AC5EE7A1-16EA-498D-B21A-83ACF78F0E5A}</ProjectGuid>
Expand All @@ -10,7 +10,7 @@
<OutputPath>..\1.3\Assemblies\</OutputPath>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<Version>2.2.0.0</Version>
<Version>2.2.1.0</Version>
<Copyright>Copyright Andreas Pardeike</Copyright>
</PropertyGroup>

Expand All @@ -30,9 +30,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Krafs.Rimworld.Ref" Version="1.3.3072" />
<PackageReference Include="Krafs.Rimworld.Ref" Version="1.3.3117" />
<PackageReference Include="Lib.Harmony" Version="2.1.1" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="5.0.2" />
<PackageReference Include="Microsoft.NETCore.Platforms" Version="5.0.4" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies.net472" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down Expand Up @@ -67,15 +67,17 @@
</Target>

<PropertyGroup>
<PostBuildEvent>echo Postprocessing
where ModBuilder 2&gt; 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"
)</PostBuildEvent>
<PostBuildEvent>
echo Postprocessing
where ModBuilder 2&gt; 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"
)
</PostBuildEvent>
<Company>Brrainz</Company>
<Authors>Andreas Pardeike</Authors>
<Description></Description>
Expand All @@ -84,4 +86,4 @@ if defined INSTALL_MOD (
<Product>Camera+</Product>
</PropertyGroup>

</Project>
</Project>
43 changes: 43 additions & 0 deletions Source/Extensions.cs
Original file line number Diff line number Diff line change
@@ -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<string> 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<string> 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;
}
}
}
118 changes: 40 additions & 78 deletions Source/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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)]
Expand All @@ -188,83 +180,54 @@ 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)
return true;
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<string, string>), typeof(GameFont), typeof(bool), typeof(bool) })]
[StaticConstructorOnStartup]
static class GenMapUI_DrawPawnLabel_Patch
{
static readonly Texture2D downedTexture = ContentFinder<Texture2D>.Get("DownedMarker", true);
static readonly Texture2D draftedTexture = ContentFinder<Texture2D>.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<string, string>), typeof(GameFont), typeof(bool), typeof(bool) })]
static class GenMapUI_DrawPawnLabel_Patch
{
[HarmonyPriority(10000)]
public static bool Prefix(Pawn pawn, float truncateToWidth)
{
if (CameraPlusMain.skipCustomRendering)
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);
}
}

Expand All @@ -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()"
Expand Down
49 changes: 49 additions & 0 deletions Source/ReversePatches.cs
Original file line number Diff line number Diff line change
@@ -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<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> 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 { }
}
}
}

0 comments on commit f25a6c8

Please sign in to comment.