Skip to content

Commit df26a63

Browse files
authored
fix(VGE): sync oxygen gizmo via sync method with typed FieldRef (#577)
Replaces the oxygen gizmo sync fields with a SyncMethod + SyncWorker so the Gizmo_Slider.targetValuePct cache round-trips cleanly instead of being overwritten every frame by the base-class slider logic. Uses AccessTools.FieldRef<object, ThingComp> / FieldRef<object, Gizmo_Slider> so callsites don't need casts. targetType is set via reflection on the ISyncField because RegisterSyncField resolves it via FieldInfo.ReflectedType, which returns the base Gizmo_Slider rather than the concrete subclass. See rwmt/Multiplayer#880.
1 parent 998c226 commit df26a63

1 file changed

Lines changed: 25 additions & 10 deletions

File tree

Source/Mods/VanillaGravshipExpanded.cs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ class VanillaGravshipExpanded
3434

3535
// Gizmo_OxygenProvider
3636
private static Type oxygenGizmoType;
37-
private static AccessTools.FieldRef<object, object> oxygenProviderFromGizmo;
38-
private static ISyncField oxygenRechargeAtField;
39-
private static ISyncField oxygenAutoRechargeField;
37+
private static AccessTools.FieldRef<object, ThingComp> oxygenProviderFromGizmo;
38+
private static ISyncField oxygenTargetValuePctField;
39+
private static AccessTools.FieldRef<object, Gizmo_Slider> oxygenGizmoFromComp;
4040

4141
// Building_VacBarrier_Recolorable color sync
4242
private static Type vacBarrierRecolorableType;
@@ -382,13 +382,17 @@ private static void LatePatch()
382382

383383
{
384384
var compType = AccessTools.TypeByName("VanillaGravshipExpanded.CompApparelOxygenProvider");
385-
oxygenRechargeAtField = MP.RegisterSyncField(compType, "rechargeAtCharges").SetBufferChanges();
386-
oxygenAutoRechargeField = MP.RegisterSyncField(compType, "automaticRechargeEnabled");
385+
MP.RegisterSyncMethod(AccessTools.PropertySetter(compType, "AutomaticRechargeEnabled"));
387386

388387
oxygenGizmoType = AccessTools.TypeByName("VanillaGravshipExpanded.Gizmo_OxygenProvider");
389-
oxygenProviderFromGizmo = AccessTools.FieldRefAccess<object>(oxygenGizmoType, "oxygenProvider");
388+
oxygenProviderFromGizmo = AccessTools.FieldRefAccess<ThingComp>(oxygenGizmoType, "oxygenProvider");
389+
oxygenGizmoFromComp = AccessTools.FieldRefAccess<Gizmo_Slider>(compType, "oxygenConfigurationGizmo");
390+
391+
oxygenTargetValuePctField = MP.RegisterSyncField(oxygenGizmoType, "targetValuePct").SetBufferChanges();
392+
AccessTools.Field(oxygenTargetValuePctField.GetType(), "targetType")
393+
.SetValue(oxygenTargetValuePctField, oxygenGizmoType);
394+
MP.RegisterSyncWorker<Gizmo_Slider>(SyncOxygenGizmo, oxygenGizmoType);
390395

391-
// Watch both fields around GizmoOnGUI with explicit WatchBegin/WatchEnd.
392396
MpCompat.harmony.Patch(
393397
AccessTools.DeclaredMethod(typeof(Gizmo_Slider), nameof(Gizmo_Slider.GizmoOnGUI)),
394398
prefix: new HarmonyMethod(typeof(VanillaGravshipExpanded), nameof(PreOxygenGizmoOnGUI)),
@@ -783,10 +787,8 @@ private static void PreOxygenGizmoOnGUI(Gizmo_Slider __instance)
783787
if (!MP.IsInMultiplayer || __instance.GetType() != oxygenGizmoType)
784788
return;
785789

786-
var comp = oxygenProviderFromGizmo(__instance);
787790
MP.WatchBegin();
788-
oxygenRechargeAtField.Watch(comp);
789-
oxygenAutoRechargeField.Watch(comp);
791+
oxygenTargetValuePctField.Watch(__instance);
790792
}
791793

792794
private static void PostOxygenGizmoOnGUI(Gizmo_Slider __instance)
@@ -797,6 +799,19 @@ private static void PostOxygenGizmoOnGUI(Gizmo_Slider __instance)
797799
MP.WatchEnd();
798800
}
799801

802+
private static void SyncOxygenGizmo(SyncWorker sync, ref Gizmo_Slider gizmo)
803+
{
804+
if (sync.isWriting)
805+
{
806+
sync.Write(oxygenProviderFromGizmo(gizmo));
807+
}
808+
else
809+
{
810+
var comp = sync.Read<ThingComp>();
811+
gizmo = oxygenGizmoFromComp(comp);
812+
}
813+
}
814+
800815
/// <summary>
801816
/// Intercept the paste color gizmo action. ColorClipboard is per-client
802817
/// state, so we capture the color value and sync per-barrier.

0 commit comments

Comments
 (0)