diff --git a/References/EccentricDefenseGrid.dll b/References/EccentricDefenseGrid.dll new file mode 100644 index 0000000..bbafd52 Binary files /dev/null and b/References/EccentricDefenseGrid.dll differ diff --git a/References/EccentricDefenseGrid.txt b/References/EccentricDefenseGrid.txt new file mode 100644 index 0000000..bf7be85 --- /dev/null +++ b/References/EccentricDefenseGrid.txt @@ -0,0 +1 @@ +2CAF9AB8B7DE9F0347A53E1F688395533DA5B163 \ No newline at end of file diff --git a/Source/Mods/EccentricTechFlares.cs b/Source/Mods/EccentricTechFlares.cs new file mode 100644 index 0000000..a9a6d62 --- /dev/null +++ b/Source/Mods/EccentricTechFlares.cs @@ -0,0 +1,61 @@ +using HarmonyLib; +using Multiplayer.API; +using Verse; +using System.Reflection; +using System; +namespace Multiplayer.Compat +{ + /// Eccentric Extras - Flares by Aelanna + /// + [MpCompatFor("Aelanna.EccentricTech.Flares2")] + internal class EccentricTechFlares + { + + private static ConstructorInfo commandThrowIlluminatorConstructor; + private static Type compIlluminatorPackType; + public EccentricTechFlares(ModContentPack mod) + { + // RNG + { + } + + // Gizmos + { + var commandThrowIlluminatorType = AccessTools.TypeByName("EccentricFlares.Command_ThrowIlluminator"); + compIlluminatorPackType = AccessTools.TypeByName("EccentricFlares.CompIlluminatorPack"); + + commandThrowIlluminatorConstructor = AccessTools.DeclaredConstructor(commandThrowIlluminatorType, [compIlluminatorPackType]); + + MP.RegisterSyncWorker(SyncCommandThrowIlluminator, commandThrowIlluminatorType); + MP.RegisterSyncMethod(commandThrowIlluminatorType, "SelectOption"); + + + + LongEventHandler.ExecuteWhenFinished(LatePatch); + } + + } + public static void LatePatch() + { + var type = AccessTools.TypeByName("EccentricFlares.CompIlluminatorPack"); + + MP.RegisterSyncMethod(compIlluminatorPackType, "DoStartThrow"); + MpCompat.RegisterLambdaMethod(type, "CompGetWornGizmosExtra", 1); + } + + private static void SyncCommandThrowIlluminator(SyncWorker sync, ref object command) + { + + if (sync.isWriting) + { + Traverse traverse = Traverse.Create(command); + ThingComp comp = traverse.Field("pack").GetValue(); + sync.Write(comp); + } + else + { + command = commandThrowIlluminatorConstructor.Invoke([sync.Read()]); + } + } + } +} diff --git a/Source/Mods/VanillaExpandedFramework.cs b/Source/Mods/VanillaExpandedFramework.cs index b147edc..d5481e9 100644 --- a/Source/Mods/VanillaExpandedFramework.cs +++ b/Source/Mods/VanillaExpandedFramework.cs @@ -93,6 +93,16 @@ private static void SyncCommandWithBuilding(SyncWorker sync, ref Command command else building.SetValue(sync.Read()); } + private static void SyncCommandWithCompBuilding(SyncWorker sync, ref Command command) + { + var traverse = Traverse.Create(command); + var building = traverse.Field("building"); + + if (sync.isWriting) + sync.Write(building.GetValue() as ThingComp); + else + building.SetValue(sync.Read()); + } #endregion @@ -619,7 +629,6 @@ private static void SyncHireable(SyncWorker sync, ref object obj) #region Vanilla Furniture Expanded // Vanilla Furniture Expanded - private static AccessTools.FieldRef setStoneBuildingField; private static Type randomBuildingGraphicCompType; private static FastInvokeHandler randomBuildingGraphicCompChangeGraphicMethod; @@ -634,14 +643,12 @@ private static void PatchVanillaFurnitureExpanded() var type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetItemsToSpawn"); MpCompat.RegisterLambdaDelegate(type, "ProcessInput", 1); - MP.RegisterSyncWorker(SyncCommandWithBuilding, type, shouldConstruct: true); + MP.RegisterSyncWorker(SyncCommandWithCompBuilding, type, shouldConstruct: true); MpCompat.RegisterLambdaMethod("VanillaFurnitureExpanded.CompRockSpawner", "CompGetGizmosExtra", 0); type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetStoneType"); - setStoneBuildingField = AccessTools.FieldRefAccess(type, "building"); - MpCompat.RegisterLambdaMethod(type, "ProcessInput", 0); - MP.RegisterSyncWorker(SyncSetStoneTypeCommand, type, shouldConstruct: true); + MP.RegisterSyncWorker(SyncCommandWithCompBuilding, type, shouldConstruct: true); MpCompat.RegisterLambdaDelegate(type, "ProcessInput", 1); type = randomBuildingGraphicCompType = AccessTools.TypeByName("VanillaFurnitureExpanded.CompRandomBuildingGraphic"); @@ -679,14 +686,6 @@ private static void PatchVanillaFurnitureExpanded() MP.RegisterSyncWorker(SyncCompGlower); } - private static void SyncSetStoneTypeCommand(SyncWorker sync, ref Command obj) - { - if (sync.isWriting) - sync.Write(setStoneBuildingField(obj)); - else - setStoneBuildingField(obj) = sync.Read(); - } - private static bool Dialog_ChooseGraphic_ReplacementButton(Rect butRect, bool doMouseoverSound, Thing thingToChange, int index, Window window) { var result = Widgets.ButtonInvisible(butRect, doMouseoverSound); diff --git a/Source_Referenced/EccentricDefenseGrid.cs b/Source_Referenced/EccentricDefenseGrid.cs new file mode 100644 index 0000000..28dea76 --- /dev/null +++ b/Source_Referenced/EccentricDefenseGrid.cs @@ -0,0 +1,232 @@ +using HarmonyLib; +using Multiplayer.API; +using RimWorld; +using Verse; +using EccentricDefenseGrid; +using System.Linq; + +namespace Multiplayer.Compat +{ + /// EccentricTech.DefenseGrid by Aelanna + /// + [MpCompatFor("Aelanna.EccentricTech.DefenseGrid")] + internal class EccentricTechDefenseGrid + // + { + private static ISyncField autoReload; + private static CompArtilleryMissileLauncher parentCompArtilleryMissileLauncher; + public EccentricTechDefenseGrid(ModContentPack mod) + { + // RNG + { + // patch this or every effect + // Seems all effcts go through this class and many of them contains rand + var type = AccessTools.TypeByName("EccentricProjectiles.EffectMapComponent"); + var methods = new[] + { + AccessTools.Method(type, "MapComponentTick"), + AccessTools.Method(type,"CreateEffect") + }; + PatchingUtilities.PatchPushPopRand(methods); + } + + // Gizmos + { + var type = AccessTools.TypeByName("EccentricDefenseGrid.CompArtilleryDesignator"); + MP.RegisterSyncMethod(type, "NextDesignationMode"); + MP.RegisterSyncMethod(type, "SetDesignationMode"); + MP.RegisterSyncMethod(type, "SetOrdnanceIndex"); + // This delegate set field `ordnanceDef` & call `DoArtilleryDesignation` + MpCompat.RegisterLambdaDelegate(type, "DoArtilleryTargeting", 0); + + type = AccessTools.TypeByName("EccentricDefenseGrid.DefenseGridNetwork"); + MP.RegisterSyncMethod(type, "NextDesignationMode"); + MP.RegisterSyncMethod(type, "SetDesignationMode"); + MP.RegisterSyncMethod(type, "SetSelectedOrdnance"); + MpCompat.RegisterLambdaDelegate(type, "DoArtilleryTargeting", 0); + + MP.RegisterSyncWorker(SyncDefenseGridNetwork, type); + type = AccessTools.TypeByName("EccentricDefenseGrid.OrdnanceCount"); + MP.RegisterSyncWorker(SyncOrdnanceCount, type, shouldConstruct: true); + + + + type = AccessTools.TypeByName("EccentricDefenseGrid.DefenseGridMapComponent"); + + MP.RegisterSyncMethod(type, "RecountOrdnance"); + + type = AccessTools.TypeByName("EccentricDefenseGrid.CompArtilleryMissileLauncher"); + MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0, 1); + + + type = AccessTools.TypeByName("EccentricDefenseGrid.CompDefenseProjector"); + //called from gizmo + MP.RegisterSyncMethod(type, "ApplyRadius").SetContext(SyncContext.MapSelected); + MP.RegisterSyncMethod(type, "ApplyColor").SetContext(SyncContext.MapSelected); + MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 1).SetDebugOnly(); + + type = AccessTools.TypeByName("EccentricDefenseGrid.CompDefenseGenerator"); + MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 2, 4, 6, 8, 10, 11, 12).TakeLast(2).SetDebugOnly(); + + type = AccessTools.TypeByName("EccentricDefenseGrid.CompDefenseHeatsink"); + MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0, 1, 2).SetDebugOnly(); + + + } + { + var type = AccessTools.TypeByName("EccentricDefenseGrid.OrdnanceSlot"); + + MP.RegisterSyncWorker(SyncOrdnanceSlot, type); + } + // ITab + { + + var type = AccessTools.TypeByName("EccentricDefenseGrid.ITab_OrdnanceStorage"); + + + MpCompat.harmony.Patch(AccessTools.Method(type, "FillTab"), + prefix: new HarmonyMethod(typeof(EccentricTechDefenseGrid), nameof(PreFillTab)), + postfix: new HarmonyMethod(typeof(EccentricTechDefenseGrid), nameof(PostFillTab))); + + + MpCompat.RegisterLambdaDelegate(type, "DrawOrdnance_GenerateMenu", 0, 1).SetContext(SyncContext.MapSelected); + + + + type = AccessTools.TypeByName("EccentricDefenseGrid.OrdnanceSlot"); + autoReload = MP.RegisterSyncField(type, "autoReload"); + type = AccessTools.TypeByName("EccentricDefenseGrid.CompArtilleryMissileLauncher"); + + MP.RegisterSyncWorker(SyncCompArtilleryMissileLauncher, type); + } + + } + + private static void PreFillTab(ITab __instance) + { + if (!MP.IsInMultiplayer) + { + return; + } + Building building = __instance.SelThing as Building; + parentCompArtilleryMissileLauncher = building.GetComp(); + + MP.WatchBegin(); + parentCompArtilleryMissileLauncher.slots.ForEach((slot) => autoReload.Watch(slot)); + } + private static void PostFillTab() + { + if (!MP.IsInMultiplayer) + return; + parentCompArtilleryMissileLauncher = null; + MP.WatchEnd(); + } + private static void SyncOrdnanceSlot(SyncWorker sync, ref OrdnanceSlot obj) + { + if (sync.isWriting) + { + sync.Write(obj is null); + if (obj is null) + return; + + + } + else + { + // is null + // does exist as method `DrawOrdnance_GenerateMenu` could be called with this param null + if (sync.Read()) + { + obj = null; + return; + } + } + + CompArtilleryMissileLauncher compArtilleryMissileLauncher = Find.Selector.SingleSelectedThing?.TryGetComp(); + if (compArtilleryMissileLauncher != null) + { + if (sync.isWriting) + { + sync.Write(compArtilleryMissileLauncher.slots.IndexOf(obj)); + return; + } + else + { + int index = sync.Read(); + if (index != -1) + { + obj = compArtilleryMissileLauncher.slots[index]; + return; + + } + else + { + // to normal + } + } + + } + + // normally copied by exposeFields + //sync.Bind(ref obj, ordnanceSlot); + if (sync.isWriting) + { + + sync.Write(obj.autoReload); + sync.Write(obj.ordnance as ThingWithComps); + sync.Write(obj.def.defName); + } + else + { + + + obj.autoReload = sync.Read(); + obj.ordnance = sync.Read() as Ordnance; + obj.def = DefDatabase.GetNamed(sync.Read()); + + } + } + private static void SyncOrdnanceCount(SyncWorker sync, ref object ordnanceCount) + { + OrdnanceCount _oc = ordnanceCount as OrdnanceCount; + if (sync.isWriting) + { + sync.Write(_oc.def.defName); + sync.Write(_oc.count); + } + else + { + _oc.def = DefDatabase.GetNamed(sync.Read()); + _oc.count = sync.Read(); + } + } + private static void SyncDefenseGridNetwork(SyncWorker sync, ref object network) + { + DefenseGridNetwork _net = network as DefenseGridNetwork; + if (sync.isWriting) + { + sync.Write(_net.mapComponent.map); + sync.Write(_net.id); + } + else + { + Map map = sync.Read(); + int id = sync.Read(); + network = map.GetComponent().networks.Find((net) => net.id == id); + } + } + + private static void SyncCompArtilleryMissileLauncher(SyncWorker sync, ref CompArtilleryMissileLauncher compArtilleryMissileLauncher) + { + if (sync.isWriting) + { + sync.Write(compArtilleryMissileLauncher.parent as ThingWithComps); + } + else + { + compArtilleryMissileLauncher = sync.Read().GetComp(); + } + } + + } +}