74 Commits

Author SHA1 Message Date
e4700847df Fix player-only option in ModuleWingManager 2025-02-25 09:46:59 +01:00
acdc4d2a78 Update ModuleEnergyManager to patch OnAnchorStatusChanged instead of OnAttached 2025-02-25 08:42:16 +01:00
7964f8f395 Remove projectile and missile projectile configuration from ModuleWeaponGunManager 2025-02-24 22:20:19 +01:00
9e3e4fa367 Add projectile explode on stick configuration option 2025-02-24 22:18:54 +01:00
b10eb8752b Add projectile and missile projectile configuration to ModuleWeaponGunManager 2025-02-24 22:01:13 +01:00
d0ffe1951b Replace TechBoosterManager with ModuleFuelTankManager 2025-02-24 21:06:13 +01:00
4f51f8599e Add TechBoosterManager with configurable fuel multipliers 2025-02-24 18:28:09 +01:00
5723e9592e Add ModuleHeartManager with configurable multipliers 2025-02-24 16:43:13 +01:00
dc7be36bdb Add player-only configuration to module managers 2025-02-24 15:51:39 +01:00
0b4883ed6c Make apply only to player option 2025-02-24 15:46:42 +01:00
446ef52012 Add IsObjectTank method with error handling to CykUtil 2025-02-24 15:41:54 +01:00
af0c47e9e5 Add CykUtil for checking player tank ownership 2025-02-24 15:37:42 +01:00
106afee250 Code format 2025-02-24 15:37:00 +01:00
d53a5bb6cc Fix wing and item producer module naming and patching 2025-02-24 15:06:42 +01:00
c23be11e4b Only apply booleans if they're true 2025-02-24 11:30:58 +01:00
c460a65234 Fix typos n shit 2025-02-24 11:20:51 +01:00
c441d3ad10 Fix booster cast 2025-02-24 10:47:34 +01:00
91e2bf4b61 Enhance MultipliedObjectManager with robust error handling and reference management 2025-02-24 10:44:07 +01:00
622094fbe9 Add ModuleWeaponManager for configurable weapon rotate speed 2025-02-24 10:18:42 +01:00
bdced22781 Add TankBeamManager for configurable tank beam settings 2025-02-24 10:17:37 +01:00
708607b2f5 Add ModuleWheelsManager for configurable wheel torque settings 2025-02-24 10:14:40 +01:00
dbeb55e2aa Add BooleanField for configurable boolean field settings 2025-02-24 10:10:34 +01:00
212c82b448 Add ModuleWeaponGunManager for configurable weapon gun settings 2025-02-24 10:08:22 +01:00
0c440a4876 Add ModuleRemoteChargerManager for configurable remote charger settings 2025-02-24 10:03:50 +01:00
bd554f4c0f Add ModuleItemProducerManager for configurable item producer settings 2025-02-24 10:02:41 +01:00
cda2f3a75c Update FieldConfiguration to support generic multiplier types 2025-02-24 09:59:03 +01:00
11c7d74489 Make both the multiplier and field generic 2025-02-24 09:57:36 +01:00
95fdbc7cda Add ModuleItemHolderManager for configurable item holder settings 2025-02-24 09:53:24 +01:00
551acd2690 Add ModuleGyroManager for configurable gyro active speed 2025-02-24 09:42:27 +01:00
e485f5b2d2 Remove redundant configuration variables and clean up commented code 2025-02-24 09:40:41 +01:00
f7f73a6891 Add ModuleEnergyStoreManager for configurable energy store capacity 2025-02-24 09:40:32 +01:00
a5fd22a9c5 Simplify configuration variable names across module managers 2025-02-24 09:38:32 +01:00
0f494e7ae1 Add ModuleEnergyManager for configurable energy module settings 2025-02-24 09:36:31 +01:00
e86c26a0d8 Code polish 2025-02-24 09:34:41 +01:00
f17ef5b559 Rename FireDataManager to ModuleWeaponGunManager 2025-02-24 09:34:02 +01:00
320c032e30 Add ModuleBoosterManager for configurable booster thrust multipliers 2025-02-24 09:33:27 +01:00
9718e254aa Refactor FireData configuration to FireDataManager 2025-02-24 09:26:10 +01:00
b69db2edc8 Refactor shield configuration to ModuleShieldGeneratorManager 2025-02-24 09:14:44 +01:00
255d563b86 Refactor settings to modulewingmanager 2025-02-24 09:13:05 +01:00
fe5b4084ff Add FireData configuration multipliers for kickback and muzzle velocity 2025-02-24 09:05:44 +01:00
ba6ebf6d07 Add aerofoil configuration multipliers and ModuleWingManager 2025-02-24 09:01:10 +01:00
4f695d907b Write out this shit for dotnet6 2025-02-24 08:48:45 +01:00
897f0a3546 Add shield healing radius multiplier configuration 2025-02-24 08:48:45 +01:00
edc8fd5a5b Enhance ObjectFieldMultiplier with flexible field configuration and selective application 2025-02-24 08:44:18 +01:00
13610a301a Fix multiplication in multiplier 2025-02-24 08:33:13 +01:00
e0b9bed690 Remove old shit 2025-02-24 08:30:46 +01:00
fd8ce5c59e Improve ObjectFieldMultiplier with naming conventions and documentation 2025-02-24 00:26:12 +01:00
c8302ea177 Refactor ObjectFieldMultiplier with code style improvements and minor optimizations 2025-02-24 00:24:49 +01:00
89a557dc96 Extract generic object field multiplier logic to separate file 2025-02-24 00:13:43 +01:00
741ab21977 Enhance ModuleShieldGeneratorManager with robust error handling and debug logging 2025-02-24 00:10:32 +01:00
336a4dfff7 Refactor ModuleShieldGeneratorManager with generic multiplied object management 2025-02-24 00:08:42 +01:00
a53bcc246e Refactor the fuck out of ModuleShieldGeneratorManager with generic multiplier handling 2025-02-24 00:06:04 +01:00
5df952a69a Add battery capacity multiplier configuration 2025-02-23 23:50:36 +01:00
4ad206a198 Add shield and energy module configuration multipliers 2025-02-23 23:46:44 +01:00
e16a941413 Add shop block multipliers 2025-02-23 18:15:17 +01:00
8c58bf504c "Fix" rotation speed maybe 2025-02-23 16:02:33 +01:00
b5d75ccffd Add rotation speed log patch 2025-02-23 15:44:18 +01:00
44c24e4ae7 Format 2025-02-23 15:40:05 +01:00
5e2b2546bf Update terratech 2025-02-23 15:31:57 +01:00
03c8043c77 Night raidering 2025-02-23 15:31:52 +01:00
a71a25226f More cheap train 2024-12-31 16:06:04 +01:00
cd104d142e Implement auto loot 2024-12-31 15:21:57 +01:00
983aaa68e6 Add night rider 2024-12-31 13:46:32 +01:00
3c7b9f7360 Add additional reverse engineer chance 2024-12-10 11:34:24 +01:00
80173da3b0 Implement reverse engineer chance multiplier 2024-12-10 11:30:57 +01:00
1c6dbb79e6 Update configuration manager and unity explorer 2024-12-10 11:30:50 +01:00
b24100c89b Add disassemble multiplier 2024-12-09 23:19:54 +01:00
b1ca039574 Reduce bonus attribute bonus 2024-12-09 21:11:02 +01:00
dd3c227447 Always get some skills please 2024-12-09 17:25:29 +01:00
dd515529f9 More better logging 2024-12-09 17:24:46 +01:00
6d468300a2 Add xp multiplier 2024-12-09 12:51:23 +01:00
f6bc2eff3f Add multipliers for fucking level up stats 2024-12-09 12:26:10 +01:00
490aa3bf2e Fix up the fuCKIGN versions 2024-12-09 11:45:41 +01:00
f5498cad02 Migrate back to whatever the fuck works (framework 481) 2024-12-09 11:30:32 +01:00
64 changed files with 2431 additions and 1498 deletions

4
.gitignore vendored
View File

@@ -6,3 +6,7 @@ ConfigurationManager
MelonLoader.Installer.exe
ConfigurationManager
Projects/Regiments/Regiments/obj/Release
Projects/CykaOfQud/.vs/
Projects/CykaOfQud/.vscode/

Binary file not shown.

Binary file not shown.

View File

