@@ -123,31 +123,38 @@ static void Postfix(ref FloodUnfogResult __result)
123123 __result . allOnScreen = false ;
124124 }
125125 }
126-
126+
127127 [ HarmonyPatch ]
128- static class UnnaturalCorpsePatch // v1.5
128+ static class UnnaturalCorpsePatch
129129 {
130130 static IEnumerable < MethodBase > TargetMethods ( )
131131 {
132+ // both of these actually combine "is valid" semantics with "is unseen"
132133 yield return AccessTools . DeclaredMethod ( typeof ( AnomalyUtility ) , nameof ( AnomalyUtility . IsValidUnseenCell ) ) ;
133134 yield return AccessTools . DeclaredMethod ( typeof ( UnnaturalCorpse ) , nameof ( UnnaturalCorpse . IsOutsideView ) ) ;
134135 }
135136
136- static MethodInfo CellRectContains = AccessTools . Method ( typeof ( CellRect ) , nameof ( CellRect . Contains ) ) ;
137-
138- static IEnumerable < CodeInstruction > Transpiler ( IEnumerable < CodeInstruction > insts )
139- {
140- foreach ( var inst in insts )
141- {
142- yield return inst ;
143-
144- // consider it always outside view (not contained in CurrentViewRect)
145- if ( inst . operand == CellRectContains )
146- {
147- yield return new CodeInstruction ( OpCodes . Ldc_I4_0 ) ;
148- yield return new CodeInstruction ( OpCodes . And ) ;
149- }
150- }
137+ // primarily for `IsValidUnseenCell()` but works fine for `IsOutsideView()` as well (maybe others)
138+ static IEnumerable < CodeInstruction > Transpiler ( IEnumerable < CodeInstruction > insts , ILGenerator gen )
139+ {
140+ var cm = new CodeMatcher ( insts , gen ) ;
141+
142+ cm . MatchStartForward ( Code . Call [ AccessTools . DeclaredPropertyGetter ( typeof ( Find ) , nameof ( Find . CurrentMap ) ) ] ) ;
143+ cm . SearchForward ( inst => inst . Branches ( out _ ) ) ;
144+ // consider it always on current map, so we can proceed (with finding a nice walkable cell etc.)
145+ // keeping `Beq` and `Bne` avoids needing `[Code.Pop, Code.Pop]`
146+ if ( cm . Opcode == OpCodes . Beq_S )
147+ cm . Advance ( 1 ) . Insert ( Code . Br_S [ cm . InstructionAt ( - 1 ) . operand ] ) ; // force jump as if equal
148+ else if ( cm . Opcode == OpCodes . Bne_Un_S )
149+ cm . CreateLabelWithOffsets ( 1 , out var label ) . Operand = label ; // not-equal jump goes nowhere
150+ else
151+ cm . ThrowIfFalse ( "Couldn't find equality branch opcode following `Find.CurrentMap`" , _ => false ) ;
152+
153+ cm . MatchStartForward ( Code . Call [ AccessTools . DeclaredMethod ( typeof ( CellRect ) , nameof ( CellRect . Contains ) ) ] ) ;
154+ // consider it always outside view (not contained in `CurrentViewRect`) so we can proceed
155+ cm . Advance ( 1 ) . Insert ( [ Code . Ldc_I4_0 , Code . And ] ) ;
156+
157+ return cm . Instructions ( ) ;
151158 }
152159 }
153160
0 commit comments