From 29a4dcab57a96839478089dcc7778f17147c2142 Mon Sep 17 00:00:00 2001 From: SokyranTheDragon <36712560+SokyranTheDragon@users.noreply.github.com> Date: Fri, 24 May 2024 23:54:11 +0200 Subject: [PATCH] More Anomaly syncing (#448) * More Anomaly syncing I'm trying to avoid (too many) spoilers about anomaly, so I'm patching stuff as I go through and progress the DLC. I've gone through and tested some of the stuff that I already saw in game, and fixed whatever needed fixing. Changes: - Creating corpse stockpile for harbinger trees needed `SyncContext.MapSelected` - Synced a float menu option for capturing entity into any holding building - The interaction would work if selecting a specific holding building - Synced a float menu option for drafted carrying an entity to a holding building - It was not needed, but was synced like the other similar methods to save up on the amount of data that would end up being synced - Moved the gizmo for carry to shuttle interaction lower, as the other sync delegates were ordered by their `lambdaOrdinal` - Synced `CompStudiable.studyEnabled` field changes from `ITab_StudyNotes.DrawTitle` - Changing it using a gizmo was synced already - Synced `CompHoldingPlatformTarget.containmentMode` field changes from `ITab_Entity.FillTab` * Sync extract bioferrite checkbox The checkbox was added in a recent update, so it requires an update to `Krafs.RimWorld.Ref` package to work. I've not included it here as I feel it would not fit the PR this belongs to. * Add SetDebugOnly for a dev-mode only gizmo * Sync ActivityGizmo/CompActivity, don't sync HarbingerTree.UpdateRoots Syncing of `HarbingerTree.UpdateRoots` was removed, as the method would naturally be queued up during simulation (SpawnSetup) and called in as a long event, causing the call to be synced. If dev mode syncing was disabled it would end up never being called. Synced following fields: - `ActivityGizmo.targetValuePct` - `CompActivity.suppressIfAbove` - `CompActivity.suppressionEnabled` This required creating a sync worker for `ActivityGizmo`. The syncing here is pretty similar to syncing of `GeneGizmo_Resource`, `Gene_Resource`, and `Gene_Hemogen`. It would potentially be possible to make a more universal approach, but I could not think of one myself. `SyncGeneGizmoResource` and `SyncActivityGizmoTarget` sync the same field (`Gizmo_Slider.targetValuePct`), but we can't register sync field targeting `Gizmo_Slider` as that type is not syncable. --- Source/Client/Syncing/Dict/SyncDictDlc.cs | 17 ++++++++ Source/Client/Syncing/Game/SyncDelegates.cs | 6 ++- Source/Client/Syncing/Game/SyncFields.cs | 43 +++++++++++++++++++++ Source/Client/Syncing/Game/SyncMethods.cs | 3 +- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/Source/Client/Syncing/Dict/SyncDictDlc.cs b/Source/Client/Syncing/Dict/SyncDictDlc.cs index 2f0e2eae..4ee131b2 100644 --- a/Source/Client/Syncing/Dict/SyncDictDlc.cs +++ b/Source/Client/Syncing/Dict/SyncDictDlc.cs @@ -299,6 +299,23 @@ public static class SyncDictDlc } }, #endregion + + #region Anomaly + + { + (ByteWriter data, ActivityGizmo gizmo) => WriteSync(data, gizmo.Comp), + (ByteReader data) => + { + var comp = ReadSync(data); + + // The gizmo may not yet be initialized for the comp. + comp.gizmo ??= new ActivityGizmo(comp.parent); + + return (ActivityGizmo)comp.gizmo; + } + } + + #endregion }; } } diff --git a/Source/Client/Syncing/Game/SyncDelegates.cs b/Source/Client/Syncing/Game/SyncDelegates.cs index b9d5e4ba..75e8e013 100644 --- a/Source/Client/Syncing/Game/SyncDelegates.cs +++ b/Source/Client/Syncing/Game/SyncDelegates.cs @@ -23,10 +23,12 @@ public static void Init() SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), 7).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Capture slave SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), 8).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Capture prisoner SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), 9).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Carry to cryptosleep casket - SyncDelegate.LocalFunc(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), "CarryToShuttleAct").CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Carry to shuttle + SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), 12).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Capture entity SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), 50).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Reload + SyncDelegate.LocalFunc(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddHumanlikeOrders), "CarryToShuttleAct").CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Carry to shuttle SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddDraftedOrders), 3).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Drafted carry to bed SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddDraftedOrders), 4).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Drafted carry to bed (arrest) + SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddDraftedOrders), 5).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Drafted carry entity to holding building SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddDraftedOrders), 6).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Drafted carry to transport shuttle SyncDelegate.Lambda(typeof(FloatMenuMakerMap), nameof(FloatMenuMakerMap.AddDraftedOrders), 7).CancelIfAnyFieldNull().SetContext(mouseKeyContext); // Drafted carry to cryptosleep casket @@ -195,7 +197,7 @@ public static void Init() SyncDelegate.Lambda(typeof(Pawn), nameof(Pawn.GetGizmos), 5).SetDebugOnly(); // Set growth tier // Building_HoldingPlatform and related comps - SyncDelegate.Lambda(typeof(Building_HoldingPlatform), nameof(Building_HoldingPlatform.GetGizmos), 1); // Set escape tick + SyncDelegate.Lambda(typeof(Building_HoldingPlatform), nameof(Building_HoldingPlatform.GetGizmos), 1).SetDebugOnly(); // Set escape tick SyncMethod.Lambda(typeof(CompActivity), nameof(CompActivity.CompGetGizmosExtra), 0).SetDebugOnly(); // Dev activity -5% SyncMethod.Lambda(typeof(CompActivity), nameof(CompActivity.CompGetGizmosExtra), 1).SetDebugOnly(); // Dev activity +5% SyncMethod.Lambda(typeof(CompActivity), nameof(CompActivity.CompGetGizmosExtra), 2).SetDebugOnly(); // Dev go active/go passive diff --git a/Source/Client/Syncing/Game/SyncFields.cs b/Source/Client/Syncing/Game/SyncFields.cs index 13144683..a0e28313 100644 --- a/Source/Client/Syncing/Game/SyncFields.cs +++ b/Source/Client/Syncing/Game/SyncFields.cs @@ -82,6 +82,14 @@ public static class SyncFields public static ISyncField SyncMechCarrierGizmoTargetValue; public static ISyncField SyncMechCarrierMaxToFill; + public static ISyncField SyncStudiableCompEnabled; + public static ISyncField SyncEntityContainmentMode; + public static ISyncField SyncExtractBioferrite; + + public static ISyncField SyncActivityGizmoTarget; + public static ISyncField SyncActivityCompTarget; + public static ISyncField SyncActivityCompSuppression; + public static void Init() { SyncMedCare = Sync.Field(typeof(Pawn), nameof(Pawn.playerSettings), nameof(Pawn_PlayerSettings.medCare)); @@ -208,6 +216,14 @@ public static void Init() SyncMechAutoRepair = Sync.Field(typeof(CompMechRepairable), nameof(CompMechRepairable.autoRepair)); SyncMechCarrierGizmoTargetValue = Sync.Field(typeof(MechCarrierGizmo), nameof(MechCarrierGizmo.targetValue)).SetBufferChanges(); SyncMechCarrierMaxToFill = Sync.Field(typeof(CompMechCarrier), nameof(CompMechCarrier.maxToFill)).SetBufferChanges(); + + SyncStudiableCompEnabled = Sync.Field(typeof(CompStudiable), nameof(CompStudiable.studyEnabled)); + SyncEntityContainmentMode = Sync.Field(typeof(CompHoldingPlatformTarget), nameof(CompHoldingPlatformTarget.containmentMode)); + SyncExtractBioferrite = Sync.Field(typeof(CompHoldingPlatformTarget), nameof(CompHoldingPlatformTarget.extractBioferrite)); + + SyncActivityGizmoTarget = Sync.Field(typeof(ActivityGizmo), nameof(ActivityGizmo.targetValuePct)).SetBufferChanges(); + SyncActivityCompTarget = Sync.Field(typeof(CompActivity), nameof(CompActivity.suppressIfAbove)).SetBufferChanges(); + SyncActivityCompSuppression = Sync.Field(typeof(CompActivity), nameof(CompActivity.suppressionEnabled)); } [MpPrefix(typeof(StorytellerUI), nameof(StorytellerUI.DrawStorytellerSelectionInterface))] @@ -523,6 +539,14 @@ static void SyncGeneResourceChange(Gizmo_Slider __instance) if (geneGizmo.gene is Gene_Hemogen) SyncGeneHemogenAllowed.Watch(geneGizmo.gene); } + else if (__instance is ActivityGizmo activityGizmo) + { + SyncActivityGizmoTarget.Watch(activityGizmo); + + var comp = activityGizmo.Comp; + SyncActivityCompTarget.Watch(comp); + SyncActivityCompSuppression.Watch(comp); + } } [MpPrefix(typeof(ITab_ContentsGenepackHolder), nameof(ITab_ContentsGenepackHolder.DoItemsLists))] @@ -557,6 +581,25 @@ static void WatchMechCarrierMaxToFill(MechCarrierGizmo __instance) SyncMechCarrierGizmoTargetValue.Watch(__instance); SyncMechCarrierMaxToFill.Watch(__instance.carrier); } + + [MpPrefix(typeof(ITab_StudyNotes), nameof(ITab_StudyNotes.DrawTitle))] + static void CompStudiableEnabledCheckbox(ITab_StudyNotes __instance) + { + var comp = __instance.StudiableThing.TryGetComp(); + if (comp != null) + SyncStudiableCompEnabled.Watch(comp); + } + + [MpPrefix(typeof(ITab_Entity), nameof(ITab_Entity.FillTab))] + static void CompHoldingPlatformTargetMode(ITab_Entity __instance) + { + var comp = __instance.SelPawn.TryGetComp(); + if (comp != null) + { + SyncEntityContainmentMode.Watch(comp); + SyncExtractBioferrite.Watch(comp); + } + } } } diff --git a/Source/Client/Syncing/Game/SyncMethods.cs b/Source/Client/Syncing/Game/SyncMethods.cs index 4de00c18..5790a8c9 100644 --- a/Source/Client/Syncing/Game/SyncMethods.cs +++ b/Source/Client/Syncing/Game/SyncMethods.cs @@ -385,10 +385,9 @@ public static void Init() SyncMethod.Lambda(typeof(Building_VoidMonolith), nameof(Building_VoidMonolith.GetGizmos), 2).SetDebugOnly(); // Dev relink // Harbinger Tree - SyncMethod.Register(typeof(HarbingerTree), nameof(HarbingerTree.CreateCorpseStockpile)); + SyncMethod.Register(typeof(HarbingerTree), nameof(HarbingerTree.CreateCorpseStockpile)).SetContext(SyncContext.MapSelected); SyncMethod.Register(typeof(HarbingerTree), nameof(HarbingerTree.AddNutrition)).SetDebugOnly(); SyncMethod.Register(typeof(HarbingerTree), nameof(HarbingerTree.SpawnNewTree)).SetDebugOnly(); - SyncMethod.Register(typeof(HarbingerTree), nameof(HarbingerTree.UpdateRoots)).SetDebugOnly(); SyncMethod.LocalFunc(typeof(HarbingerTree), nameof(HarbingerTree.GetGizmos), "DelayedSplatter").SetDebugOnly(); // Set blood splatters delay // Pawn creep joiner tracker