@@ -1,49 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk">
<?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>
<GAME_DIR>C:/Games/Caves.of.Qud.Build.16668101</GAME_DIR>
<GAME_MANAGED>$(GAME_DIR)/CoQ_Data/Managed</GAME_MANAGED>
<GAME_BEPINEX>$(GAME_DIR)/BepInEx</GAME_BEPINEX>
<TargetFramework>net8.0</TargetFramework>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CykaOfQud</RootNamespace>
<AssemblyName>CykaOfQud</AssemblyName>
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>
<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'">
<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="Patches.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>$(GAME_BEPINEX)/core/0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="BepInEx">
<HintPath>$(GAME_BEPINEX)/core/BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine">
<HintPath>$(GAME_MANAGED)/UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(GAME_MANAGED)/UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="XRL">
<HintPath>$(GAME_MANAGED)/Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using HarmonyLib.Tools;
// To make harmony work I had to hack t he game apart a little
// The game by default does not like harmony mods and unpatches all methods when running
// So to stop it from doing this remove calls to:
// System.Void XRL.ModInfo::UnapplyHarmonyPatches()
namespace CykaOfQud {
[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
public class Main : BaseUnityPlugin {
@@ -13,79 +15,37 @@ namespace CykaOfQud {
private const string pluginName = "CykaOfQud";
private const string pluginVersion = "1.0.0";
public static ConfigEntry<float> xpPerLevelMultiplier;
public static ConfigEntry<float> xpMultiplier;
public static ConfigEntry<float> hitpointsPerLevelMultiplier;
public static ConfigEntry<float> skillPointsPerLevelMultiplier;
public static ConfigEntry<float> mutationPointsPerLevelMultiplier;
public static ConfigEntry<float> attributePointsPerLevelMultiplier;
public static ConfigEntry<float> attributeBonusPerLevelMultiplier;
public static ConfigEntry<float> disassemblyBonusMultiplier;
// public static ConfigEntry<float> excavatorMineTileIterationsMultiplier;
// public static ConfigEntry<int> truckCapacityMultiplier;
// public static ConfigEntry<int> cargoShipCapacityMultiplier;
// public static ConfigEntry<float> excavatorMiningCapacityMultiplier;
// public static ConfigEntry<int> excavatorMiningAreaMultiplier;
// public static ConfigEntry<float> excavatorMinReachMultiplier;
// public static ConfigEntry<float> excavatorMaxReachMultiplier;
// public static ConfigEntry<float> bufferCapacityMultiplier;
// public static ConfigEntry<float> unityGenerationMultiplier;
// public static ConfigEntry<float> depotTransferSpeedMultiplier;
// public static ConfigEntry<float> worldMineSpeedMultiplier;
// public static ConfigEntry<float> housingCapacityMultiplier;
// public static ConfigEntry<float> dumpDelayMultiplier;
// public static ConfigEntry<float> transportSpeedMultiplier;
// public static ConfigEntry<float> shipyardCargoMultiplier;
// public static ConfigEntry<int> autosaveInterval;
// public static ConfigEntry<string> recipeMultipliers;
// public static Dictionary<string, int> recipeMultipliersDict;
public static ConfigEntry<float> reverseEngineerChanceMultiplier;
public static ConfigEntry<int> reverseEngineerChanceAdditional;
public static ConfigEntry<bool> debugMode;
public void Awake() {
xpPerLevelMultiplier = Config.Bind("General", "XP Per Level Multiplier", 1f,
new ConfigDescription("XP Per Level Multiplier"));
// excavatorCapacityMultiplier = Config.Bind("General", "Excavator Capacity Multiplier", 1,
// new ConfigDescription("Excavator Capacity Multiplier"));
// excavatorMineTileIterationsMultiplier = Config.Bind("General", "Excavator Mine Tile Iterations Multiplier",
// 1f,
// new ConfigDescription("Excavator Mine Tile Iterations Multiplier"));
// truckCapacityMultiplier = Config.Bind("General", "Truck Capacity Multiplier", 1,
// new ConfigDescription("Truck Capacity Multiplier"));
// cargoShipCapacityMultiplier = Config.Bind("General", "Cargo Ship Capacity Multiplier", 1,
// new ConfigDescription("Cargo Ship Capacity Multiplier"));
// excavatorMiningAreaMultiplier = Config.Bind("General", "Excavator Mining Area Multiplier", 1,
// new ConfigDescription("Excavator Mining Area Multiplier"));
// excavatorMiningCapacityMultiplier = Config.Bind("General", "Excavator Mining Capacity Multiplier", 1f,
// new ConfigDescription("Excavator Mining Capacity Multiplier"));
// excavatorMinReachMultiplier = Config.Bind("General", "Excavator Min Reach Multiplier", 1f,
// new ConfigDescription("Excavator Min Reach Multiplier"));
// excavatorMaxReachMultiplier = Config.Bind("General", "Excavator Max Reach Multiplier", 1f,
// new ConfigDescription("Excavator Max Reach Multiplier"));
// bufferCapacityMultiplier = Config.Bind("General", "Buffer Capacity Multiplier", 1f,
// new ConfigDescription("Buffer Capacity Multiplier"));
// unityGenerationMultiplier = Config.Bind("General", "Unity Generation Multiplier", 1f,
// new ConfigDescription("Unity Generation Multiplier"));
// depotTransferSpeedMultiplier = Config.Bind("General", "Depot Transfer Speed Multiplier", 1f,
// new ConfigDescription("Depot Transfer Speed Multiplier"));
// worldMineSpeedMultiplier = Config.Bind("General", "World Mine Speed Multiplier", 1f,
// new ConfigDescription("World Mine Speed Multiplier"));
// housingCapacityMultiplier = Config.Bind("General", "Housing Capacity Multiplier", 1f,
// new ConfigDescription("Housing Capacity Multiplier"));
// dumpDelayMultiplier = Config.Bind("General", "Dump Delay Multiplier", 1f,
// new ConfigDescription("Dump Delay Multiplier"));
// transportSpeedMultiplier = Config.Bind("General", "Transport Speed Multiplier", 1f,
// new ConfigDescription("Transport Speed Multiplier"));
// shipyardCargoMultiplier = Config.Bind("General", "Shipyard Cargo Multiplier", 1f,
// new ConfigDescription("Shipyard Cargo Multiplier"));
// autosaveInterval = Config.Bind("General", "Autosave Interval", 1,
// new ConfigDescription("Autosave Interval in minutes"));
// recipeMultipliers = Config.Bind("General", "Recipe Multipliers", "dirt:4",
// new ConfigDescription("Recipe Multipliers"));
// recipeMultipliersDict = recipeMultipliers.Value.Split(',')
// .ToDictionary(x => x.Split(':')[0], x => int.Parse(x.Split(':')[1]));
// recipeMultipliers.SettingChanged += (sender, args) => {
// recipeMultipliersDict = recipeMultipliers.Value.Split(',')
// .ToDictionary(x => x.Split(':')[0], x => int.Parse(x.Split(':')[1]));
// Console.WriteLine("IndustrialCyka: Recipe multipliers parsed as:");
// foreach (var kvp in recipeMultipliersDict)
// Console.WriteLine("\tIndustrialCyka: {0} x {1}", kvp.Key, kvp.Value);
// };
xpMultiplier = Config.Bind("General", "XP Multiplier", 4f, new ConfigDescription("XP Multiplier"));
hitpointsPerLevelMultiplier = Config.Bind("General", "Hitpoints Per Level Multiplier", 1f,
new ConfigDescription("Hitpoints Per Level Multiplier"));
skillPointsPerLevelMultiplier = Config.Bind("General", "Skill Points Per Level Multiplier", 1f,
new ConfigDescription("Skill Points Per Level Multiplier"));
mutationPointsPerLevelMultiplier = Config.Bind("General", "Mutation Points Per Level Multiplier", 1f,
new ConfigDescription("Mutation Points Per Level Multiplier"));
attributePointsPerLevelMultiplier = Config.Bind("General", "Attribute Points Per Level Multiplier", 1f,
new ConfigDescription("Attribute Points Per Level Multiplier"));
attributeBonusPerLevelMultiplier = Config.Bind("General", "Attribute Bonus Per Level Multiplier", 1f,
new ConfigDescription("Attribute Bonus Per Level Multiplier"));
disassemblyBonusMultiplier = Config.Bind("General", "Disassembly Bonus Multiplier", 1f,
new ConfigDescription("Disassembly Bonus Multiplier"));
reverseEngineerChanceMultiplier = Config.Bind("General", "Reverse Engineer Chance Multiplier", 1f,
new ConfigDescription("Reverse Engineer Chance Multiplier"));
reverseEngineerChanceAdditional = Config.Bind("General", "Reverse Engineer Chance Additional", 0,
new ConfigDescription("Reverse Engineer Chance Additional"));
debugMode = Config.Bind("General", "Debug Mode", false, new ConfigDescription("Debug Mode"));

View File

@@ -1,4 +1,10 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/Environment/Hierarchy/Build/BuildTool/AutoDownloadSdk/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue">C:\Users\Administrator\scoop\apps\dotnet-sdk\current\dotnet.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsBuildSolutionLoadingNodeCount/@EntryValue">16</s:Int64>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Users\Administrator\scoop\apps\vsbuildtools2019\16.11.40\vs\MSBuild\Current\Bin\MSBuild.exe</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">1048576</s:Int64>
<s:Boolean x:Key="/Default/Environment/Hierarchy/Build/BuildTool/RecentBuildToolPaths/=C_003A_005CUsers_005CAdministrator_005Cscoop_005Capps_005Cvsbuildtools2019_005Ccurrent_005Cvs_005CMSBuild_005CCurrent_005CBin_005Camd64_005CMSBuild_002Eexe/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>

View File

@@ -1,624 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using CykaOfQud;
using HarmonyLib;
//using Mafi;
//using Mafi.Collections.ImmutableCollections;
//using Mafi.Core;
//using Mafi.Core.Buildings.Cargo.Modules;
//using Mafi.Core.Buildings.Cargo.Ships.Modules;
//using Mafi.Core.Buildings.Settlements;
//using Mafi.Core.Buildings.Shipyard;
//using Mafi.Core.Buildings.Storages;
//using Mafi.Core.Entities;
//using Mafi.Core.Entities.Dynamic;
//using Mafi.Core.Entities.Static;
//using Mafi.Core.Entities.Static.Layout;
//using Mafi.Core.Factory.Machines;
//using Mafi.Core.Factory.Recipes;
//using Mafi.Core.Factory.Transports;
//using Mafi.Core.Population;
//using Mafi.Core.Ports.Io;
//using Mafi.Core.Products;
//using Mafi.Core.Prototypes;
//using Mafi.Core.SaveGame;
//using Mafi.Core.Terrain;
//using Mafi.Core.Vehicles.Excavators;
//using Mafi.Core.World.Entities;
using XRL.World;
namespace CykaOfIndustry {
[HarmonyPatch]
public class Patches {
[HarmonyPostfix]
[HarmonyPatch(typeof(XRL.World.Parts.Leveler), "GetXPForLevel")]
static int xpPerLevelMultiplier(ref int __result) {
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.Experience), "HandleEvent")]
static void xpMultiplier(ref AwardedXPEvent E) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: Old XP for level {0}", __result);
__result = (int)(__result * Main.xpPerLevelMultiplier.Value);
Console.WriteLine("CykaOfQud: AwardedXPEvent: Old XP {0}", E.Amount);
E.Amount = (int)(E.Amount * Main.xpMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: New XP for level {0}", __result);
return __result;
Console.WriteLine("CykaOfQud: AwardedXPEvent: New XP {0}", E.Amount);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddHitpoints")]
static void hitpointsPerLevelMultiplier(StringBuilder sb, ref int HPGain) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddHitpoints: Old HP for level {0}", HPGain);
if (HPGain == 0)
HPGain = 1;
HPGain = (int)(HPGain * Main.hitpointsPerLevelMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddHitpoints: New HP for level {0}", HPGain);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddSkillPoints")]
static void skillPointsPerLevelMultiplier(StringBuilder sb, ref int SPGain) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddSkillPoints: Old SP for level {0}", SPGain);
if (SPGain == 0)
SPGain = 1;
SPGain = (int)(SPGain * Main.skillPointsPerLevelMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddSkillPoints: New SP for level {0}", SPGain);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddMutationPoints")]
static void mutationPointsPerLevelMultiplier(StringBuilder sb, ref int MPGain) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddMutationPoints: Old MP for level {0}", MPGain);
if (MPGain == 0)
MPGain = 1;
MPGain = (int)(MPGain * Main.mutationPointsPerLevelMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddMutationPoints: New MP for level {0}", MPGain);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddAttributePoints")]
static void attributePointsPerLevelMultiplier(StringBuilder sb, ref int APGain) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddAttributePoints: Old AP for level {0}", APGain);
if (APGain == 0)
APGain = 1;
APGain = (int)(APGain * Main.attributePointsPerLevelMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddAttributePoints: New AP for level {0}", APGain);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddAttributeBonus")]
static void attributeBonusPerLevelMultiplier(StringBuilder sb, ref int ABGain) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddAttributeBonus: Old AB for level {0}", ABGain);
ABGain = (int)(ABGain * Main.attributeBonusPerLevelMultiplier.Value);
if (ABGain == 0)
ABGain = 2;
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddAttributeBonus: New AB for level {0}", ABGain);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(XRL.World.Parts.BitLocker), "AddBits")]
static void disassemblyBonusMultiplier(ref string Bits) {
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddBits: Old {0}", Bits);
StringBuilder output = new StringBuilder();
foreach (char c in Bits) {
output.Append(new string(c, (int)Math.Ceiling(Main.disassemblyBonusMultiplier.Value)));
}
Bits = output.ToString();
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: AddBits: New {0}", Bits);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GetTinkeringBonusEvent), nameof(GetTinkeringBonusEvent.GetFor),
new Type[] {
typeof(GameObject), typeof(GameObject), typeof(string), typeof(int), typeof(int), typeof(int),
typeof(bool), typeof(bool), typeof(bool), typeof(bool)
},
new ArgumentType[] {
ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal,
ArgumentType.Out, ArgumentType.Out, ArgumentType.Out, ArgumentType.Normal, ArgumentType.Normal
})]
static void reverseEngineerChanceMultiplier(GameObject Actor, GameObject Item, string Type, int BaseRating,
int Bonus, ref int SecondaryBonus, ref bool Interrupt, ref bool PsychometryApplied, bool Interruptable,
bool ForSifrah, ref int __result) {
if (Main.debugMode.Value)
Console.WriteLine(
"CykaOfQud: GetFor: Actor {0} Item {1} Type {2} BaseRating {3} Bonus {4} SecondaryBonus {5} Interrupt {6} PsychometryApplied {7} Interruptable {8} ForSifrah {9} Result {10}",
Actor.ID, Item.ID, Type, BaseRating, Bonus, SecondaryBonus, Interrupt, PsychometryApplied,
Interruptable, ForSifrah, __result);
__result = (int)(__result * Main.reverseEngineerChanceMultiplier.Value);
__result += Main.reverseEngineerChanceAdditional.Value;
if (__result > 100)
__result = 100;
if (Main.debugMode.Value)
Console.WriteLine("CykaOfQud: GetFor: New Result {0}", __result);
}
}
// [HarmonyPrefix]
// [HarmonyPatch(typeof(ExcavatorProtoBuilder.ExcavatorProtoBuilderState), "SetMinedThicknessByDistanceMeters")]
// static void excavatorMiningAreaMultiplier(ref float[] thicknessMeters) {
// for (int i = 0; i < thicknessMeters.Length; i++) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old mining area {0}", thicknessMeters[i]);
// thicknessMeters[i] *= Main.excavatorMiningCapacityMultiplier.Value;
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New mining area {0}", thicknessMeters[i]);
// }
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(ExcavatorProtoBuilder.ExcavatorProtoBuilderState), "SetMaxMiningDistance")]
// static void excavatorReachMultiplier(ref RelTile1i minMiningDistance, ref RelTile1i maxMiningDistance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old min mining distance {0}, max mining distance {1}",
// minMiningDistance, maxMiningDistance);
// minMiningDistance = new RelTile1i((int)(minMiningDistance.Value * Main.excavatorMinReachMultiplier.Value));
// maxMiningDistance = new RelTile1i((int)(maxMiningDistance.Value * Main.excavatorMaxReachMultiplier.Value));
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New min mining distance {0}, max mining distance {1}",
// minMiningDistance, maxMiningDistance);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(TruckProtoBuilder.TruckProtoBuilderState), "SetCapacity")]
// static void truckCapacityMultiplier(ref int quantity) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old truck capacity {0}", quantity);
// quantity *= Main.truckCapacityMultiplier.Value;
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New truck capacity {0}", quantity);
// }
//
// // [HarmonyPrefix]
// // [HarmonyPatch(typeof(StorageProtoBuilder.State), "SetCapacity")]
// // static void storageCapacityMultiplier(ref int capacity) {
//// // Console.WriteLine("IndustrialCyka: Old storage capacity: {0}", capacity);
// // capacity = (int)(capacity * Main.storageCapacityMultiplier.Value);
//// // Console.WriteLine("IndustrialCyka: New storage capacity: {0}", capacity);
// // }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(CargoShipModuleProto), MethodType.Constructor,
// new[] {
// typeof(Proto.ID), typeof(Proto.Str), typeof(ProductType), typeof(Quantity),
// typeof(CargoShipModuleProto.Gfx)
// })]
// static void cargoShipCapacityMultiplier(CargoShipModuleProto __instance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old ship capacity {0}", __instance.Capacity);
// __instance.Capacity = new Quantity(__instance.Capacity.Value * Main.cargoShipCapacityMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New ship capacity {0}", __instance.Capacity);
// }
//
// // No workey... idk how it's supposed to work, speed is always 1 or 100%
// // [HarmonyPrefix]
// // [HarmonyPatch(typeof(DrivingEntity), "SetSpeedFactor")]
// // static void vehicleSpeedMultiplier(ref Percent speedFactor) {
//// // Console.WriteLine("IndustrialCyka: Old speed: {0}", speedFactor.ToString());
// // // typeof(Percent)
// // // .GetField("RawValue",BindingFlags.Instance|BindingFlags.NonPublic)
// // // .SetValue(speedFactor,speedFactor.ToFloat() / Main.vehicleSpeedMultiplier.Value);
// // Percent newSpeedFactor = Percent.FromFloat(speedFactor.ToFloat() / Main.vehicleSpeedMultiplier.Value);
// // speedFactor = newSpeedFactor;
//// // Console.WriteLine("IndustrialCyka: New speed: {1}", newSpeedFactor.RawValue.ToString());
// // }
//
//// [HarmonyPostfix]
//// [HarmonyPatch(typeof(SmoothDriver), "SetSpeedFactor")]
//// static void vehicleSpeedMultiplier(SmoothDriver __instance) {
//// Fix32 speedMulti = Fix32.FromFloat(Main.vehicleSpeedMultiplier.Value);
////
//// Traverse traverse = Traverse.Create(__instance);
//// Traverse maxForwardsSpeedField = traverse.Field("m_maxForwardsSpeed");
//// Traverse maxBackwardsSpeedField = traverse.Field("m_maxBackwardsSpeed");
//// Traverse maxAccelerationField = traverse.Field("m_maxAcceleration");
////
//// // Console.WriteLine("IndustrialCyka: Old speeds: (F) {0}, (B) {1}, (A) {2}", maxForwardsSpeedField.GetValue(),
//// // maxBackwardsSpeedField.GetValue(), maxAccelerationField.GetValue());
////
//// maxForwardsSpeedField.SetValue((Fix32)maxForwardsSpeedField.GetValue() * speedMulti);
//// maxBackwardsSpeedField.SetValue((Fix32)maxBackwardsSpeedField.GetValue() * speedMulti);
//// maxAccelerationField.SetValue((Fix32)maxAccelerationField.GetValue() * speedMulti);
////
//// // Console.WriteLine("IndustrialCyka: New speeds: (F) {0}, (B) {1}, (A) {2}", maxForwardsSpeedField.GetValue(),
//// // maxBackwardsSpeedField.GetValue(), maxAccelerationField.GetValue());
//// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(StorageBaseProto), MethodType.Constructor,
// new[] {
// typeof(StaticEntityProto.ID),
// typeof(Proto.Str),
// typeof(EntityLayout),
// typeof(Quantity),
// typeof(EntityCosts),
// typeof(LayoutEntityProto.Gfx),
// typeof(Quantity),
// typeof(Duration),
// typeof(IEnumerable<Tag>)
// })]
// static void storageCapacityMultiplier(StorageProto __instance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old storage capacity {0}", __instance.Capacity);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old storage transfer limit {0}", __instance.TransferLimit);
// Traverse traverse = Traverse.Create(__instance);
//
// traverse.Field("Capacity")
// .SetValue(new Quantity((int)(__instance.Capacity.Value * Main.storageCapacityMultiplier.Value)));
// traverse.Field("TransferLimit").SetValue(new Quantity(10000));
// traverse.Field("TransferLimitDuration").SetValue(Duration.FromTicks(1));
//
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New storage capacity {0}", __instance.Capacity);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New storage transfer limit {0}", __instance.TransferLimit);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(UpointsManager), "GenerateUnity")]
// static void unityGenerationMultiplier(Proto.ID categoryId, ref Upoints generated) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old generated {0} unity", generated.Value);
// Fix32 multi = Fix32.FromFloat(Main.unityGenerationMultiplier.Value);
// generated = new Upoints(generated.Value * multi);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New generated {0} unity", generated.Value);
// }
//
// [HarmonyTranspiler]
// [HarmonyPatch(typeof(Machine), "updateWorkOnRecipes")]
// static IEnumerable<CodeInstruction> unityBooster(IEnumerable<CodeInstruction> instructions) {
// Dictionary<int, OpCode> matchTable = new Dictionary<int, OpCode>();
// matchTable[0] = OpCodes.Ldsfld;
// matchTable[1] = OpCodes.Br;
// matchTable[2] = OpCodes.Ldc_I4_2;
// int matches = 0;
// int totalMatch = matchTable.Count;
//
// var codes = new List<CodeInstruction>(instructions);
// for (int i = 0; i < codes.Count; i++) {
// if (matches >= totalMatch) {
// break;
// }
//
// if (codes[i].opcode.Equals(matchTable[matches])) {
// if (matches == totalMatch - 1) {
// codes[i].opcode = OpCodes.Ldc_I4_6;
// }
//
// matches++;
// }
// }
//
// // for (int i = 0; i < codes.Count; i++) {
// // Console.WriteLine(codes[i].ToString());
// // }
//
// return codes.AsEnumerable();
// }
//
// // Could not make this work either... idk why... Doesn't make sense...
// // [HarmonyPostfix]
// // [HarmonyPatch(typeof(SimpleVirtualResource), "MineResourceAt")]
// // static void infiniteGroundResources(SimpleVirtualResource __instance) {
//// // Console.WriteLine("IndustrialCyka: Patching ground resources (Capacity)");
// // Traverse traverse = Traverse.Create(__instance);
// // Traverse capacityField = traverse.Field("Capacity");
// // capacityField.SetValue(1000000000);
// // Traverse quantityField = traverse.Field("Quantity");
// // quantityField.SetValue(1000000000);
// // }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(ProductBuffer), "ForceNewCapacityTo")]
// static void bufferCapacityMultiplier(ref Quantity newCapacity) {
// if (newCapacity.Value <= 0) {
// return;
// }
//
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old buffer capacity {0}", newCapacity);
// Quantity newNewCapacity = new Quantity((int)(newCapacity.Value * Main.bufferCapacityMultiplier.Value));
// newCapacity = newNewCapacity;
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New buffer capacity {0}", newCapacity);
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(CargoDepotModuleProto), MethodType.Constructor,
// new[] {
// typeof(CargoDepotModuleProto.ID),
// typeof(Proto.Str),
// typeof(EntityLayout),
// typeof(ProductType),
// typeof(Option<CargoDepotModuleProto>),
// typeof(Quantity),
// typeof(Quantity),
// typeof(Duration),
// typeof(Electricity),
// typeof(bool),
// typeof(Percent),
// typeof(EntityCosts),
// typeof(CargoDepotModuleProto.Gfx),
// typeof(IEnumerable<Tag>),
// })]
// static void depotTransferSpeedMultiplier(CargoDepotModuleProto __instance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old depot transfer speed {0}", __instance.QuantityPerExchange);
// Traverse traverse = Traverse.Create(__instance);
//
// traverse.Field("QuantityPerExchange")
// .SetValue(new Quantity((int)(__instance.QuantityPerExchange.Value *
// Main.depotTransferSpeedMultiplier.Value)));
//
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New depot transfer speed {0}", __instance.QuantityPerExchange);
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
// new[] {
// typeof(EntityProto.ID),
// typeof(Proto.Str),
// typeof(ProductQuantity),
// typeof(Duration),
// typeof(Upoints),
// typeof(UpointsCategoryProto),
// typeof(EntityCosts),
// typeof(Func<int, EntityCosts>),
// typeof(int),
// typeof(Quantity),
// typeof(WorldMapEntityProto.Gfx),
// typeof(int),
// typeof(int),
// typeof(IEnumerable<Tag>),
// })]
// static void worldMineSpeedMultiplier(WorldMapMineProto __instance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old world mine speed {0}",
// __instance.ProducedProductPerStep.Quantity);
// ProductQuantity newProductQuantity = new ProductQuantity(__instance.ProducedProductPerStep.Product,
// new Quantity((int)(__instance.ProducedProductPerStep.Quantity.Value *
// Main.worldMineSpeedMultiplier.Value)));
//
// Traverse.Create(__instance)
// .Field("ProducedProductPerStep")
// .SetValue(newProductQuantity);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New world mine speed {0}",
// __instance.ProducedProductPerStep.Quantity);
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
// new[] {
// typeof(EntityProto.ID),
// typeof(Proto.Str),
// typeof(ProductQuantity),
// typeof(Duration),
// typeof(Upoints),
// typeof(UpointsCategoryProto),
// typeof(EntityCosts),
// typeof(Func<int, EntityCosts>),
// typeof(int),
// typeof(Quantity),
// typeof(WorldMapEntityProto.Gfx),
// typeof(int),
// typeof(int),
// typeof(IEnumerable<Tag>),
// })]
// static void worldMineLevelIncrementMultiplier(WorldMapMineProto __instance) {
// Traverse traverse = Traverse.Create(__instance);
//
// // int level = traverse.Field("Level").GetValue<int>();
// int maxLevel = traverse.Field("MaxLevel").GetValue<int>();
// // int levelsPerUpgrade = traverse.Field("LevelsPerUpgrade").GetValue<int>();
//
// int newLevelsPerUpgrade = 10;
// int newMaxLevel = (int)Math.Ceiling((double)maxLevel / newLevelsPerUpgrade) * newLevelsPerUpgrade;
//
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old max level {0}, new max level {1}", maxLevel, newMaxLevel);
// traverse.Field("MaxLevel").SetValue(newMaxLevel);
// traverse.Field("LevelsPerUpgrade").SetValue(newLevelsPerUpgrade);
// }
//
// [HarmonyTranspiler]
// [HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
// new[] {
// typeof(EntityProto.ID),
// typeof(Proto.Str),
// typeof(ProductQuantity),
// typeof(Duration),
// typeof(Upoints),
// typeof(UpointsCategoryProto),
// typeof(EntityCosts),
// typeof(Func<int, EntityCosts>),
// typeof(int),
// typeof(Quantity),
// typeof(WorldMapEntityProto.Gfx),
// typeof(int),
// typeof(int),
// typeof(IEnumerable<Tag>),
// })]
// static IEnumerable<CodeInstruction> cookWorldMineLevelIncrementMultiplier(
// IEnumerable<CodeInstruction> instructions) {
// Dictionary<int, OpCode> matchTable = new Dictionary<int, OpCode>();
// matchTable[0] = OpCodes.Rem;
// matchTable[1] = OpCodes.Ldfld;
// matchTable[2] = OpCodes.Ldarg_0;
// matchTable[3] = OpCodes.Ldfld;
// matchTable[4] = OpCodes.Ldarg_0;
// int matches = 0;
// int totalMatch = matchTable.Count;
//
// var codes = new List<CodeInstruction>(instructions);
// for (int i = codes.Count - 1; i >= 0; i--) {
// if (matches >= totalMatch) {
// break;
// }
//
// if (codes[i].opcode.Equals(matchTable[matches])) {
// if (matches == totalMatch - 1) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Patching world mine level increment");
// codes[i + 4].opcode = OpCodes.Add;
// codes[i + 5].opcode = OpCodes.Brtrue_S;
// break;
// }
//
// matches++;
// }
// else {
// matches = 0;
// }
// }
//
// return codes.AsEnumerable();
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(SettlementHousingModuleProto), MethodType.Constructor, new[] {
// typeof(StaticEntityProto.ID),
// typeof(Proto.Str),
// typeof(EntityLayout),
// typeof(EntityCosts),
// typeof(int),
// typeof(Upoints),
// typeof(ImmutableArray<KeyValuePair<ImmutableArray<PopNeedProto>, Percent>>),
// typeof(IReadOnlyDictionary<PopNeedProto, Percent>),
// typeof(Option<SettlementHousingModuleProto>),
// typeof(SettlementHousingModuleProto.Gfx),
// })]
// static void housingCapacityMultiplier(SettlementHousingModuleProto __instance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old housing capacity {0}", __instance.Capacity);
// Traverse.Create(__instance).Field<int>("Capacity").Value =
// (int)(__instance.Capacity * Main.housingCapacityMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New housing capacity {0}", __instance.Capacity);
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(StackerProto), MethodType.Constructor, new[] {
// typeof(StaticEntityProto.ID),
// typeof(Proto.Str),
// typeof(EntityLayout),
// typeof(EntityCosts),
// typeof(Electricity),
// typeof(ThicknessTilesI),
// typeof(RelTile3i),
// typeof(Duration),
// typeof(Duration),
// typeof(StackerProto.Gfx),
// typeof(ThicknessTilesI),
// typeof(IEnumerable<Tag>),
// })]
// static void dumpDelayMultiplier(StackerProto __instance) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old dumpDelay {0}", __instance.DumpDelay);
// Duration newDelay =
// new Duration(Math.Max((int)(__instance.DumpDelay.Ticks * Main.dumpDelayMultiplier.Value), 1));
// Traverse.Create(__instance).Field("DumpDelay").SetValue(newDelay);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New dumpDelay {0}", __instance.DumpDelay);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(TransportProto), MethodType.Constructor, new[] {
// typeof(StaticEntityProto.ID),
// typeof(Proto.Str),
// typeof(ThicknessTilesF),
// typeof(Quantity),
// typeof(RelTile1f),
// typeof(RelTile1f),
// typeof(RelTile1i),
// typeof(bool),
// typeof(bool),
// typeof(Option<TerrainTileSurfaceProto>),
// typeof(RelTile1i),
// typeof(IoPortShapeProto),
// typeof(Electricity),
// typeof(Percent),
// typeof(bool),
// typeof(bool),
// typeof(EntityCosts),
// typeof(RelTile1i),
// typeof(Duration),
// typeof(Option<TransportProto>),
// typeof(VirtualProductProto),
// typeof(Quantity),
// typeof(TransportProto.Gfx),
// })]
// static void transportSpeedMultiplier(ref StaticEntityProto.ID id, ref Proto.Str strings,
// ref ThicknessTilesF surfaceRelativeHeight, ref Quantity maxQuantityPerTransportedProduct,
// ref RelTile1f transportedProductsSpacing, ref RelTile1f speedPerTick, ref RelTile1i zStepLength,
// ref bool needsPillarsAtGround, ref bool canBeBuried,
// ref Option<TerrainTileSurfaceProto> tileSurfaceWhenOnGround, ref RelTile1i maxPillarSupportRadius,
// ref IoPortShapeProto portsShape, ref Electricity baseElectricityCost, ref Percent cornersSharpnessPercent,
// ref bool allowMixedProducts, ref bool isBuildable, ref EntityCosts costs, ref RelTile1i lengthPerCost,
// ref Duration constructionDurationPerProduct, ref Option<TransportProto> nextTier,
// ref VirtualProductProto maintenanceProduct, Quantity maintenancePerTile, ref TransportProto.Gfx graphics) {
// if (TransportPillarProto.MAX_PILLAR_HEIGHT.Value < 25)
// typeof(TransportPillarProto).GetField("MAX_PILLAR_HEIGHT").SetValue(null, new ThicknessTilesI(25));
// if (IoPort.MAX_TRANSFER_PER_TICK.Value < 10000)
// typeof(IoPort).GetField("MAX_TRANSFER_PER_TICK").SetValue(null, new Quantity(10000));
//
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Old maxQuantityPerTransportedProduct {0}",
// maxQuantityPerTransportedProduct);
// maxQuantityPerTransportedProduct *= 1000;
// maxQuantityPerTransportedProduct = maxQuantityPerTransportedProduct.Min(new Quantity(10000));
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: New maxQuantityPerTransportedProduct {0}",
// maxQuantityPerTransportedProduct);
//
// speedPerTick *= 10;
// transportedProductsSpacing = speedPerTick;
// zStepLength = RelTile1i.One;
// canBeBuried = true;
// maxPillarSupportRadius = new RelTile1i(8);
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(ShipyardProto), MethodType.Constructor, new[] {
// typeof(StaticEntityProto.ID),
// typeof(Proto.Str),
// typeof(EntityLayout),
// typeof(EntityCosts),
// typeof(bool),
// typeof(Quantity),
// typeof(Option<ShipyardProto>),
// typeof(ImmutableArray<ImmutableArray<RectangleTerrainArea2iRelative>>),
// typeof(StackerProto.Gfx),
// typeof(ImmutableArray<String>),
// typeof(bool),
// })]
// static void shipyardCargoMultiplier(ShipyardProto __instance) {
// Traverse.Create(__instance).Field("CargoCapacity").SetValue(new Quantity(
// (int)(__instance.CargoCapacity.Value * Main.shipyardCargoMultiplier.Value)));
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(SaveManager), "isTimeForAutoSave")]
// static void autosaveInterval(ref bool __result, SaveManager __instance) {
// if (Main.autosaveInterval.Value <= 0) {
// __result = false;
// return;
// }
//
// var trav = Traverse.Create(__instance);
// var lastSaveTime = trav.Field("m_lastSaveTime").GetValue<long>();
// var num = (Environment.TickCount - lastSaveTime).Abs() / 1000L;
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Autosave interval: {0}", num);
// __result = num > Main.autosaveInterval.Value;
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(MachineProto), nameof(MachineProto.AddRecipe))]
// static void machineProtoAddRecipe(MachineProto __instance, ref RecipeProto recipe) {
// Console.WriteLine("Recipe outputs for {0}:", __instance.Id);
// recipe.AllOutputs.ForEach(o => {
// var id = o.Product.Id.ToString();
// Console.WriteLine("\tIndustrialCyka: Recipe output {0} x {1}", id, o.Quantity);
// if (!Main.recipeMultipliersDict.ContainsKey(id)) {
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Recipe output {0} not found in multipliers, nothing to do", id);
// return;
// }
// var multiplier = Main.recipeMultipliersDict[id];
// var trav = Traverse.Create(o);
// trav.Field("Quantity").SetValue(new Quantity(trav.Field("Quantity").GetValue<Quantity>().Value * multiplier));
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Recipe output {0} changed to {1}", id, trav.Field("Quantity").GetValue<Quantity>());
// });
// }
// }
//
// [HarmonyPatch(typeof(Excavator), "MineMixedAt")]
// public class MineMixedAtPatch {
// public static Dictionary<ExcavatorProto, Quantity>
// originalCapacity = new Dictionary<ExcavatorProto, Quantity>();
//
// public static Dictionary<ExcavatorProto, ImmutableArray<ThicknessTilesF>> originalMinedThicknessByDistance =
// new Dictionary<ExcavatorProto, ImmutableArray<ThicknessTilesF>>();
//
// public static Dictionary<ExcavatorProto.Timings, int> originalMineTileIterations =
// new Dictionary<ExcavatorProto.Timings, int>();
//
// public static Dictionary<ExcavatorProto, RelTile1i> originalMaxMiningDistance =
// new Dictionary<ExcavatorProto, RelTile1i>();
//
// static void Prefix(ref Excavator __instance) {
// if (!originalCapacity.ContainsKey(__instance.Prototype)) {
// originalCapacity.Add(__instance.Prototype, __instance.Prototype.Capacity);
// }
//
// var trav = Traverse.Create(__instance.Prototype);
// trav.Field("Capacity")
// .SetValue(new Quantity(originalCapacity[__instance.Prototype].Value *
// Main.excavatorCapacityMultiplier.Value));
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Excavator capacity: {0}", __instance.Prototype.Capacity.Value);
//
// if (!originalMinedThicknessByDistance.ContainsKey(__instance.Prototype)) {
// originalMinedThicknessByDistance.Add(__instance.Prototype,
// trav.Field("MinedThicknessByDistance").GetValue<ImmutableArray<ThicknessTilesF>>());
// }
//
// trav.Field("MinedThicknessByDistance")
// .SetValue(originalMinedThicknessByDistance[__instance.Prototype]
// .SelectMany(t => Enumerable.Repeat(t, Main.excavatorMiningAreaMultiplier.Value))
// .Select(t =>
// new ThicknessTilesF((int)(t.Value.ToFloat() * Main.excavatorMiningCapacityMultiplier.Value)))
// .ToImmutableArray());
// if (Main.debugMode.Value)
// originalMinedThicknessByDistance[__instance.Prototype].ForEach(t => Console.WriteLine(t.Value));
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Excavator mined thickness: {0}",
// __instance.Prototype.MinedThicknessByDistance);
//
// if (!originalMaxMiningDistance.ContainsKey(__instance.Prototype)) {
// originalMaxMiningDistance.Add(__instance.Prototype,
// trav.Field("MaxMiningDistance").GetValue<RelTile1i>());
// }
//
// var value = originalMaxMiningDistance[__instance.Prototype];
// var newValueMiningDistance = new RelTile1i((int)(value.Value * Main.excavatorMaxReachMultiplier.Value));
// trav.Field("MaxMiningDistance")
// .SetValue(newValueMiningDistance);
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Excavator max mining distance: {0}",
// __instance.Prototype.MaxMiningDistance);
//
// var trav2 = Traverse.Create(__instance.Prototype.MineTimings);
// if (!originalMineTileIterations.ContainsKey(__instance.Prototype.MineTimings)) {
// originalMineTileIterations.Add(__instance.Prototype.MineTimings,
// trav2.Field("MineTileIterations").GetValue<int>());
// }
//
// var newValue = (int)(originalMineTileIterations[__instance.Prototype.MineTimings] *
// Main.excavatorMineTileIterationsMultiplier.Value);
// trav2.Field("MineTileIterations").SetValue(newValue);
// trav2.Field("PrepareToMineDuration").SetValue(new Duration(1));
// trav2.Field("MineDuration").SetValue(new Duration(1));
// trav2.Field("PrepareToDumpDuration").SetValue(new Duration(1));
// trav2.Field("DumpDuration").SetValue(new Duration(1));
// if (Main.debugMode.Value)
// Console.WriteLine("IndustrialCyka: Excavator mine tile iterations 2: {0}",
// trav2.Field("MineTileIterations").GetValue<int>());
// }
// }
}

