Skip to content

Commit 1bcb548

Browse files
authored
Plans now sync when: (#566)
- Colour changes - Places with colour - Copied - Partially copied - Deleted Shuffle now only runs on cells when its deterministic. Serialized Plan
1 parent 3fad9e9 commit 1bcb548

File tree

6 files changed

+137
-12
lines changed

6 files changed

+137
-12
lines changed

Source/Client/AsyncTime/AsyncTimeComp.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,17 @@ void RestoreState()
399399
if (mode == DesignatorMode.SingleCell)
400400
{
401401
IntVec3 cell = SyncSerialization.ReadSync<IntVec3>(data);
402+
if (designator is Designator_Plan_Add addDesignator)
403+
addDesignator.colorDef = SyncSerialization.ReadSync<ColorDef>(data);
402404

403405
designator.DesignateSingleCell(cell);
404406
designator.Finalize(true);
405407
}
406408
else if (mode == DesignatorMode.MultiCell)
407409
{
408410
IntVec3[] cells = SyncSerialization.ReadSync<IntVec3[]>(data);
411+
if (designator is Designator_Plan_Add addDesignator)
412+
addDesignator.colorDef = SyncSerialization.ReadSync<ColorDef>(data);
409413

410414
designator.DesignateMultiCell(cells);
411415
}

Source/Client/Patches/Designators.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public static class DesignatorPatches
2525
public static bool DesignateSingleCell(Designator __instance, IntVec3 __0)
2626
{
2727
if (!Multiplayer.InInterface) return true;
28+
if (__instance is Designator_Plan_Copy or Designator_Plan_CopySelection or Designator_Plan_CopySelectionPaste) return true;
2829

2930
Designator designator = __instance;
3031

@@ -35,6 +36,9 @@ public static bool DesignateSingleCell(Designator __instance, IntVec3 __0)
3536
WriteData(writer, DesignatorMode.SingleCell, designator);
3637
SyncSerialization.WriteSync(writer, __0);
3738

39+
if (__instance is Designator_Plan_Add addDesignator)
40+
SyncSerialization.WriteSync(writer, addDesignator.colorDef);
41+
3842
SendSyncCommand(map.uniqueID, writer);
3943
Multiplayer.WriterLog.AddCurrentNode(writer);
4044

@@ -58,6 +62,9 @@ public static bool DesignateMultiCell(Designator __instance, IEnumerable<IntVec3
5862
WriteData(writer, DesignatorMode.MultiCell, designator);
5963
SyncSerialization.WriteSync(writer, cellArray);
6064

65+
if (__instance is Designator_Plan_Add addDesignator)
66+
SyncSerialization.WriteSync(writer, addDesignator.colorDef);
67+
6168
SendSyncCommand(map.uniqueID, writer);
6269
Multiplayer.WriterLog.AddCurrentNode(writer);
6370

Source/Client/Patches/Determinism.cs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,35 +147,46 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst
147147
}
148148
}
149149

150-
[HarmonyPatch(typeof(Zone), nameof(Zone.Cells), MethodType.Getter)]
151-
static class ZoneCellsShufflePatch
150+
public static class CellsShufflePatchShared
152151
{
153-
static FieldInfo CellsShuffled = AccessTools.Field(typeof(Zone), nameof(Zone.cellsShuffled));
154-
155-
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts)
152+
public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts, FieldInfo cellsShuffledField)
156153
{
157154
bool found = false;
158-
159-
foreach (var inst in insts)
155+
foreach (CodeInstruction inst in insts)
160156
{
161157
yield return inst;
162-
163-
if (!found && inst.operand == CellsShuffled)
158+
if (!found && inst.operand == cellsShuffledField)
164159
{
165-
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(ZoneCellsShufflePatch), nameof(ShouldShuffle)));
160+
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(CellsShufflePatchShared), nameof(ShouldShuffle)));
166161
yield return new CodeInstruction(OpCodes.Not);
167162
yield return new CodeInstruction(OpCodes.Or);
168163
found = true;
169164
}
170165
}
171166
}
172167

173-
static bool ShouldShuffle()
168+
public static bool ShouldShuffle()
174169
{
175170
return Multiplayer.Client == null || Multiplayer.Ticking;
176171
}
177172
}
178173

