Compare commits
31 Commits
rework
...
f56aae2dbf
| Author | SHA1 | Date | |
|---|---|---|---|
| f56aae2dbf | |||
| 1e1268cee6 | |||
| 005c1805e9 | |||
| fbcabc90b7 | |||
| f72fcee86c | |||
| 5bde3c20b4 | |||
| 28bb3038c5 | |||
| 8c4e8b9366 | |||
| dcf88a498e | |||
| 402909f3fd | |||
| fbe307281c | |||
| eed75e919f | |||
| 1af46039ea | |||
| 5adb7defec | |||
| fff44bfc93 | |||
| 22b048a629 | |||
| 69125d6342 | |||
| 1d5855989b | |||
| e4a99d093a | |||
| b54210ec69 | |||
| dcc039afcb | |||
| 793fc2b48d | |||
| 2c1f5d5688 | |||
| 7aca70b7b6 | |||
| 44705dcc75 | |||
| 2e483b1869 | |||
| ce6ea32f4e | |||
| 1d8699761e | |||
| 9d40375b8c | |||
| 573c517dac | |||
| 8fbabf3931 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ Projects/Regiments/Regiments/obj/Release
|
|||||||
Projects/CykaOfQud/.vs/
|
Projects/CykaOfQud/.vs/
|
||||||
|
|
||||||
Projects/CykaOfQud/.vscode/
|
Projects/CykaOfQud/.vscode/
|
||||||
|
*.suo
|
||||||
|
|||||||
BIN
BepInEx.Patcher.exe
Normal file
BIN
BepInEx.Patcher.exe
Normal file
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
bin/Release/DaveCEO.dll,"C:\Games\Airport CEO\BepInEx\plugins\DaveCEO.dll"
|
|
||||||
3
Projects/AirportCEO/AirportCEO/sync.yml
Normal file
3
Projects/AirportCEO/AirportCEO/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/DaveCEO.dll
|
||||||
|
target: C:\Games\Airport CEO\BepInEx\plugins\DaveCEO.dll
|
||||||
|
delete: true
|
||||||
3
Projects/BlacksmithMaster/.clang-format
Normal file
3
Projects/BlacksmithMaster/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 120
|
||||||
16
Projects/BlacksmithMaster/BlacksmithMaster.sln
Normal file
16
Projects/BlacksmithMaster/BlacksmithMaster.sln
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlacksmithMaster", "BlacksmithMaster\BlacksmithMaster.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
|
||||||
@@ -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\Blacksmith.Master.Early.Access</GAME_DIR>
|
||||||
|
<GAME_MANAGED>$(GAME_DIR)/Blacksmith Master_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>BlacksmithMaster</RootNamespace>
|
||||||
|
<AssemblyName>BlacksmithMaster</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>
|
||||||
223
Projects/BlacksmithMaster/BlacksmithMaster/Class1.cs
Normal file
223
Projects/BlacksmithMaster/BlacksmithMaster/Class1.cs
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
using HarmonyLib.Tools;
|
||||||
|
using static TavernData;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
|
||||||
|
public class Main : BaseUnityPlugin {
|
||||||
|
private const string PluginGuid = "Cykasmith";
|
||||||
|
private const string PluginName = "Cykasmith";
|
||||||
|
private const string PluginVersion = "1.0.0";
|
||||||
|
|
||||||
|
public static ConfigEntry<bool> debug;
|
||||||
|
public static ConfigEntry<bool> debugXp;
|
||||||
|
public static ConfigEntry<bool> debugMoney;
|
||||||
|
public static ConfigEntry<bool> debugResearch;
|
||||||
|
public static ConfigEntry<bool> debugSalary;
|
||||||
|
public static ConfigEntry<bool> debugCustomers;
|
||||||
|
public static ConfigEntry<bool> debugDecorations;
|
||||||
|
public static ConfigEntry<bool> debugSpeed;
|
||||||
|
public static ConfigEntry<bool> debugHiring;
|
||||||
|
// public static ConfigEntry<bool> debugMining;
|
||||||
|
|
||||||
|
public static ConfigEntry<float> xpMultiplier;
|
||||||
|
public static ConfigEntry<float> moneyMultiplier;
|
||||||
|
public static ConfigEntry<float> researchMultiplier;
|
||||||
|
public static ConfigEntry<float> salaryMultiplier;
|
||||||
|
public static ConfigEntry<float> dailyCustomerMultiplier;
|
||||||
|
public static ConfigEntry<float> dailyCustomerOffset;
|
||||||
|
public static ConfigEntry<float> decorationAdditionMultiplier;
|
||||||
|
public static ConfigEntry<float> decorationAdditionOffset;
|
||||||
|
public static ConfigEntry<float> globalSpeedMultiplier;
|
||||||
|
public static ConfigEntry<float> globalSpeedOffset;
|
||||||
|
public static ConfigEntry<float> hiringCostMultiplier;
|
||||||
|
// public static ConfigEntry<float> miningMultiplier;
|
||||||
|
public static ConfigEntry<bool> alwaysEvenly;
|
||||||
|
public static ConfigEntry<bool> alwaysChad;
|
||||||
|
|
||||||
|
public void Awake() {
|
||||||
|
debug = Config.Bind("Debug", "Global Debug", false);
|
||||||
|
debugXp = Config.Bind("Debug", "XP Debug", false);
|
||||||
|
debugMoney = Config.Bind("Debug", "Money Debug", false);
|
||||||
|
debugResearch = Config.Bind("Debug", "Research Debug", false);
|
||||||
|
debugSalary = Config.Bind("Debug", "Salary Debug", false);
|
||||||
|
debugCustomers = Config.Bind("Debug", "Customers Debug", false);
|
||||||
|
debugDecorations = Config.Bind("Debug", "Decorations Debug", false);
|
||||||
|
debugSpeed = Config.Bind("Debug", "Speed Debug", false);
|
||||||
|
debugHiring = Config.Bind("Debug", "Hiring Debug", false);
|
||||||
|
// debugMining = Config.Bind("Debug", "Mining Debug", false);
|
||||||
|
|
||||||
|
xpMultiplier =
|
||||||
|
Config.Bind("General", "XP Multiplier", 1f,
|
||||||
|
new ConfigDescription("XP Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
moneyMultiplier =
|
||||||
|
Config.Bind("General", "Money Multiplier", 1f,
|
||||||
|
new ConfigDescription("Money Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
researchMultiplier = Config.Bind(
|
||||||
|
"General", "Research Multiplier", 1f,
|
||||||
|
new ConfigDescription("Research Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
salaryMultiplier =
|
||||||
|
Config.Bind("General", "Salary Multiplier", 1f,
|
||||||
|
new ConfigDescription("Salary Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
dailyCustomerMultiplier = Config.Bind(
|
||||||
|
"General", "Daily Customer Multiplier", 1f,
|
||||||
|
new ConfigDescription("Daily Customer Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
dailyCustomerOffset = Config.Bind(
|
||||||
|
"General", "Daily Customer Offset", 0f,
|
||||||
|
new ConfigDescription("Daily Customer Offset", new AcceptableValueRange<float>(-1024f, 1024f)));
|
||||||
|
decorationAdditionMultiplier = Config.Bind(
|
||||||
|
"General", "Decoration Addition Multiplier", 1f,
|
||||||
|
new ConfigDescription("Decoration Addition Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
decorationAdditionOffset = Config.Bind(
|
||||||
|
"General", "Decoration Addition Offset", 0f,
|
||||||
|
new ConfigDescription("Decoration Addition Offset", new AcceptableValueRange<float>(-1024f, 1024f)));
|
||||||
|
globalSpeedMultiplier = Config.Bind(
|
||||||
|
"General", "Global Speed Multiplier", 1f,
|
||||||
|
new ConfigDescription("Global Speed Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
globalSpeedOffset = Config.Bind(
|
||||||
|
"General", "Global Speed Offset", 0f,
|
||||||
|
new ConfigDescription("Global Speed Offset", new AcceptableValueRange<float>(-1024f, 1024f)));
|
||||||
|
hiringCostMultiplier = Config.Bind(
|
||||||
|
"General", "Hiring Cost Multiplier", 1f,
|
||||||
|
new ConfigDescription("Hiring Cost Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
// miningMultiplier =
|
||||||
|
// Config.Bind("General", "Mining Multiplier", 1f,
|
||||||
|
// new ConfigDescription("Mining Multiplier", new AcceptableValueRange<float>(0.01f, 1024f)));
|
||||||
|
alwaysEvenly =
|
||||||
|
Config.Bind("General", "Always Evenly", false,
|
||||||
|
new ConfigDescription("Always Evenly", new AcceptableValueRange<bool>(false, true)));
|
||||||
|
alwaysChad = Config.Bind("General", "Always Chad", false,
|
||||||
|
new ConfigDescription("Always Chad", new AcceptableValueRange<bool>(false, true)));
|
||||||
|
|
||||||
|
Logger.LogInfo("Cykasmith loaded");
|
||||||
|
HarmonyFileLog.Enabled = true;
|
||||||
|
Harmony harmony = new Harmony(PluginGuid);
|
||||||
|
harmony.PatchAll();
|
||||||
|
var originalMethods = harmony.GetPatchedMethods();
|
||||||
|
Logger.LogInfo("Patched " + originalMethods.Count() + " methods");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogDebug(string message, ConfigEntry<bool> debugFlag = null) {
|
||||||
|
if (debug.Value || (debugFlag != null && debugFlag.Value))
|
||||||
|
Console.WriteLine(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(StaffBase), "AddXp")]
|
||||||
|
public class TavernData_AddXp {
|
||||||
|
public static void Prefix(ref int amount) {
|
||||||
|
Main.LogDebug("Original XP amount: " + amount, Main.debugXp);
|
||||||
|
amount = (int)((float)amount * Main.xpMultiplier.Value);
|
||||||
|
Main.LogDebug("Modified XP amount: " + amount, Main.debugXp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(TavernModel), "ChangeMoney")]
|
||||||
|
public class TavernModel_ChangeMoney {
|
||||||
|
public static void Prefix(ref int value) {
|
||||||
|
Main.LogDebug("Original money amount: " + value, Main.debugMoney);
|
||||||
|
if (value > 0)
|
||||||
|
value = (int)((float)value * Main.moneyMultiplier.Value);
|
||||||
|
Main.LogDebug("Modified money amount: " + value, Main.debugMoney);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(ResourcesModel), "ChangeResearchPoints")]
|
||||||
|
public class ResourcesModel_ChangeResearchPoints {
|
||||||
|
public static void Prefix(ref int value) {
|
||||||
|
Main.LogDebug("Original research amount: " + value, Main.debugResearch);
|
||||||
|
if (value > 0)
|
||||||
|
value = (int)((float)value * Main.researchMultiplier.Value);
|
||||||
|
Main.LogDebug("Modified research amount: " + value, Main.debugResearch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(StaffInfo), "Salary", MethodType.Getter)]
|
||||||
|
public class StaffInfo_GetSalary {
|
||||||
|
public static void Postfix(ref int __result) {
|
||||||
|
Main.LogDebug("Original salary: " + __result, Main.debugSalary);
|
||||||
|
__result = (int)((float)__result * Main.salaryMultiplier.Value);
|
||||||
|
Main.LogDebug("Modified salary: " + __result, Main.debugSalary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(TavernModel), "GetNumberOfCustomersPerDay")]
|
||||||
|
public class TavernModel_GetNumberOfCustomersPerDay {
|
||||||
|
public static void Postfix(ref int __result) {
|
||||||
|
Main.LogDebug("Original number of customers per day: " + __result, Main.debugCustomers);
|
||||||
|
__result = (int)(__result * Main.dailyCustomerMultiplier.Value + Main.dailyCustomerOffset.Value);
|
||||||
|
Main.LogDebug("Modified number of customers per day: " + __result, Main.debugCustomers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(TavernModel), "GetBonusPercentageFromDecorations")]
|
||||||
|
public class TavernModel_GetBonusPercentageFromDecorations {
|
||||||
|
public static void Postfix(ref int __result) {
|
||||||
|
Main.LogDebug("Original bonus percentage from decorations: " + __result, Main.debugDecorations);
|
||||||
|
__result = (int)(__result * Main.decorationAdditionMultiplier.Value + Main.decorationAdditionOffset.Value);
|
||||||
|
Main.LogDebug("Modified bonus percentage from decorations: " + __result, Main.debugDecorations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(Economy), "GetWalkingSpeed")]
|
||||||
|
public class Economy_GetWalkingSpeed {
|
||||||
|
public static void Postfix(ref float __result) {
|
||||||
|
Main.LogDebug("Original walking speed: " + __result, Main.debugSpeed);
|
||||||
|
__result = __result * Main.globalSpeedMultiplier.Value + Main.globalSpeedOffset.Value;
|
||||||
|
Main.LogDebug("Modified walking speed: " + __result, Main.debugSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(StaffModel), "GetCostToHire")]
|
||||||
|
public class StaffModel_GetCostToHire {
|
||||||
|
public static void Postfix(ref int __result) {
|
||||||
|
Main.LogDebug("Original hiring cost: " + __result, Main.debugHiring);
|
||||||
|
__result = (int)(__result * Main.hiringCostMultiplier.Value);
|
||||||
|
Main.LogDebug("Modified hiring cost: " + __result, Main.debugHiring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(StaffUtil), "FillBasicInfo")]
|
||||||
|
public class StaffUtil_FillBasicInfo {
|
||||||
|
public static void Postfix(TavernData.StaffType staffType, Random rnd, ref TavernData.StaffInfo newPerson) {
|
||||||
|
Main.LogDebug("Setting skill assignment strategy to evenly", Main.debug);
|
||||||
|
if (Main.alwaysEvenly.Value)
|
||||||
|
newPerson.SkillAssignmentStrategy = TavernData.SkillAssignmentStrategyType.Balanced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(HireData), "GetStaffInfo")]
|
||||||
|
public class TavernData_GetStaffInfo {
|
||||||
|
public static void Prefix(Random rnd, int id, string staffName, bool isMale, ref bool shouldBeSuperWorker,
|
||||||
|
ref EliteTraitType forcedEliteTrait) {
|
||||||
|
Main.LogDebug("Setting shouldBeSuperWorker to true", Main.debug);
|
||||||
|
if (Main.alwaysChad.Value)
|
||||||
|
shouldBeSuperWorker = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does not work, I don't know why...
|
||||||
|
// [HarmonyPatch(typeof(MineBoxController), "AddMineralPiece")]
|
||||||
|
// public class MineBoxController_AddMineralPiece {
|
||||||
|
// private static int before;
|
||||||
|
// public static void Prefix(ref MineBoxController __instance) {
|
||||||
|
// var trav = Traverse.Create(__instance);
|
||||||
|
// var piecesInsideAmount = trav.Field("PiecesInsideAmount");
|
||||||
|
// Main.LogDebug("Original pieces: " + piecesInsideAmount.GetValue<int>(), Main.debugMining);
|
||||||
|
// before = piecesInsideAmount.GetValue<int>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static void Postfix(ref MineBoxController __instance) {
|
||||||
|
// var trav = Traverse.Create(__instance);
|
||||||
|
// var piecesInsideAmount = trav.Field("PiecesInsideAmount");
|
||||||
|
// Main.LogDebug("Original pieces: " + piecesInsideAmount.GetValue<int>(), Main.debugMining);
|
||||||
|
// var delta = piecesInsideAmount.GetValue<int>() - before;
|
||||||
|
// piecesInsideAmount.SetValue(before + (int)(delta * Main.miningMultiplier.Value));
|
||||||
|
// Main.LogDebug("Modified pieces: " + piecesInsideAmount.GetValue<int>(), Main.debugMining);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
28
Projects/BlacksmithMaster/BlacksmithMaster/CykUtil.cs
Normal file
28
Projects/BlacksmithMaster/BlacksmithMaster/CykUtil.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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/BlacksmithMaster/BlacksmithMaster/MultiBuy.cs
Normal file
71
Projects/BlacksmithMaster/BlacksmithMaster/MultiBuy.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,531 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
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/BlacksmithMaster/BlacksmithMaster/Patches.cs
Normal file
24
Projects/BlacksmithMaster/BlacksmithMaster/Patches.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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("BlacksmithMaster")]
|
||||||
|
[assembly:AssemblyDescription("")]
|
||||||
|
[assembly:AssemblyConfiguration("")]
|
||||||
|
[assembly:AssemblyCompany("")]
|
||||||
|
[assembly:AssemblyProduct("BlacksmithMaster")]
|
||||||
|
[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")]
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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/BlacksmithMaster/BlacksmithMaster/TankManager.cs
Normal file
53
Projects/BlacksmithMaster/BlacksmithMaster/TankManager.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HarmonyLib;
|
||||||
|
using Snapshots;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace BlacksmithMaster {
|
||||||
|
[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/BlacksmithMaster/BlacksmithMaster/log.cs
Normal file
14
Projects/BlacksmithMaster/BlacksmithMaster/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/BlacksmithMaster/sync.yml
Normal file
3
Projects/BlacksmithMaster/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: BlacksmithMaster/obj/Release/BlacksmithMaster.dll
|
||||||
|
target: C:/Games/Blacksmith.Master.Early.Access/BepInEx/plugins/BlacksmithMaster.dll
|
||||||
|
delete: true
|
||||||
Submodule Projects/CaptainOfIndustry/COI_MineDumpControl updated: 3c83562726...1b382ae204
@@ -1 +0,0 @@
|
|||||||
bin/Release/CykaOfIndustry.dll,"C:\Program Files (x86)\Steam\steamapps\common\Captain of Industry\BepInEx\plugins\CykaOfIndustry.dll"
|
|
||||||
3
Projects/CaptainOfIndustry/CykaOfIndustry/sync.yml
Normal file
3
Projects/CaptainOfIndustry/CykaOfIndustry/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/CykaOfIndustry.dll
|
||||||
|
target: C:\Program Files (x86)\Steam\steamapps\common\Captain of Industry\BepInEx\plugins\CykaOfIndustry.dll
|
||||||
|
delete: true
|
||||||
Submodule Projects/CaptainOfIndustry/DifficultySettingsMod updated: 6ab4d6bf69...f01441f9f2
Submodule Projects/CaptainOfIndustry/DoubleQoLMod updated: 99be285f06...b3cbf640e4
@@ -1 +0,0 @@
|
|||||||
bin/Release/CykaOfQud.dll,"C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll"
|
|
||||||
3
Projects/CykaOfQud/sync.yml
Normal file
3
Projects/CykaOfQud/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/CykaOfQud.dll
|
||||||
|
target: C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll
|
||||||
|
delete: true
|
||||||
3
Projects/Ereshor/.clang-format
Normal file
3
Projects/Ereshor/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 120
|
||||||
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
|
||||||
40
Projects/Ereshor/Ereshor/Class1.cs
Normal file
40
Projects/Ereshor/Ereshor/Class1.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(GameData), "AddExperience")]
|
||||||
|
public class GameData_AddExperience {
|
||||||
|
public static void Prefix(ref int xp) {
|
||||||
|
xp = (int) ((float)xp * Main.xpMultiplier.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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: C:/Games/Erenshor.Early.Access/BepInEx/plugins/Ereshor.dll
|
||||||
|
delete: true
|
||||||
@@ -43,7 +43,8 @@ using Zenject;
|
|||||||
// System.Single Gameplay.Units.Movements.Movement::CalculateSpeed()
|
// System.Single Gameplay.Units.Movements.Movement::CalculateSpeed()
|
||||||
// GameConfig looks interesting
|
// GameConfig looks interesting
|
||||||
// See dayLengthInSeconds (defaults to 720 actually)
|
// See dayLengthInSeconds (defaults to 720 actually)
|
||||||
// System.Single Controllers.Time.TimeController::GetSunsetHour(System.Int32,System.Double,System.Double)
|
// System.Single
|
||||||
|
// Controllers.Time.TimeController::GetSunsetHour(System.Int32,System.Double,System.Double)
|
||||||
|
|
||||||
namespace InfectionFreeZone {
|
namespace InfectionFreeZone {
|
||||||
[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
|
[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
|
||||||
@@ -70,7 +71,8 @@ namespace InfectionFreeZone {
|
|||||||
public static ConfigEntry<bool> buildingQuartersCapacityMultiplierDebug;
|
public static ConfigEntry<bool> buildingQuartersCapacityMultiplierDebug;
|
||||||
public static ConfigEntry<float> buildingQuartersCapacityMultiplier;
|
public static ConfigEntry<float> buildingQuartersCapacityMultiplier;
|
||||||
|
|
||||||
public static ConfigEntry<bool> buildingDeconstructionResourcesMultiplierDebug;
|
public static ConfigEntry<bool>
|
||||||
|
buildingDeconstructionResourcesMultiplierDebug;
|
||||||
public static ConfigEntry<float> buildingDeconstructionResourcesMultiplier;
|
public static ConfigEntry<float> buildingDeconstructionResourcesMultiplier;
|
||||||
|
|
||||||
public static ConfigEntry<float> humanMovementSpeedMultiplier;
|
public static ConfigEntry<float> humanMovementSpeedMultiplier;
|
||||||
@@ -102,7 +104,8 @@ namespace InfectionFreeZone {
|
|||||||
public static ConfigEntry<int> adultAge;
|
public static ConfigEntry<int> adultAge;
|
||||||
public static ConfigEntry<int> oldAge;
|
public static ConfigEntry<int> oldAge;
|
||||||
|
|
||||||
public static ConfigEntry<float> rotationTimestepMultiplier; // This is NOT unused!
|
public static ConfigEntry<float>
|
||||||
|
rotationTimestepMultiplier; // This is NOT unused!
|
||||||
public static ConfigEntry<float> sunsetHourOffset;
|
public static ConfigEntry<float> sunsetHourOffset;
|
||||||
public static ConfigEntry<float> sunriseHourOffset;
|
public static ConfigEntry<float> sunriseHourOffset;
|
||||||
|
|
||||||
@@ -112,92 +115,122 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
public static ConfigEntry<bool> towerEchoSelectionDebug;
|
public static ConfigEntry<bool> towerEchoSelectionDebug;
|
||||||
public static ConfigEntry<bool> towerEchoSelection;
|
public static ConfigEntry<bool> towerEchoSelection;
|
||||||
public static List<WeakReference<StructureDefenceModule>> towerEchoSelectionList;
|
public static List<WeakReference<StructureDefenceModule>>
|
||||||
|
towerEchoSelectionList;
|
||||||
|
|
||||||
public static ConfigEntry<bool> buildingMaxVolumeDebug;
|
public static ConfigEntry<bool> buildingMaxVolumeDebug;
|
||||||
public static ConfigEntry<float> buildingMaxVolume;
|
public static ConfigEntry<float> buildingMaxVolume;
|
||||||
|
|
||||||
// See System.Void UI.InfoPanels.NestedUIElements.SelectWeaponPanel::OnWeaponItemClicked(UI.InfoPanels.NestedUIElements.WeaponItem)
|
// See System.Void
|
||||||
|
// UI.InfoPanels.NestedUIElements.SelectWeaponPanel::OnWeaponItemClicked(UI.InfoPanels.NestedUIElements.WeaponItem)
|
||||||
|
|
||||||
public void Awake() {
|
public void Awake() {
|
||||||
resourceMultiplierDebug = Config.Bind("General", "Resource Multiplier Debug", false);
|
resourceMultiplierDebug =
|
||||||
|
Config.Bind("General", "Resource Multiplier Debug", false);
|
||||||
resourceMultiplier = Config.Bind("General", "Resource Multiplier", 1f);
|
resourceMultiplier = Config.Bind("General", "Resource Multiplier", 1f);
|
||||||
|
|
||||||
peopleMultiplierDebug = Config.Bind("General", "People Multiplier Debug", false);
|
peopleMultiplierDebug =
|
||||||
|
Config.Bind("General", "People Multiplier Debug", false);
|
||||||
peopleMultiplier = Config.Bind("General", "People Multiplier", 1f);
|
peopleMultiplier = Config.Bind("General", "People Multiplier", 1f);
|
||||||
|
|
||||||
resourceGatheringMultiplierDebug = Config.Bind("General", "Resource Gathering Multiplier Debug", false);
|
resourceGatheringMultiplierDebug =
|
||||||
resourceGatheringMultiplier = Config.Bind("General", "Resource Gathering Multiplier", 1f);
|
Config.Bind("General", "Resource Gathering Multiplier Debug", false);
|
||||||
|
resourceGatheringMultiplier =
|
||||||
|
Config.Bind("General", "Resource Gathering Multiplier", 1f);
|
||||||
|
|
||||||
resourceScavengingMultiplierDebug = Config.Bind("General", "Resource Scavenging Multiplier Debug", false);
|
resourceScavengingMultiplierDebug =
|
||||||
resourceScavengingMultiplier = Config.Bind("General", "Resource Scavenging Multiplier", 1f);
|
Config.Bind("General", "Resource Scavenging Multiplier Debug", false);
|
||||||
|
resourceScavengingMultiplier =
|
||||||
|
Config.Bind("General", "Resource Scavenging Multiplier", 1f);
|
||||||
|
|
||||||
buildingStorageCapacityMultiplierDebug =
|
buildingStorageCapacityMultiplierDebug = Config.Bind(
|
||||||
Config.Bind("General", "Building Storage Capacity Multiplier Debug", false);
|
"General", "Building Storage Capacity Multiplier Debug", false);
|
||||||
buildingStorageCapacityMultiplier = Config.Bind("General", "Building Storage Capacity Multiplier", 1f);
|
buildingStorageCapacityMultiplier =
|
||||||
|
Config.Bind("General", "Building Storage Capacity Multiplier", 1f);
|
||||||
|
|
||||||
buildingQuartersCapacityMultiplierDebug =
|
buildingQuartersCapacityMultiplierDebug = Config.Bind(
|
||||||
Config.Bind("General", "Building Quarters Capacity Multiplier Debug", false);
|
"General", "Building Quarters Capacity Multiplier Debug", false);
|
||||||
buildingQuartersCapacityMultiplier = Config.Bind("General", "Building Quarters Capacity Multiplier", 1f);
|
buildingQuartersCapacityMultiplier =
|
||||||
|
Config.Bind("General", "Building Quarters Capacity Multiplier", 1f);
|
||||||
|
|
||||||
buildingDeconstructionResourcesMultiplierDebug = Config.Bind("General",
|
buildingDeconstructionResourcesMultiplierDebug = Config.Bind(
|
||||||
"Building Deconstruction Resources Multiplier Debug", false);
|
"General", "Building Deconstruction Resources Multiplier Debug", false);
|
||||||
buildingDeconstructionResourcesMultiplier =
|
buildingDeconstructionResourcesMultiplier = Config.Bind(
|
||||||
Config.Bind("General", "Building Deconstruction Resources Multiplier", 1f);
|
"General", "Building Deconstruction Resources Multiplier", 1f);
|
||||||
deconstructionWorkersPer100m =
|
deconstructionWorkersPer100m = Config.Bind(
|
||||||
Config.Bind("General", "Building Deconstruction Workers Per 100m", 0.0045f);
|
"General", "Building Deconstruction Workers Per 100m", 0.0045f);
|
||||||
|
|
||||||
|
humanMovementSpeedMultiplier =
|
||||||
|
Config.Bind("General", "Human Movement Speed Multiplier", 1f);
|
||||||
|
vehicleMovementSpeedMultiplier =
|
||||||
|
Config.Bind("General", "Vehicle Movement Speed Multiplier", 1f);
|
||||||
|
|
||||||
humanMovementSpeedMultiplier = Config.Bind("General", "Human Movement Speed Multiplier", 1f);
|
vehicleTrunkCapacityMultiplierDebug = Config.Bind(
|
||||||
vehicleMovementSpeedMultiplier = Config.Bind("General", "Vehicle Movement Speed Multiplier", 1f);
|
"General", "Vehicle Trunk Capacity Multiplier Debug", false);
|
||||||
|
vehicleTrunkCapacityMultiplier =
|
||||||
|
Config.Bind("General", "Vehicle Trunk Capacity Multiplier", 1f);
|
||||||
|
|
||||||
vehicleTrunkCapacityMultiplierDebug =
|
deconstructionTimeMultiplierDebug =
|
||||||
Config.Bind("General", "Vehicle Trunk Capacity Multiplier Debug", false);
|
Config.Bind("General", "Deconstruction Time Multiplier Debug", false);
|
||||||
vehicleTrunkCapacityMultiplier = Config.Bind("General", "Vehicle Trunk Capacity Multiplier", 1f);
|
deconstructionTimeMultiplier =
|
||||||
|
Config.Bind("General", "Deconstruction Time Multiplier", 1f);
|
||||||
|
|
||||||
deconstructionTimeMultiplierDebug = Config.Bind("General", "Deconstruction Time Multiplier Debug", false);
|
constructionTimeMultiplierDebug =
|
||||||
deconstructionTimeMultiplier = Config.Bind("General", "Deconstruction Time Multiplier", 1f);
|
Config.Bind("General", "Construction Time Multiplier Debug", false);
|
||||||
|
constructionTimeMultiplier =
|
||||||
|
Config.Bind("General", "Construction Time Multiplier", 1f);
|
||||||
|
|
||||||
constructionTimeMultiplierDebug = Config.Bind("General", "Construction Time Multiplier Debug", false);
|
productionTimeMultiplierDebug =
|
||||||
constructionTimeMultiplier = Config.Bind("General", "Construction Time Multiplier", 1f);
|
Config.Bind("General", "Production Time Multiplier Debug", false);
|
||||||
|
productionTimeMultiplier =
|
||||||
|
Config.Bind("General", "Production Time Multiplier", 1f);
|
||||||
|
|
||||||
productionTimeMultiplierDebug = Config.Bind("General", "Production Time Multiplier Debug", false);
|
birthingConfigDebug =
|
||||||
productionTimeMultiplier = Config.Bind("General", "Production Time Multiplier", 1f);
|
Config.Bind("Birthing Config", "Birthing Config Debug", false);
|
||||||
|
maxCitizensInZoneToChildrenBorn = Config.Bind(
|
||||||
birthingConfigDebug = Config.Bind("Birthing Config", "Birthing Config Debug", false);
|
"Birthing Config", "Max Citizens in Zone to Children Born", 600);
|
||||||
maxCitizensInZoneToChildrenBorn =
|
moraleInfluenceFloorParam =
|
||||||
Config.Bind("Birthing Config", "Max Citizens in Zone to Children Born", 600);
|
Config.Bind("Birthing Config", "Morale Influence Floor Param", 0.3f);
|
||||||
moraleInfluenceFloorParam = Config.Bind("Birthing Config", "Morale Influence Floor Param", 0.3f);
|
moraleInfluenceCeilingParam =
|
||||||
moraleInfluenceCeilingParam = Config.Bind("Birthing Config", "Morale Influence Ceiling Param", 2f);
|
Config.Bind("Birthing Config", "Morale Influence Ceiling Param", 2f);
|
||||||
foodStockInfluenceFloorParam = Config.Bind("Birthing Config", "Food Stock Influence Floor Param", 0f);
|
foodStockInfluenceFloorParam =
|
||||||
foodStockInfluenceCeilingParam = Config.Bind("Birthing Config", "Food Stock Influence Ceiling Param", 1f);
|
Config.Bind("Birthing Config", "Food Stock Influence Floor Param", 0f);
|
||||||
quartersRatioInfluenceFloorParam =
|
foodStockInfluenceCeilingParam = Config.Bind(
|
||||||
Config.Bind("Birthing Config", "Quarters Ratio Influence Floor Param", 0.6f);
|
"Birthing Config", "Food Stock Influence Ceiling Param", 1f);
|
||||||
quartersRatioInfluenceCeilingParam =
|
quartersRatioInfluenceFloorParam = Config.Bind(
|
||||||
Config.Bind("Birthing Config", "Quarters Ratio Influence Ceiling Param", 1.4f);
|
"Birthing Config", "Quarters Ratio Influence Floor Param", 0.6f);
|
||||||
childToAdultRatioInfluenceFloorParam =
|
quartersRatioInfluenceCeilingParam = Config.Bind(
|
||||||
Config.Bind("Birthing Config", "Child to Adult Ratio Influence Floor Param", 1f);
|
"Birthing Config", "Quarters Ratio Influence Ceiling Param", 1.4f);
|
||||||
childToAdultRatioInfluenceCeilingParam =
|
childToAdultRatioInfluenceFloorParam = Config.Bind(
|
||||||
Config.Bind("Birthing Config", "Child to Adult Ratio Influence Ceiling Param", 0f);
|
"Birthing Config", "Child to Adult Ratio Influence Floor Param", 1f);
|
||||||
|
childToAdultRatioInfluenceCeilingParam = Config.Bind(
|
||||||
|
"Birthing Config", "Child to Adult Ratio Influence Ceiling Param", 0f);
|
||||||
adultAge = Config.Bind("Birthing Config", "Adult Age", 12);
|
adultAge = Config.Bind("Birthing Config", "Adult Age", 12);
|
||||||
oldAge = Config.Bind("Birthing Config", "Old Age", 60);
|
oldAge = Config.Bind("Birthing Config", "Old Age", 60);
|
||||||
|
|
||||||
rotationTimestepMultiplier = Config.Bind("General", "Rotation Timestep Multiplier", 1f);
|
rotationTimestepMultiplier =
|
||||||
|
Config.Bind("General", "Rotation Timestep Multiplier", 1f);
|
||||||
sunsetHourOffset = Config.Bind("General", "Sunset Hour Offset", 0f);
|
sunsetHourOffset = Config.Bind("General", "Sunset Hour Offset", 0f);
|
||||||
sunriseHourOffset = Config.Bind("General", "Sunrise Hour Offset", 0f);
|
sunriseHourOffset = Config.Bind("General", "Sunrise Hour Offset", 0f);
|
||||||
|
|
||||||
productionProfitMultiplierDebug = Config.Bind("General", "Production Profit Multiplier Debug", false);
|
productionProfitMultiplierDebug =
|
||||||
productionProfitMultiplier =
|
Config.Bind("General", "Production Profit Multiplier Debug", false);
|
||||||
Config.Bind("General", "Production Profit Multiplier (Resource ID: multiplier)", "");
|
productionProfitMultiplier = Config.Bind(
|
||||||
|
"General", "Production Profit Multiplier (Resource ID: multiplier)",
|
||||||
|
"");
|
||||||
productionProfitMultiplierDict = new Dictionary<ResourceID, float>();
|
productionProfitMultiplierDict = new Dictionary<ResourceID, float>();
|
||||||
productionProfitMultiplier.SettingChanged += delegate { UpdateProductionProfitMultiplierDict(); };
|
productionProfitMultiplier.SettingChanged += delegate {
|
||||||
|
UpdateProductionProfitMultiplierDict();
|
||||||
|
};
|
||||||
UpdateProductionProfitMultiplierDict();
|
UpdateProductionProfitMultiplierDict();
|
||||||
|
|
||||||
towerEchoSelectionDebug = Config.Bind("General", "Tower Echo Selection Debug", false);
|
towerEchoSelectionDebug =
|
||||||
|
Config.Bind("General", "Tower Echo Selection Debug", false);
|
||||||
towerEchoSelection = Config.Bind("General", "Tower Echo Selection", false);
|
towerEchoSelection = Config.Bind("General", "Tower Echo Selection", false);
|
||||||
towerEchoSelectionList = new List<WeakReference<StructureDefenceModule>>();
|
towerEchoSelectionList = new List<WeakReference<StructureDefenceModule>>();
|
||||||
|
|
||||||
buildingMaxVolumeDebug = Config.Bind("General", "Building Max Volume Debug", false);
|
buildingMaxVolumeDebug =
|
||||||
|
Config.Bind("General", "Building Max Volume Debug", false);
|
||||||
buildingMaxVolume = Config.Bind("General", "Building Max Volume", 50000f);
|
buildingMaxVolume = Config.Bind("General", "Building Max Volume", 50000f);
|
||||||
|
|
||||||
Logger.LogInfo("Cyka mod loaded");
|
Logger.LogInfo("Cyka mod loaded");
|
||||||
@@ -290,21 +323,27 @@ namespace InfectionFreeZone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(GatherResourcesWork), "InstantiateResources", new Type[] { })]
|
[HarmonyPatch(typeof(GatherResourcesWork), "InstantiateResources",
|
||||||
|
new Type[] {})]
|
||||||
public static void PrefixGatheredResource(ref ScavengeWork __instance) {
|
public static void PrefixGatheredResource(ref ScavengeWork __instance) {
|
||||||
var trav = Traverse.Create(__instance);
|
var trav = Traverse.Create(__instance);
|
||||||
var resourcesToDropNew = new Dictionary<ResourceID, int>();
|
var resourcesToDropNew = new Dictionary<ResourceID, int>();
|
||||||
var resourcesToDrop = trav.Field<Dictionary<ResourceID, int>>("_resourcesToDrop");
|
var resourcesToDrop =
|
||||||
|
trav.Field<Dictionary<ResourceID, int>>("_resourcesToDrop");
|
||||||
if (Main.resourceGatheringMultiplierDebug.Value)
|
if (Main.resourceGatheringMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Resources to drop: {resourcesToDrop}");
|
Console.WriteLine($"Resources to drop: {resourcesToDrop}");
|
||||||
if (resourcesToDrop.Value.Count > 0) {
|
if (resourcesToDrop.Value.Count > 0) {
|
||||||
foreach (KeyValuePair<ResourceID, int> resource in resourcesToDrop.Value) {
|
foreach (KeyValuePair<ResourceID, int> resource in resourcesToDrop
|
||||||
|
.Value) {
|
||||||
if (Main.resourceGatheringMultiplierDebug.Value)
|
if (Main.resourceGatheringMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Resource {resource.Key} to drop: {resource.Value}");
|
Console.WriteLine(
|
||||||
var newResourceValue = (int)(resource.Value * Main.resourceScavengingMultiplier.Value);
|
$"Resource {resource.Key} to drop: {resource.Value}");
|
||||||
|
var newResourceValue =
|
||||||
|
(int)(resource.Value * Main.resourceScavengingMultiplier.Value);
|
||||||
resourcesToDropNew.Add(resource.Key, newResourceValue);
|
resourcesToDropNew.Add(resource.Key, newResourceValue);
|
||||||
if (Main.resourceGatheringMultiplierDebug.Value)
|
if (Main.resourceGatheringMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Resource {resource.Key} to drop modified to: {newResourceValue}");
|
Console.WriteLine(
|
||||||
|
$"Resource {resource.Key} to drop modified to: {newResourceValue}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +353,8 @@ namespace InfectionFreeZone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(PlaceableObjectDraft), "GetCapacity", typeof(float), typeof(float))]
|
[HarmonyPatch(typeof(PlaceableObjectDraft), "GetCapacity", typeof(float),
|
||||||
|
typeof(float))]
|
||||||
public static void PostfixGetCapacity(ref int __result) {
|
public static void PostfixGetCapacity(ref int __result) {
|
||||||
if (Main.buildingStorageCapacityMultiplier.Value <= 0)
|
if (Main.buildingStorageCapacityMultiplier.Value <= 0)
|
||||||
return;
|
return;
|
||||||
@@ -341,7 +381,8 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(Building), "DeconstructionResources", MethodType.Getter)]
|
[HarmonyPatch(typeof(Building), "DeconstructionResources", MethodType.Getter)]
|
||||||
public static ResourceQuantity[] PostfixDeconstructionResources(ResourceQuantity[] __result) {
|
public static ResourceQuantity[] PostfixDeconstructionResources(
|
||||||
|
ResourceQuantity[] __result) {
|
||||||
if (Main.buildingDeconstructionResourcesMultiplier.Value <= 0)
|
if (Main.buildingDeconstructionResourcesMultiplier.Value <= 0)
|
||||||
return __result;
|
return __result;
|
||||||
|
|
||||||
@@ -352,12 +393,17 @@ namespace InfectionFreeZone {
|
|||||||
Console.WriteLine($"Resource quantity is {resourceQuantity}");
|
Console.WriteLine($"Resource quantity is {resourceQuantity}");
|
||||||
|
|
||||||
if (Main.buildingDeconstructionResourcesMultiplierDebug.Value)
|
if (Main.buildingDeconstructionResourcesMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Resource quantity value is {resourceQuantity.value}");
|
Console.WriteLine(
|
||||||
modifiedResult[i] = new ResourceQuantity(resourceQuantity.resourceType,
|
$"Resource quantity value is {resourceQuantity.value}");
|
||||||
resourceQuantity.value * Main.buildingDeconstructionResourcesMultiplier.Value);
|
modifiedResult[i] = new ResourceQuantity(
|
||||||
// resourceQuantity.value *= Main.buildingDeconstructionResourcesMultiplier.Value;
|
resourceQuantity.resourceType,
|
||||||
|
resourceQuantity.value *
|
||||||
|
Main.buildingDeconstructionResourcesMultiplier.Value);
|
||||||
|
// resourceQuantity.value *=
|
||||||
|
// Main.buildingDeconstructionResourcesMultiplier.Value;
|
||||||
if (Main.buildingDeconstructionResourcesMultiplierDebug.Value)
|
if (Main.buildingDeconstructionResourcesMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Resource quantity value modified to {modifiedResult[i].value}");
|
Console.WriteLine(
|
||||||
|
$"Resource quantity value modified to {modifiedResult[i].value}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return modifiedResult;
|
return modifiedResult;
|
||||||
@@ -365,7 +411,8 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(BuildingDestruction), "Initialize")]
|
[HarmonyPatch(typeof(BuildingDestruction), "Initialize")]
|
||||||
public static void PrefixBuildingDeconstruction(ref BuildingDestruction __instance) {
|
public static void
|
||||||
|
PrefixBuildingDeconstruction(ref BuildingDestruction __instance) {
|
||||||
if (Main.deconstructionWorkersPer100m.Value <= 0)
|
if (Main.deconstructionWorkersPer100m.Value <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -376,7 +423,8 @@ namespace InfectionFreeZone {
|
|||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Building deconstruction workers per 100m is {configV.deconstructWorkersPer100m3OfBuilding}");
|
$"Building deconstruction workers per 100m is {configV.deconstructWorkersPer100m3OfBuilding}");
|
||||||
|
|
||||||
configV.deconstructWorkersPer100m3OfBuilding = Main.deconstructionWorkersPer100m.Value;
|
configV.deconstructWorkersPer100m3OfBuilding =
|
||||||
|
Main.deconstructionWorkersPer100m.Value;
|
||||||
config.Value = configV;
|
config.Value = configV;
|
||||||
if (Main.buildingDeconstructionResourcesMultiplierDebug.Value)
|
if (Main.buildingDeconstructionResourcesMultiplierDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
@@ -385,8 +433,10 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(Movement), "CalculateSpeed")]
|
[HarmonyPatch(typeof(Movement), "CalculateSpeed")]
|
||||||
public static void PostfixCalculateSpeedHuman(Movement __instance, ref float __result) {
|
public static void PostfixCalculateSpeedHuman(Movement __instance,
|
||||||
// Humans are "Human(Clone)", infected are "inf_human(Clone)" and vehicles are "ve_<name>"
|
ref float __result) {
|
||||||
|
// Humans are "Human(Clone)", infected are "inf_human(Clone)" and vehicles
|
||||||
|
// are "ve_<name>"
|
||||||
var name = __instance.ToString();
|
var name = __instance.ToString();
|
||||||
if (name.StartsWith("Human"))
|
if (name.StartsWith("Human"))
|
||||||
__result *= Main.humanMovementSpeedMultiplier.Value;
|
__result *= Main.humanMovementSpeedMultiplier.Value;
|
||||||
@@ -395,18 +445,22 @@ namespace InfectionFreeZone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(Vehicle), "Constructor",
|
[HarmonyPatch(typeof(Vehicle), "Constructor", typeof(GroupIconsPool),
|
||||||
typeof(GroupIconsPool), typeof(SignalBus), typeof(WeatherController))]
|
typeof(SignalBus), typeof(WeatherController))]
|
||||||
public static void PostfixVehicle(ref Vehicle __instance) {
|
public static void PostfixVehicle(ref Vehicle __instance) {
|
||||||
if (Main.vehicleTrunkCapacityMultiplier.Value <= 0)
|
if (Main.vehicleTrunkCapacityMultiplier.Value <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Main.vehicleTrunkCapacityMultiplierDebug.Value)
|
if (Main.vehicleTrunkCapacityMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Vehicle trunk capacity is {__instance.Trunk.Capacity}");
|
Console.WriteLine(
|
||||||
__instance.Trunk.SetCapacity((int)(__instance.Trunk.Capacity * Main.vehicleTrunkCapacityMultiplier.Value),
|
$"Vehicle trunk capacity is {__instance.Trunk.Capacity}");
|
||||||
|
__instance.Trunk.SetCapacity(
|
||||||
|
(int)(__instance.Trunk.Capacity *
|
||||||
|
Main.vehicleTrunkCapacityMultiplier.Value),
|
||||||
true);
|
true);
|
||||||
if (Main.vehicleTrunkCapacityMultiplierDebug.Value)
|
if (Main.vehicleTrunkCapacityMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Vehicle trunk capacity modified to {__instance.Trunk.Capacity}");
|
Console.WriteLine(
|
||||||
|
$"Vehicle trunk capacity modified to {__instance.Trunk.Capacity}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// GatherResourcesWork
|
// GatherResourcesWork
|
||||||
@@ -415,8 +469,10 @@ namespace InfectionFreeZone {
|
|||||||
// ProductionWork
|
// ProductionWork
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(DisassembleWork), MethodType.Constructor,
|
[HarmonyPatch(typeof(DisassembleWork), MethodType.Constructor,
|
||||||
typeof(Structure), typeof(float), typeof(int), typeof(ResourcesController), typeof(SignalBus))]
|
typeof(Structure), typeof(float), typeof(int),
|
||||||
public static void PrefixDisassembleWork(Structure structure, ref float timeToDeconstruct) {
|
typeof(ResourcesController), typeof(SignalBus))]
|
||||||
|
public static void PrefixDisassembleWork(Structure structure,
|
||||||
|
ref float timeToDeconstruct) {
|
||||||
if (Main.deconstructionTimeMultiplier.Value <= 0)
|
if (Main.deconstructionTimeMultiplier.Value <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -429,9 +485,10 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(ConstructableWork), MethodType.Constructor,
|
[HarmonyPatch(typeof(ConstructableWork), MethodType.Constructor,
|
||||||
typeof(Structure), typeof(Dictionary<ResourceID, int>), typeof(float), typeof(StockroomsController),
|
typeof(Structure), typeof(Dictionary<ResourceID, int>),
|
||||||
typeof(SignalBus))]
|
typeof(float), typeof(StockroomsController), typeof(SignalBus))]
|
||||||
public static void PrefixConstructWork(Structure structure, Dictionary<ResourceID, int> cost,
|
public static void PrefixConstructWork(Structure structure,
|
||||||
|
Dictionary<ResourceID, int> cost,
|
||||||
ref float timeToConstruct) {
|
ref float timeToConstruct) {
|
||||||
if (Main.deconstructionTimeMultiplier.Value <= 0)
|
if (Main.deconstructionTimeMultiplier.Value <= 0)
|
||||||
return;
|
return;
|
||||||
@@ -459,7 +516,8 @@ namespace InfectionFreeZone {
|
|||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(CitizensController), "IncreasePopulation")]
|
[HarmonyPatch(typeof(CitizensController), "IncreasePopulation")]
|
||||||
// Could not find a better way to do this
|
// Could not find a better way to do this
|
||||||
public static void PostfixCharactersConfig(ref CitizensController __instance) {
|
public static void
|
||||||
|
PostfixCharactersConfig(ref CitizensController __instance) {
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine($"Citizens controller IncreasePopulation");
|
Console.WriteLine($"Citizens controller IncreasePopulation");
|
||||||
var trav = Traverse.Create(__instance);
|
var trav = Traverse.Create(__instance);
|
||||||
@@ -475,36 +533,43 @@ namespace InfectionFreeZone {
|
|||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine($"Old age is {charactersConfigV.oldAge}");
|
Console.WriteLine($"Old age is {charactersConfigV.oldAge}");
|
||||||
|
|
||||||
bornConfig.MaxCitizensInZoneToChildrenBorn = Main.maxCitizensInZoneToChildrenBorn.Value;
|
bornConfig.MaxCitizensInZoneToChildrenBorn =
|
||||||
|
Main.maxCitizensInZoneToChildrenBorn.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Max citizens in zone to children born is {bornConfig.MaxCitizensInZoneToChildrenBorn}");
|
$"Max citizens in zone to children born is {bornConfig.MaxCitizensInZoneToChildrenBorn}");
|
||||||
|
|
||||||
bornConfig.MoraleInfluenceFloorParam = Main.moraleInfluenceFloorParam.Value;
|
bornConfig.MoraleInfluenceFloorParam = Main.moraleInfluenceFloorParam.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine($"Morale influence floor param is {bornConfig.MoraleInfluenceFloorParam}");
|
Console.WriteLine(
|
||||||
|
$"Morale influence floor param is {bornConfig.MoraleInfluenceFloorParam}");
|
||||||
|
|
||||||
bornConfig.MoraleInfluenceCeilingParam = Main.moraleInfluenceCeilingParam.Value;
|
bornConfig.MoraleInfluenceCeilingParam =
|
||||||
|
Main.moraleInfluenceCeilingParam.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Morale influence ceiling param is {bornConfig.MoraleInfluenceCeilingParam}");
|
$"Morale influence ceiling param is {bornConfig.MoraleInfluenceCeilingParam}");
|
||||||
|
|
||||||
bornConfig.FoodStockInfluenceFloorParam = Main.foodStockInfluenceFloorParam.Value;
|
bornConfig.FoodStockInfluenceFloorParam =
|
||||||
|
Main.foodStockInfluenceFloorParam.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Food stock influence floor param is {bornConfig.FoodStockInfluenceFloorParam}");
|
$"Food stock influence floor param is {bornConfig.FoodStockInfluenceFloorParam}");
|
||||||
|
|
||||||
bornConfig.FoodStockInfluenceCeilingParam = Main.foodStockInfluenceCeilingParam.Value;
|
bornConfig.FoodStockInfluenceCeilingParam =
|
||||||
|
Main.foodStockInfluenceCeilingParam.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Food stock influence ceiling param is {bornConfig.FoodStockInfluenceCeilingParam}");
|
$"Food stock influence ceiling param is {bornConfig.FoodStockInfluenceCeilingParam}");
|
||||||
|
|
||||||
bornConfig.QuartersRatioInfluenceFloorParam = Main.quartersRatioInfluenceFloorParam.Value;
|
bornConfig.QuartersRatioInfluenceFloorParam =
|
||||||
|
Main.quartersRatioInfluenceFloorParam.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Quarters ratio influence floor param is {bornConfig.QuartersRatioInfluenceFloorParam}");
|
$"Quarters ratio influence floor param is {bornConfig.QuartersRatioInfluenceFloorParam}");
|
||||||
|
|
||||||
bornConfig.QuartersRatioInfluenceCeilingParam = Main.quartersRatioInfluenceCeilingParam.Value;
|
bornConfig.QuartersRatioInfluenceCeilingParam =
|
||||||
|
Main.quartersRatioInfluenceCeilingParam.Value;
|
||||||
if (Main.birthingConfigDebug.Value)
|
if (Main.birthingConfigDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Quarters ratio influence ceiling param is {bornConfig.QuartersRatioInfluenceCeilingParam}");
|
$"Quarters ratio influence ceiling param is {bornConfig.QuartersRatioInfluenceCeilingParam}");
|
||||||
@@ -527,18 +592,24 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(PlaceObjectsInSingleLineCursor), "RotateRight")]
|
[HarmonyPatch(typeof(PlaceObjectsInSingleLineCursor), "RotateRight")]
|
||||||
public static IEnumerable<CodeInstruction> PostfixRotateRight(IEnumerable<CodeInstruction> instructions) {
|
public static IEnumerable<CodeInstruction>
|
||||||
|
PostfixRotateRight(IEnumerable<CodeInstruction> instructions) {
|
||||||
var codes = new List<CodeInstruction>(instructions);
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
for (var i = 0; i < codes.Count; i++) {
|
for (var i = 0; i < codes.Count; i++) {
|
||||||
var code = codes[i];
|
var code = codes[i];
|
||||||
Console.WriteLine($"Opcode is {code.opcode}");
|
Console.WriteLine($"Opcode is {code.opcode}");
|
||||||
if (code.opcode == OpCodes.Ldc_R4 && Mathf.Approximately((float)code.operand, 100f)) {
|
if (code.opcode == OpCodes.Ldc_R4 &&
|
||||||
|
Mathf.Approximately((float)code.operand, 100f)) {
|
||||||
Console.WriteLine($"Operand is {code.operand}");
|
Console.WriteLine($"Operand is {code.operand}");
|
||||||
codes[i] = new CodeInstruction(OpCodes.Ldsfld,
|
codes[i] = new CodeInstruction(
|
||||||
|
OpCodes.Ldsfld,
|
||||||
AccessTools.Field(typeof(Main), "rotationTimestepMultiplier"));
|
AccessTools.Field(typeof(Main), "rotationTimestepMultiplier"));
|
||||||
codes.Insert(i + 1,
|
codes.Insert(i + 1, new CodeInstruction(
|
||||||
new CodeInstruction(OpCodes.Call,
|
OpCodes.Call,
|
||||||
AccessTools.PropertyGetter(typeof(Main).GetField("rotationTimestepMultiplier").FieldType,
|
AccessTools.PropertyGetter(
|
||||||
|
typeof(Main)
|
||||||
|
.GetField("rotationTimestepMultiplier")
|
||||||
|
.FieldType,
|
||||||
"Value")));
|
"Value")));
|
||||||
Console.WriteLine($"Operand modified to {codes[i].operand}");
|
Console.WriteLine($"Operand modified to {codes[i].operand}");
|
||||||
}
|
}
|
||||||
@@ -549,18 +620,24 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(PlaceObjectsInSingleLineCursor), "RotateLeft")]
|
[HarmonyPatch(typeof(PlaceObjectsInSingleLineCursor), "RotateLeft")]
|
||||||
public static IEnumerable<CodeInstruction> PostfixRotateLeft(IEnumerable<CodeInstruction> instructions) {
|
public static IEnumerable<CodeInstruction>
|
||||||
|
PostfixRotateLeft(IEnumerable<CodeInstruction> instructions) {
|
||||||
var codes = new List<CodeInstruction>(instructions);
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
for (var i = 0; i < codes.Count; i++) {
|
for (var i = 0; i < codes.Count; i++) {
|
||||||
var code = codes[i];
|
var code = codes[i];
|
||||||
Console.WriteLine($"Opcode is {code.opcode}");
|
Console.WriteLine($"Opcode is {code.opcode}");
|
||||||
if (code.opcode == OpCodes.Ldc_R4 && Mathf.Approximately((float)code.operand, 100f)) {
|
if (code.opcode == OpCodes.Ldc_R4 &&
|
||||||
|
Mathf.Approximately((float)code.operand, 100f)) {
|
||||||
Console.WriteLine($"Operand is {code.operand}");
|
Console.WriteLine($"Operand is {code.operand}");
|
||||||
codes[i] = new CodeInstruction(OpCodes.Ldsfld,
|
codes[i] = new CodeInstruction(
|
||||||
|
OpCodes.Ldsfld,
|
||||||
AccessTools.Field(typeof(Main), "rotationTimestepMultiplier"));
|
AccessTools.Field(typeof(Main), "rotationTimestepMultiplier"));
|
||||||
codes.Insert(i + 1,
|
codes.Insert(i + 1, new CodeInstruction(
|
||||||
new CodeInstruction(OpCodes.Call,
|
OpCodes.Call,
|
||||||
AccessTools.PropertyGetter(typeof(Main).GetField("rotationTimestepMultiplier").FieldType,
|
AccessTools.PropertyGetter(
|
||||||
|
typeof(Main)
|
||||||
|
.GetField("rotationTimestepMultiplier")
|
||||||
|
.FieldType,
|
||||||
"Value")));
|
"Value")));
|
||||||
Console.WriteLine($"Operand modified to {codes[i].operand}");
|
Console.WriteLine($"Operand modified to {codes[i].operand}");
|
||||||
}
|
}
|
||||||
@@ -585,7 +662,8 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(ProductionWork), "ProduceResources")]
|
[HarmonyPatch(typeof(ProductionWork), "ProduceResources")]
|
||||||
public static void PrefixProduceResources(List<ProductionDataPart> productionDataParts) {
|
public static void
|
||||||
|
PrefixProduceResources(List<ProductionDataPart> productionDataParts) {
|
||||||
if (Main.productionProfitMultiplierDict.Count == 0)
|
if (Main.productionProfitMultiplierDict.Count == 0)
|
||||||
return;
|
return;
|
||||||
if (productionDataParts.Count == 0)
|
if (productionDataParts.Count == 0)
|
||||||
@@ -596,7 +674,8 @@ namespace InfectionFreeZone {
|
|||||||
if (Main.productionProfitMultiplierDebug.Value)
|
if (Main.productionProfitMultiplierDebug.Value)
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Production data part is {productionDataPart.type} x {productionDataPart.amount}");
|
$"Production data part is {productionDataPart.type} x {productionDataPart.amount}");
|
||||||
if (Main.productionProfitMultiplierDict.TryGetValue(productionDataPart.type, out var setpoint)) {
|
if (Main.productionProfitMultiplierDict.TryGetValue(
|
||||||
|
productionDataPart.type, out var setpoint)) {
|
||||||
if (Main.productionProfitMultiplierDebug.Value)
|
if (Main.productionProfitMultiplierDebug.Value)
|
||||||
Console.WriteLine($"Production data part has setpoint {setpoint}");
|
Console.WriteLine($"Production data part has setpoint {setpoint}");
|
||||||
productionDataPart.amount = (int)setpoint;
|
productionDataPart.amount = (int)setpoint;
|
||||||
@@ -609,10 +688,12 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(StructureDefenceModule), "Awake")]
|
[HarmonyPatch(typeof(StructureDefenceModule), "Awake")]
|
||||||
public static void PostfixStructureDefenceModule(StructureDefenceModule __instance) {
|
public static void
|
||||||
|
PostfixStructureDefenceModule(StructureDefenceModule __instance) {
|
||||||
if (Main.towerEchoSelectionDebug.Value)
|
if (Main.towerEchoSelectionDebug.Value)
|
||||||
Console.WriteLine($"Structure defence module created");
|
Console.WriteLine($"Structure defence module created");
|
||||||
Main.towerEchoSelectionList.Add(new WeakReference<StructureDefenceModule>(__instance));
|
Main.towerEchoSelectionList.Add(
|
||||||
|
new WeakReference<StructureDefenceModule>(__instance));
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
@@ -634,7 +715,8 @@ namespace InfectionFreeZone {
|
|||||||
|
|
||||||
if (Main.towerEchoSelectionDebug.Value) {
|
if (Main.towerEchoSelectionDebug.Value) {
|
||||||
Console.WriteLine($"Selected weapon item is {selectedItem.name}");
|
Console.WriteLine($"Selected weapon item is {selectedItem.name}");
|
||||||
Console.WriteLine($"Echoing weapon to {Main.towerEchoSelectionList.Count} towers");
|
Console.WriteLine(
|
||||||
|
$"Echoing weapon to {Main.towerEchoSelectionList.Count} towers");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < Main.towerEchoSelectionList.Count; i++) {
|
for (var i = 0; i < Main.towerEchoSelectionList.Count; i++) {
|
||||||
@@ -654,11 +736,13 @@ namespace InfectionFreeZone {
|
|||||||
towerEchoSelectionT.SetFieldOfView(selectedItem.WeaponData);
|
towerEchoSelectionT.SetFieldOfView(selectedItem.WeaponData);
|
||||||
towerEchoSelectionT.SetupWeapon(selectedItem.WeaponData);
|
towerEchoSelectionT.SetupWeapon(selectedItem.WeaponData);
|
||||||
|
|
||||||
var selectedWeapon = towerEchoSelectionT.SelectedWeapon == null
|
var selectedWeapon =
|
||||||
|
towerEchoSelectionT.SelectedWeapon == null
|
||||||
? "null"
|
? "null"
|
||||||
: towerEchoSelectionT.SelectedWeapon.ToString();
|
: towerEchoSelectionT.SelectedWeapon.ToString();
|
||||||
if (Main.towerEchoSelectionDebug.Value)
|
if (Main.towerEchoSelectionDebug.Value)
|
||||||
Console.WriteLine($"Tower defence weapon modified to {selectedWeapon}");
|
Console.WriteLine(
|
||||||
|
$"Tower defence weapon modified to {selectedWeapon}");
|
||||||
}
|
}
|
||||||
} catch (NullReferenceException e) {
|
} catch (NullReferenceException e) {
|
||||||
Console.WriteLine($"Failed to set tower defence weapon: {e}");
|
Console.WriteLine($"Failed to set tower defence weapon: {e}");
|
||||||
@@ -669,8 +753,8 @@ namespace InfectionFreeZone {
|
|||||||
// TODO: Add toggle for this
|
// TODO: Add toggle for this
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(ValidatableStructure), "Awake")]
|
[HarmonyPatch(typeof(ValidatableStructure), "Awake")]
|
||||||
public static IEnumerable<CodeInstruction> PostfixValidatableStructure(
|
public static IEnumerable<CodeInstruction>
|
||||||
IEnumerable<CodeInstruction> instructions) {
|
PostfixValidatableStructure(IEnumerable<CodeInstruction> instructions) {
|
||||||
var codes = new List<CodeInstruction>(instructions);
|
var codes = new List<CodeInstruction>(instructions);
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int start2 = 0;
|
int start2 = 0;
|
||||||
@@ -678,40 +762,52 @@ namespace InfectionFreeZone {
|
|||||||
int end2 = 0;
|
int end2 = 0;
|
||||||
for (var i = 0; i < codes.Count; i++) {
|
for (var i = 0; i < codes.Count; i++) {
|
||||||
if (codes[i].opcode == OpCodes.Ldc_I4_5) {
|
if (codes[i].opcode == OpCodes.Ldc_I4_5) {
|
||||||
Console.WriteLine($"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
Console.WriteLine(
|
||||||
codes[i] = new CodeInstruction(OpCodes.Ldc_I4_2); // Array size after our deletion is 3 from 5
|
$"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
||||||
|
codes[i] = new CodeInstruction(
|
||||||
|
OpCodes.Ldc_I4_2); // Array size after our deletion is 3 from 5
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codes[i].opcode == OpCodes.Ldstr && codes[i].operand.ToString() == "Tower") {
|
if (codes[i].opcode == OpCodes.Ldstr &&
|
||||||
Console.WriteLine($"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
codes[i].operand.ToString() == "Tower") {
|
||||||
|
Console.WriteLine(
|
||||||
|
$"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
||||||
start2 = i - 2;
|
start2 = i - 2;
|
||||||
end2 = i + 2;
|
end2 = i + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codes[i].opcode == OpCodes.Ldstr && codes[i].operand.ToString() == "Farmland") {
|
if (codes[i].opcode == OpCodes.Ldstr &&
|
||||||
Console.WriteLine($"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
codes[i].operand.ToString() == "Farmland") {
|
||||||
|
Console.WriteLine(
|
||||||
|
$"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Opcode is {codes[i - 1].opcode} and operand is {codes[i - 1].operand} at index {i - 1}");
|
$"Opcode is {codes[i - 1].opcode} and operand is {codes[i - 1].operand} at index {i - 1}");
|
||||||
codes[i - 1].opcode =
|
codes[i - 1].opcode =
|
||||||
OpCodes.Ldc_I4_1; // Because we deleted the previous element this one is now index 1 instead of 2
|
OpCodes.Ldc_I4_1; // Because we deleted the previous element this
|
||||||
|
// one is now index 1 instead of 2
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codes[i].opcode == OpCodes.Ldstr && codes[i].operand.ToString() == "Wall") {
|
if (codes[i].opcode == OpCodes.Ldstr &&
|
||||||
Console.WriteLine($"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
codes[i].operand.ToString() == "Wall") {
|
||||||
|
Console.WriteLine(
|
||||||
|
$"Opcode is {codes[i].opcode} and operand is {codes[i].operand} at index {i}");
|
||||||
start = i - 2;
|
start = i - 2;
|
||||||
end = i + 6;
|
end = i + 6;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($"Start is {start} with opcode {codes[start].opcode} and operand {codes[start].operand}");
|
Console.WriteLine(
|
||||||
Console.WriteLine($"End is {end} with opcode {codes[end].opcode} and operand {codes[end].operand}");
|
$"Start is {start} with opcode {codes[start].opcode} and operand {codes[start].operand}");
|
||||||
|
Console.WriteLine(
|
||||||
|
$"End is {end} with opcode {codes[end].opcode} and operand {codes[end].operand}");
|
||||||
codes.RemoveRange(start, end - start);
|
codes.RemoveRange(start, end - start);
|
||||||
Console.WriteLine($"Removed {end - start} instructions");
|
Console.WriteLine($"Removed {end - start} instructions");
|
||||||
|
|
||||||
Console.WriteLine(
|
Console.WriteLine(
|
||||||
$"Start2 is {start2} with opcode {codes[start2].opcode} and operand {codes[start2].operand}");
|
$"Start2 is {start2} with opcode {codes[start2].opcode} and operand {codes[start2].operand}");
|
||||||
Console.WriteLine($"End2 is {end2} with opcode {codes[end2].opcode} and operand {codes[end2].operand}");
|
Console.WriteLine(
|
||||||
|
$"End2 is {end2} with opcode {codes[end2].opcode} and operand {codes[end2].operand}");
|
||||||
codes.RemoveRange(start2, end2 - start2);
|
codes.RemoveRange(start2, end2 - start2);
|
||||||
Console.WriteLine($"Removed {end2 - start2} instructions");
|
Console.WriteLine($"Removed {end2 - start2} instructions");
|
||||||
|
|
||||||
@@ -722,14 +818,16 @@ namespace InfectionFreeZone {
|
|||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(WallConstructor), MethodType.Constructor,
|
[HarmonyPatch(typeof(WallConstructor), MethodType.Constructor,
|
||||||
typeof(Wall.Factory), typeof(WorkersRadio), typeof(WallConfig))]
|
typeof(Wall.Factory), typeof(WorkersRadio), typeof(WallConfig))]
|
||||||
public static void PostfixWallConstructor(Wall.Factory factory, WorkersRadio workersRadio,
|
public static void PostfixWallConstructor(Wall.Factory factory,
|
||||||
|
WorkersRadio workersRadio,
|
||||||
ref WallConfig wallConfig) {
|
ref WallConfig wallConfig) {
|
||||||
Console.WriteLine($"Wall config created");
|
Console.WriteLine($"Wall config created");
|
||||||
wallConfig.maxAngel = 2f;
|
wallConfig.maxAngel = 2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(AdaptController), MethodType.Constructor, typeof(AdaptConfig))]
|
[HarmonyPatch(typeof(AdaptController), MethodType.Constructor,
|
||||||
|
typeof(AdaptConfig))]
|
||||||
public static void PostfixAdaptConfig(ref AdaptConfig adaptConfig) {
|
public static void PostfixAdaptConfig(ref AdaptConfig adaptConfig) {
|
||||||
var trav = Traverse.Create(adaptConfig);
|
var trav = Traverse.Create(adaptConfig);
|
||||||
var buildingsMaxVolume = trav.Field<float>("buildingsMaxVolume");
|
var buildingsMaxVolume = trav.Field<float>("buildingsMaxVolume");
|
||||||
@@ -740,7 +838,8 @@ namespace InfectionFreeZone {
|
|||||||
buildingsMaxVolume.Value = Main.buildingMaxVolume.Value;
|
buildingsMaxVolume.Value = Main.buildingMaxVolume.Value;
|
||||||
|
|
||||||
if (Main.buildingMaxVolumeDebug.Value)
|
if (Main.buildingMaxVolumeDebug.Value)
|
||||||
Console.WriteLine($"Building max volume modified to {buildingsMaxVolume.Value}");
|
Console.WriteLine(
|
||||||
|
$"Building max volume modified to {buildingsMaxVolume.Value}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,8 @@ using System.Runtime.InteropServices;
|
|||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly:ComVisible(false)]
|
[assembly:ComVisible(false)]
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
// The following GUID is for the ID of the typelib if this project is exposed to
|
||||||
|
// COM
|
||||||
[assembly:Guid("DA9D274E-486F-4F82-84FF-CD9388CB0B09")]
|
[assembly:Guid("DA9D274E-486F-4F82-84FF-CD9388CB0B09")]
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
@@ -28,8 +29,7 @@ using System.Runtime.InteropServices;
|
|||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision
|
||||||
// by using the '*' as shown below:
|
// Numbers by using the '*' as shown below: [assembly: AssemblyVersion("1.0.*")]
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
|
||||||
[assembly:AssemblyVersion("1.0.0.0")]
|
[assembly:AssemblyVersion("1.0.0.0")]
|
||||||
[assembly:AssemblyFileVersion("1.0.0.0")]
|
[assembly:AssemblyFileVersion("1.0.0.0")]
|
||||||
@@ -1 +0,0 @@
|
|||||||
InfectionFreeZone/bin/Release/InfectionFreeZone.dll,"C:\Games\Infection.Free.Zone.v0.24.8.21a\BepInEx\plugins\InfectionFreeZone.dll"
|
|
||||||
3
Projects/InfectionFreeZone/sync.yml
Normal file
3
Projects/InfectionFreeZone/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/InfectionFreeZone.dll
|
||||||
|
target: C:\Games\Infection.Free.Zone.v0.24.8.21a\BepInEx\plugins\InfectionFreeZone.dll
|
||||||
|
delete: true
|
||||||
@@ -1 +0,0 @@
|
|||||||
bin/Release/CykaRaider.dll,"C:/Games/NightRaider/BepInEx/plugins/CykaRaider.dll"
|
|
||||||
3
Projects/NightRaider/sync.yml
Normal file
3
Projects/NightRaider/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/CykaRaider.dll
|
||||||
|
target: C:/Games/NightRaider/BepInEx/plugins/CykaRaider.dll
|
||||||
|
delete: true
|
||||||
3
Projects/Quasimorph/.clang-format
Normal file
3
Projects/Quasimorph/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 120
|
||||||
16
Projects/Quasimorph/Quasimorph.sln
Normal file
16
Projects/Quasimorph/Quasimorph.sln
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quasimorph", "Quasimorph\Quasimorph.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
|
||||||
47
Projects/Quasimorph/Quasimorph/Class1.cs
Normal file
47
Projects/Quasimorph/Quasimorph/Class1.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
using HarmonyLib.Tools;
|
||||||
|
using MGSC;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
|
||||||
|
public class Main : BaseUnityPlugin {
|
||||||
|
private const string PluginGuid = "Quasicyka";
|
||||||
|
private const string PluginName = "Quasicyka";
|
||||||
|
private const string PluginVersion = "1.0.0";
|
||||||
|
|
||||||
|
public static ConfigEntry<bool> debug;
|
||||||
|
public static ConfigEntry<int> scrappingMultiplier;
|
||||||
|
public static ConfigEntry<float> xpMultiplier;
|
||||||
|
|
||||||
|
public void Awake() {
|
||||||
|
debug = Config.Bind("General", "Debug", false);
|
||||||
|
scrappingMultiplier =
|
||||||
|
Config.Bind("General", "Scrapping Multiplier", 1,
|
||||||
|
new ConfigDescription("Scrapping Multiplier", new AcceptableValueRange<int>(1, 10000)));
|
||||||
|
xpMultiplier =
|
||||||
|
Config.Bind("General", "XP Multiplier", 1f,
|
||||||
|
new ConfigDescription("XP Multiplier", new AcceptableValueRange<float>(0.01f, 100f)));
|
||||||
|
|
||||||
|
Logger.LogInfo("Quasicyka loaded");
|
||||||
|
HarmonyFileLog.Enabled = true;
|
||||||
|
Harmony harmony = new Harmony(PluginGuid);
|
||||||
|
harmony.PatchAll();
|
||||||
|
var originalMethods = harmony.GetPatchedMethods();
|
||||||
|
Logger.LogInfo("Patched " + originalMethods.Count() + " methods");
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(Perk), "AddExp")]
|
||||||
|
[HarmonyPrefix]
|
||||||
|
public static void AddExp(ref int val) {
|
||||||
|
if (debug.Value)
|
||||||
|
Console.WriteLine($"Before: {val}");
|
||||||
|
val = (int)((float)val * scrappingMultiplier.Value);
|
||||||
|
if (debug.Value)
|
||||||
|
Console.WriteLine($"After: {val}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Projects/Quasimorph/Quasimorph/CykUtil.cs
Normal file
28
Projects/Quasimorph/Quasimorph/CykUtil.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
84
Projects/Quasimorph/Quasimorph/ModuleBoosterManager.cs
Normal file
84
Projects/Quasimorph/Quasimorph/ModuleBoosterManager.cs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleEnergyManager.cs
Normal file
67
Projects/Quasimorph/Quasimorph/ModuleEnergyManager.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleEnergyStoreManager.cs
Normal file
60
Projects/Quasimorph/Quasimorph/ModuleEnergyStoreManager.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleFuelTankManager.cs
Normal file
67
Projects/Quasimorph/Quasimorph/ModuleFuelTankManager.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleGyroManager.cs
Normal file
60
Projects/Quasimorph/Quasimorph/ModuleGyroManager.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleHeartManager.cs
Normal file
76
Projects/Quasimorph/Quasimorph/ModuleHeartManager.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleItemHolderManager.cs
Normal file
164
Projects/Quasimorph/Quasimorph/ModuleItemHolderManager.cs
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleItemProducerManager.cs
Normal file
77
Projects/Quasimorph/Quasimorph/ModuleItemProducerManager.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleRemoteChargerManager.cs
Normal file
77
Projects/Quasimorph/Quasimorph/ModuleRemoteChargerManager.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleWeaponGunManager.cs
Normal file
121
Projects/Quasimorph/Quasimorph/ModuleWeaponGunManager.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleWeaponManager.cs
Normal file
60
Projects/Quasimorph/Quasimorph/ModuleWeaponManager.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleWheelsManager.cs
Normal file
71
Projects/Quasimorph/Quasimorph/ModuleWheelsManager.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ModuleWingManager.cs
Normal file
83
Projects/Quasimorph/Quasimorph/ModuleWingManager.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/MultiBuy.cs
Normal file
71
Projects/Quasimorph/Quasimorph/MultiBuy.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ObjectFieldMultiplier.cs
Normal file
531
Projects/Quasimorph/Quasimorph/ObjectFieldMultiplier.cs
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
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/Quasimorph/Quasimorph/Patches.cs
Normal file
24
Projects/Quasimorph/Quasimorph/Patches.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/ProjectilePatch.cs
Normal file
22
Projects/Quasimorph/Quasimorph/ProjectilePatch.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[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/Quasimorph/Quasimorph/Properties/AssemblyInfo.cs
Normal file
35
Projects/Quasimorph/Quasimorph/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("Quasimorph")]
|
||||||
|
[assembly:AssemblyDescription("")]
|
||||||
|
[assembly:AssemblyConfiguration("")]
|
||||||
|
[assembly:AssemblyCompany("")]
|
||||||
|
[assembly:AssemblyProduct("Quasimorph")]
|
||||||
|
[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")]
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user