Skip to content

Commit

Permalink
Update to A18
Browse files Browse the repository at this point in the history
  • Loading branch information
NoImageAvailable committed Nov 3, 2017
1 parent 98cd97b commit 80bc0ae
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 14 deletions.
4 changes: 2 additions & 2 deletions About/About.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<ModMetaData>
<name>Don't Shave Your Head A17.1</name>
<name>Don't Shave Your Head A18</name>
<author>NoImageAvailable, Dark Inquisitor</author>
<targetVersion>0.17.1557</targetVersion>
<targetVersion>0.18.1704</targetVersion>
<url>https://ludeon.com/forums/index.php?topic=30920.0</url>
<description>
Allows showing of hair below helmets and other headgear.
Expand Down
Binary file modified Assemblies/DontShaveYourHead.dll
Binary file not shown.
Binary file not shown.
15 changes: 15 additions & 0 deletions Source/DontShaveYourHead/BodyPartGroupDefOfDSYH.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
using UnityEngine;

namespace DontShaveYourHead
{
public static class BodyPartGroupDefOfDSYH
{
public static BodyPartGroupDef Teeth;
}
}
4 changes: 2 additions & 2 deletions Source/DontShaveYourHead/DontShaveYourHead.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\..\RimWorld1557Win_Data\Managed\Assembly-CSharp.dll</HintPath>
<HintPath>..\..\..\..\RimWorldWin_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
Expand All @@ -48,7 +48,7 @@
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine">
<HintPath>..\..\..\..\RimWorld1557Win_Data\Managed\UnityEngine.dll</HintPath>
<HintPath>..\..\..\..\RimWorldWin_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
Expand Down
43 changes: 35 additions & 8 deletions Source/DontShaveYourHead/Harmony_PawnGraphicSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,50 @@ namespace DontShaveYourHead
[HarmonyPatch(typeof(PawnGraphicSet), "ResolveApparelGraphics")]
public static class Harmony_PawnGraphicSet_ResolveApparelGraphics
{
private enum Coverage
{
None,
Jaw,
UpperHead,
FullHead
}

public static void Postfix(PawnGraphicSet __instance)
{
Pawn pawn = __instance.pawn;

// Define coverage-appropriate path
string pathAppendString = "";
if (pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.FullHead))
{
pathAppendString = "FullHead";
}
else if (pawn.apparel.BodyPartGroupIsCovered(BodyPartGroupDefOf.UpperHead))

// Find maximum coverage of non-mask headwear
var maxCoverage = Coverage.None;
foreach(Apparel cur in pawn.apparel.WornApparel)
{
pathAppendString = "UpperHead";
if (!cur.def.apparel.hatRenderedFrontOfFace)
{
var coveredGroups = cur.def.apparel.bodyPartGroups;
var curCoverage = Coverage.None;
if (coveredGroups.Contains(BodyPartGroupDefOf.FullHead))
{
curCoverage = Coverage.FullHead;
}
if (coveredGroups.Contains(BodyPartGroupDefOf.UpperHead))
{
curCoverage = Coverage.UpperHead;
}
if (coveredGroups.Contains(DefDatabase<BodyPartGroupDef>.GetNamed("Teeth")))
{
curCoverage = Coverage.Jaw;
}
if (maxCoverage < curCoverage)
{
maxCoverage = curCoverage;
}
}
}
else if (pawn.apparel.BodyPartGroupIsCovered(DefDatabase<BodyPartGroupDef>.GetNamed("Teeth")))
if (maxCoverage != Coverage.None)
{
pathAppendString = "Jaw";
pathAppendString = maxCoverage.ToString();
}

// Set hair graphics to headgear-appropriate texture
Expand Down
25 changes: 23 additions & 2 deletions Source/DontShaveYourHead/Harmony_PawnRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@ public static class Harmony_PawnRenderer
{
public static void DrawNowOrLaterShifted(Mesh mesh, Vector3 loc, Quaternion quat, Material mat, bool drawNow)
{
loc.y += 0.001f;
loc.y -= 0.001f;
GenDraw.DrawMeshNowOrLater(mesh, loc, quat, mat, drawNow);
}

// Shifts hat render position upwards to allow proper rendering in portraits
public static void DrawHatNowOrLaterShifted(Mesh mesh, Vector3 loc, Quaternion quat, Material mat, bool drawNow)
{
loc.y += 0.03515625f;
GenDraw.DrawMeshNowOrLater(mesh, loc, quat, mat, drawNow);
}

public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
var codes = instructions.ToList();

// look for headGraphic block
int idxHGfx = codes.FirstIndexOf(ci => ci.operand == typeof(PawnGraphicSet).GetField(nameof(PawnGraphicSet.headGraphic)));
if (idxHGfx == -1)
Expand Down Expand Up @@ -72,7 +79,21 @@ public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructio
codes[idxbodyDrawType - 2].opcode = OpCodes.Ldc_I4_0; // 2nd use of bodyDrawType has <c>flag</c> we want to skip check of
codes[idxbodyDrawType - 2].operand = null;
codes[idxDrawMeshNowOrLater].operand = typeof(Harmony_PawnRenderer).GetMethod(nameof(Harmony_PawnRenderer.DrawNowOrLaterShifted));

// Get IL code of hatRenderedFrontOfFace to find hat render block
var hatBlockIndex = codes.FirstIndexOf(c => c.operand == typeof(ApparelProperties).GetField(nameof(ApparelProperties.hatRenderedFrontOfFace)));

// Find next DrawMeshNowOrLaterCall as it is responsible for drawing non-mask hats
for(int i = hatBlockIndex; i < codes.Count; i++)
{
var code = codes[i];
if (code.operand == typeof(GenDraw).GetMethod(nameof(GenDraw.DrawMeshNowOrLater)))
{
Log.Warning("Found DrawMeshNowOrLater at i=" + i.ToString());
code.operand = typeof(Harmony_PawnRenderer).GetMethod(nameof(Harmony_PawnRenderer.DrawHatNowOrLaterShifted)); // Reroute to custom method
break;
}
}

return codes;
}
Expand Down

0 comments on commit 80bc0ae

Please sign in to comment.