public static CodeMatcher AddLabel(this CodeMatcher codeMatcher, out Label label) { label = new Label(); codeMatcher.AddLabels(new[] { label }); return(codeMatcher); }
static void PatchClearFromConstructionObstacles(CodeMatcher codeCursor, ILGenerator generator) { codeCursor.Start(); codeCursor.MatchForward(false, new CodeMatch(OpCodes.Ldloc_1), new CodeMatch(OpCodes.Ldloc_3), new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(List <GameObject>), nameof(List <GameObject> .Count))), new CodeMatch(OpCodes.Ldc_I4_0), new CodeMatch(OpCodes.Ceq), new CodeMatch(OpCodes.And), new CodeMatch(OpCodes.Stloc_1) ); if (codeCursor.IsValid) { // Remove boolean result assignent as we are "moving" it to after obstacle highlighting block var labels = codeCursor.Instruction.ExtractLabels(); codeCursor.RemoveInstructions(7); codeCursor.AddLabels(labels); codeCursor.MatchForward(true, new CodeMatch(OpCodes.Ldloc_3), new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(List <GameObject>), nameof(List <GameObject> .Count))), new CodeMatch(OpCodes.Ldc_I4_0), new CodeMatch(OpCodes.Ble) ); if (codeCursor.IsValid) { var countCondBranchOperand = (Label)codeCursor.Operand; codeCursor.MatchForward(false, new CodeMatch(instruction => instruction.labels.Contains(countCondBranchOperand))); if (codeCursor.IsValid) { labels = codeCursor.Instruction.ExtractLabels(); // Make it to allow construction by clearing contruction obstacles for boolean result assignment if destroying obstacles is enabled var disabledDestroyObstaclesLabel = generator.DefineLabel(); codeCursor.InsertAndAdvance( new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Config), nameof(Config.Instance))).WithLabels(labels), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(Config), nameof(Config.destroyLargerObstaclesOnConstruction))), new CodeInstruction(OpCodes.Brfalse_S, disabledDestroyObstaclesLabel) ); codeCursor.InsertAndAdvance( new CodeInstruction(OpCodes.Ldloc_3), new CodeInstruction(OpCodes.Call, AccessTools.Method($"{typeof(UpdateAllowedPatch)}:{nameof(ClearConstructionObstacles)}", new Type[] { typeof(List <GameObject>) })) ); // Assign boolean result here (was before highlighting block) codeCursor.InsertAndAdvance( new CodeInstruction(OpCodes.Ldloc_1).WithLabels(disabledDestroyObstaclesLabel), new CodeInstruction(OpCodes.Ldloc_3), new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(List <GameObject>), nameof(List <GameObject> .Count))), new CodeInstruction(OpCodes.Ldc_I4_0), new CodeInstruction(OpCodes.Ceq), new CodeInstruction(OpCodes.And), new CodeInstruction(OpCodes.Stloc_1) ); } } } }