From 98faa5e692d26d25d2b37947cac9eaabade87620 Mon Sep 17 00:00:00 2001 From: SokyranTheDragon <36712560+SokyranTheDragon@users.noreply.github.com> Date: Fri, 16 Aug 2024 04:48:31 +0200 Subject: [PATCH] Update Vehicle Framework to sync designators, remove redundant patch (#460) First, the patch to remove red cells being drawn in some specific situations. This was fixed in the mod itself, so the patch is now redundant. Second, 2 patches and syncing was added to road area designators. The mod has 2 designators (add/remove area), and the add designator has 2 modes (prioritize/avoid, stored as a static field). Changing the mode was not synced previously, so this change should handle it: - The road mode (prioritize/avoid) is stored by MP Compat whenever the player changes it - Whenever the player interacts with the designator, their selected value is restored from the value stored by MP Compat - When syncing the designator, that player's value will be synced and applied to any interaction that will use it --- Source_Referenced/VehicleFramework.cs | 77 ++++++++++++--------------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/Source_Referenced/VehicleFramework.cs b/Source_Referenced/VehicleFramework.cs index 247aad2..1c27660 100644 --- a/Source_Referenced/VehicleFramework.cs +++ b/Source_Referenced/VehicleFramework.cs @@ -37,6 +37,9 @@ public class VehicleFramework // VehiclePawn.<>c__DisplayClass250_0 private static AccessTools.FieldRef vehiclePawnInnerClassParentField; + + // Designator_AreaRoad + private static Designator_AreaRoad.RoadType localRoadType = Designator_AreaRoad.RoadType.Prioritize; #endregion @@ -90,11 +93,6 @@ static ISyncMethod TrySyncDeclaredMethod(Type targetType, string targetMethodNam foreach (var m in methods.Where(m => m != null)) MpCompat.harmony.Patch(m, transpiler: transpiler); - // Disable an issue where a lot of red regions pop-up for 50 ticks when hosting, - // or when the `PathingHelper.ThingAffectingRegionsStateChange` method is called for things that spawned. - MpCompat.harmony.Patch(AccessTools.DeclaredMethod(typeof(VehicleRegionDirtyer), nameof(VehicleRegionDirtyer.Notify_ThingAffectingRegionsSpawned)), - transpiler: new HarmonyMethod(typeof(VehicleFramework), nameof(DisableDebugFlashing))); - // // Slightly replace how pathfinding is handled by the mod. // // Currently, the vehicle will wait before moving for as long as the path is being calculated. // // We need to make sure it's ready on the same tick for all players, as otherwise a desync will happen. @@ -681,45 +679,6 @@ private static IEnumerable ReplaceThreadAvailable(IEnumerable DisableDebugFlashing(IEnumerable instr, MethodBase baseMethod) - { - var target = AccessTools.DeclaredMethod(typeof(Ext_Map), nameof(Ext_Map.DrawCell_ThreadSafe)); - var replacement = AccessTools.DeclaredMethod(typeof(VehicleFramework), nameof(NoCellDrawing)); - var replacedAnything = false; - - foreach (var ci in instr) - { - if (ci.Calls(target)) - { - ci.opcode = OpCodes.Call; - ci.operand = replacement; - replacedAnything = true; - } - - yield return ci; - } - - if (!replacedAnything) - { - var name = (baseMethod.DeclaringType?.Namespace).NullOrEmpty() ? baseMethod.Name : $"{baseMethod.DeclaringType!.Name}:{baseMethod.Name}"; - Log.Warning($"Failed to patch {nameof(Ext_Map)}.{nameof(Ext_Map.DrawCell_ThreadSafe)} calls (patch most likely no longer needed) for method {name}"); - } - } - - private static void NoCellDrawing(Map map, IntVec3 cell, float colorPct, string text, int duration) - { - // Do nothing in MP. - // We could prefix the method that we patch instead and prevent it from running, but - // it would prevent it from running it from other places in the mod. - - if (!MP.IsInMultiplayer) - map.DrawCell_ThreadSafe(cell, colorPct, text, duration); - } - - #endregion - #region MP safe pathfinding // private static bool PrePathTicker(Vehicle_PathFollower __instance) @@ -1396,6 +1355,18 @@ private static void SyncFlightNode(SyncWorker sync, ref FlightNode node) node = sync.Read(type); } + [MpCompatSyncWorker(typeof(Designator_AreaRoadExpand), shouldConstruct = true)] + private static void SyncAreaRoadDesignator(SyncWorker sync, ref Designator_AreaRoadExpand designator) + { + // We need to sync the road type (prioritize/avoid) to properly sync the designator. + // Sync the local player's road type, as the normal one may become overwritten by + // this specific sync worker delegate. + if (sync.isWriting) + sync.Write(localRoadType); + else + Designator_AreaRoad.roadType = sync.Read(); + } + #endregion #region Sessions @@ -2613,5 +2584,23 @@ private static IEnumerable LogResult(IEnumerable localRoadType = ___roadType; + + [MpCompatPrefix(typeof(Designator_AreaRoad), nameof(Designator_AreaRoad.DesignateSingleCell))] + [MpCompatPrefix(typeof(Designator_AreaRoad), nameof(Designator_AreaRoad.CanDesignateCell))] + private static void RestoreLocalRoadType() + { + // If in MP and not executing synced commands, restore the current player's road type. + // It may become overwritten by a different value when syncing. + if (MP.IsInMultiplayer && !MP.IsExecutingSyncCommand) + Designator_AreaRoad.roadType = localRoadType; + } + + #endregion } } \ No newline at end of file