Skip to content

Commit

Permalink
handle Find.CurrentMap
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeOptimist committed May 6, 2024
1 parent 1cfbc5c commit 6e441f9
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions Source/Client/Patches/Determinism.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,31 +123,38 @@ static void Postfix(ref FloodUnfogResult __result)
__result.allOnScreen = false;
}
}

[HarmonyPatch]
static class UnnaturalCorpsePatch // v1.5
static class UnnaturalCorpsePatch
{
static IEnumerable<MethodBase> TargetMethods()
{
// both of these actually combine "is valid" semantics with "is unseen"
yield return AccessTools.DeclaredMethod(typeof(AnomalyUtility), nameof(AnomalyUtility.IsValidUnseenCell));
yield return AccessTools.DeclaredMethod(typeof(UnnaturalCorpse), nameof(UnnaturalCorpse.IsOutsideView));
}

static MethodInfo CellRectContains = AccessTools.Method(typeof(CellRect), nameof(CellRect.Contains));

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts)
{
foreach (var inst in insts)
{
yield return inst;

// consider it always outside view (not contained in CurrentViewRect)
if (inst.operand == CellRectContains)
{
yield return new CodeInstruction(OpCodes.Ldc_I4_0);
yield return new CodeInstruction(OpCodes.And);
}
}
// primarily for `IsValidUnseenCell()` but works fine for `IsOutsideView()` as well (maybe others)
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts, ILGenerator gen)
{
var cm = new CodeMatcher(insts, gen);

cm.MatchStartForward(Code.Call[AccessTools.DeclaredPropertyGetter(typeof(Find), nameof(Find.CurrentMap))]);
cm.SearchForward(inst => inst.Branches(out _));
// consider it always on current map, so we can proceed (with finding a nice walkable cell etc.)
// keeping `Beq` and `Bne` avoids needing `[Code.Pop, Code.Pop]`
if (cm.Opcode == OpCodes.Beq_S)
cm.Advance(1).Insert(Code.Br_S[cm.InstructionAt(-1).operand]); // force jump as if equal
else if (cm.Opcode == OpCodes.Bne_Un_S)
cm.CreateLabelWithOffsets(1, out var label).Operand = label; // not-equal jump goes nowhere
else
cm.ThrowIfFalse("Couldn't find equality branch opcode following `Find.CurrentMap`", _ => false);

cm.MatchStartForward(Code.Call[AccessTools.DeclaredMethod(typeof(CellRect), nameof(CellRect.Contains))]);
// consider it always outside view (not contained in `CurrentViewRect`) so we can proceed
cm.Advance(1).Insert([Code.Ldc_I4_0, Code.And]);

return cm.Instructions();
}
}

Expand Down

0 comments on commit 6e441f9

Please sign in to comment.