View 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("Regiments")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Regiments")]
[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("DA9D274E-486F-4F82-84FF-CD9388CB0B09")]
// 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")]

View File

@@ -1,6 +0,0 @@
{
"sdk": {
"version": "8.0.0",
"rollForward": "latestFeature"
}
}

View File

@@ -1 +1 @@
bin/Release/net8.0/CykaOfQud.dll,"C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll"
bin/Release/CykaOfQud.dll,"C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll"

View File

@@ -0,0 +1,3 @@
{
"dotnet.preferCSharpExtension": true
}

View File

@@ -0,0 +1,39 @@
using System.Linq;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using HarmonyLib.Tools;
namespace CykaRaider {
[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
public class Main : BaseUnityPlugin {
private const string pluginGuid = "CykaRaider";
private const string pluginName = "CykaRaider";
private const string pluginVersion = "1.0.0";
public static ConfigEntry<int> lootTimeAdder;
public static ConfigEntry<float> maxStackMultiplier;
public static ConfigEntry<bool> autoLoot;
public static ConfigEntry<float> upgradePriceMultiplier;
public static ConfigEntry<bool> debugMode;
public void Awake() {
debugMode = Config.Bind("General", "Debug Mode", false, new ConfigDescription("Debug Mode"));
lootTimeAdder = Config.Bind("General", "Loot Time Adder", 0, new ConfigDescription("Loot Time Adder"));
maxStackMultiplier = Config.Bind("General", "Max Stack Multiplier", 1f, new ConfigDescription("Max Stack Multiplier"));
autoLoot = Config.Bind("General", "Auto Loot", false, new ConfigDescription("Auto Loot"));
upgradePriceMultiplier = Config.Bind("General", "Upgrade Price Multiplier", 1f, new ConfigDescription("Upgrade Price Multiplier"));
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");
foreach (var method in originalMethods) {
Logger.LogInfo("Patched " + method.Name);
}
}
}
}

View File

@@ -0,0 +1,63 @@
<?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>
<GAME_DIR>C:/Games/NightRaider</GAME_DIR>
<GAME_MANAGED>$(GAME_DIR)/NightRaider_Data/Managed</GAME_MANAGED>
<GAME_BEPINEX>$(GAME_DIR)/BepInEx</GAME_BEPINEX>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CykaRaider</RootNamespace>
<AssemblyName>CykaRaider</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="Patches.cs" />
<Compile Include="Properties\AssemblyInfo.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="UnityEngine.UI">
<HintPath>$(GAME_MANAGED)/UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="XRL">
<HintPath>$(GAME_MANAGED)/Assembly-CSharp.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CykaRaider", "CykaRaider.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

View File

@@ -0,0 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/Environment/Hierarchy/Build/BuildTool/AutoDownloadSdk/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue">C:\Users\Administrator\scoop\apps\dotnet-sdk\current\dotnet.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsBuildSolutionLoadingNodeCount/@EntryValue">16</s:Int64>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">1048576</s:Int64>
<s:Boolean x:Key="/Default/Environment/Hierarchy/Build/BuildTool/RecentBuildToolPaths/=C_003A_005CUsers_005CAdministrator_005Cscoop_005Capps_005Cvsbuildtools2019_005Ccurrent_005Cvs_005CMSBuild_005CCurrent_005CBin_005Camd64_005CMSBuild_002Eexe/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -0,0 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/Environment/Hierarchy/Build/BuildTool/AutoDownloadSdk/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue">C:\Users\Administrator\scoop\apps\dotnet-sdk\current\dotnet.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsBuildSolutionLoadingNodeCount/@EntryValue">16</s:Int64>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">1048576</s:Int64>
<s:Boolean x:Key="/Default/Environment/Hierarchy/Build/BuildTool/RecentBuildToolPaths/=C_003A_005CUsers_005CAdministrator_005Cscoop_005Capps_005Cvsbuildtools2019_005Ccurrent_005Cvs_005CMSBuild_005CCurrent_005CBin_005Camd64_005CMSBuild_002Eexe/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -0,0 +1,210 @@
using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using HarmonyLib;
using UnityEngine.UI;
namespace CykaRaider
{
[HarmonyPatch]
public class Patches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(GameManager), "FixedUpdate")]
static void lootTimeAdder(GameManager __instance) {
var trav = Traverse.Create(__instance);
var lootTime = trav.Field("lootTime").GetValue<int>();
if (lootTime > 0) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: FixedUpdate: Old lootTime {0}", lootTime);
lootTime += Main.lootTimeAdder.Value;
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: FixedUpdate: New lootTime {0}", lootTime);
trav.Field("lootTime").SetValue(lootTime);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(DataHub), "GetFixedData")]
static void maxStackMultiplier(DataHub __instance) {
foreach (var itemData in __instance.itemDataDic) {
if (itemData.Value.maxStack > 0) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: GetFixedData: Old maxStack {0}", itemData.Value.maxStack);
itemData.Value.maxStack = (int)(itemData.Value.maxStack * Main.maxStackMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: GetFixedData: New maxStack {0}", itemData.Value.maxStack);
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MyBagControl), "GetAllButtonShow")]
static void autoLoot(MyBagControl __instance) {
if (Main.autoLoot.Value) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: autoLoot: AutoLoot is enabled");
var trav = Traverse.Create(__instance);
var button = trav.Field("getAll_BT").GetValue<Button>();
button.onClick.Invoke();
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: autoLoot: Button clicked");
__instance.BeClosed();
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: autoLoot: Bag closed");
}
}
[HarmonyPatch(typeof(NPCControl), "UpgradeSkill")]
public static class upgradePriceMultiplier {
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: upgradePriceMultiplier: Transpiler");
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++) {
// Does not work for -125k.... idk why... go fix....
if (codes[i].opcode == OpCodes.Ldc_I4 && ((int)codes[i].operand == 125000 || (int)codes[i].operand == -125000)) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: upgradePriceMultiplier: Old price {0}", codes[i].operand);
codes[i].operand = (int)((int)codes[i].operand * Main.upgradePriceMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: upgradePriceMultiplier: New price {0}", codes[i].operand);
}
}
return codes;
}
}
[HarmonyPatch(typeof(NPCControl), "RefreshSkill")]
public static class refreshSkillPriceMultiplier {
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: refreshSkillPriceMultiplier: Transpiler");
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++) {
if (codes[i].opcode == OpCodes.Ldc_I4 && ((int)codes[i].operand == 125000 || (int)codes[i].operand == -125000)) {
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: refreshSkillPriceMultiplier: Old price {0}", codes[i].operand);
codes[i].operand = (int)((int)codes[i].operand * Main.upgradePriceMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("CykaRaider: refreshSkillPriceMultiplier: New price {0}", codes[i].operand);
}
}
return codes;
}
}
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.Experience), "HandleEvent")]
// static void xpMultiplier(ref AwardedXPEvent E) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AwardedXPEvent: Old XP {0}", E.Amount);
// E.Amount = (int)(E.Amount * Main.xpMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AwardedXPEvent: New XP {0}", E.Amount);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddHitpoints")]
// static void hitpointsPerLevelMultiplier(StringBuilder sb, ref int HPGain) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddHitpoints: Old HP for level {0}", HPGain);
// if (HPGain == 0)
// HPGain = 1;
// HPGain = (int)(HPGain * Main.hitpointsPerLevelMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddHitpoints: New HP for level {0}", HPGain);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddSkillPoints")]
// static void skillPointsPerLevelMultiplier(StringBuilder sb, ref int SPGain) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddSkillPoints: Old SP for level {0}", SPGain);
// if (SPGain == 0)
// SPGain = 1;
// SPGain = (int)(SPGain * Main.skillPointsPerLevelMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddSkillPoints: New SP for level {0}", SPGain);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddMutationPoints")]
// static void mutationPointsPerLevelMultiplier(StringBuilder sb, ref int MPGain) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddMutationPoints: Old MP for level {0}", MPGain);
// if (MPGain == 0)
// MPGain = 1;
// MPGain = (int)(MPGain * Main.mutationPointsPerLevelMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddMutationPoints: New MP for level {0}", MPGain);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddAttributePoints")]
// static void attributePointsPerLevelMultiplier(StringBuilder sb, ref int APGain) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddAttributePoints: Old AP for level {0}", APGain);
// if (APGain == 0)
// APGain = 1;
// APGain = (int)(APGain * Main.attributePointsPerLevelMultiplier.Value);
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddAttributePoints: New AP for level {0}", APGain);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.Leveler), "AddAttributeBonus")]
// static void attributeBonusPerLevelMultiplier(StringBuilder sb, ref int ABGain) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddAttributeBonus: Old AB for level {0}", ABGain);
// ABGain = (int)(ABGain * Main.attributeBonusPerLevelMultiplier.Value);
// if (ABGain == 0)
// ABGain = 2;
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddAttributeBonus: New AB for level {0}", ABGain);
// }
//
// [HarmonyPrefix]
// [HarmonyPatch(typeof(XRL.World.Parts.BitLocker), "AddBits")]
// static void disassemblyBonusMultiplier(ref string Bits) {
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddBits: Old {0}", Bits);
//
// StringBuilder output = new StringBuilder();
// foreach (char c in Bits) {
// output.Append(new string(c, (int)Math.Ceiling(Main.disassemblyBonusMultiplier.Value)));
// }
//
// Bits = output.ToString();
//
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: AddBits: New {0}", Bits);
// }
//
// [HarmonyPostfix]
// [HarmonyPatch(typeof(GetTinkeringBonusEvent), nameof(GetTinkeringBonusEvent.GetFor),
// new Type[] {
// typeof(GameObject), typeof(GameObject), typeof(string), typeof(int), typeof(int), typeof(int),
// typeof(bool), typeof(bool), typeof(bool), typeof(bool)
// },
// new ArgumentType[] {
// ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal,
// ArgumentType.Out, ArgumentType.Out, ArgumentType.Out, ArgumentType.Normal, ArgumentType.Normal
// })]
// static void reverseEngineerChanceMultiplier(GameObject Actor, GameObject Item, string Type, int BaseRating,
// int Bonus, ref int SecondaryBonus, ref bool Interrupt, ref bool PsychometryApplied, bool Interruptable,
// bool ForSifrah, ref int __result) {
// if (Main.debugMode.Value)
// Console.WriteLine(
// "CykaRaider: GetFor: Actor {0} Item {1} Type {2} BaseRating {3} Bonus {4} SecondaryBonus {5} Interrupt {6} PsychometryApplied {7} Interruptable {8} ForSifrah {9} Result {10}",
// Actor.ID, Item.ID, Type, BaseRating, Bonus, SecondaryBonus, Interrupt, PsychometryApplied,
// Interruptable, ForSifrah, __result);
// __result = (int)(__result * Main.reverseEngineerChanceMultiplier.Value);
// __result += Main.reverseEngineerChanceAdditional.Value;
// if (__result > 100)
// __result = 100;
// if (Main.debugMode.Value)
// Console.WriteLine("CykaRaider: GetFor: New Result {0}", __result);
// }
// }
}
}

