Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 50 additions & 6 deletions Source/Client/Syncing/Game/SyncFields.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
using RimWorld.Planet;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;
using UnityEngine;
using Verse;
using static Verse.Widgets;
Expand Down Expand Up @@ -396,12 +399,42 @@ static void DialogBillConfig(Dialog_BillConfig __instance)
}
}

[MpPrefix(typeof(BillRepeatModeUtility), nameof(BillRepeatModeUtility.MakeConfigFloatMenu), lambdaOrdinal: 0)]
[MpPrefix(typeof(BillRepeatModeUtility), nameof(BillRepeatModeUtility.MakeConfigFloatMenu), lambdaOrdinal: 1)]
[MpPrefix(typeof(BillRepeatModeUtility), nameof(BillRepeatModeUtility.MakeConfigFloatMenu), lambdaOrdinal: 2)]
static void BillRepeatMode(object __instance)
[MpTranspiler(typeof(BillRepeatModeUtility), nameof(BillRepeatModeUtility.MakeConfigFloatMenu))]
static IEnumerable<CodeInstruction> BillConfigFloatMenuTranspiler(IEnumerable<CodeInstruction> insts, MethodBase orig)
{
SyncBillProduction.Watch(__instance.GetPropertyOrField("bill"));
// Find the last occurence of Find.WindowStack.Add(new FloatMenu(opts)) by searching for Find.WindowStack property access.
var findWindowStackGetProp = AccessTools.DeclaredPropertyGetter(typeof(Find), nameof(Find.WindowStack));
var found = 0;
foreach (var inst in insts)
{
if (inst.Calls(findWindowStackGetProp))
{
found++;
yield return new CodeInstruction(OpCodes.Ldarg_0); // Bill_Production bill
yield return new CodeInstruction(OpCodes.Ldloc_1); // List<FloatMenuOption> options
yield return new CodeInstruction(OpCodes.Call, ((Delegate) SyncBillConfigFloatMenuOptions).Method);
}

yield return inst;
}

if (found == 0)
{
throw new Exception("Unexpected code structure in BillRepeatModeUtility.MakeConfigFloatMenu (couldn't find `Find.WindowStack`)." +
" Bill repeat mode will not be synchronized!");
}

if (found > 1)
{
Log.Warning(
$"Atypical code structure in BillRepeatModeUtility.MakeConfigFloatMenu (`Find.WindowStack` occurred ${found} times)." +
" This may cause unexpected behaviour or desynchronization when interacting with a bill's repeat mode.");
}
}

private static void SyncBillConfigFloatMenuOptions(Bill_Production bill, List<FloatMenuOption> opts)
{
WatchMenuOptions(() => SyncBillProduction.Watch(bill), opts);
}

[MpPrefix(typeof(ITab_Bills), nameof(ITab_Bills.TabUpdate))]
Expand Down Expand Up @@ -491,11 +524,22 @@ static IEnumerable<DropdownMenuElement<T>> WatchDropdowns<T>(Action watchAction,
foreach (var entry in dropdowns)
{
if (entry.option.action != null)
entry.option.action = (SyncFieldUtil.FieldWatchPrefix + watchAction + entry.option.action + SyncFieldUtil.FieldWatchPostfix);
entry.option.action = SyncFieldUtil.FieldWatchPrefix + watchAction + entry.option.action + SyncFieldUtil.FieldWatchPostfix;
yield return entry;
}
}

static void WatchMenuOptions(Action watchAction, IEnumerable<FloatMenuOption> opts)
{
foreach (var entry in opts)
{
if (entry.action != null)
{
entry.action = SyncFieldUtil.FieldWatchPrefix + watchAction + entry.action + SyncFieldUtil.FieldWatchPostfix;
}
}
}

[MpPrefix(typeof(Gizmo_PruningConfig), nameof(Gizmo_PruningConfig.DrawBar))]
static void WatchTreeConnectionStrength(Gizmo_PruningConfig __instance)
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Client/Util/MpPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ public MpTranspiler(string typeName, string method) : base(typeName, method)
{
}

public MpTranspiler(Type type, string method, Type[] argTypes) : base(type, method, argTypes)
public MpTranspiler(Type type, string method, Type[] argTypes = null) : base(type, method, argTypes)
{
}

Expand Down
Loading