Copy terratech to erenshor
This commit is contained in:
		
							
								
								
									
										3
									
								
								Projects/Ereshor/.clang-format
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Projects/Ereshor/.clang-format
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | BasedOnStyle: Google | ||||||
|  | IndentWidth: 4 | ||||||
|  | ColumnLimit: 120 | ||||||
							
								
								
									
										
											BIN
										
									
								
								Projects/Ereshor/.vs/Ereshor/v16/.suo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Projects/Ereshor/.vs/Ereshor/v16/.suo
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										16
									
								
								Projects/Ereshor/Ereshor.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Projects/Ereshor/Ereshor.sln
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  |  | ||||||
|  | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ereshor", "Ereshor\Ereshor.csproj", "{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}" | ||||||
|  | EndProject | ||||||
|  | Global | ||||||
|  | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
|  | 		Debug|Any CPU = Debug|Any CPU | ||||||
|  | 		Release|Any CPU = Release|Any CPU | ||||||
|  | 	EndGlobalSection | ||||||
|  | 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||||
|  | 		{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 	EndGlobalSection | ||||||
|  | EndGlobal | ||||||
							
								
								
									
										33
									
								
								Projects/Ereshor/Ereshor/Class1.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Projects/Ereshor/Ereshor/Class1.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | using System.Linq; | ||||||
|  | using BepInEx; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  | using HarmonyLib.Tools; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [BepInPlugin(PluginGuid, PluginName, PluginVersion)] | ||||||
|  |     public class Main : BaseUnityPlugin { | ||||||
|  |         private const string PluginGuid = "CykaMod"; | ||||||
|  |         private const string PluginName = "CykaMod"; | ||||||
|  |         private const string PluginVersion = "1.0.0"; | ||||||
|  |  | ||||||
|  |         public static ConfigEntry<bool> debug; | ||||||
|  |  | ||||||
|  |         public static ConfigEntry<float> xpMultiplier; | ||||||
|  |  | ||||||
|  |         public void Awake() { | ||||||
|  |             debug = Config.Bind("General", "Debug", false); | ||||||
|  |  | ||||||
|  |             xpMultiplier = | ||||||
|  |                 Config.Bind("General", "XP Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("XP Multiplier", new AcceptableValueRange<float>(0.01f, 1024f))); | ||||||
|  |  | ||||||
|  |             Logger.LogInfo("Cyka mod loaded"); | ||||||
|  |             HarmonyFileLog.Enabled = true; | ||||||
|  |             Harmony harmony = new Harmony(PluginGuid); | ||||||
|  |             harmony.PatchAll(); | ||||||
|  |             var originalMethods = harmony.GetPatchedMethods(); | ||||||
|  |             Logger.LogInfo("Patched " + originalMethods.Count() + " methods"); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								Projects/Ereshor/Ereshor/CykUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								Projects/Ereshor/Ereshor/CykUtil.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | using System; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     public class CykUtil { | ||||||
|  |         public static bool IsPlayerTank(Module module) { | ||||||
|  |             if (module == null) | ||||||
|  |                 return false; | ||||||
|  |             TankBlock block = module.block; | ||||||
|  |             if (block == null) | ||||||
|  |                 return false; | ||||||
|  |             Tank tank = block.tank; | ||||||
|  |             if (tank == null) | ||||||
|  |                 return false; | ||||||
|  |             return tank.ControllableByLocalPlayer; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static Func<object, bool> isObjectPlayerTank = obj => { | ||||||
|  |             if (obj == null) | ||||||
|  |                 return false; | ||||||
|  |             try { | ||||||
|  |                 return IsPlayerTank(obj as Module); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 Console.WriteLine("Failed to check if object is a player tank: " + e.Message); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										94
									
								
								Projects/Ereshor/Ereshor/Ereshor.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								Projects/Ereshor/Ereshor/Ereshor.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project ToolsVersion="4.0" DefaultTargets="Build" | ||||||
|  |   xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" | ||||||
|  |     Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||||||
|  |     <GAME_DIR>C:/Games/Erenshor.Early.Access</GAME_DIR> | ||||||
|  |     <GAME_MANAGED>$(GAME_DIR)/Erenshor_Data/Managed</GAME_MANAGED> | ||||||
|  |     <GAME_BEPINEX>$(GAME_DIR)/BepInEx</GAME_BEPINEX> | ||||||
|  |     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||||||
|  |     <ProjectGuid>{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}</ProjectGuid> | ||||||
|  |     <OutputType>Library</OutputType> | ||||||
|  |     <AppDesignerFolder>Properties</AppDesignerFolder> | ||||||
|  |     <RootNamespace>Ereshor</RootNamespace> | ||||||
|  |     <AssemblyName>Ereshor</AssemblyName> | ||||||
|  |     <TargetFrameworkVersion>v4.8</TargetFrameworkVersion> | ||||||
|  |     <FileAlignment>512</FileAlignment> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|  |     <PlatformTarget>AnyCPU</PlatformTarget> | ||||||
|  |     <DebugSymbols>true</DebugSymbols> | ||||||
|  |     <DebugType>full</DebugType> | ||||||
|  |     <Optimize>false</Optimize> | ||||||
|  |     <OutputPath>bin\Debug\</OutputPath> | ||||||
|  |     <DefineConstants>DEBUG;TRACE</DefineConstants> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <WarningLevel>4</WarningLevel> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||||
|  |     <PlatformTarget>AnyCPU</PlatformTarget> | ||||||
|  |     <DebugType>pdbonly</DebugType> | ||||||
|  |     <Optimize>true</Optimize> | ||||||
|  |     <OutputPath>bin\Release\</OutputPath> | ||||||
|  |     <DefineConstants>TRACE</DefineConstants> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <WarningLevel>4</WarningLevel> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Compile Include="Class1.cs" /> | ||||||
|  |     <!-- <Compile Include="ModuleShieldGeneratorManager.cs" /> | ||||||
|  |     <Compile Include="ObjectFieldMultiplier.cs" /> | ||||||
|  |     <Compile Include="Patches.cs" /> | ||||||
|  |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
|  |     <Compile Include="SeekingProjectileManager.cs" /> | ||||||
|  |     <Compile Include="ModuleWingManager.cs" /> | ||||||
|  |     <Compile Include="ModuleBoosterManager.cs" /> | ||||||
|  |     <Compile Include="ModuleWeaponGunManager.cs" /> | ||||||
|  |     <Compile Include="ModuleEnergyManager.cs" /> | ||||||
|  |     <Compile Include="ModuleEnergyStoreManager.cs" /> | ||||||
|  |     <Compile Include="ModuleGyroManager.cs" /> | ||||||
|  |     <Compile Include="ModuleItemHolderManager.cs" /> | ||||||
|  |     <Compile Include="ModuleItemProducerManager.cs" /> | ||||||
|  |     <Compile Include="ModuleRemoteChargerManager.cs" /> | ||||||
|  |     <Compile Include="ModuleWheelsManager.cs" /> | ||||||
|  |     <Compile Include="TankBeamManager.cs" /> | ||||||
|  |     <Compile Include="ModuleWeaponManager.cs" /> | ||||||
|  |     <Compile Include="CykUtil.cs" /> | ||||||
|  |     <Compile Include="ModuleHeartManager.cs" /> | ||||||
|  |     <Compile Include="ModuleFuelTankManager.cs" /> | ||||||
|  |     <Compile Include="ProjectilePatch.cs" /> | ||||||
|  |     <Compile Include="TankManager.cs" /> | ||||||
|  |     <Compile Include="UISnapshotPanelBuyAll.cs" /> | ||||||
|  |     <Compile Include="MultiBuy.cs" /> --> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Reference Include="0Harmony"> | ||||||
|  |       <HintPath>$(GAME_BEPINEX)/core/0Harmony.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="BepInEx"> | ||||||
|  |       <HintPath>$(GAME_BEPINEX)/core/BepInEx.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="UnityEngine"> | ||||||
|  |       <HintPath>$(GAME_MANAGED)/UnityEngine.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="UnityEngine.CoreModule"> | ||||||
|  |       <HintPath>$(GAME_MANAGED)/UnityEngine.CoreModule.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="Assembly-CSharp"> | ||||||
|  |       <HintPath>$(GAME_MANAGED)/Assembly-CSharp.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |     <Reference Include="ConfigurationManager"> | ||||||
|  |       <HintPath>$(GAME_BEPINEX)/plugins/ConfigurationManager/ConfigurationManager.dll</HintPath> | ||||||
|  |     </Reference> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||||
|  |   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | ||||||
|  |          Other similar extension points exist, see Microsoft.Common.targets. | ||||||
|  |     <Target Name="BeforeBuild"> | ||||||
|  |     </Target> | ||||||
|  |     <Target Name="AfterBuild"> | ||||||
|  |     </Target> | ||||||
|  |     --> | ||||||
|  | </Project> | ||||||
							
								
								
									
										84
									
								
								Projects/Ereshor/Ereshor/ModuleBoosterManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								Projects/Ereshor/Ereshor/ModuleBoosterManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleBoosterManager { | ||||||
|  |         private static readonly MultipliedObjectManager<FanJet> FanManager = | ||||||
|  |             new MultipliedObjectManager<FanJet>(ConfigureFanThruster); | ||||||
|  |         private static readonly MultipliedObjectManager<BoosterJet> JetManager = | ||||||
|  |             new MultipliedObjectManager<BoosterJet>(ConfigureJetThruster); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> fanThrustMultiplier; | ||||||
|  |         private static ConfigEntry<float> jetThrustMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Booster", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             fanThrustMultiplier = | ||||||
|  |                 config.Bind("Booster", "Fan Thrust Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Fan Thrust Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             fanThrustMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             jetThrustMultiplier = | ||||||
|  |                 config.Bind("Booster", "Jet Thrust Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Jet Thrust Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             jetThrustMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureFanThruster(MultipliedObject<FanJet> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_Force", fanThrustMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureJetThruster(MultipliedObject<BoosterJet> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_Force", jetThrustMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.isObjectPlayerTank(obj); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleBooster), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleBooster __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var fans = trav.Field("fans").GetValue<List<FanJet>>(); | ||||||
|  |             var jets = trav.Field("jets").GetValue<List<BoosterJet>>(); | ||||||
|  |  | ||||||
|  |             foreach (var fan in fans) FanManager.OnObjectAttached(fan); | ||||||
|  |             foreach (var jet in jets) JetManager.OnObjectAttached(jet); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleBooster), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleBooster __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var fans = trav.Field("fans").GetValue<List<FanJet>>(); | ||||||
|  |             var jets = trav.Field("jets").GetValue<List<BoosterJet>>(); | ||||||
|  |  | ||||||
|  |             foreach (var fan in fans) FanManager.OnObjectDetached(fan); | ||||||
|  |             foreach (var jet in jets) JetManager.OnObjectDetached(jet); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             FanManager.ApplyAll(); | ||||||
|  |             JetManager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleBooster: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleBooster); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								Projects/Ereshor/Ereshor/ModuleEnergyManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Projects/Ereshor/Ereshor/ModuleEnergyManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleEnergyManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleEnergy> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleEnergy>(ConfigureModuleEnergy); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> outputMultiplier; | ||||||
|  |         private static ConfigEntry<float> powerUpDelayMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Energy", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             outputMultiplier = | ||||||
|  |                 config.Bind("Energy", "Output Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Output Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             outputMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             powerUpDelayMultiplier = config.Bind( | ||||||
|  |                 "Energy", "Power Up Delay Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Power Up Delay Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             powerUpDelayMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureModuleEnergy(MultipliedObject<ModuleEnergy> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_OutputPerSecond", outputMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_PowerUpDelay", powerUpDelayMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleEnergy), "OnAnchorStatusChanged")] | ||||||
|  |         public static void PostfixCreate(ModuleEnergy __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleEnergy __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleEnergy: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleEnergy); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								Projects/Ereshor/Ereshor/ModuleEnergyStoreManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Projects/Ereshor/Ereshor/ModuleEnergyStoreManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleEnergyStoreManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleEnergyStore> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleEnergyStore>(ConfigureModuleEnergyStore); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> capacityMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Energy", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             capacityMultiplier = | ||||||
|  |                 config.Bind("Energy", "Capacity Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Capacity Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             capacityMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureModuleEnergyStore(MultipliedObject<ModuleEnergyStore> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_Capacity", capacityMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleEnergyStore), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleEnergyStore __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleEnergyStore), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleEnergyStore __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleEnergyStore: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleEnergyStore); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								Projects/Ereshor/Ereshor/ModuleFuelTankManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Projects/Ereshor/Ereshor/ModuleFuelTankManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleFuelTankManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleFuelTank> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleFuelTank>(ConfigureFuelTank); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> fuelCapacityMultiplier; | ||||||
|  |         private static ConfigEntry<float> fuelRefillMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("FuelTank", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             fuelCapacityMultiplier = config.Bind( | ||||||
|  |                 "FuelTank", "Fuel Capacity Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Fuel Capacity Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             fuelCapacityMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             fuelRefillMultiplier = | ||||||
|  |                 config.Bind("FuelTank", "Fuel Refill Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Fuel Refill Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             fuelRefillMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureFuelTank(MultipliedObject<ModuleFuelTank> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_Capacity", fuelCapacityMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_RefillRate", fuelRefillMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.isObjectPlayerTank(obj); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleFuelTank), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleFuelTank __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleFuelTank), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleFuelTank __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleFuelTank: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleFuelTank); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								Projects/Ereshor/Ereshor/ModuleGyroManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Projects/Ereshor/Ereshor/ModuleGyroManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleGyroManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleGyro> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleGyro>(ConfigureModuleGyro); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> activeSpeedMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Gyro", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             activeSpeedMultiplier = config.Bind( | ||||||
|  |                 "Gyro", "Active Speed Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Active Speed Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             activeSpeedMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureModuleGyro(MultipliedObject<ModuleGyro> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_ActiveSpeed", activeSpeedMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleGyro), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleGyro __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleGyro), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleGyro __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleGyro: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleGyro); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								Projects/Ereshor/Ereshor/ModuleHeartManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								Projects/Ereshor/Ereshor/ModuleHeartManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleHeartManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleHeart> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleHeart>(ConfigureHeart); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> eventHorizonRadiusMultiplier; | ||||||
|  |         private static ConfigEntry<float> setupTimeMultiplier; | ||||||
|  |         private static ConfigEntry<float> startShrinkingRadiusMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Heart", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             eventHorizonRadiusMultiplier = config.Bind( | ||||||
|  |                 "Heart", "Event Horizon Radius Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Event Horizon Radius Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             eventHorizonRadiusMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             setupTimeMultiplier = | ||||||
|  |                 config.Bind("Heart", "Setup Time Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Setup Time Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             setupTimeMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             startShrinkingRadiusMultiplier = config.Bind( | ||||||
|  |                 "Heart", "Start Shrinking Radius Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Start Shrinking Radius Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             startShrinkingRadiusMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureHeart(MultipliedObject<ModuleHeart> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_EventHorizonRadius", eventHorizonRadiusMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_SetupTime", setupTimeMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_StartShrinkingRadius", startShrinkingRadiusMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.isObjectPlayerTank(obj); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleHeart), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleHeart __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleHeart), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleHeart __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleHeart: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleHeart); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										164
									
								
								Projects/Ereshor/Ereshor/ModuleItemHolderManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								Projects/Ereshor/Ereshor/ModuleItemHolderManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleItemHolderManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleItemHolder> BeamManager = | ||||||
|  |             new MultipliedObjectManager<ModuleItemHolder>(ConfigureBeam); | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleItemHolderBeam> BeamHolderManager = | ||||||
|  |             new MultipliedObjectManager<ModuleItemHolderBeam>(ConfigureBeamHolder); | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleItemPickup> BeamPickupManager = | ||||||
|  |             new MultipliedObjectManager<ModuleItemPickup>(ConfigureBeamPickup); | ||||||
|  |  | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleItemHolderMagnet> MagnetHolderManager = | ||||||
|  |             new MultipliedObjectManager<ModuleItemHolderMagnet>(ConfigureMagnetHolder); | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleItemPickup> MagnetPickupManager = | ||||||
|  |             new MultipliedObjectManager<ModuleItemPickup>(ConfigureMagnetPickup); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> capacityPerStackMultiplier; | ||||||
|  |         private static ConfigEntry<float> beamStrengthMultiplier; | ||||||
|  |         private static ConfigEntry<float> beamHeightIncrementScaleMultiplier; | ||||||
|  |         private static ConfigEntry<float> beamPickupRangeMultiplier; | ||||||
|  |         private static ConfigEntry<float> magnetStrengthMultiplier; | ||||||
|  |         private static ConfigEntry<float> magnetPickupRangeMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Item Holder", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             capacityPerStackMultiplier = config.Bind( | ||||||
|  |                 "Item Holder", "Capacity Per Stack Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Capacity Per Stack Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             capacityPerStackMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             beamStrengthMultiplier = config.Bind( | ||||||
|  |                 "Item Holder", "Beam Strength Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Beam Strength Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             beamStrengthMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             beamHeightIncrementScaleMultiplier = | ||||||
|  |                 config.Bind("Item Holder", "Beam Height Increment Scale Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Beam Height Increment Scale Multiplier", | ||||||
|  |                                                   new AcceptableValueRange<float>(min, max))); | ||||||
|  |             beamHeightIncrementScaleMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             beamPickupRangeMultiplier = config.Bind( | ||||||
|  |                 "Item Holder", "Beam Pickup Range Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Beam Pickup Range Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             beamPickupRangeMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             magnetStrengthMultiplier = config.Bind( | ||||||
|  |                 "Item Holder", "Magnet Strength Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Magnet Strength Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             magnetStrengthMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             magnetPickupRangeMultiplier = config.Bind( | ||||||
|  |                 "Item Holder", "Magnet Pickup Range Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Magnet Pickup Range Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             magnetPickupRangeMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureBeam(MultipliedObject<ModuleItemHolder> obj) { | ||||||
|  |             obj.AddField( | ||||||
|  |                 new FieldConfiguration<int, float>("m_CapacityPerStack", capacityPerStackMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureBeamHolder(MultipliedObject<ModuleItemHolderBeam> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_BeamStrength", beamStrengthMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_HeightIncrementScale", | ||||||
|  |                                                               beamHeightIncrementScaleMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureBeamPickup(MultipliedObject<ModuleItemPickup> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_PickupRange", beamPickupRangeMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureMagnetHolder(MultipliedObject<ModuleItemHolderMagnet> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_Strength", magnetStrengthMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureMagnetPickup(MultipliedObject<ModuleItemPickup> obj) { | ||||||
|  |             obj.AddField( | ||||||
|  |                 new FieldConfiguration<float, float>("m_PickupRange", magnetPickupRangeMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemHolder), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleItemHolder __instance) { | ||||||
|  |             BeamManager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemHolder), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleItemHolder __instance) { | ||||||
|  |             BeamManager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemHolderBeam), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleItemHolderBeam __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>(); | ||||||
|  |  | ||||||
|  |             BeamHolderManager.OnObjectAttached(__instance); | ||||||
|  |             BeamPickupManager.OnObjectAttached(pickup); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemHolderBeam), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleItemHolderBeam __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>(); | ||||||
|  |  | ||||||
|  |             BeamHolderManager.OnObjectDetached(__instance); | ||||||
|  |             BeamPickupManager.OnObjectDetached(pickup); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleItemHolderMagnet __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>(); | ||||||
|  |  | ||||||
|  |             MagnetHolderManager.OnObjectAttached(__instance); | ||||||
|  |             MagnetPickupManager.OnObjectAttached(pickup); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleItemHolderMagnet __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>(); | ||||||
|  |  | ||||||
|  |             MagnetHolderManager.OnObjectDetached(__instance); | ||||||
|  |             MagnetPickupManager.OnObjectDetached(pickup); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             BeamManager.ApplyAll(); | ||||||
|  |             BeamHolderManager.ApplyAll(); | ||||||
|  |             BeamPickupManager.ApplyAll(); | ||||||
|  |             MagnetHolderManager.ApplyAll(); | ||||||
|  |             MagnetPickupManager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleItemHolder: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleItemHolder); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								Projects/Ereshor/Ereshor/ModuleItemProducerManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								Projects/Ereshor/Ereshor/ModuleItemProducerManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleItemProducerManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleItemProducer> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleItemProducer>(ConfigureModuleItemProducer); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> resourceGroundRadiusMultiplier; | ||||||
|  |         private static ConfigEntry<float> minDispenseIntervalMultiplier; | ||||||
|  |         private static ConfigEntry<float> secPerItemProducedMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Item Producer", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             resourceGroundRadiusMultiplier = config.Bind( | ||||||
|  |                 "Item Producer", "Resource Ground Radius Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Resource Ground Radius Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             resourceGroundRadiusMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             minDispenseIntervalMultiplier = config.Bind( | ||||||
|  |                 "Item Producer", "Min Dispense Interval Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Min Dispense Interval Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             minDispenseIntervalMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             secPerItemProducedMultiplier = config.Bind( | ||||||
|  |                 "Item Producer", "Sec Per Item Produced Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Sec Per Item Produced Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             secPerItemProducedMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureModuleItemProducer(MultipliedObject<ModuleItemProducer> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_ResourceGroundRadius", resourceGroundRadiusMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_MinDispenseInterval", minDispenseIntervalMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_SecPerItemProduced", secPerItemProducedMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemProducer), "GetClosestResourceReservoirInRange")] | ||||||
|  |         public static void PostfixCreate(ModuleItemProducer __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleItemProducer __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleItemProducer: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleItemProducer); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								Projects/Ereshor/Ereshor/ModuleRemoteChargerManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								Projects/Ereshor/Ereshor/ModuleRemoteChargerManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleRemoteChargerManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleRemoteCharger> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleRemoteCharger>(ConfigureModuleRemoteCharger); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> arcFiringIntervalMultiplier; | ||||||
|  |         private static ConfigEntry<float> chargingRadiusMultiplier; | ||||||
|  |         private static ConfigEntry<float> powerTransferPerArcMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             const float min = 0.01f; | ||||||
|  |             const float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Remote Charger", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             arcFiringIntervalMultiplier = config.Bind( | ||||||
|  |                 "Remote Charger", "Arc Firing Interval Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Arc Firing Interval Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             arcFiringIntervalMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             chargingRadiusMultiplier = config.Bind( | ||||||
|  |                 "Remote Charger", "Charging Radius Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Charging Radius Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             chargingRadiusMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             powerTransferPerArcMultiplier = config.Bind( | ||||||
|  |                 "Remote Charger", "Power Transfer Per Arc Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Power Transfer Per Arc Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             powerTransferPerArcMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureModuleRemoteCharger(MultipliedObject<ModuleRemoteCharger> obj) { | ||||||
|  |             obj.AddField( | ||||||
|  |                 new FieldConfiguration<float, float>("m_ArcFiringInterval", arcFiringIntervalMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField( | ||||||
|  |                 new FieldConfiguration<float, float>("m_ChargingRadius", chargingRadiusMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_PowerTransferPerArc", powerTransferPerArcMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleRemoteCharger), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleRemoteCharger __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleRemoteCharger), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleRemoteCharger __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleRemoteCharger: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleRemoteCharger); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										88
									
								
								Projects/Ereshor/Ereshor/ModuleShieldGeneratorManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								Projects/Ereshor/Ereshor/ModuleShieldGeneratorManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleShieldGeneratorManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleShieldGenerator> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleShieldGenerator>(ConfigureShieldGenerator); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> radiusMultiplier; | ||||||
|  |         private static ConfigEntry<float> radiusMultiplierHealing; | ||||||
|  |         private static ConfigEntry<float> heartbeatIntervalMultiplier; | ||||||
|  |         private static ConfigEntry<float> powerUpDelayMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             const float min = 0.01f; | ||||||
|  |             const float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Shield", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             radiusMultiplier = | ||||||
|  |                 config.Bind("Shield", "Radius Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Radius Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             radiusMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             heartbeatIntervalMultiplier = config.Bind( | ||||||
|  |                 "Shield", "Heartbeat Interval Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Heartbeat Interval Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             heartbeatIntervalMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             powerUpDelayMultiplier = config.Bind( | ||||||
|  |                 "Shield", "Power Up Delay Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Power Up Delay Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             powerUpDelayMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             radiusMultiplierHealing = config.Bind( | ||||||
|  |                 "Shield", "Radius Multiplier Healing", 1f, | ||||||
|  |                 new ConfigDescription("Radius Multiplier Healing", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             radiusMultiplierHealing.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureShieldGenerator(MultipliedObject<ModuleShieldGenerator> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_HealingHeartbeatInterval", heartbeatIntervalMultiplier, | ||||||
|  |                                                               ShouldApply)); | ||||||
|  |  | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_Radius", radiusMultiplier, __instance => { | ||||||
|  |                 if (!ShouldApply(__instance)) | ||||||
|  |                     return radiusMultiplier; | ||||||
|  |                 var shield = (ModuleShieldGenerator)__instance; | ||||||
|  |                 return shield.m_Healing ? radiusMultiplierHealing : radiusMultiplier; | ||||||
|  |             })); | ||||||
|  |  | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_PowerUpDelay", powerUpDelayMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleShieldGenerator __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleShieldGenerator __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleShieldGenerator: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleShieldGenerator); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										121
									
								
								Projects/Ereshor/Ereshor/ModuleWeaponGunManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								Projects/Ereshor/Ereshor/ModuleWeaponGunManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleWeaponGunManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleWeaponGun> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleWeaponGun>(ConfigureManager); | ||||||
|  |         private static readonly MultipliedObjectManager<FireData> FireDataManager = | ||||||
|  |             new MultipliedObjectManager<FireData>(ConfigureFireData); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> kickbackStrengthMultiplier; | ||||||
|  |         private static ConfigEntry<float> muzzleVelocityMultiplier; | ||||||
|  |         private static ConfigEntry<float> burstCooldownMultiplier; | ||||||
|  |         private static ConfigEntry<float> burstShotCountMultiplier; | ||||||
|  |         private static ConfigEntry<float> shotCooldownMultiplier; | ||||||
|  |         private static ConfigEntry<bool> seekingRoundsAll; | ||||||
|  |         private static ConfigEntry<bool> resetBurstOnInterruptAll; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             const float min = 0.01f; | ||||||
|  |             const float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("WeaponGun", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             kickbackStrengthMultiplier = config.Bind( | ||||||
|  |                 "FireData", "Kickback Strength Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Kickback Strength Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             kickbackStrengthMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             muzzleVelocityMultiplier = config.Bind( | ||||||
|  |                 "FireData", "Muzzle Velocity Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Muzzle Velocity Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             muzzleVelocityMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             burstCooldownMultiplier = config.Bind( | ||||||
|  |                 "FireData", "Burst Cooldown Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Burst Cooldown Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             burstCooldownMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             burstShotCountMultiplier = config.Bind( | ||||||
|  |                 "FireData", "Burst Shot Count Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Burst Shot Count Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             burstShotCountMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             shotCooldownMultiplier = config.Bind( | ||||||
|  |                 "FireData", "Shot Cooldown Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Shot Cooldown Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             shotCooldownMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             seekingRoundsAll = | ||||||
|  |                 config.Bind("FireData", "Seeking Rounds All", false, | ||||||
|  |                             new ConfigDescription("Seeking Rounds All", new AcceptableValueRange<bool>(false, true))); | ||||||
|  |             seekingRoundsAll.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             resetBurstOnInterruptAll = config.Bind( | ||||||
|  |                 "FireData", "Reset Burst On Interrupt All", false, | ||||||
|  |                 new ConfigDescription("Reset Burst On Interrupt All", new AcceptableValueRange<bool>(false, true))); | ||||||
|  |             resetBurstOnInterruptAll.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureManager(MultipliedObject<ModuleWeaponGun> obj) { | ||||||
|  |             obj.AddBooleanField(new BooleanFieldConfiguration("m_SeekingRounds", seekingRoundsAll, ShouldApply)); | ||||||
|  |             obj.AddBooleanField( | ||||||
|  |                 new BooleanFieldConfiguration("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_BurstCooldown", burstCooldownMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<int, float>("m_BurstShotCount", burstShotCountMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_ShotCooldown", shotCooldownMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureFireData(MultipliedObject<FireData> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_MuzzleVelocity", muzzleVelocityMultiplier)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_KickbackStrength", kickbackStrengthMultiplier)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWeaponGun), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleWeaponGun __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |             if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance)) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var firingData = trav.Field("m_FiringData"); | ||||||
|  |             FireDataManager.OnObjectAttached(firingData.GetValue<FireData>()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWeaponGun), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleWeaponGun __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance)) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             var firingData = trav.Field("m_FiringData"); | ||||||
|  |             FireDataManager.OnObjectDetached(firingData.GetValue<FireData>()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             FireDataManager.ApplyAll(); | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleWeaponGun: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleWeaponGun); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								Projects/Ereshor/Ereshor/ModuleWeaponManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								Projects/Ereshor/Ereshor/ModuleWeaponManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleWeaponManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleWeapon> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleWeapon>(ConfigureManager); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> rotateSpeedMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             const float min = 0.01f; | ||||||
|  |             const float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("ModuleWeapon", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             rotateSpeedMultiplier = config.Bind( | ||||||
|  |                 "ModuleWeapon", "Rotate Speed Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Rotate Speed Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             rotateSpeedMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureManager(MultipliedObject<ModuleWeapon> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("m_RotateSpeed", rotateSpeedMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWeapon), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleWeapon __instance) { | ||||||
|  |             Manager.OnObjectAttached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWeapon), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleWeapon __instance) { | ||||||
|  |             Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleWeapon: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleWeapon); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								Projects/Ereshor/Ereshor/ModuleWheelsManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								Projects/Ereshor/Ereshor/ModuleWheelsManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleWheelsManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ManWheels.TorqueParams> TorqueParamsManager = | ||||||
|  |             new MultipliedObjectManager<ManWheels.TorqueParams>(ConfigureTorqueParams); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> torqueRpmMultiplier; | ||||||
|  |         private static ConfigEntry<float> torqueMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             const float min = 0.01f; | ||||||
|  |             const float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("TorqueParams", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             torqueRpmMultiplier = | ||||||
|  |                 config.Bind("TorqueParams", "Torque RPM Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Torque RPM Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             torqueRpmMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             torqueMultiplier = | ||||||
|  |                 config.Bind("TorqueParams", "Torque Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Torque Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             torqueMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureTorqueParams(MultipliedObject<ManWheels.TorqueParams> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("torqueCurveMaxRpm", torqueRpmMultiplier, ShouldApply)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("torqueCurveMaxTorque", torqueMultiplier, ShouldApply)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWheels), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleWheels __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var torqueParams = trav.Field("torqueParams"); | ||||||
|  |             TorqueParamsManager.OnObjectAttached(torqueParams.GetValue<ManWheels.TorqueParams>()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWheels), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleWheels __instance) { | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var torqueParams = trav.Field("torqueParams"); | ||||||
|  |             TorqueParamsManager.OnObjectDetached(torqueParams.GetValue<ManWheels.TorqueParams>()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             TorqueParamsManager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleWheels: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleWheels); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										83
									
								
								Projects/Ereshor/Ereshor/ModuleWingManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								Projects/Ereshor/Ereshor/ModuleWingManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | using System; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ModuleWingManager { | ||||||
|  |         private static readonly MultipliedObjectManager<ModuleWing.Aerofoil> Manager = | ||||||
|  |             new MultipliedObjectManager<ModuleWing.Aerofoil>(ConfigureAerofoil); | ||||||
|  |  | ||||||
|  |         private static ConfigEntry<bool> playerOnly; | ||||||
|  |         private static ConfigEntry<float> angleRangeMultiplier; | ||||||
|  |         private static ConfigEntry<float> turnSpeedMultiplier; | ||||||
|  |         private static ConfigEntry<float> liftStrengthMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             const float min = 0.01f; | ||||||
|  |             const float max = 32f; | ||||||
|  |  | ||||||
|  |             playerOnly = config.Bind("Aerofoil", "Player Only", false, new ConfigDescription("Player Only")); | ||||||
|  |             playerOnly.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             angleRangeMultiplier = | ||||||
|  |                 config.Bind("Aerofoil", "Angle Range Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Angle Range Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             angleRangeMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             turnSpeedMultiplier = | ||||||
|  |                 config.Bind("Aerofoil", "Turn Speed Multiplier", 1f, | ||||||
|  |                             new ConfigDescription("Turn Speed Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             turnSpeedMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             liftStrengthMultiplier = config.Bind( | ||||||
|  |                 "Aerofoil", "Lift Strength Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Lift Strength Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             liftStrengthMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureAerofoil(MultipliedObject<ModuleWing.Aerofoil> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("flapAngleRangeActual", angleRangeMultiplier)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("flapAngleRangeVisual", angleRangeMultiplier)); | ||||||
|  |  | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("flapTurnSpeed", turnSpeedMultiplier)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("liftStrength", liftStrengthMultiplier)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static readonly Func<object, bool> ShouldApply = obj => { | ||||||
|  |             if (!playerOnly.Value) | ||||||
|  |                 return true; | ||||||
|  |             return CykUtil.IsPlayerTank(obj as Module); | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWing), "OnAttached")] | ||||||
|  |         public static void PostfixCreate(ModuleWing __instance) { | ||||||
|  |             if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance)) | ||||||
|  |                 return; | ||||||
|  |             for (int i = 0; i < __instance.m_Aerofoils.Length; i++) { | ||||||
|  |                 var aerofoil = __instance.m_Aerofoils[i]; | ||||||
|  |                 Manager.OnObjectAttached(aerofoil); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ModuleWing), "OnDetaching")] | ||||||
|  |         public static void PostfixDestroy(ModuleWing __instance) { | ||||||
|  |             if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance)) | ||||||
|  |                 return; | ||||||
|  |             foreach (var aerofoil in __instance.m_Aerofoils) Manager.OnObjectDetached(aerofoil); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static readonly Func<Module, bool> Register = obj => { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Registering ModuleWing: {0}", obj); | ||||||
|  |             PostfixCreate(obj as ModuleWing); | ||||||
|  |             return true; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								Projects/Ereshor/Ereshor/MultiBuy.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								Projects/Ereshor/Ereshor/MultiBuy.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | using System; | ||||||
|  | using System.Reflection; | ||||||
|  | using HarmonyLib; | ||||||
|  | using UnityEngine; | ||||||
|  | using UnityEngine.EventSystems; | ||||||
|  | using UnityEngine.UI; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class MultiBuy { | ||||||
|  |         public static UIShopBlockSelect panel; | ||||||
|  |         public static Traverse panelTraverse; | ||||||
|  |  | ||||||
|  |         [HarmonyPostfix] | ||||||
|  |         [HarmonyPatch(typeof(UIShopBlockSelect), "OnSpawn")] | ||||||
|  |         public static void PostfixCreate(UIShopBlockSelect __instance) { | ||||||
|  |             panel = __instance; | ||||||
|  |             if (Main.debugBuyAll.Value) | ||||||
|  |                 Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance); | ||||||
|  |             panelTraverse = Traverse.Create(__instance); | ||||||
|  |             var placeButton = panelTraverse.Field("m_PurchaseBlockButton").GetValue<Button>(); | ||||||
|  |             placeButton.gameObject.AddComponent<MultiBuyRightClickHandler>(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     class MultiBuyRightClickHandler : MonoBehaviour, IPointerClickHandler { | ||||||
|  |         // private void Awake() { | ||||||
|  |         // } | ||||||
|  |  | ||||||
|  |         public void OnPointerClick(PointerEventData eventData) { | ||||||
|  |             if (Main.debugBuyAll.Value) | ||||||
|  |                 Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: {0} {1}", gameObject.name, | ||||||
|  |                                   eventData.button); | ||||||
|  |             try { | ||||||
|  |                 if (eventData.button == PointerEventData.InputButton.Right) { | ||||||
|  |                     UIBlockSelectGrid grid = MultiBuy.panelTraverse.Field("m_Grid").GetValue<UIBlockSelectGrid>(); | ||||||
|  |                     BlockTypes blockTypes; | ||||||
|  |                     bool ok = grid.TryGetSelection(out blockTypes); | ||||||
|  |                     if (!ok) { | ||||||
|  |                         if (Main.debugBuyAll.Value) | ||||||
|  |                             Console.WriteLine( | ||||||
|  |                                 "MultiBuyRightClickHandler.OnPointerClick: Failed to get block selection from grid"); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     uint shopBlockPoolID = MultiBuy.panelTraverse.Field("m_ShopBlockPoolID").GetValue<uint>(); | ||||||
|  |  | ||||||
|  |                     MethodInfo canPurchaseMethod = | ||||||
|  |                         AccessTools.Method(typeof(UIShopBlockSelect), "CanPurchaseBlock", new[] { typeof(BlockTypes) }); | ||||||
|  |                     Func<BlockTypes, bool> canPurchase = (Func<BlockTypes, bool>)Delegate.CreateDelegate( | ||||||
|  |                         typeof(Func<BlockTypes, bool>), MultiBuy.panel, canPurchaseMethod); | ||||||
|  |  | ||||||
|  |                     for (int i = 0; i < Main.multiBuyAmount.Value; i++) { | ||||||
|  |                         if (!canPurchase.Invoke(blockTypes)) { | ||||||
|  |                             if (Main.debugBuyAll.Value) | ||||||
|  |                                 Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Can purchase no more {0}", | ||||||
|  |                                                   blockTypes); | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  |                         Singleton.Manager<ManPurchases>.inst.RequestPurchaseBlock(shopBlockPoolID, blockTypes, 1); | ||||||
|  |                         if (Main.debugBuyAll.Value) | ||||||
|  |                             Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Purchased {0} block", | ||||||
|  |                                               blockTypes); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Exception occurred: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										531
									
								
								Projects/Ereshor/Ereshor/ObjectFieldMultiplier.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										531
									
								
								Projects/Ereshor/Ereshor/ObjectFieldMultiplier.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,531 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     public interface IFieldModifier { | ||||||
|  |         void CaptureOriginal(); | ||||||
|  |         void Apply(); | ||||||
|  |         void Restore(); | ||||||
|  |         void LogValue(string prefix); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Represents a field that can be multiplied by a configurable value | ||||||
|  |     /// </summary> | ||||||
|  |     /// <typeparam name="TField">The type of the field value</typeparam> | ||||||
|  |     /// <typeparam name="TMul">The type of the multiplier</typeparam> | ||||||
|  |     public class FieldConfiguration<TField, TMul> { | ||||||
|  |         private string _fieldName; | ||||||
|  |         private ConfigEntry<TMul> _defaultMultiplier; | ||||||
|  |         private Func<object, ConfigEntry<TMul>> _conditionalMultiplier; | ||||||
|  |         private Func<object, bool> _applyCondition; | ||||||
|  |  | ||||||
|  |         public string FieldName { | ||||||
|  |             get { return _fieldName; } | ||||||
|  |             set { _fieldName = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public ConfigEntry<TMul> DefaultMultiplier { | ||||||
|  |             get { return _defaultMultiplier; } | ||||||
|  |             set { _defaultMultiplier = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Func<object, ConfigEntry<TMul>> ConditionalMultiplier { | ||||||
|  |             get { return _conditionalMultiplier; } | ||||||
|  |             set { _conditionalMultiplier = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Func<object, bool> ApplyCondition { | ||||||
|  |             get { return _applyCondition; } | ||||||
|  |             set { _applyCondition = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _defaultMultiplier = defaultMultiplier; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier, | ||||||
|  |                                   Func<object, ConfigEntry<TMul>> conditionalMultiplier) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _defaultMultiplier = defaultMultiplier; | ||||||
|  |             _conditionalMultiplier = conditionalMultiplier; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier, | ||||||
|  |                                   Func<object, bool> applyCondition) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _defaultMultiplier = defaultMultiplier; | ||||||
|  |             _applyCondition = applyCondition; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier, | ||||||
|  |                                   Func<object, ConfigEntry<TMul>> conditionalMultiplier, | ||||||
|  |                                   Func<object, bool> applyCondition) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _defaultMultiplier = defaultMultiplier; | ||||||
|  |             _conditionalMultiplier = conditionalMultiplier; | ||||||
|  |             _applyCondition = applyCondition; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public ConfigEntry<TMul> GetMultiplier(object __instance) { | ||||||
|  |             if (_conditionalMultiplier == null) { | ||||||
|  |                 return _defaultMultiplier; | ||||||
|  |             } | ||||||
|  |             return _conditionalMultiplier(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool ShouldApply(object __instance) { | ||||||
|  |             if (_applyCondition == null) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             return _applyCondition(__instance); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class MultipliedField<TField, TMul> : IFieldModifier { | ||||||
|  |         private readonly string _fieldName; | ||||||
|  |         private readonly ConfigEntry<TMul> _multiplier; | ||||||
|  |         private readonly Traverse _parentTraverse; | ||||||
|  |         private readonly Func<object, bool> _applyCondition; | ||||||
|  |         private TField _originalValue; | ||||||
|  |  | ||||||
|  |         public string FieldName { | ||||||
|  |             get { return _fieldName; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public MultipliedField(string fieldName, ConfigEntry<TMul> multiplier, Traverse parentTraverse, | ||||||
|  |                                Func<object, bool> applyCondition = null) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _multiplier = multiplier; | ||||||
|  |             _parentTraverse = parentTraverse; | ||||||
|  |             _applyCondition = applyCondition; | ||||||
|  |  | ||||||
|  |             if (!parentTraverse.Field(fieldName).FieldExists()) { | ||||||
|  |                 throw new ArgumentException( | ||||||
|  |                     string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Verify TField is a numeric type | ||||||
|  |             if (!IsNumericType(typeof(TField))) { | ||||||
|  |                 throw new ArgumentException( | ||||||
|  |                     string.Format("Field type {0} must be a numeric type", typeof(TField).Name)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // Verify TMul is a numeric type | ||||||
|  |             if (!IsNumericType(typeof(TMul))) { | ||||||
|  |                 throw new ArgumentException( | ||||||
|  |                     string.Format("Multiplier type {0} must be a numeric type", typeof(TMul).Name)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static bool IsNumericType(Type type) { | ||||||
|  |             return type == typeof(byte) || type == typeof(sbyte) || type == typeof(short) || type == typeof(ushort) || | ||||||
|  |                    type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) || | ||||||
|  |                    type == typeof(float) || type == typeof(double) || type == typeof(decimal); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private TField MultiplyValues(TField fieldValue, TMul multiplierValue) { | ||||||
|  |             // Convert both to double for the multiplication | ||||||
|  |             double fieldDouble = Convert.ToDouble(fieldValue); | ||||||
|  |             double multiplierDouble = Convert.ToDouble(multiplierValue); | ||||||
|  |             double result = fieldDouble * multiplierDouble; | ||||||
|  |             // Convert back to TField | ||||||
|  |             return (TField)Convert.ChangeType(result, typeof(TField)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public TField GetValue() { | ||||||
|  |             var value = _parentTraverse.Field(_fieldName).GetValue(); | ||||||
|  |             if (value == null) | ||||||
|  |                 throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName)); | ||||||
|  |             return (TField)value; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetValue(TField value) { | ||||||
|  |             _parentTraverse.Field(_fieldName).SetValue(value); | ||||||
|  |             var verifyValue = GetValue(); | ||||||
|  |             if (!verifyValue.Equals(value)) | ||||||
|  |                 throw new InvalidOperationException( | ||||||
|  |                     string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void CaptureOriginal() { | ||||||
|  |             _originalValue = GetValue(); | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Apply() { | ||||||
|  |             try { | ||||||
|  |                 if (_applyCondition != null && !_applyCondition(_parentTraverse.GetValue())) { | ||||||
|  |                     if (Main.debug.Value) | ||||||
|  |                         Console.WriteLine("Skipping {0}: condition not met", _fieldName); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 var newValue = MultiplyValues(_originalValue, _multiplier.Value); | ||||||
|  |  | ||||||
|  |                 if (Main.debug.Value) | ||||||
|  |                     Console.WriteLine("Applying to {0}: {1} * {2} = {3}", _fieldName, _originalValue, _multiplier.Value, | ||||||
|  |                                       newValue); | ||||||
|  |  | ||||||
|  |                 SetValue(newValue); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 throw new InvalidOperationException(string.Format("Failed to apply multiplication to {0}", _fieldName), | ||||||
|  |                                                     e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Restore() { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue); | ||||||
|  |             SetValue(_originalValue); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void LogValue(string prefix) { | ||||||
|  |             if (!Main.debug.Value) | ||||||
|  |                 return; | ||||||
|  |             var currentValue = GetValue(); | ||||||
|  |             Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, multiplier: {5})", prefix, _parentTraverse, _fieldName, | ||||||
|  |                               currentValue, _originalValue, _multiplier.Value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class BooleanFieldConfiguration { | ||||||
|  |         private string _fieldName; | ||||||
|  |         private ConfigEntry<bool> _value; | ||||||
|  |         private Func<object, ConfigEntry<bool>> _conditionalValue; | ||||||
|  |         private Func<object, bool> _applyCondition; | ||||||
|  |  | ||||||
|  |         public string FieldName { | ||||||
|  |             get { return _fieldName; } | ||||||
|  |             set { _fieldName = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public ConfigEntry<bool> Value { | ||||||
|  |             get { return _value; } | ||||||
|  |             set { _value = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Func<object, ConfigEntry<bool>> ConditionalValue { | ||||||
|  |             get { return _conditionalValue; } | ||||||
|  |             set { _conditionalValue = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public Func<object, bool> ApplyCondition { | ||||||
|  |             get { return _applyCondition; } | ||||||
|  |             set { _applyCondition = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _value = value; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value, | ||||||
|  |                                          Func<object, ConfigEntry<bool>> conditionalValue) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _value = value; | ||||||
|  |             _conditionalValue = conditionalValue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value, Func<object, bool> applyCondition) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _value = value; | ||||||
|  |             _applyCondition = applyCondition; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value, | ||||||
|  |                                          Func<object, ConfigEntry<bool>> conditionalValue, | ||||||
|  |                                          Func<object, bool> applyCondition) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _value = value; | ||||||
|  |             _conditionalValue = conditionalValue; | ||||||
|  |             _applyCondition = applyCondition; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public ConfigEntry<bool> GetValue(object __instance) { | ||||||
|  |             if (_conditionalValue == null) { | ||||||
|  |                 return _value; | ||||||
|  |             } | ||||||
|  |             return _conditionalValue(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool ShouldApply(object __instance) { | ||||||
|  |             if (_applyCondition == null) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             return _applyCondition(__instance); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class BooleanField : IFieldModifier { | ||||||
|  |         private readonly string _fieldName; | ||||||
|  |         private readonly ConfigEntry<bool> _value; | ||||||
|  |         private readonly Traverse _parentTraverse; | ||||||
|  |         private readonly Func<object, bool> _applyCondition; | ||||||
|  |         private bool _originalValue; | ||||||
|  |  | ||||||
|  |         public string FieldName { | ||||||
|  |             get { return _fieldName; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public BooleanField(string fieldName, ConfigEntry<bool> value, Traverse parentTraverse, | ||||||
|  |                             Func<object, bool> applyCondition = null) { | ||||||
|  |             _fieldName = fieldName; | ||||||
|  |             _value = value; | ||||||
|  |             _parentTraverse = parentTraverse; | ||||||
|  |             _applyCondition = applyCondition; | ||||||
|  |  | ||||||
|  |             if (!parentTraverse.Field(fieldName).FieldExists()) { | ||||||
|  |                 throw new ArgumentException( | ||||||
|  |                     string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public bool GetValue() { | ||||||
|  |             var value = _parentTraverse.Field(_fieldName).GetValue(); | ||||||
|  |             if (value == null) | ||||||
|  |                 throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName)); | ||||||
|  |             return (bool)value; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void SetValue(bool value) { | ||||||
|  |             _parentTraverse.Field(_fieldName).SetValue(value); | ||||||
|  |             var verifyValue = GetValue(); | ||||||
|  |             if (verifyValue != value) | ||||||
|  |                 throw new InvalidOperationException( | ||||||
|  |                     string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void CaptureOriginal() { | ||||||
|  |             _originalValue = GetValue(); | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Apply() { | ||||||
|  |             try { | ||||||
|  |                 if (_applyCondition != null && !_applyCondition(_parentTraverse.GetValue())) { | ||||||
|  |                     if (Main.debug.Value) | ||||||
|  |                         Console.WriteLine("Skipping {0}: condition not met", _fieldName); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (_value.Value) { | ||||||
|  |                     if (Main.debug.Value) | ||||||
|  |                         Console.WriteLine("Applying to {0}: forcing to true", _fieldName); | ||||||
|  |  | ||||||
|  |                     SetValue(true); | ||||||
|  |                 } else { | ||||||
|  |                     if (Main.debug.Value) | ||||||
|  |                         Console.WriteLine("Applying to {0}: leaving as {1} (config is false)", _fieldName, GetValue()); | ||||||
|  |                 } | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 throw new InvalidOperationException(string.Format("Failed to apply value to {0}", _fieldName), e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Restore() { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue); | ||||||
|  |             SetValue(_originalValue); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void LogValue(string prefix) { | ||||||
|  |             if (!Main.debug.Value) | ||||||
|  |                 return; | ||||||
|  |             var currentValue = GetValue(); | ||||||
|  |             Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, config: {5})", prefix, _parentTraverse, _fieldName, | ||||||
|  |                               currentValue, _originalValue, _value.Value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Represents an object with multiple fields that can be multiplied | ||||||
|  |     /// </summary> | ||||||
|  |     /// <typeparam name="T">The type of the object being managed</typeparam> | ||||||
|  |     public class MultipliedObject<T> { | ||||||
|  |         private readonly T _instance; | ||||||
|  |         private readonly Traverse _objectTraverse; | ||||||
|  |         private readonly Dictionary<string, IFieldModifier> _fields; | ||||||
|  |  | ||||||
|  |         public MultipliedObject(T __instance) { | ||||||
|  |             _instance = __instance; | ||||||
|  |             _objectTraverse = Traverse.Create(__instance); | ||||||
|  |             _fields = new Dictionary<string, IFieldModifier>(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void AddField<TField, TMul>(FieldConfiguration<TField, TMul> config) { | ||||||
|  |             var multiplier = config.GetMultiplier(_instance); | ||||||
|  |             _fields[config.FieldName] = | ||||||
|  |                 new MultipliedField<TField, TMul>(config.FieldName, multiplier, _objectTraverse, config.ShouldApply); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void AddBooleanField(BooleanFieldConfiguration config) { | ||||||
|  |             var value = config.GetValue(_instance); | ||||||
|  |             _fields[config.FieldName] = new BooleanField(config.FieldName, value, _objectTraverse, config.ShouldApply); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void CaptureFrom() { | ||||||
|  |             foreach (var field in _fields.Values) { | ||||||
|  |                 field.CaptureOriginal(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void ApplyTo(IEnumerable<string> fieldNames = null) { | ||||||
|  |             IEnumerable<string> fieldsToApply = fieldNames ?? _fields.Keys; | ||||||
|  |             foreach (var fieldName in fieldsToApply.Where(name => _fields.ContainsKey(name))) | ||||||
|  |                 _fields[fieldName].Apply(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void RestoreTo(IEnumerable<string> fieldNames = null) { | ||||||
|  |             IEnumerable<string> fieldsToRestore = fieldNames ?? _fields.Keys; | ||||||
|  |             foreach (var fieldName in fieldsToRestore.Where(name => _fields.ContainsKey(name))) | ||||||
|  |                 _fields[fieldName].Restore(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void LogValues(string prefix) { | ||||||
|  |             if (!Main.debug.Value) | ||||||
|  |                 return; | ||||||
|  |             foreach (var field in _fields.Values) { | ||||||
|  |                 field.LogValue(prefix); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Manages a collection of objects whose fields can be multiplied | ||||||
|  |     /// </summary> | ||||||
|  |     /// <typeparam name="T">The type of objects being managed</typeparam> | ||||||
|  |     public class MultipliedObjectManager<T> { | ||||||
|  |         private readonly Dictionary<T, MultipliedObject<T>> _managedObjects; | ||||||
|  |         private readonly Action<MultipliedObject<T>> _configureObject; | ||||||
|  |  | ||||||
|  |         public MultipliedObjectManager(Action<MultipliedObject<T>> configureObject) { | ||||||
|  |             if (configureObject == null) | ||||||
|  |                 throw new ArgumentNullException("configureObject"); | ||||||
|  |  | ||||||
|  |             _configureObject = configureObject; | ||||||
|  |             _managedObjects = new Dictionary<T, MultipliedObject<T>>(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private void SafeRemove(T __instance) { | ||||||
|  |             if (__instance == null) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 _managedObjects.Remove(__instance); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 Console.WriteLine("Error removing __instance from _managedObjects: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void OnObjectAttached(T __instance) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("{0}.OnAttached", typeof(T).Name); | ||||||
|  |  | ||||||
|  |             if (__instance == null) { | ||||||
|  |                 Console.WriteLine("Attempted to attach null __instance"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 if (_managedObjects.ContainsKey(__instance)) { | ||||||
|  |                     if (Main.debug.Value) | ||||||
|  |                         Console.WriteLine("{0} already managed, skipping", typeof(T).Name); | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 var multipliedObject = new MultipliedObject<T>(__instance); | ||||||
|  |                 _configureObject(multipliedObject); | ||||||
|  |                 multipliedObject.CaptureFrom(); | ||||||
|  |                 _managedObjects.Add(__instance, multipliedObject); | ||||||
|  |                 multipliedObject.LogValues("Patching"); | ||||||
|  |  | ||||||
|  |                 ApplyTo(__instance); | ||||||
|  |                 multipliedObject.LogValues("Patched"); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 Console.WriteLine("Error in OnObjectAttached: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void OnObjectDetached(T __instance) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("{0}.OnDetaching", typeof(T).Name); | ||||||
|  |             if (__instance == null) { | ||||||
|  |                 Console.WriteLine("Attempted to detach null __instance"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 MultipliedObject<T> multipliedObject; | ||||||
|  |                 if (_managedObjects.TryGetValue(__instance, out multipliedObject)) { | ||||||
|  |                     if (Main.debug.Value) | ||||||
|  |                         multipliedObject.LogValues("Restoring"); | ||||||
|  |  | ||||||
|  |                     try { | ||||||
|  |                         RestoreTo(__instance); | ||||||
|  |                         multipliedObject.LogValues("Restored"); | ||||||
|  |                     } catch (Exception e) { | ||||||
|  |                         Console.WriteLine("Error restoring values: {0}", e); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     SafeRemove(__instance); | ||||||
|  |                 } | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 Console.WriteLine("Error in OnObjectDetached: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void ApplyAll(IEnumerable<string> fieldNames = null) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name); | ||||||
|  |  | ||||||
|  |             // Make a copy of the keys to avoid modification during enumeration | ||||||
|  |             var instances = _managedObjects.Keys.ToList(); | ||||||
|  |  | ||||||
|  |             foreach (var __instance in instances) { | ||||||
|  |                 try { | ||||||
|  |                     RestoreTo(__instance, fieldNames); | ||||||
|  |                     ApplyTo(__instance, fieldNames); | ||||||
|  |                 } catch (Exception e) { | ||||||
|  |                     Console.WriteLine("Error applying to __instance: {0}", e); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void ApplyTo(T __instance, IEnumerable<string> fieldNames = null) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Applying {0}", typeof(T).Name); | ||||||
|  |             if (__instance == null) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 MultipliedObject<T> obj; | ||||||
|  |                 if (_managedObjects.TryGetValue(__instance, out obj)) | ||||||
|  |                     obj.ApplyTo(fieldNames); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 Console.WriteLine("Error in ApplyTo: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void RestoreTo(T __instance, IEnumerable<string> fieldNames = null) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Restoring {0}", typeof(T).Name); | ||||||
|  |             if (__instance == null) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 MultipliedObject<T> obj; | ||||||
|  |                 if (_managedObjects.TryGetValue(__instance, out obj)) | ||||||
|  |                     obj.RestoreTo(fieldNames); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 Console.WriteLine("Error in RestoreTo: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										24
									
								
								Projects/Ereshor/Ereshor/Patches.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Projects/Ereshor/Ereshor/Patches.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class Patches { | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ManLicenses), "AddXP")] | ||||||
|  |         static void XpMulti(FactionSubTypes corporation, ref int xp, bool showUI = true) { | ||||||
|  |             xp = (int)(xp * Main.xpMultiplier.Value); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(ManPlayer), "AddMoney")] | ||||||
|  |         static void MoneyMulti(ref int amount) { | ||||||
|  |             amount = (int)(amount * Main.moneyMultiplier.Value); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(TechHolders), "SetHeartbeatInterval")] | ||||||
|  |         static void HeartbeatMulti(ref float interval) { | ||||||
|  |             interval *= Main.heartbeatIntervalMultiplier.Value; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								Projects/Ereshor/Ereshor/ProjectilePatch.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Projects/Ereshor/Ereshor/ProjectilePatch.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | using System; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class ProjectilePatch { | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(Projectile), "StickToObjectWithVisuals")] | ||||||
|  |         static void Prefix(Projectile __instance) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("Projectile created"); | ||||||
|  |             var trav = Traverse.Create(__instance); | ||||||
|  |             var explodeOnStick = trav.Field("m_ExplodeOnStick"); | ||||||
|  |  | ||||||
|  |             if (!explodeOnStick.GetValue<bool>()) { | ||||||
|  |                 if (Main.debug.Value) | ||||||
|  |                     Console.WriteLine("Exploding on stick"); | ||||||
|  |                 explodeOnStick.SetValue(Main.projectileExplodeOnStick.Value); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								Projects/Ereshor/Ereshor/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								Projects/Ereshor/Ereshor/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | using System.Reflection; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  |  | ||||||
|  | // General Information about an assembly is controlled through the following | ||||||
|  | // set of attributes. Change these attribute values to modify the information | ||||||
|  | // associated with an assembly. | ||||||
|  | [assembly:AssemblyTitle("Ereshor")] | ||||||
|  | [assembly:AssemblyDescription("")] | ||||||
|  | [assembly:AssemblyConfiguration("")] | ||||||
|  | [assembly:AssemblyCompany("")] | ||||||
|  | [assembly:AssemblyProduct("Ereshor")] | ||||||
|  | [assembly:AssemblyCopyright("Copyright ©  2023")] | ||||||
|  | [assembly:AssemblyTrademark("")] | ||||||
|  | [assembly:AssemblyCulture("")] | ||||||
|  |  | ||||||
|  | // Setting ComVisible to false makes the types in this assembly not visible | ||||||
|  | // to COM components.  If you need to access a type in this assembly from | ||||||
|  | // COM, set the ComVisible attribute to true on that type. | ||||||
|  | [assembly:ComVisible(false)] | ||||||
|  |  | ||||||
|  | // The following GUID is for the ID of the typelib if this project is exposed to COM | ||||||
|  | [assembly:Guid("EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE")] | ||||||
|  |  | ||||||
|  | // Version information for an assembly consists of the following four values: | ||||||
|  | // | ||||||
|  | //      Major Version | ||||||
|  | //      Minor Version | ||||||
|  | //      Build Number | ||||||
|  | //      Revision | ||||||
|  | // | ||||||
|  | // You can specify all the values or you can default the Build and Revision Numbers | ||||||
|  | // by using the '*' as shown below: | ||||||
|  | // [assembly: AssemblyVersion("1.0.*")] | ||||||
|  | [assembly:AssemblyVersion("1.0.0.0")] | ||||||
|  | [assembly:AssemblyFileVersion("1.0.0.0")] | ||||||
							
								
								
									
										30
									
								
								Projects/Ereshor/Ereshor/SeekingProjectileManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								Projects/Ereshor/Ereshor/SeekingProjectileManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | using System; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     public class SeekingProjectileManager { | ||||||
|  |         [HarmonyPatch(typeof(SeekingProjectile), "OnSpawn")] | ||||||
|  |         class Patch { | ||||||
|  |             public static void Postfix(SeekingProjectile __instance) { | ||||||
|  |                 if (Main.debug.Value) | ||||||
|  |                     Console.WriteLine("SeekingProjectile created"); | ||||||
|  |  | ||||||
|  |                 SetField( | ||||||
|  |                     __instance, "m_VisionConeAngle", | ||||||
|  |                     Main.seekingProjectileVisionConeAngleMultiplier.Value * GetField(__instance, "m_VisionConeAngle")); | ||||||
|  |                 SetField(__instance, "m_VisionRange", | ||||||
|  |                          Main.seekingProjectileVisionRangeMultiplier.Value * GetField(__instance, "m_VisionRange")); | ||||||
|  |                 SetField(__instance, "m_TurnSpeed", | ||||||
|  |                          Main.seekingProjectileTurningSpeedMultiplier.Value * GetField(__instance, "m_TurnSpeed")); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static float GetField(SeekingProjectile seekingProjectile, string field) { | ||||||
|  |             return Traverse.Create(seekingProjectile).Field(field).GetValue() as float ? ?? 0f; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void SetField(SeekingProjectile seekingProjectile, string field, float value) { | ||||||
|  |             Traverse.Create(seekingProjectile).Field(field).SetValue(value); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										53
									
								
								Projects/Ereshor/Ereshor/TankBeamManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Projects/Ereshor/Ereshor/TankBeamManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class TankBeamManager { | ||||||
|  |         private static readonly MultipliedObjectManager<TankBeam> Manager = | ||||||
|  |             new MultipliedObjectManager<TankBeam>(ConfigureBeam); | ||||||
|  |  | ||||||
|  |         public static ConfigEntry<float> hoverClearanceMultiplier; | ||||||
|  |         public static ConfigEntry<float> nudgeSpeedForwardMultiplier; | ||||||
|  |         public static ConfigEntry<float> nudgeSpeedRotateMultiplier; | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             float min = 0.01f; | ||||||
|  |             float max = 32f; | ||||||
|  |  | ||||||
|  |             hoverClearanceMultiplier = config.Bind( | ||||||
|  |                 "TankBeam", "Hover Clearance Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Hover Clearance Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             hoverClearanceMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             nudgeSpeedForwardMultiplier = config.Bind( | ||||||
|  |                 "TankBeam", "Nudge Speed Forward Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Nudge Speed Forward Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             nudgeSpeedForwardMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |  | ||||||
|  |             nudgeSpeedRotateMultiplier = config.Bind( | ||||||
|  |                 "TankBeam", "Nudge Speed Rotate Multiplier", 1f, | ||||||
|  |                 new ConfigDescription("Nudge Speed Rotate Multiplier", new AcceptableValueRange<float>(min, max))); | ||||||
|  |             nudgeSpeedRotateMultiplier.SettingChanged += (sender, args) => DoPatch(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static void ConfigureBeam(MultipliedObject<TankBeam> obj) { | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("hoverClearance", hoverClearanceMultiplier)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("nudgeSpeedForward", nudgeSpeedForwardMultiplier)); | ||||||
|  |             obj.AddField(new FieldConfiguration<float, float>("nudgeSpeedRotate", nudgeSpeedRotateMultiplier)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(TankBeam), "EnableBeam")] | ||||||
|  |         public static void PostfixCreate(TankBeam __instance, ref bool enable) { | ||||||
|  |             if (enable) | ||||||
|  |                 Manager.OnObjectAttached(__instance); | ||||||
|  |             else | ||||||
|  |                 Manager.OnObjectDetached(__instance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static void DoPatch() { | ||||||
|  |             Manager.ApplyAll(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										53
									
								
								Projects/Ereshor/Ereshor/TankManager.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Projects/Ereshor/Ereshor/TankManager.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using BepInEx.Configuration; | ||||||
|  | using HarmonyLib; | ||||||
|  | using UnityEngine; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class TankManager { | ||||||
|  |         public static ConfigEntry<bool> recheck; | ||||||
|  |         public static Dictionary<Type, Func<Module, bool>> moduleManagerMapper = | ||||||
|  |             new Dictionary<Type, Func<Module, bool>>(); | ||||||
|  |  | ||||||
|  |         public static void Setup(ConfigFile config) { | ||||||
|  |             recheck = config.Bind("Tank", "Recheck", false, new ConfigDescription("Recheck")); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleBooster), ModuleBoosterManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleEnergy), ModuleEnergyManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleEnergyStore), ModuleEnergyStoreManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleFuelTank), ModuleFuelTankManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleGyro), ModuleGyroManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleHeart), ModuleHeartManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleItemHolder), ModuleItemHolderManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleItemProducer), ModuleItemProducerManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleRemoteCharger), ModuleRemoteChargerManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleShieldGenerator), ModuleShieldGeneratorManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleWeaponGun), ModuleWeaponGunManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleWeapon), ModuleWeaponManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleWheels), ModuleWheelsManager.Register); | ||||||
|  |             moduleManagerMapper.Add(typeof(ModuleWing), ModuleWingManager.Register); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPrefix] | ||||||
|  |         [HarmonyPatch(typeof(Tank), "NotifyAnchor")] | ||||||
|  |         public static void PostfixCreate(Tank __instance, ModuleAnchor anchor, bool anchored) { | ||||||
|  |             if (Main.debug.Value) | ||||||
|  |                 Console.WriteLine("TankManager.NotifyAnchor: {0}", __instance); | ||||||
|  |             if (!__instance.ControllableByLocalPlayer) | ||||||
|  |                 return; | ||||||
|  |             if (!recheck.Value) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             foreach (Transform child in __instance.transform) { | ||||||
|  |                 GameObject childObj = child.gameObject; | ||||||
|  |                 Component[] components = childObj.GetComponents<Component>(); | ||||||
|  |                 foreach (Component component in components) { | ||||||
|  |                     Func<Module, bool> manager; | ||||||
|  |                     if (moduleManagerMapper.TryGetValue(component.GetType(), out manager)) | ||||||
|  |                         manager(component as Module); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										181
									
								
								Projects/Ereshor/Ereshor/UISnapshotPanelBuyAll.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								Projects/Ereshor/Ereshor/UISnapshotPanelBuyAll.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using HarmonyLib; | ||||||
|  | using Snapshots; | ||||||
|  | using UnityEngine; | ||||||
|  | using UnityEngine.EventSystems; | ||||||
|  | using UnityEngine.UI; | ||||||
|  |  | ||||||
|  | namespace Ereshor { | ||||||
|  |     [HarmonyPatch] | ||||||
|  |     public class UISnapshotPanelBuyAll { | ||||||
|  |         public static UISnapshotPanel panel; | ||||||
|  |         public static Traverse panelTraverse; | ||||||
|  |         public static SnapshotLiveData selectedData; | ||||||
|  |  | ||||||
|  |         [HarmonyPostfix] | ||||||
|  |         [HarmonyPatch(typeof(UISnapshotPanel), "OnPool")] | ||||||
|  |         public static void PostfixCreate(UISnapshotPanel __instance) { | ||||||
|  |             if (Main.debugBuyAll.Value) | ||||||
|  |                 Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance); | ||||||
|  |             panel = __instance; | ||||||
|  |             panelTraverse = Traverse.Create(__instance); | ||||||
|  |             var placeButton = panelTraverse.Field("m_PlaceButton").GetValue<Button>(); | ||||||
|  |             placeButton.gameObject.AddComponent<RightClickHandler>(); | ||||||
|  |  | ||||||
|  |             var swapButton = panelTraverse.Field("m_SwapButton").GetValue<Button>(); | ||||||
|  |             swapButton.gameObject.AddComponent<RightClickHandlerSwap>(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         [HarmonyPostfix] | ||||||
|  |         [HarmonyPatch(typeof(UISnapshotPanel), "OnSelectedChanged")] | ||||||
|  |         public static void PostfixCreate(UISnapshotPanel __instance, ref SnapshotLiveData selectedData) { | ||||||
|  |             if (Main.debugBuyAll.Value) | ||||||
|  |                 Console.WriteLine("UISnapshotPanel.OnSelectedChanged: {0}", __instance); | ||||||
|  |             UISnapshotPanelBuyAll.selectedData = selectedData; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public abstract class BaseRightClickHandler : MonoBehaviour, IPointerClickHandler { | ||||||
|  |         protected static Traverse m_TechAvailLookupTraverse; | ||||||
|  |         protected static Dictionary<Snapshot, TechDataAvailValidation> m_TechAvailLookup; | ||||||
|  |  | ||||||
|  |         protected virtual void Awake() { | ||||||
|  |             var trav = Traverse.Create(Singleton.Manager<ManSnapshots>.inst); | ||||||
|  |             m_TechAvailLookupTraverse = trav.Field("m_TechAvailLookup"); | ||||||
|  |             m_TechAvailLookup = m_TechAvailLookupTraverse.GetValue<Dictionary<Snapshot, TechDataAvailValidation>>(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected Dictionary<BlockTypes, int> CalculateMissingBlocks( | ||||||
|  |             Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> blockAvailability, bool isSpawning) { | ||||||
|  |             Dictionary<BlockTypes, int> missing = new Dictionary<BlockTypes, int>(); | ||||||
|  |  | ||||||
|  |             foreach (var kvp in blockAvailability) { | ||||||
|  |                 int numMissing; | ||||||
|  |                 if (isSpawning) | ||||||
|  |                     numMissing = kvp.Value.numRequired - kvp.Value.numInInventory; | ||||||
|  |                 else | ||||||
|  |                     numMissing = kvp.Value.numRequired - kvp.Value.numInInventory - kvp.Value.numOnPlayerTech; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (missing.Count == 0) | ||||||
|  |                 foreach (var kvp in blockAvailability) missing.Add(kvp.Key, kvp.Value.numRequired); | ||||||
|  |             return missing; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected int CalculateTotalCost(Dictionary<BlockTypes, int> missingBlocks) { | ||||||
|  |             int totalCost = 0; | ||||||
|  |             RecipeManager recipeManager = Singleton.Manager<RecipeManager>.inst; | ||||||
|  |  | ||||||
|  |             foreach (var kvp in missingBlocks) { | ||||||
|  |                 int cost = recipeManager.GetBlockBuyPrice(kvp.Key) * kvp.Value; | ||||||
|  |                 totalCost += cost; | ||||||
|  |  | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("{0} of {1} would cost {2}, total now {3}", kvp.Value, kvp.Key, cost, totalCost); | ||||||
|  |             } | ||||||
|  |             return totalCost; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected bool TryPurchaseBlocks(Dictionary<BlockTypes, int> missingBlocks, int totalCost) { | ||||||
|  |             ManPlayer player = Singleton.Manager<ManPlayer>.inst; | ||||||
|  |             if (player.GetCurrentMoney() < totalCost) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Not enough money, have {0} but need {1}, nothing to do", | ||||||
|  |                                       player.GetCurrentMoney(), totalCost); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             player.PayMoney(totalCost); | ||||||
|  |             foreach (var kvp in missingBlocks) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Buying {0} of {1}", kvp.Value, kvp.Key); | ||||||
|  |                 player.PlayerInventory.HostAddItem(kvp.Key, kvp.Value); | ||||||
|  |             } | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected bool ProcessPurchase( | ||||||
|  |             Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> blockAvailability, bool isSpawning) { | ||||||
|  |             try { | ||||||
|  |                 if (blockAvailability == null) { | ||||||
|  |                     if (Main.debugBuyAll.Value) | ||||||
|  |                         Console.WriteLine("Block availability is null (wtf?), nothing to do"); | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 var missingBlocks = CalculateMissingBlocks(blockAvailability, isSpawning); | ||||||
|  |                 int totalCost = CalculateTotalCost(missingBlocks); | ||||||
|  |  | ||||||
|  |                 if (totalCost > 0) { | ||||||
|  |                     if (Main.debugBuyAll.Value) | ||||||
|  |                         Console.WriteLine("Total cost: {0}", totalCost); | ||||||
|  |                     return TryPurchaseBlocks(missingBlocks, totalCost); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("No blocks missing or no cost calculated"); | ||||||
|  |                 return false; | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Error during purchase processing: {0}", e); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         protected Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> GetCurrentBlockAvailability() { | ||||||
|  |             SnapshotLiveData selectedSnapshotData = UISnapshotPanelBuyAll.selectedData; | ||||||
|  |             Snapshot selectedSnapshot = selectedSnapshotData.m_Snapshot; | ||||||
|  |             if (selectedSnapshot == null) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Selected snapshot is null wtf??: {0}", gameObject.name); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             TechDataAvailValidation techDataAvail; | ||||||
|  |             if (!m_TechAvailLookup.TryGetValue(selectedSnapshot, out techDataAvail)) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Failed to find TechDataAvailValidation for snapshot: {0}", selectedSnapshot); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             var trav = Traverse.Create(techDataAvail); | ||||||
|  |             var mBlockAvailabilityField = trav.Field("m_BlockAvailability"); | ||||||
|  |             var mBlockAvailability = | ||||||
|  |                 mBlockAvailabilityField | ||||||
|  |                     .GetValue<Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability>>(); | ||||||
|  |  | ||||||
|  |             return mBlockAvailability; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public abstract void OnPointerClick(PointerEventData eventData); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class RightClickHandler : BaseRightClickHandler { | ||||||
|  |         public override void OnPointerClick(PointerEventData eventData) { | ||||||
|  |             if (Main.debugBuyAll.Value) | ||||||
|  |                 Console.WriteLine("UISnapshotPanel.OnPointerClick: {0} {1}", gameObject.name, eventData.button); | ||||||
|  |             try { | ||||||
|  |                 if (eventData.button == PointerEventData.InputButton.Right) | ||||||
|  |                     ProcessPurchase(GetCurrentBlockAvailability(), true); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Shit exploded fml: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class RightClickHandlerSwap : BaseRightClickHandler { | ||||||
|  |         public override void OnPointerClick(PointerEventData eventData) { | ||||||
|  |             if (Main.debugBuyAll.Value) | ||||||
|  |                 Console.WriteLine("UISnapshotPanel.OnPointerClick: {0} {1}", gameObject.name, eventData.button); | ||||||
|  |             try { | ||||||
|  |                 if (eventData.button == PointerEventData.InputButton.Right) | ||||||
|  |                     ProcessPurchase(GetCurrentBlockAvailability(), false); | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 if (Main.debugBuyAll.Value) | ||||||
|  |                     Console.WriteLine("Shit exploded fml: {0}", e); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								Projects/Ereshor/Ereshor/log.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Projects/Ereshor/Ereshor/log.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | static void Postfix(UIItemSelectGrid __instance) { | ||||||
|  |     try { | ||||||
|  |         StringBuilder sb = new StringBuilder(); | ||||||
|  |         sb.AppendLine("--------------------"); | ||||||
|  |         sb.AppendLine("void UIItemSelectGrid::Repopulate()"); | ||||||
|  |         sb.Append("- __instance: ").AppendLine(__instance.ToString()); | ||||||
|  |         foreach (var item in __instance.m_FilteredItemList) { | ||||||
|  |             sb.Append("- item: ").AppendLine(item.ToString()); | ||||||
|  |         } | ||||||
|  |         UnityExplorer.ExplorerCore.Log(sb.ToString()); | ||||||
|  |     } catch (System.Exception ex) { | ||||||
|  |         UnityExplorer.ExplorerCore.LogWarning($"Exception in patch of void UIItemSelectGrid::Repopulate():\n{ex}"); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								Projects/Ereshor/sync.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Projects/Ereshor/sync.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | - source: Ereshor/obj/Release/Ereshor.dll | ||||||
|  |   target: ~/scoop/apps/steam/current/steamapps/common/Ereshor/BepInEx/plugins/Ereshor.dll | ||||||
|  |   delete: true | ||||||
		Reference in New Issue
	
	Block a user