174+
[HarmonyPatch(typeof(Zone), nameof(Zone.Cells), MethodType.Getter)]
175+
static class ZoneCellsShufflePatch
176+
{
177+
static readonly FieldInfo CellsShuffled = AccessTools.Field(typeof(Zone), "cellsShuffled");
178+
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts)
179+
=> CellsShufflePatchShared.Transpiler(insts, CellsShuffled);
180+
}
181+
182+
[HarmonyPatch(typeof(Plan), nameof(Plan.Cells), MethodType.Getter)]
183+
static class PlanCellsShufflePatch
184+
{
185+
static readonly FieldInfo CellsShuffled = AccessTools.Field(typeof(Plan), "cellsShuffled");
186+
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts)
187+
=> CellsShufflePatchShared.Transpiler(insts, CellsShuffled);
188+
}
189+
179190
[HarmonyPatch]
180191
static class SortArchivablesById
181192
{

Source/Client/Patches/Plans.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using HarmonyLib;
2+
using Multiplayer.API;
3+
using RimWorld;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Reflection;
8+
using System.Text;
9+
using System.Threading.Tasks;
10+
using Verse;
11+
12+
namespace Multiplayer.Client.Patches
13+
{
14+
[HarmonyPatch]
15+
public static class PlanGetGizmosPatch
16+
{
17+
static IEnumerable<MethodBase> TargetMethods()
18+
{
19+
Type planType = AccessTools.TypeByName("Verse.Plan+<>c__DisplayClass45_0");
20+
yield return AccessTools.Method(planType, "<GetGizmos>b__1");
21+
}
22+
23+
static bool Prefix(object __instance)
24+
{
25+
if (Multiplayer.Client == null) return true;
26+
27+
Plan plan = (Plan)AccessTools.Field(__instance.GetType(), "<>4__this").GetValue(__instance);
28+
ColorDef color = (ColorDef)AccessTools.Field(__instance.GetType(), "newCol").GetValue(__instance);
29+
30+
SyncSetPlanColor(plan, color);
31+
return false;
32+
}
33+
34+
[SyncMethod]
35+
public static void SyncSetPlanColor(Plan plan, ColorDef color)
36+
{
37+
plan.Color = color;
38+
AccessTools.Method(typeof(Plan), "CheckContiguous").Invoke(plan, null);
39+
}
40+
}
41+
42+
[HarmonyPatch(typeof(Designator_Plan_Copy), nameof(Designator_Plan_Copy.DesignateSingleCell))]
43+
public static class PlanCopySingleCellPatch
44+
{
45+
static bool Prefix(Designator_Plan_Copy __instance, IntVec3 c)
46+
{
47+
if (Multiplayer.Client == null) return true;
48+
49+
SyncDesignateSingleCell(__instance, __instance.cells, __instance.colorDef);
50+
return false;
51+
}
52+
53+
[SyncMethod]
54+
public static void SyncDesignateSingleCell(Designator_Plan_Add designator, List<IntVec3> cells, ColorDef colorDef)
55+
{
56+
designator.colorDef = colorDef;
57+
designator.PlanCells(cells);
58+
}
59+
}
60+
61+
[HarmonyPatch(typeof(Designator_Plan_CopySelectionPaste), nameof(Designator_Plan_CopySelectionPaste.DesignateSingleCell))]
62+
public static class PlanCopySelectionPasteSingleCellPatch
63+
{
64+
static bool Prefix(Designator_Plan_CopySelectionPaste __instance, IntVec3 c)
65+
{
66+
if (Multiplayer.Client == null) return true;
67+
68+
foreach (ColorDef color in __instance.colors)
69+
SyncDesignateSingleCell(__instance, __instance.GetCurrentCells(c, color).ToList(), color);
70+
71+
return false;
72+
}
73+
74+
[SyncMethod]
75+
public static void SyncDesignateSingleCell(Designator_Plan_CopySelectionPaste designator, List<IntVec3> cells, ColorDef colorDef)
76+
{
77+
designator.SelectedPlan = null;
78+
designator.colorDef = colorDef;
79+
designator.PlanCells(cells);
80+
}
81+
}
82+
}

Source/Client/Syncing/Dict/SyncDictRimWorld.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ public static class SyncDictRimWorld
10261026
{
10271027
// TODO: Consider using int16 rather that int32 to minimize network traffic.
10281028
// Investigate if the tiles/layers are small enough to allow that.
1029-
(ByteWriter data, PlanetTile tile) =>
1029+
(ByteWriter data, PlanetTile tile) =>
10301030
{
10311031
data.WriteInt32(tile.tileId);
10321032
data.WriteInt32(tile.layerId);
@@ -1095,6 +1095,26 @@ public static class SyncDictRimWorld
10951095
return data.MpContext().map.zoneManager.AllZones.Find(zone => zone.ID == zoneId);
10961096
}, true
10971097
},
1098+
{
1099+
(ByteWriter data, Plan plan) =>
1100+
{
1101+
if (plan == null)
1102+
{
1103+
data.WriteInt32(-1);
1104+
}
1105+
else
1106+
{
1107+
data.MpContext().map = plan.Map;
1108+
data.WriteInt32(plan.ID);
1109+
}
1110+
},
1111+
(ByteReader data) => {
1112+
int zoneId = data.ReadInt32();
1113+
if (zoneId == -1)
1114+
return null;
1115+
return data.MpContext().map.planManager.AllPlans.Find(p => p.ID == zoneId);
1116+
}, true
1117+
},
10981118
#endregion
10991119

11001120
#region Globals

Source/Client/Syncing/Game/SyncMethods.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public static void Init()
4242
SyncMethod.Register(typeof(Pawn_GuestTracker), nameof(Pawn_GuestTracker.SetExclusiveInteraction)).CancelIfAnyArgNull();
4343
SyncMethod.Register(typeof(Pawn_GuestTracker), nameof(Pawn_GuestTracker.ToggleNonExclusiveInteraction)).CancelIfAnyArgNull();
4444
SyncMethod.Register(typeof(Zone), nameof(Zone.Delete));
45+
SyncMethod.Register(typeof(Plan), nameof(Plan.Delete));
4546
SyncMethod.Register(typeof(BillStack), nameof(BillStack.AddBill)).ExposeParameter(0); // Only used for pasting
4647
SyncMethod.Register(typeof(BillStack), nameof(BillStack.Delete)).CancelIfAnyArgNull().SetPostInvoke(TryDirtyCurrentPawnTable);
4748
SyncMethod.Register(typeof(BillStack), nameof(BillStack.Reorder)).CancelIfAnyArgNull();

0 commit comments

Comments
 (0)