View 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("Regiments")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Regiments")]
[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("DA9D274E-486F-4F82-84FF-CD9388CB0B09")]
// 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")]

View File

@@ -0,0 +1 @@
bin/Release/CykaRaider.dll,"C:/Games/NightRaider/BepInEx/plugins/CykaRaider.dll"

View File

@@ -0,0 +1,3 @@
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 120

View File

@@ -5,7 +5,10 @@
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CConfigurationManager_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CUnityEngine_002ECoreModule_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CUnityEngine_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ABaseUnityPlugin_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F9185a461e2a54cd99ed3b83eace57b3d1f200_003F59_003Fb886ba39_003FBaseUnityPlugin_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATraverse_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F474744d65d8e460fa08cd5fd82b5d65f32000_003F24_003F10e7e9ab_003FTraverse_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue">&lt;AssemblyExplorer /&gt;</s:String>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">262144</s:Int64>
</wpf:ResourceDictionary>

View File

@@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class BeamPropertiesManager {
private static Dictionary<ModuleItemHolderBeam, float> strenghts = new Dictionary<ModuleItemHolderBeam, float>();
private static Dictionary<ModuleItemHolderBeam, float> radii = new Dictionary<ModuleItemHolderBeam, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnAttached")]
static void PostfixCreate(ModuleItemHolderBeam __instance) {
// Console.WriteLine("ModuleItemHolderBeam.OnAttached");
if (!strenghts.ContainsKey(__instance)) {
strenghts.Add(__instance, GetStrength(__instance));
radii.Add(__instance, GetRadius(__instance));
// Console.WriteLine("Patching {0}; m_BeamStrength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_BeamStrength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnDetaching")]
static void PostfixDestroy(ModuleItemHolderBeam __instance) {
// Console.WriteLine("ModuleItemHolderBeam.OnDetaching");
// Console.WriteLine("Restoring {0}; m_BeamStrength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_BeamStrength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
strenghts.Remove(__instance);
radii.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleItemHolderBeam", strenghts.Count);
foreach (KeyValuePair<ModuleItemHolderBeam, float> keyValuePair in strenghts) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleItemHolderBeam moduleItemHolderBeam) {
SetStrength(moduleItemHolderBeam, strenghts[moduleItemHolderBeam] * Main.beamStrenghtMultiplier.Value);
SetRadius(moduleItemHolderBeam, radii[moduleItemHolderBeam] * Main.beamRadiusMultiplier.Value);
}
static void DoRestoreSingle(ModuleItemHolderBeam moduleItemHolderBeam) {
if (strenghts.ContainsKey(moduleItemHolderBeam)) {
SetStrength(moduleItemHolderBeam, strenghts[moduleItemHolderBeam]);
SetRadius(moduleItemHolderBeam, radii[moduleItemHolderBeam]);
}
}
private static float GetStrength(ModuleItemHolderBeam moduleItemHolderBeam) {
return Traverse.Create(moduleItemHolderBeam).Field("m_BeamStrength").GetValue() as float? ?? 0f;
}
private static void SetStrength(ModuleItemHolderBeam moduleItemHolderBeam, float value) {
Traverse.Create(moduleItemHolderBeam).Field("m_BeamStrength").SetValue(value);
}
private static float GetRadius(ModuleItemHolderBeam moduleItemHolderBeam) {
ModuleItemPickup moduleItemPickup = Traverse.Create(moduleItemHolderBeam).Field("m_Pickup").GetValue() as ModuleItemPickup;
if (moduleItemPickup) {
float radius = Traverse.Create(moduleItemPickup).Field("m_PickupRange").GetValue() as float? ?? 0f;
return radius;
}
return 0f;
}
private static void SetRadius(ModuleItemHolderBeam moduleItemHolderBeam, float value) {
ModuleItemPickup moduleItemPickup = Traverse.Create(moduleItemHolderBeam).Field("m_Pickup").GetValue() as ModuleItemPickup;
if (moduleItemPickup) {
Traverse.Create(moduleItemPickup).Field("m_PickupRange").SetValue(value);
}
}
}
}

View File

@@ -14,101 +14,61 @@ namespace TerraTech {
private const string pluginName = "CykaMod";
private const string pluginVersion = "1.0.0";
public static ConfigEntry<bool> debug;
public static ConfigEntry<float> xpMultiplier;
public static ConfigEntry<float> moneyMultiplier;
public static ConfigEntry<float> energyGenMultiplier;
public static ConfigEntry<float> heartbeatIntervalMultiplier;
public static ConfigEntry<float> shootingSpeedMultiplier;
public static ConfigEntry<float> muzzleVelocityMultiplier;
public static ConfigEntry<bool> allProjectilesHoming;
public static ConfigEntry<float> magnetStrenghtMultiplier;
public static ConfigEntry<float> magnetRadiusMultiplier;
public static ConfigEntry<float> beamStrenghtMultiplier;
public static ConfigEntry<float> beamRadiusMultiplier;
public static ConfigEntry<float> fuelTankRefillMultiplier;
public static ConfigEntry<float> fuelTankCapacityMultiplier;
public static ConfigEntry<float> minerGroundArea;
public static ConfigEntry<float> minerMiningSpeed;
public static ConfigEntry<float> wheelTorqueMultiplier;
public static ConfigEntry<float> wheelSpeedMultiplier;
public static ConfigEntry<float> jetThrustMultiplier;
public static ConfigEntry<float> seekingProjectileVisionConeAngleMultiplier;
public static ConfigEntry<float> seekingProjectileVisionRangeMultiplier;
public static ConfigEntry<float> seekingProjectileTurningSpeedMultiplier;
public static ConfigEntry<float> wirelessChargingRadiusMultiplier;
public static ConfigEntry<float> wirelessChargingPowerPerArcMultiplier;
public static ConfigEntry<float> wirelessChargingArcFiringIntervalMultiplier;
public static ConfigEntry<bool> projectileExplodeOnStick;
public void Awake() {
xpMultiplier = Config.Bind("General", "XP Multiplier", 1f, new ConfigDescription("XP Multiplier", new AcceptableValueRange<float>(1f, 32f)));
moneyMultiplier = Config.Bind("General", "Money Multiplier", 1f,
new ConfigDescription("Money Multiplier", new AcceptableValueRange<float>(1f, 32f)));
energyGenMultiplier = Config.Bind("General", "Energy Generation Multiplier", 1f,
new ConfigDescription("Energy Generation Multiplier", new AcceptableValueRange<float>(1f, 64f)));
heartbeatIntervalMultiplier = Config.Bind("General", "Heartbeat Interval Multiplier", 1f,
new ConfigDescription("Heartbeat Interval Multiplier", new AcceptableValueRange<float>(0.1f, 2f)));
debug = Config.Bind("General", "Debug", false);
float min = 0.01f;
float max = 32f;
shootingSpeedMultiplier = Config.Bind("Weapons", "Shooting Speed Multiplier", 1f,
new ConfigDescription("Shooting Speed Multiplier", new AcceptableValueRange<float>(0.2f, 8f)));
muzzleVelocityMultiplier = Config.Bind("Weapons", "Muzzle Velocity Multiplier", 1f,
new ConfigDescription("Muzzle Velocity Multiplier", new AcceptableValueRange<float>(0.2f, 32f)));
seekingProjectileVisionConeAngleMultiplier = Config.Bind("Weapons", "Seeking Projectile Cone Vision Angle Multiplier", 1f,
new ConfigDescription("Seeking Projectile Cone Vision Angle Multiplier", new AcceptableValueRange<float>(0.2f, 32f)));
seekingProjectileVisionRangeMultiplier = Config.Bind("Weapons", "Seeking Projectile Vision Range Multiplier", 1f,
new ConfigDescription("Seeking Projectile Vision Range Multiplier", new AcceptableValueRange<float>(0.2f, 32f)));
seekingProjectileTurningSpeedMultiplier = Config.Bind("Weapons", "Seeking Projectile Turn Speed Multiplier", 1f,
new ConfigDescription("Seeking Projectile Turn Speed Multiplier", new AcceptableValueRange<float>(0.2f, 32f)));
ModuleWingManager.Setup(Config);
ModuleBoosterManager.Setup(Config);
ModuleShieldGeneratorManager.Setup(Config);
ModuleWeaponGunManager.Setup(Config);
ModuleEnergyManager.Setup(Config);
ModuleEnergyStoreManager.Setup(Config);
ModuleGyroManager.Setup(Config);
ModuleItemHolderManager.Setup(Config);
ModuleItemProducerManager.Setup(Config);
ModuleRemoteChargerManager.Setup(Config);
ModuleWheelsManager.Setup(Config);
TankBeamManager.Setup(Config);
ModuleWeaponManager.Setup(Config);
ModuleHeartManager.Setup(Config);
ModuleFuelTankManager.Setup(Config);
magnetStrenghtMultiplier = Config.Bind("Attractors", "Magnet Strength Multiplier", 1f,
new ConfigDescription("Magnet Strength Multiplier", new AcceptableValueRange<float>(1f, 16f)));
magnetRadiusMultiplier = Config.Bind("Attractors", "Magnet Radius Multiplier", 1f,
new ConfigDescription("Magnet Radius Multiplier", new AcceptableValueRange<float>(1f, 16f)));
beamStrenghtMultiplier = Config.Bind("Attractors", "Beam Strength Multiplier", 1f,
new ConfigDescription("Beam Strength Multiplier", new AcceptableValueRange<float>(1f, 16f)));
beamRadiusMultiplier = Config.Bind("Attractors", "Beam Radius Multiplier", 1f,
new ConfigDescription("Beam Radius Multiplier", new AcceptableValueRange<float>(1f, 16f)));
xpMultiplier =
Config.Bind("General", "XP Multiplier", 1f,
new ConfigDescription("XP Multiplier", new AcceptableValueRange<float>(min, max)));
moneyMultiplier =
Config.Bind("General", "Money Multiplier", 1f,
new ConfigDescription("Money Multiplier", new AcceptableValueRange<float>(min, max)));
heartbeatIntervalMultiplier = Config.Bind(
"General", "Heartbeat Interval Multiplier", 1f,
new ConfigDescription("Heartbeat Interval Multiplier", new AcceptableValueRange<float>(min, max)));
wirelessChargingRadiusMultiplier = Config.Bind("Power", "Wireless Charger Radius Multiplier", 1f,
new ConfigDescription("Wireless Charger Radius Multiplier", new AcceptableValueRange<float>(0.2f, 16f)));
wirelessChargingArcFiringIntervalMultiplier = Config.Bind("Power", "Wireless Charger Arc Firing Interval", 1f,
new ConfigDescription("Wireless Charger Arc Firing Interval", new AcceptableValueRange<float>(0.02f, 16f)));
wirelessChargingPowerPerArcMultiplier = Config.Bind("Power", "Wireless Charger Power Per Arc", 1f,
new ConfigDescription("Wireless Charger Power Per Arc", new AcceptableValueRange<float>(0.2f, 16f)));
fuelTankRefillMultiplier = Config.Bind("Propulsion", "Fuel Tank Refill Rate Multiplier", 1f,
new ConfigDescription("Fuel Tank Refill Rate Multiplier", new AcceptableValueRange<float>(1f, 32f)));
fuelTankCapacityMultiplier = Config.Bind("Propulsion", "Fuel Tank Capacity Multiplier", 1f,
new ConfigDescription("Fuel Tank Capacity Multiplier", new AcceptableValueRange<float>(1f, 32f)));
wheelTorqueMultiplier = Config.Bind("Propulsion", "Wheel Torque Multiplier", 1f,
new ConfigDescription("Wheel Torque Multiplier", new AcceptableValueRange<float>(1f, 32f)));
wheelSpeedMultiplier = Config.Bind("Propulsion", "Wheel Max RPM Multiplier", 1f,
new ConfigDescription("Wheel Max RPM Multiplier", new AcceptableValueRange<float>(1f, 32f)));
jetThrustMultiplier = Config.Bind("Propulsion", "Jet Thrust Multiplier", 1f,
new ConfigDescription("Jet Thrust Multiplier", new AcceptableValueRange<float>(1f, 32f)));
minerGroundArea = Config.Bind("Production", "Miner Ground Deposit Scan Area", 1f,
new ConfigDescription("Miner Ground Deposit Scan Area", new AcceptableValueRange<float>(1f, 32f)));
minerMiningSpeed = Config.Bind("Production", "Miner Mining Speed", 1f,
new ConfigDescription("Miner Mining Speed", new AcceptableValueRange<float>(1f, 32f)));
allProjectilesHoming = Config.Bind("General", "Make All Projectiles Home", false);
shootingSpeedMultiplier.SettingChanged += (sender, args) => WeaponPropertiesManager.DoPatch();
energyGenMultiplier.SettingChanged += (sender, args) => GeneratorPropertiesManager.DoPatch();
magnetStrenghtMultiplier.SettingChanged += (sender, args) => MagnetPropertiesManager.DoPatch();
magnetRadiusMultiplier.SettingChanged += (sender, args) => MagnetPropertiesManager.DoPatch();
beamStrenghtMultiplier.SettingChanged += (sender, args) => BeamPropertiesManager.DoPatch();
beamRadiusMultiplier.SettingChanged += (sender, args) => BeamPropertiesManager.DoPatch();
fuelTankRefillMultiplier.SettingChanged += (sender, args) => FuelPropertiesManager.DoPatch();
fuelTankCapacityMultiplier.SettingChanged += (sender, args) => FuelPropertiesManager.DoPatch();
wheelTorqueMultiplier.SettingChanged += (sender, args) => WheelPropertiesManager.DoPatch();
wheelSpeedMultiplier.SettingChanged += (sender, args) => WheelPropertiesManager.DoPatch();
jetThrustMultiplier.SettingChanged += (sender, args) => ThrusterPropertiesManager.DoPatch();
minerGroundArea.SettingChanged += (sender, args) => MinerPropertiesManager.DoPatch();
minerMiningSpeed.SettingChanged += (sender, args) => MinerPropertiesManager.DoPatch();
wirelessChargingPowerPerArcMultiplier.SettingChanged += (sender, args) => WirelessChargerPropertiesManager.DoPatch();
wirelessChargingArcFiringIntervalMultiplier.SettingChanged += (sender, args) => WirelessChargerPropertiesManager.DoPatch();
wirelessChargingRadiusMultiplier.SettingChanged += (sender, args) => WirelessChargerPropertiesManager.DoPatch();
seekingProjectileVisionConeAngleMultiplier =
Config.Bind("Weapons", "Seeking Projectile Cone Vision Angle Multiplier", 1f,
new ConfigDescription("Seeking Projectile Cone Vision Angle Multiplier",
new AcceptableValueRange<float>(min, max)));
seekingProjectileVisionRangeMultiplier =
Config.Bind("Weapons", "Seeking Projectile Vision Range Multiplier", 1f,
new ConfigDescription("Seeking Projectile Vision Range Multiplier",
new AcceptableValueRange<float>(min, max)));
seekingProjectileTurningSpeedMultiplier =
Config.Bind("Weapons", "Seeking Projectile Turn Speed Multiplier", 1f,
new ConfigDescription("Seeking Projectile Turn Speed Multiplier",
new AcceptableValueRange<float>(min, max)));
projectileExplodeOnStick = Config.Bind(
"Weapons", "Projectile Explode On Stick", false,
new ConfigDescription("Projectile Explode On Stick", new AcceptableValueRange<bool>(false, true)));
Logger.LogInfo("Cyka mod loaded");
HarmonyFileLog.Enabled = true;

View File

@@ -0,0 +1,28 @@
using System;
namespace TerraTech {
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;
}
};
}
}

