From 7ca64b8e77e46d71da3bd57b021dc0bc07d067e2 Mon Sep 17 00:00:00 2001 From: Thomas Smith Date: Wed, 13 Nov 2024 16:12:46 +0000 Subject: [PATCH 1/4] Fixed deprecated workflow actions. Added editorconfig. --- .editorconfig | 5 +++++ .github/workflows/release.yml | 10 +++++----- .github/workflows/staging.yml | 9 +++++---- EcoLawExtensionsMod/Registration.cs | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 EcoLawExtensionsMod/Registration.cs diff --git a/.editorconfig b/.editorconfig index c825f67..edce4f4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,3 +2,8 @@ # CA1416: Validate platform compatibility dotnet_diagnostic.CA1416.severity = silent + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ba92f36..44cbc1a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,10 +9,10 @@ jobs: name: Build Mod runs-on: ubuntu-latest env: - MODKIT_VERSION: 0.11.0.2-beta-release-707 + MODKIT_VERSION: 0.11.1.1-beta-release-758 ECO_BRANCH: staging steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup .NET Core 7.0 uses: actions/setup-dotnet@v1 with: @@ -23,7 +23,7 @@ jobs: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 - name: Cache Eco dlls id: cache-eco-dlls - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ./eco-dlls key: ${{ env.MODKIT_VERSION }}-ref-dlls @@ -35,7 +35,7 @@ jobs: env: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 - name: Upload build artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: mod-binaries-${{github.event.release.tag_name}} path: EcoLawExtensionsMod/bin/Release/net7.0/EcoLawExtensionsMod.* @@ -47,7 +47,7 @@ jobs: steps: - name: Download build artifact (mod) id: download-mod - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: mod-binaries-${{github.event.release.tag_name}} - name: Upload release asset (mod) diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 0f30a88..50d5caf 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -7,12 +7,13 @@ on: jobs: build-mod: + name: Build Mod runs-on: ubuntu-latest env: - MODKIT_VERSION: 0.11.0.2-beta-release-707 + MODKIT_VERSION: 0.11.1.1-beta-release-758 ECO_BRANCH: staging steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Setup .NET Core 7.0 uses: actions/setup-dotnet@v1 with: @@ -23,7 +24,7 @@ jobs: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 - name: Cache Eco dlls id: cache-eco-dlls - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ./eco-dlls key: ${{ env.MODKIT_VERSION }}-ref-dlls @@ -35,7 +36,7 @@ jobs: env: DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 - name: Upload build artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: mod-binaries-staging path: EcoLawExtensionsMod/bin/Release/net7.0/EcoLawExtensionsMod.* diff --git a/EcoLawExtensionsMod/Registration.cs b/EcoLawExtensionsMod/Registration.cs new file mode 100644 index 0000000..25981e8 --- /dev/null +++ b/EcoLawExtensionsMod/Registration.cs @@ -0,0 +1,14 @@ +namespace Eco.Mods.LawExtensions +{ + using Core.Plugins.Interfaces; + + public class LawExtensionsMod : IModInit + { + public static ModRegistration Register() => new() + { + ModName = "LawExtensions", + ModDescription = "Extends the law system with a number of helpful utility game values and legal actions.", + ModDisplayName = "Law Extensions", + }; + } +} From 10a6b0467f33f6f96e581f16c95695d189c6b390 Mon Sep 17 00:00:00 2001 From: Thomas Smith Date: Wed, 13 Nov 2024 16:16:59 +0000 Subject: [PATCH 2/4] Added X/ZCoordAt game values. --- EcoLawExtensionsMod/GameValues/CoordAt.cs | 54 +++++++++++++++++++++++ README.md | 8 ++++ 2 files changed, 62 insertions(+) create mode 100644 EcoLawExtensionsMod/GameValues/CoordAt.cs diff --git a/EcoLawExtensionsMod/GameValues/CoordAt.cs b/EcoLawExtensionsMod/GameValues/CoordAt.cs new file mode 100644 index 0000000..f470270 --- /dev/null +++ b/EcoLawExtensionsMod/GameValues/CoordAt.cs @@ -0,0 +1,54 @@ +using System; +using System.Linq; + +namespace Eco.Mods.LawExtensions +{ + using Core.Controller; + using Core.Utils; + using Core.Utils.PropertyScanning; + + using Shared.Localization; + using Shared.Networking; + using Shared.Utils; + using Shared.Math; + + using Gameplay.Civics.GameValues; + + [Eco, LocCategory("World"), LocDescription("The X coord of a location.")] + public class XCoordAt : GameValue + { + [Eco, Advanced, LocDescription("The position to read the X coord of.")] public GameValue Location { get; set; } + + private Eval FailNullSafeFloat(Eval eval, string paramName) => + eval != null ? Eval.Make($"Invalid {Localizer.DoStr(paramName)} specified on {GetType().GetLocDisplayName()}: {eval.Message}", float.MinValue) + : Eval.Make($"{Localizer.DoStr(paramName)} not set on {GetType().GetLocDisplayName()}.", float.MinValue); + + public override Eval Value(IContextObject action) + { + var location = this.Location?.Value(action); if (location?.Val == null) return this.FailNullSafeFloat(location, nameof(this.Location)); + + var value = location.Val.X; + return Eval.Make($"{Text.StyledNum(value)} (X coord)", (float)value); + } + public override LocString Description() => Localizer.Do($"X coord"); + } + + [Eco, LocCategory("World"), LocDescription("The Z coord of a location.")] + public class ZCoordAt : GameValue + { + [Eco, Advanced, LocDescription("The position to read the Z coord of.")] public GameValue Location { get; set; } + + private Eval FailNullSafeFloat(Eval eval, string paramName) => + eval != null ? Eval.Make($"Invalid {Localizer.DoStr(paramName)} specified on {GetType().GetLocDisplayName()}: {eval.Message}", float.MinValue) + : Eval.Make($"{Localizer.DoStr(paramName)} not set on {GetType().GetLocDisplayName()}.", float.MinValue); + + public override Eval Value(IContextObject action) + { + var location = this.Location?.Value(action); if (location?.Val == null) return this.FailNullSafeFloat(location, nameof(this.Location)); + + var value = location.Val.Z; + return Eval.Make($"{Text.StyledNum(value)} (Z coord)", (float)value); + } + public override LocString Description() => Localizer.Do($"Z coord"); + } +} diff --git a/README.md b/README.md index a2c0998..645b4d9 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,14 @@ Extracts the Y coordinate from a location. This will be an integer in whole bloc | - | - | - | | Location | Vector3 | The location to get the height of. Usually this is passed in context from the law trigger. | +#### X/Z Coord At + +Extracts the X/Z coordinate from a location. This will be an integer in whole blocks. + +| Property Name | Type | Description | +| - | - | - | +| Location | Vector3 | The location to get the X/Z coord of. Usually this is passed in context from the law trigger. | + #### Turn On Machines Tries to turn on machines belonging to a citizen or group that are currently turned off. The filter can specify how the machines were turned off - for example, only try to turn on machines that were turned off legally (e.g. via prevent on Pollute Air). From 8fd6095c517806a61309fd4fa41265ba7a06e3cd Mon Sep 17 00:00:00 2001 From: Thomas Smith Date: Wed, 13 Nov 2024 16:47:54 +0000 Subject: [PATCH 3/4] Added IgnoreAtLocation option to distance to closest plant/world object game values. --- .../GameValues/DistanceToClosestPlant.cs | 18 ++++++++++++---- .../DistanceToClosestWorldObject.cs | 21 ++++++++++++++----- README.md | 2 ++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/EcoLawExtensionsMod/GameValues/DistanceToClosestPlant.cs b/EcoLawExtensionsMod/GameValues/DistanceToClosestPlant.cs index ccef82d..e2fd460 100644 --- a/EcoLawExtensionsMod/GameValues/DistanceToClosestPlant.cs +++ b/EcoLawExtensionsMod/GameValues/DistanceToClosestPlant.cs @@ -25,6 +25,8 @@ public class DistanceToClosestPlant : GameValue [Eco, AllowNullInView, AllowEmpty, LocDescription("The plant to search for.")] public GamePickerList PlantType { get; set; } = new (); + [Eco, Advanced, LocDescription("Whether to ignore plants at the target location.")] public GameValue IgnoreAtLocation { get; set; } = new No(); + private Eval FailNullSafeFloat(Eval eval, string paramName) => eval != null ? Eval.Make($"Invalid {Localizer.DoStr(paramName)} specified on {GetType().GetLocDisplayName()}: {eval.Message}", float.MinValue) : Eval.Make($"{Localizer.DoStr(paramName)} not set on {GetType().GetLocDisplayName()}.", float.MinValue); @@ -32,6 +34,7 @@ private Eval FailNullSafeFloat(Eval eval, string paramName) => public override Eval Value(IContextObject action) { var location = this.Location?.Value(action); if (location?.Val == null) return this.FailNullSafeFloat(location, nameof(this.Location)); + var ignoreAtLocation = this.IgnoreAtLocation?.Value(action); if (ignoreAtLocation?.Val == null) return this.FailNullSafeFloat(ignoreAtLocation, nameof(this.IgnoreAtLocation)); var allRelevantPlants = EcoSim.PlantSim.All .Where(x => PlantType.ContainsType(x.Species.GetType())); @@ -40,10 +43,17 @@ public override Eval Value(IContextObject action) return Eval.Make($"{Text.Style(Text.Styles.Currency, "infinite")} (distance to nearest {PlantType.DescribeEntries(Localizer.DoStr(","))})", float.MaxValue); } - var nearest = allRelevantPlants - .Select(x => (x, World.WrappedDistance(x.Position, location.Val))) - .OrderBy(x => x.Item2) - .FirstOrDefault(); + var plantsWithDistances = allRelevantPlants + .Select(x => (x, World.WrappedDistance(x.Position, location.Val))); + + if (ignoreAtLocation.Val) + { + plantsWithDistances = plantsWithDistances + .Where(x => x.Item2 > 0.0f); + } + + var nearest = plantsWithDistances + .MinBy(x => x.Item2); return Eval.Make($"{Text.StyledNum(nearest.Item2)} (distance to {nearest.x.Species.DisplayName})", nearest.Item2); } diff --git a/EcoLawExtensionsMod/GameValues/DistanceToClosestWorldObject.cs b/EcoLawExtensionsMod/GameValues/DistanceToClosestWorldObject.cs index ae462f3..a800243 100644 --- a/EcoLawExtensionsMod/GameValues/DistanceToClosestWorldObject.cs +++ b/EcoLawExtensionsMod/GameValues/DistanceToClosestWorldObject.cs @@ -12,11 +12,12 @@ namespace Eco.Mods.LawExtensions using Shared.Utils; using Shared.Math; using Shared.IoC; + using Shared.Voxel; using Gameplay.Civics.GameValues; using Gameplay.Systems.TextLinks; - using Gameplay.Players; using Gameplay.Objects; + [Eco, LocCategory("World"), LocDescription("How close the nearest world object of a particular type is.")] public class DistanceToClosestWorldObject : GameValue @@ -25,6 +26,8 @@ public class DistanceToClosestWorldObject : GameValue [Eco, AllowNullInView, AllowEmpty, LocDescription("The object to search for.")] public GamePickerList ObjectType { get; set; } = new (); + [Eco, Advanced, LocDescription("Whether to ignore world objects at the target location.")] public GameValue IgnoreAtLocation { get; set; } = new No(); + private Eval FailNullSafeFloat(Eval eval, string paramName) => eval != null ? Eval.Make($"Invalid {Localizer.DoStr(paramName)} specified on {GetType().GetLocDisplayName()}: {eval.Message}", float.MinValue) : Eval.Make($"{Localizer.DoStr(paramName)} not set on {GetType().GetLocDisplayName()}.", float.MinValue); @@ -32,6 +35,7 @@ private Eval FailNullSafeFloat(Eval eval, string paramName) => public override Eval Value(IContextObject action) { var location = this.Location?.Value(action); if (location?.Val == null) return this.FailNullSafeFloat(location, nameof(this.Location)); + var ignoreAtLocation = this.IgnoreAtLocation?.Value(action); if (ignoreAtLocation?.Val == null) return this.FailNullSafeFloat(ignoreAtLocation, nameof(this.IgnoreAtLocation)); var allRelevantObjects = ServiceHolder.Obj.All .Where(x => ObjectType.ContainsType(x.GetType())); @@ -40,10 +44,17 @@ public override Eval Value(IContextObject action) return Eval.Make($"{Text.Style(Text.Styles.Currency, "infinite")} (distance to nearest {ObjectType.DescribeEntries(Localizer.DoStr(","))})", float.MaxValue); } - var nearest = allRelevantObjects - .Select(x => (x, x.Position3i.WrappedDistance(location.Val))) - .OrderBy(x => x.Item2) - .FirstOrDefault(); + var objectsWithDistances = allRelevantObjects + .Select(x => (x, World.WrappedDistance(x.Position, location.Val))); + + if (ignoreAtLocation.Val) + { + objectsWithDistances = objectsWithDistances + .Where(x => x.Item2 > 0.0f); + } + + var nearest = objectsWithDistances + .MinBy(x => x.Item2); return Eval.Make($"{Text.StyledNum(nearest.Item2)} (distance to {nearest.x.UILink()})", nearest.Item2); } diff --git a/README.md b/README.md index 645b4d9..c63a170 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ Finds the closest world object matching a filter to a location and gets the dist | - | - | - | | Location | Vector3 | The location to test. Usually this is passed in context from the law trigger. | | ObjectType | Object Picker | A filter for objects to search for. | +| IgnoreAtLocation | Yes/No | Ignore any world objects directly at the location, e.g. with a distance of 0. This is useful to find the next nearest world object from a world object. Defaults to No. | #### Distance to Closest Plant @@ -88,6 +89,7 @@ Finds the closest plant matching a filter to a location and gets the distance to | - | - | - | | Location | Vector3 | The location to test. Usually this is passed in context from the law trigger. | | PlantType | Plant Species Picker | A filter for plants to search for. | +| IgnoreAtLocation | Yes/No | Ignore any plants directly at the location, e.g. with a distance of 0. This is useful to find the next nearest plant from a plant. Defaults to No. | #### Layer Value At From 58d008151bdf5a6b11517ffa3d862f63de8bdd46 Mon Sep 17 00:00:00 2001 From: Thomas Smith Date: Wed, 4 Dec 2024 21:45:37 +0000 Subject: [PATCH 4/4] Updated to Eco 0.11.1.3 release build. Updated to .net 8. Removed use of harmony for power grid detour. --- .github/workflows/release.yml | 10 +- .github/workflows/staging.yml | 10 +- .../EcoLawExtensionsMod.csproj | 13 +- EcoLawExtensionsMod/FodyWeavers.xml | 9 -- EcoLawExtensionsMod/FodyWeavers.xsd | 141 ------------------ .../PowerGridComponentTickPatch.cs | 20 --- EcoLawExtensionsMod/LawExtensionsPlugin.cs | 34 ++++- README.md | 6 +- 8 files changed, 44 insertions(+), 199 deletions(-) delete mode 100644 EcoLawExtensionsMod/FodyWeavers.xml delete mode 100644 EcoLawExtensionsMod/FodyWeavers.xsd delete mode 100644 EcoLawExtensionsMod/HarmonyPatches/PowerGridComponentTickPatch.cs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 44cbc1a..5f0e18a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,14 +9,14 @@ jobs: name: Build Mod runs-on: ubuntu-latest env: - MODKIT_VERSION: 0.11.1.1-beta-release-758 + MODKIT_VERSION: 0.11.1.3-beta-release-795 ECO_BRANCH: staging steps: - uses: actions/checkout@v4 - - name: Setup .NET Core 7.0 - uses: actions/setup-dotnet@v1 + - name: Setup .NET Core 8.0 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '7.0.x' + dotnet-version: '8.0.x' - name: Fetch dependencies run: dotnet restore ./EcoLawExtensionsMod/EcoLawExtensionsMod.csproj env: @@ -38,7 +38,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: mod-binaries-${{github.event.release.tag_name}} - path: EcoLawExtensionsMod/bin/Release/net7.0/EcoLawExtensionsMod.* + path: EcoLawExtensionsMod/bin/Release/net8.0/EcoLawExtensionsMod.* deploy: name: Upload Release Assets needs: diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index 50d5caf..e7f667d 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -10,14 +10,14 @@ jobs: name: Build Mod runs-on: ubuntu-latest env: - MODKIT_VERSION: 0.11.1.1-beta-release-758 + MODKIT_VERSION: 0.11.1.3-beta-release-795 ECO_BRANCH: staging steps: - uses: actions/checkout@v4 - - name: Setup .NET Core 7.0 - uses: actions/setup-dotnet@v1 + - name: Setup .NET Core 8.0 + uses: actions/setup-dotnet@v4 with: - dotnet-version: '7.0.x' + dotnet-version: '8.0.x' - name: Fetch dependencies run: dotnet restore ./EcoLawExtensionsMod/EcoLawExtensionsMod.csproj env: @@ -39,4 +39,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: mod-binaries-staging - path: EcoLawExtensionsMod/bin/Release/net7.0/EcoLawExtensionsMod.* + path: EcoLawExtensionsMod/bin/Release/net8.0/EcoLawExtensionsMod.* diff --git a/EcoLawExtensionsMod/EcoLawExtensionsMod.csproj b/EcoLawExtensionsMod/EcoLawExtensionsMod.csproj index fdb433e..50108d8 100644 --- a/EcoLawExtensionsMod/EcoLawExtensionsMod.csproj +++ b/EcoLawExtensionsMod/EcoLawExtensionsMod.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 Eco.Mods.LawExtensions @@ -38,16 +38,9 @@ - - all - - - all - - - - + + diff --git a/EcoLawExtensionsMod/FodyWeavers.xml b/EcoLawExtensionsMod/FodyWeavers.xml deleted file mode 100644 index bf60e66..0000000 --- a/EcoLawExtensionsMod/FodyWeavers.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - 0Harmony - MonoMod.Common - Mono.Cecil - - - \ No newline at end of file diff --git a/EcoLawExtensionsMod/FodyWeavers.xsd b/EcoLawExtensionsMod/FodyWeavers.xsd deleted file mode 100644 index af5be0b..0000000 --- a/EcoLawExtensionsMod/FodyWeavers.xsd +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks - - - - - A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. - - - - - A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks - - - - - A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. - - - - - A list of unmanaged 32 bit assembly names to include, delimited with line breaks. - - - - - A list of unmanaged 64 bit assembly names to include, delimited with line breaks. - - - - - The order of preloaded assemblies, delimited with line breaks. - - - - - - This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. - - - - - Controls if .pdbs for reference assemblies are also embedded. - - - - - Controls if runtime assemblies are also embedded. - - - - - Controls whether the runtime assemblies are embedded with their full path or only with their assembly name. - - - - - Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. - - - - - As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. - - - - - Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. - - - - - Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. - - - - - A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | - - - - - A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. - - - - - A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with | - - - - - A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |. - - - - - A list of unmanaged 32 bit assembly names to include, delimited with |. - - - - - A list of unmanaged 64 bit assembly names to include, delimited with |. - - - - - The order of preloaded assemblies, delimited with |. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/EcoLawExtensionsMod/HarmonyPatches/PowerGridComponentTickPatch.cs b/EcoLawExtensionsMod/HarmonyPatches/PowerGridComponentTickPatch.cs deleted file mode 100644 index 745b102..0000000 --- a/EcoLawExtensionsMod/HarmonyPatches/PowerGridComponentTickPatch.cs +++ /dev/null @@ -1,20 +0,0 @@ -using HarmonyLib; - -namespace Eco.Mods.LawExtensions.HarmonyPatches -{ - using Gameplay.PowerGrids; - - [HarmonyPatch(typeof(PowerGridManager), "Tick")] - internal class PowerGridManagerTickPatch - { - internal static void Prefix(PowerGridManager __instance) - { - PowerGridLawManager.Obj.PowerGridManagerPreTick(__instance); - } - - internal static void Postfix(PowerGridManager __instance) - { - PowerGridLawManager.Obj.PowerGridManagerPostTick(__instance); - } - } -} diff --git a/EcoLawExtensionsMod/LawExtensionsPlugin.cs b/EcoLawExtensionsMod/LawExtensionsPlugin.cs index 57b6ea8..18e365a 100644 --- a/EcoLawExtensionsMod/LawExtensionsPlugin.cs +++ b/EcoLawExtensionsMod/LawExtensionsPlugin.cs @@ -1,12 +1,11 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Reflection; +using System.Threading; using System.Threading.Tasks; using System.Linq; using System.Collections.Generic; -using HarmonyLib; - namespace Eco.Mods.LawExtensions { using Core.Plugins.Interfaces; @@ -24,7 +23,7 @@ namespace Eco.Mods.LawExtensions using Gameplay.Items; using Gameplay.Components; using Gameplay.Objects; - + using Gameplay.PowerGrids; [Serialized] public class LawExtensionsData : Singleton, IStorage @@ -60,7 +59,6 @@ public class LawExtensionsPlugin : Singleton, IModKitPlugin static LawExtensionsPlugin() { - CosturaUtility.Initialize(); var dynamicTagsField = typeof(TagManager).GetField("dynamicTags", BindingFlags.Static | BindingFlags.NonPublic); if (dynamicTagsField != null) { @@ -92,8 +90,14 @@ public LawExtensionsPlugin() public void Initialize(TimedTask timer) { data.Initialize(); - var harmony = new Harmony("Eco.Mods.LawExtensions"); - harmony.PatchAll(); + try + { + SetupPowerGridManagerDetour(); + } + catch (Exception ex) + { + Logger.Error($"Failed to setup power grid manager detour ({ex.Message}) - power related law triggers will not work!"); + } // Modded tags as filters for law trigger parameters don't seem to be supported for now (or maybe it's just my crazy way of making a tag...) // SetupPoweredTag(); } @@ -114,6 +118,24 @@ public void OnEditObjectChanged(object o, string param) this.SaveConfig(); } + private void SetupPowerGridManagerDetour() + { + var tickWorkerField = typeof(PowerGridManager).GetField("tickWorker", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new Exception($"Failed to reflect PowerGridManager.tickWorker"); + var tickWorker = tickWorkerField.GetValue(PowerGridManager.Obj) as EventDrivenWorker ?? throw new Exception($"Failed to retrieve PowerGridManager.tickWorker"); + var repeatableActionField = typeof(EventDrivenWorker).GetField("repeatableAction", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new Exception($"Failed to reflect EventDrivenWorker.repeatableAction"); + var oldRepeatableAction = repeatableActionField.GetValue(tickWorker) as Func> ?? throw new Exception($"Failed to retrieve EventDrivenWorker.repeatableAction"); + Func> newRepeatableAction = (token) => + { + PowerGridLawManager.PowerGridManagerPreTick(PowerGridManager.Obj); + return oldRepeatableAction(token).ContinueWith(t => + { + PowerGridLawManager.PowerGridManagerPostTick(PowerGridManager.Obj); + return t.Result; + }); + }; + repeatableActionField.SetValue(tickWorker, newRepeatableAction); + } + private void SetupPoweredTag() { TagDefinition.Register(poweredTagDefinition); diff --git a/README.md b/README.md index c63a170..f509719 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Eco Law Extensions Mod -A server mod for Eco 11.0 that extends the law system with a number of helpful utility game values and legal actions. +A server mod for Eco 11.1 that extends the law system with a number of helpful utility game values and legal actions. Added game values: - Citizen Population - the current citizen count of a title or demographic @@ -180,7 +180,7 @@ Note that the `PowerAvailable` and `PowerProduced` values are measured in Joules 2. Extract the modkit and copy the dlls from `ReferenceAssemblies` to `eco-dlls` in the root directory (create the folder if it doesn't exist) 3. Open `EcoLawExtensionsMod.sln` in Visual Studio 2019/2022 4. Build the `EcoLawExtensionsMod` project in Visual Studio -5. Find the artifact in `EcoLawExtensionsMod\bin\{Debug|Release}\net7.0` +5. Find the artifact in `EcoLawExtensionsMod\bin\{Debug|Release}\net8.0` ### Linux @@ -188,7 +188,7 @@ Note that the `PowerAvailable` and `PowerProduced` values are measured in Joules 2. Enter the `EcoLawExtensionsMod` directory and run: `dotnet restore` `dotnet build` -3. Find the artifact in `EcoLawExtensionsMod/bin/{Debug|Release}/net7.0` +3. Find the artifact in `EcoLawExtensionsMod/bin/{Debug|Release}/net8.0` ## License [MIT](https://choosealicense.com/licenses/mit/) \ No newline at end of file