Skip to content

Commit

Permalink
Sync Time-of-Day Switches copy/paste interaction (#462)
Browse files Browse the repository at this point in the history
I've checked the GitHub page of this specific mod, and noticed copy/paste interaction which did not look synced. I've decided to take a quick look at it and give a try at syncing it. I believe everything should work fine.
  • Loading branch information
SokyranTheDragon authored Aug 19, 2024
1 parent 9ab9fd1 commit ae17a23
Showing 1 changed file with 37 additions and 1 deletion.
38 changes: 37 additions & 1 deletion Source/Mods/TimeOfDAySwitch.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using HarmonyLib;
using Multiplayer.API;
using RimWorld;
using Verse;

namespace Multiplayer.Compat
Expand All @@ -10,9 +11,44 @@ namespace Multiplayer.Compat
[MpCompatFor("Merthsoft.TimeOfDaySwitch")]
class TimeOfDAySwitch
{
// Temporary states. When pasting will temporarily store synced states,
// when executing the paste method it will temporarily store current
// player's copied state, and restore it after executing.
private static bool[] tempState;
private static AccessTools.FieldRef<bool[]> copiedStatesField;

public TimeOfDAySwitch(ModContentPack mod)
{
MP.RegisterSyncMethod(AccessTools.Method("Merthsoft.TimerSwitches.TimeOfDaySwitch:SetState"));
var type = AccessTools.TypeByName("Merthsoft.TimerSwitches.TimeOfDaySwitch");
MP.RegisterSyncMethod(type, "SetState");
// Pasting requires us to also sync the copied state which will be pasted,
// so we need to transform the target to sync it as well.
MP.RegisterSyncMethod(type, "Paste")
.SetPreInvoke(PrePaste)
.SetPostInvoke(PostPaste)
.TransformTarget(Serializer.New(
(Building_PowerSwitch building) => (building, states: copiedStatesField()),
tuple =>
{
tempState = tuple.states;
return tuple.building;
}), true);

// Field ref for accessing the copied state, we'll need to change those when copy/pasting stuff.
copiedStatesField = AccessTools.StaticFieldRefAccess<bool[]>(
AccessTools.DeclaredField("Merthsoft.TimerSwitches.ClipBoard:states"));
}

private static void PrePaste(object instance, object[] args)
{
ref var state = ref copiedStatesField();
(state, tempState) = (tempState, state);
}

private static void PostPaste(object instance, object[] args)
{
copiedStatesField() = tempState;
tempState = null;
}
}
}

0 comments on commit ae17a23

Please sign in to comment.