View File

@@ -1,55 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class FuelPropertiesManager {
private static Dictionary<ModuleFuelTank, float> refillRate = new Dictionary<ModuleFuelTank, float>();
private static Dictionary<ModuleFuelTank, float> capacity = new Dictionary<ModuleFuelTank, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnAttached")]
static void PostfixCreate(ModuleFuelTank __instance) {
// Console.WriteLine("ModuleFuelTank.OnAttached");
if (!refillRate.ContainsKey(__instance)) {
refillRate.Add(__instance, __instance.m_RefillRate);
capacity.Add(__instance, __instance.m_Capacity);
// Console.WriteLine("Patching {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnDetaching")]
static void PostfixDestroy(ModuleFuelTank __instance) {
// Console.WriteLine("ModuleFuelTank.OnAttached");
// Console.WriteLine("Restoring {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
refillRate.Remove(__instance);
capacity.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleFuelTank", refillRate.Count);
foreach (KeyValuePair<ModuleFuelTank, float> keyValuePair in refillRate) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleFuelTank moduleFuelTank) {
moduleFuelTank.m_RefillRate = refillRate[moduleFuelTank] * Main.fuelTankRefillMultiplier.Value;
moduleFuelTank.m_Capacity = capacity[moduleFuelTank] * Main.fuelTankCapacityMultiplier.Value;
}
static void DoRestoreSingle(ModuleFuelTank moduleFuelTank) {
if (refillRate.ContainsKey(moduleFuelTank)) {
moduleFuelTank.m_RefillRate = refillRate[moduleFuelTank];
moduleFuelTank.m_Capacity = capacity[moduleFuelTank];
}
}
}
}

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class GeneratorPropertiesManager {
private static Dictionary<ModuleEnergy, float> generators = new Dictionary<ModuleEnergy, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnAttached")]
static void PostfixCreate(ModuleEnergy __instance) {
// Console.WriteLine("ModuleEnergy.OnAttached");
if (!generators.ContainsKey(__instance)) {
generators.Add(__instance, GetValue(__instance));
// Console.WriteLine("Patching {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")]
static void PostfixDestroy(ModuleEnergy __instance) {
// Console.WriteLine("ModuleEnergy.OnDetaching");
// Console.WriteLine("Restoring {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_OutputPerSecond: {1}", __instance.name, GetValue(__instance));
generators.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleEnergy", generators.Count);
foreach (KeyValuePair<ModuleEnergy, float> keyValuePair in generators) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleEnergy moduleEnergy) {
SetValue(moduleEnergy, generators[moduleEnergy] * Main.energyGenMultiplier.Value);
}
static void DoRestoreSingle(ModuleEnergy moduleEnergy) {
if (generators.ContainsKey(moduleEnergy)) {
SetValue(moduleEnergy, generators[moduleEnergy]);
}
}
private static float GetValue(ModuleEnergy moduleEnergy) {
return Traverse.Create(moduleEnergy).Field("m_OutputPerSecond").GetValue() as float? ?? 0f;
}
private static void SetValue(ModuleEnergy moduleEnergy, float value) {
Traverse.Create(moduleEnergy).Field("m_OutputPerSecond").SetValue(value);
}
}
}

View File

@@ -1,22 +0,0 @@
using System.Collections.Generic;
using HarmonyLib;
using UnityEngine;
namespace TerraTech {
[HarmonyPatch(typeof(Projectile), "Fire")]
public class HomingAndVelocityProjectilePatch {
private static Dictionary<FireData, float> velocities = new Dictionary<FireData, float>();
static void Prefix(Vector3 fireDirection, ref FireData fireData, ref ModuleWeaponGun weapon, Tank shooter, ref bool seekingRounds, bool replayRounds) {
if (Main.allProjectilesHoming.Value) {
seekingRounds = true;
}
if (!velocities.ContainsKey(fireData)) {
velocities.Add(fireData, fireData.m_MuzzleVelocity);
fireData.m_MuzzleVelocity *= Main.muzzleVelocityMultiplier.Value;
} else if (velocities[fireData] != fireData.m_MuzzleVelocity * Main.muzzleVelocityMultiplier.Value) {
fireData.m_MuzzleVelocity = velocities[fireData] * Main.muzzleVelocityMultiplier.Value;
}
}
}
}

View File

@@ -1,81 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class MagnetPropertiesManager {
private static Dictionary<ModuleItemHolderMagnet, float> strenghts = new Dictionary<ModuleItemHolderMagnet, float>();
private static Dictionary<ModuleItemHolderMagnet, float> radii = new Dictionary<ModuleItemHolderMagnet, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnAttached")]
static void PostfixCreate(ModuleItemHolderMagnet __instance) {
// Console.WriteLine("ModuleItemHolderMagnet.OnAttached");
if (!strenghts.ContainsKey(__instance)) {
strenghts.Add(__instance, GetStrength(__instance));
radii.Add(__instance, GetRadius(__instance));
// Console.WriteLine("Patching {0}; m_Strength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_Strength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnDetaching")]
static void PostfixDestroy(ModuleItemHolderMagnet __instance) {
// Console.WriteLine("ModuleItemHolderMagnet.OnDetaching");
// Console.WriteLine("Restoring {0}; m_Strength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_Strength: {1}; m_Pickup.m_PickupRange: {2}", __instance.name, GetStrength(__instance), GetRadius(__instance));
strenghts.Remove(__instance);
radii.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleItemHolderMagnet", strenghts.Count);
foreach (KeyValuePair<ModuleItemHolderMagnet, float> keyValuePair in strenghts) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleItemHolderMagnet moduleItemHolderMagnet) {
SetStrength(moduleItemHolderMagnet, strenghts[moduleItemHolderMagnet] * Main.magnetStrenghtMultiplier.Value);
SetRadius(moduleItemHolderMagnet, radii[moduleItemHolderMagnet] * Main.magnetRadiusMultiplier.Value);
}
static void DoRestoreSingle(ModuleItemHolderMagnet moduleItemHolderMagnet) {
if (strenghts.ContainsKey(moduleItemHolderMagnet)) {
SetStrength(moduleItemHolderMagnet, strenghts[moduleItemHolderMagnet]);
}
if (radii.ContainsKey(moduleItemHolderMagnet)) {
SetRadius(moduleItemHolderMagnet, radii[moduleItemHolderMagnet]);
}
}
private static float GetStrength(ModuleItemHolderMagnet moduleItemHolderMagnet) {
return Traverse.Create(moduleItemHolderMagnet).Field("m_Strength").GetValue() as float? ?? 0f;
}
private static void SetStrength(ModuleItemHolderMagnet moduleItemHolderMagnet, float value) {
Traverse.Create(moduleItemHolderMagnet).Field("m_Strength").SetValue(value);
}
private static float GetRadius(ModuleItemHolderMagnet moduleItemHolderMagnet) {
ModuleItemPickup moduleItemPickup = Traverse.Create(moduleItemHolderMagnet).Field("m_Pickup").GetValue() as ModuleItemPickup;
if (moduleItemPickup) {
float radius = Traverse.Create(moduleItemPickup).Field("m_PickupRange").GetValue() as float? ?? 0f;
return radius;
}
return 0f;
}
private static void SetRadius(ModuleItemHolderMagnet moduleItemHolderMagnet, float value) {
ModuleItemPickup moduleItemPickup = Traverse.Create(moduleItemHolderMagnet).Field("m_Pickup").GetValue() as ModuleItemPickup;
if (moduleItemPickup) {
Traverse.Create(moduleItemPickup).Field("m_PickupRange").SetValue(value);
}
}
}
}

View File

@@ -1,86 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class MinerPropertiesManager {
private static Dictionary<ModuleItemProducer, float> area = new Dictionary<ModuleItemProducer, float>();
private static Dictionary<ModuleItemProducer, float> speed = new Dictionary<ModuleItemProducer, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemProducer), "GetClosestResourceReservoirInRange")]
static void PostfixCreate(ModuleItemProducer __instance) {
// Console.WriteLine("ModuleItemProducer.GetClosestResourceReservoirInRange");
if (!area.ContainsKey(__instance)) {
area.Add(__instance, GetArea(__instance));
speed.Add(__instance, GetSpeed(__instance));
// Console.WriteLine("Patching {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance),
// GetSpeed(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance),
// GetSpeed(__instance));
} else {
if (GetArea(__instance) == area[__instance]) {
// Console.WriteLine("{0} area reset, patching again... m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name,
// GetArea(__instance), GetSpeed(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance),
// GetSpeed(__instance));
}
if (GetSpeed(__instance) == speed[__instance]) {
// Console.WriteLine("{0} speed reset, patching again... m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name,
// GetArea(__instance), GetSpeed(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_ResourceGroundRadius: {1}; m_SecPerItemProduced: {2}", __instance.name, GetArea(__instance),
// GetSpeed(__instance));
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")]
static void PostfixDestroy(ModuleItemProducer __instance) {
// Console.WriteLine("ModuleItemProducer.OnRecycle");
DoRestoreSingle(__instance);
area.Remove(__instance);
speed.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleItemProducer", area.Count);
foreach (KeyValuePair<ModuleItemProducer, float> keyValuePair in area) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleItemProducer moduleItemProducer) {
SetArea(moduleItemProducer, area[moduleItemProducer] * Main.minerGroundArea.Value);
SetSpeed(moduleItemProducer, speed[moduleItemProducer] / Main.minerMiningSpeed.Value);
}
static void DoRestoreSingle(ModuleItemProducer moduleItemProducer) {
if (area.ContainsKey(moduleItemProducer)) {
SetArea(moduleItemProducer, area[moduleItemProducer]);
SetSpeed(moduleItemProducer, speed[moduleItemProducer]);
}
}
private static float GetArea(ModuleItemProducer moduleItemProducer) {
return Traverse.Create(moduleItemProducer).Field("m_ResourceGroundRadius").GetValue() as float? ?? 0f;
}
private static void SetArea(ModuleItemProducer moduleItemProducer, float value) {
Traverse.Create(moduleItemProducer).Field("m_ResourceGroundRadius").SetValue(value);
}
private static float GetSpeed(ModuleItemProducer moduleItemProducer) {
return Traverse.Create(moduleItemProducer).Field("m_SecPerItemProduced").GetValue() as float? ?? 0f;
}
private static void SetSpeed(ModuleItemProducer moduleItemProducer, float value) {
Traverse.Create(moduleItemProducer).Field("m_SecPerItemProduced").SetValue(value);
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleBoosterManager {
private static readonly MultipliedObjectManager<FanJet> fanManager =
new MultipliedObjectManager<FanJet>(ConfigureFanThruster);
private static readonly MultipliedObjectManager<BoosterJet> jetManager =
new MultipliedObjectManager<BoosterJet>(ConfigureJetThruster);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> fanThrustMultiplier;
public 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")]
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")]
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);
}
public static void DoPatch() {
fanManager.ApplyAll();
jetManager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleEnergyManager {
private static readonly MultipliedObjectManager<ModuleEnergy> manager =
new MultipliedObjectManager<ModuleEnergy>(ConfigureModuleEnergy);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> outputMultiplier;
public 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")]
static void PostfixCreate(ModuleEnergy __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")]
static void PostfixDestroy(ModuleEnergy __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleEnergyStoreManager {
private static readonly MultipliedObjectManager<ModuleEnergyStore> manager =
new MultipliedObjectManager<ModuleEnergyStore>(ConfigureModuleEnergyStore);
public static ConfigEntry<bool> playerOnly;
public 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")]
static void PostfixCreate(ModuleEnergyStore __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergyStore), "OnDetaching")]
static void PostfixDestroy(ModuleEnergyStore __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleFuelTankManager {
private static readonly MultipliedObjectManager<ModuleFuelTank> manager =
new MultipliedObjectManager<ModuleFuelTank>(ConfigureFuelTank);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> fuelCapacityMultiplier;
public 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")]
static void PostfixCreate(ModuleFuelTank __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnDetaching")]
static void PostfixDestroy(ModuleFuelTank __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleGyroManager {
private static readonly MultipliedObjectManager<ModuleGyro> manager =
new MultipliedObjectManager<ModuleGyro>(ConfigureModuleGyro);
public static ConfigEntry<bool> playerOnly;
public 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")]
static void PostfixCreate(ModuleGyro __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleGyro), "OnDetaching")]
static void PostfixDestroy(ModuleGyro __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleHeartManager {
private static readonly MultipliedObjectManager<ModuleHeart> manager =
new MultipliedObjectManager<ModuleHeart>(ConfigureHeart);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> eventHorizonRadiusMultiplier;
public static ConfigEntry<float> setupTimeMultiplier;
public 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")]
static void PostfixCreate(ModuleHeart __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleHeart), "OnDetaching")]
static void PostfixDestroy(ModuleHeart __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,157 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[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);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> capacityPerStackMultiplier;
public static ConfigEntry<float> beamStrengthMultiplier;
public static ConfigEntry<float> beamHeightIncrementScaleMultiplier;
public static ConfigEntry<float> beamPickupRangeMultiplier;
public static ConfigEntry<float> magnetStrengthMultiplier;
public 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")]
static void PostfixCreate(ModuleItemHolder __instance) {
beamManager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolder), "OnDetaching")]
static void PostfixDestroy(ModuleItemHolder __instance) {
beamManager.OnObjectDetached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnAttached")]
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")]
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")]
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")]
static void PostfixDestroy(ModuleItemHolderMagnet __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
magnetHolderManager.OnObjectDetached(__instance);
magnetPickupManager.OnObjectDetached(pickup);
}
public static void DoPatch() {
beamManager.ApplyAll();
beamHolderManager.ApplyAll();
beamPickupManager.ApplyAll();
magnetHolderManager.ApplyAll();
magnetPickupManager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,70 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleItemProducerManager {
private static readonly MultipliedObjectManager<ModuleItemProducer> manager =
new MultipliedObjectManager<ModuleItemProducer>(ConfigureModuleItemProducer);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> resourceGroundRadiusMultiplier;
public static ConfigEntry<float> minDispenseIntervalMultiplier;
public 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")]
static void PostfixCreate(ModuleItemProducer __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")]
static void PostfixDestroy(ModuleItemProducer __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,70 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleRemoteChargerManager {
private static readonly MultipliedObjectManager<ModuleRemoteCharger> manager =
new MultipliedObjectManager<ModuleRemoteCharger>(ConfigureModuleRemoteCharger);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> arcFiringIntervalMultiplier;
public static ConfigEntry<float> chargingRadiusMultiplier;
public static ConfigEntry<float> powerTransferPerArcMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
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")]
static void PostfixCreate(ModuleRemoteCharger __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnDetaching")]
static void PostfixDestroy(ModuleRemoteCharger __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,81 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleShieldGeneratorManager {
private static readonly MultipliedObjectManager<ModuleShieldGenerator> manager =
new MultipliedObjectManager<ModuleShieldGenerator>(ConfigureShieldGenerator);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> radiusMultiplier;
public static ConfigEntry<float> radiusMultiplierHealing;
public static ConfigEntry<float> heartbeatIntervalMultiplier;
public static ConfigEntry<float> powerUpDelayMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
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")]
static void PostfixCreate(ModuleShieldGenerator __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")]
static void PostfixDestroy(ModuleShieldGenerator __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,114 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWeaponGunManager {
private static readonly MultipliedObjectManager<ModuleWeaponGun> manager =
new MultipliedObjectManager<ModuleWeaponGun>(ConfigureManager);
private static readonly MultipliedObjectManager<FireData> fireDataManager =
new MultipliedObjectManager<FireData>(ConfigureFireData);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> kickbackStrengthMultiplier;
public static ConfigEntry<float> muzzleVelocityMultiplier;
public static ConfigEntry<float> burstCooldownMultiplier;
public static ConfigEntry<float> burstShotCountMultiplier;
public static ConfigEntry<float> shotCooldownMultiplier;
public static ConfigEntry<bool> seekingRoundsAll;
public static ConfigEntry<bool> resetBurstOnInterruptAll;
public static void Setup(ConfigFile config) {
float min = 0.01f;
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")]
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")]
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>());
}
public static void DoPatch() {
fireDataManager.ApplyAll();
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWeaponManager {
private static readonly MultipliedObjectManager<ModuleWeapon> manager =
new MultipliedObjectManager<ModuleWeapon>(ConfigureManager);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> rotateSpeedMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
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")]
static void PostfixCreate(ModuleWeapon __instance) {
manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeapon), "OnDetaching")]
static void PostfixDestroy(ModuleWeapon __instance) {
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWheelsManager {
private static readonly MultipliedObjectManager<ManWheels.TorqueParams> torqueParamsManager =
new MultipliedObjectManager<ManWheels.TorqueParams>(ConfigureTorqueParams);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> torqueRpmMultiplier;
public static ConfigEntry<float> torqueMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
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")]
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")]
static void PostfixDestroy(ModuleWheels __instance) {
var trav = Traverse.Create(__instance);
var torqueParams = trav.Field("torqueParams");
torqueParamsManager.OnObjectDetached(torqueParams.GetValue<ManWheels.TorqueParams>());
}
public static void DoPatch() {
torqueParamsManager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,79 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWingManager {
private static readonly MultipliedObjectManager<ModuleWing.Aerofoil> manager =
new MultipliedObjectManager<ModuleWing.Aerofoil>(ConfigureAerofoil);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> angleRangeMultiplier;
public static ConfigEntry<float> turnSpeedMultiplier;
public static ConfigEntry<float> liftStrengthMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
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")]
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")]
static void PostfixDestroy(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.OnObjectDetached(aerofoil);
}
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,531 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
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);
}
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using HarmonyLib;
namespace TerraTech {
[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);
}
}
}
}

View File

@@ -4,22 +4,22 @@ 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("TerraTech")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TerraTech")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly:AssemblyTitle("TerraTech")]
[assembly:AssemblyDescription("")]
[assembly:AssemblyConfiguration("")]
[assembly:AssemblyCompany("")]
[assembly:AssemblyProduct("TerraTech")]
[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)]
[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")]
[assembly:Guid("EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE")]
// Version information for an assembly consists of the following four values:
//
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// 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")]
[assembly:AssemblyVersion("1.0.0.0")]
[assembly:AssemblyFileVersion("1.0.0.0")]

View File

@@ -6,15 +6,21 @@ namespace TerraTech {
[HarmonyPatch(typeof(SeekingProjectile), "OnSpawn")]
class Patch {
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"));
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;
return Traverse.Create(seekingProjectile).Field(field).GetValue() as float ? ?? 0f;
}
private static void SetField(SeekingProjectile seekingProjectile, string field, float value) {

View File

@@ -0,0 +1,53 @@
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[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")]
static void PostfixCreate(TankBeam __instance, ref bool enable) {
if (enable)
manager.OnObjectAttached(__instance);
else
manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
}
}
}

View File

@@ -1,8 +1,13 @@
<?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')" />
<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:/Users/Administrator/scoop/apps/steam/current/steamapps/common/TerraTech</GAME_DIR>
<GAME_MANAGED>$(GAME_DIR)/TerraTechWin64_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>
@@ -32,39 +37,50 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="BeamPropertiesManager.cs" />
<Compile Include="Class1.cs" />
<Compile Include="FuelPropertiesManager.cs" />
<Compile Include="GeneratorPropertiesManager.cs" />
<Compile Include="HomingAndVelocityProjectilePatch.cs" />
<Compile Include="MagnetPropertiesManager.cs" />
<Compile Include="MinerPropertiesManager.cs" />
<Compile Include="ModuleShieldGeneratorManager.cs" />
<Compile Include="ObjectFieldMultiplier.cs" />
<Compile Include="Patches.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SeekingProjectileManager.cs" />
<Compile Include="ThrusterPropertiesManager.cs" />
<Compile Include="WeaponPropertiesManager.cs" />
<Compile Include="WheelPropertiesManager.cs" />
<Compile Include="WirelessChargerPropertiesManager.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" />
</ItemGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>..\libs\0Harmony.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\libs\Assembly-CSharp.dll</HintPath>
<HintPath>$(GAME_BEPINEX)/core/0Harmony.dll</HintPath>
</Reference>
<Reference Include="BepInEx">
<HintPath>..\libs\BepInEx.dll</HintPath>
</Reference>
<Reference Include="ConfigurationManager">
<HintPath>..\libs\ConfigurationManager.dll</HintPath>
<HintPath>$(GAME_BEPINEX)/core/BepInEx.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>..\libs\UnityEngine.dll</HintPath>
<HintPath>$(GAME_MANAGED)/UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\libs\UnityEngine.CoreModule.dll</HintPath>
<HintPath>$(GAME_MANAGED)/UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.Networking">
<HintPath>$(GAME_MANAGED)/UnityEngine.Networking.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>$(GAME_MANAGED)/Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="ConfigurationManager">
<HintPath>$(GAME_BEPINEX)/plugins/ConfigurationManager.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ThrusterPropertiesManager {
private static Dictionary<ModuleBooster, Dictionary<BoosterJet, float>> boosters = new Dictionary<ModuleBooster, Dictionary<BoosterJet, float>>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleBooster), "OnAttached")]
static void PostfixCreate(ModuleBooster __instance) {
// Console.WriteLine("ModuleBooster.OnAttached");
if (!boosters.ContainsKey(__instance)) {
boosters.Add(__instance, Map(__instance));
// Console.WriteLine("Patching {0}; force: {1}", __instance.name, GetForceAsString(__instance));
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; force: {1}", __instance.name, GetForceAsString(__instance));
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleBooster), "OnDetaching")]
static void PostfixDestroy(ModuleBooster __instance) {
// Console.WriteLine("ModuleBooster.OnDetaching");
// Console.WriteLine("Restoring {0}; force: {1}", __instance.name, GetForceAsString(__instance));
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; force: {1}", __instance.name, GetForceAsString(__instance));
boosters.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleBooster", boosters.Count);
foreach (KeyValuePair<ModuleBooster, Dictionary<BoosterJet, float>> keyValuePair in boosters) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleBooster moduleBooster) {
List<BoosterJet> jets = GetValue(moduleBooster);
for (var i = 0; i < jets.Count; i++) {
boosters[moduleBooster][jets[i]] = GetValue(jets[i]);
SetValue(jets[i], GetValue(jets[i]) * Main.jetThrustMultiplier.Value);
}
SetValue(moduleBooster, jets);
}
static void DoRestoreSingle(ModuleBooster moduleBooster) {
if (boosters.ContainsKey(moduleBooster)) {
foreach (BoosterJet boosterJet in GetValue(moduleBooster)) {
SetValue(boosterJet, boosters[moduleBooster][boosterJet]);
}
}
}
private static Dictionary<BoosterJet, float> Map(ModuleBooster moduleBooster) {
Dictionary<BoosterJet, float> jets = new Dictionary<BoosterJet, float>();
foreach (BoosterJet boosterJet in GetValue(moduleBooster)) {
jets.Add(boosterJet, GetValue(boosterJet));
}
return jets;
}
private static List<BoosterJet> GetValue(ModuleBooster moduleBooster) {
return Traverse.Create(moduleBooster).Field("jets").GetValue() as List<BoosterJet>;
}
private static void SetValue(ModuleBooster moduleBooster, List<BoosterJet> value) {
Traverse.Create(moduleBooster).Field("jets").SetValue(value);
}
private static float GetValue(BoosterJet boosterJet) {
return Traverse.Create(boosterJet).Field("m_Force").GetValue() as float? ?? 0f;
}
private static void SetValue(BoosterJet boosterJet, float value) {
Traverse.Create(boosterJet).Field("m_Force").SetValue(value);
}
private static string GetForceAsString(ModuleBooster moduleBooster) {
string result = "";
foreach (BoosterJet boosterJet in GetValue(moduleBooster)) {
result += GetValue(boosterJet) + ", ";
}
return result;
}
}
}

View File

@@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class WeaponPropertiesManager {
private static Dictionary<ModuleWeaponGun, float> shotCooldown = new Dictionary<ModuleWeaponGun, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeaponGun), "OnAttached")]
static void PostfixCreate(ModuleWeaponGun __instance) {
// Console.WriteLine("ModuleWeaponGun.OnAttached");
if (!shotCooldown.ContainsKey(__instance)) {
shotCooldown.Add(__instance, __instance.m_ShotCooldown);
// Console.WriteLine("Patching {0}; m_ShotCooldown: {1}", __instance.name, __instance.m_ShotCooldown);
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_ShotCooldown: {1}", __instance.name, __instance.m_ShotCooldown);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeaponGun), "OnDetaching")]
static void PostfixDestroy(ModuleWeaponGun __instance) {
// Console.WriteLine("ModuleWeaponGun.OnDetaching");
// Console.WriteLine("Restoring {0}; m_ShotCooldown: {1}", __instance.name, __instance.m_ShotCooldown);
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_ShotCooldown: {1}", __instance.name, __instance.m_ShotCooldown);
shotCooldown.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleWeaponGun", shotCooldown.Count);
foreach (KeyValuePair<ModuleWeaponGun, float> keyValuePair in shotCooldown) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleWeaponGun moduleWeaponGun) {
moduleWeaponGun.m_ShotCooldown = shotCooldown[moduleWeaponGun] / Main.shootingSpeedMultiplier.Value;
}
static void DoRestoreSingle(ModuleWeaponGun moduleWeaponGun) {
if (shotCooldown.ContainsKey(moduleWeaponGun)) {
moduleWeaponGun.m_ShotCooldown = shotCooldown[moduleWeaponGun];
}
}
}
}

View File

@@ -1,63 +0,0 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class WheelPropertiesManager {
private static Dictionary<ModuleWheels, float> torques = new Dictionary<ModuleWheels, float>();
private static Dictionary<ModuleWheels, float> maxRpm = new Dictionary<ModuleWheels, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWheels), "OnAttached")]
static void PostfixCreate(ModuleWheels __instance) {
// Console.WriteLine("ModuleWheels.OnAttached");
if (!torques.ContainsKey(__instance)) {
torques.Add(__instance, __instance.m_TorqueParams.torqueCurveMaxTorque);
maxRpm.Add(__instance, __instance.m_TorqueParams.torqueCurveMaxRpm);
// Console.WriteLine("Patching {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
// __instance.m_TorqueParams.torqueCurveMaxTorque,
// __instance.m_TorqueParams.torqueCurveMaxRpm);
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
// __instance.m_TorqueParams.torqueCurveMaxTorque,
// __instance.m_TorqueParams.torqueCurveMaxRpm);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWheels), "OnDetaching")]
static void PostfixDestroy(ModuleWheels __instance) {
// Console.WriteLine("ModuleWheels.OnDetaching");
// Console.WriteLine("Restoring {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
// __instance.m_TorqueParams.torqueCurveMaxTorque,
// __instance.m_TorqueParams.torqueCurveMaxRpm);
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_TorqueParams.torqueCurveMaxTorque: {1}; m_TorqueParams.torqueCurveMaxRpm: {2}", __instance.name,
// __instance.m_TorqueParams.torqueCurveMaxTorque,
// __instance.m_TorqueParams.torqueCurveMaxRpm);
torques.Remove(__instance);
maxRpm.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleWheels", torques.Count);
foreach (KeyValuePair<ModuleWheels, float> keyValuePair in torques) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleWheels moduleWheels) {
moduleWheels.m_TorqueParams.torqueCurveMaxRpm = maxRpm[moduleWheels] * Main.wheelSpeedMultiplier.Value;
moduleWheels.m_TorqueParams.torqueCurveMaxTorque = torques[moduleWheels] * Main.wheelTorqueMultiplier.Value;
}
static void DoRestoreSingle(ModuleWheels moduleWheels) {
if (torques.ContainsKey(moduleWheels)) {
moduleWheels.m_TorqueParams.torqueCurveMaxTorque = torques[moduleWheels];
moduleWheels.m_TorqueParams.torqueCurveMaxRpm = maxRpm[moduleWheels];
}
}
}
}

View File

@@ -1,60 +0,0 @@
using System.Collections.Generic;
using HarmonyLib;
// TODO: Fix this, no workey
namespace TerraTech {
[HarmonyPatch]
public class WirelessChargerPropertiesManager {
private static Dictionary<ModuleRemoteCharger, float> radius = new Dictionary<ModuleRemoteCharger, float>();
private static Dictionary<ModuleRemoteCharger, float> transferPerArc = new Dictionary<ModuleRemoteCharger, float>();
private static Dictionary<ModuleRemoteCharger, float> arcFiringInterval = new Dictionary<ModuleRemoteCharger, float>();
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnAttached")]
static void PostfixCreate(ModuleRemoteCharger __instance) {
// Console.WriteLine("ModuleRemoteCharger.OnAttached");
if (!radius.ContainsKey(__instance)) {
radius.Add(__instance, __instance.m_ChargingRadius);
transferPerArc.Add(__instance, __instance.m_PowerTransferPerArc);
arcFiringInterval.Add(__instance, __instance.m_ArcFiringInterval);
// Console.WriteLine("Patching {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
DoPatchSingle(__instance);
// Console.WriteLine("Patched {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnDetaching")]
static void PostfixDestroy(ModuleRemoteCharger __instance) {
// Console.WriteLine("ModuleRemoteCharger.OnAttached");
// Console.WriteLine("Restoring {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
DoRestoreSingle(__instance);
// Console.WriteLine("Restored {0}; m_RefillRate: {1}; m_Capacity: {2}", __instance.name, __instance.m_RefillRate, __instance.m_Capacity);
radius.Remove(__instance);
transferPerArc.Remove(__instance);
arcFiringInterval.Remove(__instance);
}
public static void DoPatch() {
// Console.WriteLine("Modifying {0} ModuleRemoteCharger", radius.Count);
foreach (KeyValuePair<ModuleRemoteCharger, float> keyValuePair in radius) {
DoRestoreSingle(keyValuePair.Key);
DoPatchSingle(keyValuePair.Key);
}
}
static void DoPatchSingle(ModuleRemoteCharger moduleRemoteCharger) {
moduleRemoteCharger.m_ChargingRadius = radius[moduleRemoteCharger] * Main.wirelessChargingRadiusMultiplier.Value;
moduleRemoteCharger.m_PowerTransferPerArc = radius[moduleRemoteCharger] * Main.wirelessChargingPowerPerArcMultiplier.Value;
moduleRemoteCharger.m_ArcFiringInterval = radius[moduleRemoteCharger] * Main.wirelessChargingArcFiringIntervalMultiplier.Value;
}
static void DoRestoreSingle(ModuleRemoteCharger moduleRemoteCharger) {
if (radius.ContainsKey(moduleRemoteCharger)) {
moduleRemoteCharger.m_ChargingRadius = radius[moduleRemoteCharger];
moduleRemoteCharger.m_PowerTransferPerArc = radius[moduleRemoteCharger];
moduleRemoteCharger.m_ArcFiringInterval = radius[moduleRemoteCharger];
}
}
}
}

View File

@@ -0,0 +1 @@
clang-format -i TerraTech/*.cs

1
Projects/TerraTech/sync Normal file
View File

@@ -0,0 +1 @@
TerraTech/obj/Release/TerraTech.dll,~/scoop/apps/steam/current/steamapps/common/TerraTech/BepInEx/plugins/TerraTech.dll

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.