13 Commits

88 changed files with 4114 additions and 981 deletions

BIN
BepInEx.Patcher.exe Normal file

Binary file not shown.

View File

@@ -1 +0,0 @@
bin/Release/DaveCEO.dll,"C:\Games\Airport CEO\BepInEx\plugins\DaveCEO.dll"

View File

@@ -0,0 +1,3 @@
- source: bin/Release/DaveCEO.dll
target: C:\Games\Airport CEO\BepInEx\plugins\DaveCEO.dll
delete: true

View File

@@ -1 +0,0 @@
bin/Release/CykaOfIndustry.dll,"C:\Program Files (x86)\Steam\steamapps\common\Captain of Industry\BepInEx\plugins\CykaOfIndustry.dll"

View File

@@ -0,0 +1,3 @@
- source: bin/Release/CykaOfIndustry.dll
target: C:\Program Files (x86)\Steam\steamapps\common\Captain of Industry\BepInEx\plugins\CykaOfIndustry.dll
delete: true

View File

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

View File

@@ -0,0 +1,3 @@
- source: bin/Release/CykaOfQud.dll
target: C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll
delete: true

View File

@@ -1,35 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// 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("InfectionFreeZone")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("InfectionFreeZone")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly:AssemblyTitle("InfectionFreeZone")]
[assembly:AssemblyDescription("")]
[assembly:AssemblyConfiguration("")]
[assembly:AssemblyCompany("")]
[assembly:AssemblyProduct("InfectionFreeZone")]
[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
// 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("DA9D274E-486F-4F82-84FF-CD9388CB0B09")]
// 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
// 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")]
// 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 +0,0 @@
InfectionFreeZone/bin/Release/InfectionFreeZone.dll,"C:\Games\Infection.Free.Zone.v0.24.8.21a\BepInEx\plugins\InfectionFreeZone.dll"

View File

@@ -0,0 +1,3 @@
- source: bin/Release/InfectionFreeZone.dll
target: C:\Games\Infection.Free.Zone.v0.24.8.21a\BepInEx\plugins\InfectionFreeZone.dll
delete: true

View File

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

View File

@@ -0,0 +1,3 @@
- source: bin/Release/CykaRaider.dll
target: C:/Games/NightRaider/BepInEx/plugins/CykaRaider.dll
delete: true

View File

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

Binary file not shown.

View File

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

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quasimorph", "Quasimorph\Quasimorph.csproj", "{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,35 @@
using System.Linq;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using HarmonyLib.Tools;
namespace Quasimorph {
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
public class Main : BaseUnityPlugin {
private const string PluginGuid = "Quasicyka";
private const string PluginName = "Quasicyka";
private const string PluginVersion = "1.0.0";
public static ConfigEntry<bool> debug;
public static ConfigEntry<int> scrappingMultiplier;
public static ConfigEntry<float> xpMultiplier;
public void Awake() {
debug = Config.Bind("General", "Debug", false);
scrappingMultiplier =
Config.Bind("General", "Scrapping Multiplier", 1,
new ConfigDescription("Scrapping Multiplier", new AcceptableValueRange<int>(1, 10000)));
xpMultiplier =
Config.Bind("General", "XP Multiplier", 1,
new ConfigDescription("XP Multiplier", new AcceptableValueRange<float>(0.01f, 100f)));
Logger.LogInfo("Quasicyka loaded");
HarmonyFileLog.Enabled = true;
Harmony harmony = new Harmony(PluginGuid);
harmony.PatchAll();
var originalMethods = harmony.GetPatchedMethods();
Logger.LogInfo("Patched " + originalMethods.Count() + " methods");
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
namespace Quasimorph {
public class CykUtil {
public static bool IsPlayerTank(Module module) {
if (module == null)
return false;
TankBlock block = module.block;
if (block == null)
return false;
Tank tank = block.tank;
if (tank == null)
return false;
return tank.ControllableByLocalPlayer;
}
public static Func<object, bool> isObjectPlayerTank = obj => {
if (obj == null)
return false;
try {
return IsPlayerTank(obj as Module);
} catch (Exception e) {
Console.WriteLine("Failed to check if object is a player tank: " + e.Message);
return false;
}
};
}
}

View File

@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleBoosterManager {
private static readonly MultipliedObjectManager<FanJet> FanManager =
new MultipliedObjectManager<FanJet>(ConfigureFanThruster);
private static readonly MultipliedObjectManager<BoosterJet> JetManager =
new MultipliedObjectManager<BoosterJet>(ConfigureJetThruster);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> fanThrustMultiplier;
private static ConfigEntry<float> jetThrustMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Booster", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
fanThrustMultiplier =
config.Bind("Booster", "Fan Thrust Multiplier", 1f,
new ConfigDescription("Fan Thrust Multiplier", new AcceptableValueRange<float>(min, max)));
fanThrustMultiplier.SettingChanged += (sender, args) => DoPatch();
jetThrustMultiplier =
config.Bind("Booster", "Jet Thrust Multiplier", 1f,
new ConfigDescription("Jet Thrust Multiplier", new AcceptableValueRange<float>(min, max)));
jetThrustMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureFanThruster(MultipliedObject<FanJet> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_Force", fanThrustMultiplier, ShouldApply));
}
private static void ConfigureJetThruster(MultipliedObject<BoosterJet> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_Force", jetThrustMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.isObjectPlayerTank(obj);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleBooster), "OnAttached")]
public static void PostfixCreate(ModuleBooster __instance) {
var trav = Traverse.Create(__instance);
var fans = trav.Field("fans").GetValue<List<FanJet>>();
var jets = trav.Field("jets").GetValue<List<BoosterJet>>();
foreach (var fan in fans) FanManager.OnObjectAttached(fan);
foreach (var jet in jets) JetManager.OnObjectAttached(jet);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleBooster), "OnDetaching")]
public static void PostfixDestroy(ModuleBooster __instance) {
var trav = Traverse.Create(__instance);
var fans = trav.Field("fans").GetValue<List<FanJet>>();
var jets = trav.Field("jets").GetValue<List<BoosterJet>>();
foreach (var fan in fans) FanManager.OnObjectDetached(fan);
foreach (var jet in jets) JetManager.OnObjectDetached(jet);
}
private static void DoPatch() {
FanManager.ApplyAll();
JetManager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleBooster: {0}", obj);
PostfixCreate(obj as ModuleBooster);
return true;
};
}
}

View File

@@ -0,0 +1,67 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleEnergyManager {
private static readonly MultipliedObjectManager<ModuleEnergy> Manager =
new MultipliedObjectManager<ModuleEnergy>(ConfigureModuleEnergy);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> outputMultiplier;
private static ConfigEntry<float> powerUpDelayMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Energy", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
outputMultiplier =
config.Bind("Energy", "Output Multiplier", 1f,
new ConfigDescription("Output Multiplier", new AcceptableValueRange<float>(min, max)));
outputMultiplier.SettingChanged += (sender, args) => DoPatch();
powerUpDelayMultiplier = config.Bind(
"Energy", "Power Up Delay Multiplier", 1f,
new ConfigDescription("Power Up Delay Multiplier", new AcceptableValueRange<float>(min, max)));
powerUpDelayMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureModuleEnergy(MultipliedObject<ModuleEnergy> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_OutputPerSecond", outputMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_PowerUpDelay", powerUpDelayMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnAnchorStatusChanged")]
public static void PostfixCreate(ModuleEnergy __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")]
public static void PostfixDestroy(ModuleEnergy __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleEnergy: {0}", obj);
PostfixCreate(obj as ModuleEnergy);
return true;
};
}
}

View File

@@ -0,0 +1,60 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleEnergyStoreManager {
private static readonly MultipliedObjectManager<ModuleEnergyStore> Manager =
new MultipliedObjectManager<ModuleEnergyStore>(ConfigureModuleEnergyStore);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> capacityMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Energy", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
capacityMultiplier =
config.Bind("Energy", "Capacity Multiplier", 1f,
new ConfigDescription("Capacity Multiplier", new AcceptableValueRange<float>(min, max)));
capacityMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureModuleEnergyStore(MultipliedObject<ModuleEnergyStore> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_Capacity", capacityMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergyStore), "OnAttached")]
public static void PostfixCreate(ModuleEnergyStore __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergyStore), "OnDetaching")]
public static void PostfixDestroy(ModuleEnergyStore __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleEnergyStore: {0}", obj);
PostfixCreate(obj as ModuleEnergyStore);
return true;
};
}
}

View File

@@ -0,0 +1,67 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleFuelTankManager {
private static readonly MultipliedObjectManager<ModuleFuelTank> Manager =
new MultipliedObjectManager<ModuleFuelTank>(ConfigureFuelTank);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> fuelCapacityMultiplier;
private static ConfigEntry<float> fuelRefillMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("FuelTank", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
fuelCapacityMultiplier = config.Bind(
"FuelTank", "Fuel Capacity Multiplier", 1f,
new ConfigDescription("Fuel Capacity Multiplier", new AcceptableValueRange<float>(min, max)));
fuelCapacityMultiplier.SettingChanged += (sender, args) => DoPatch();
fuelRefillMultiplier =
config.Bind("FuelTank", "Fuel Refill Multiplier", 1f,
new ConfigDescription("Fuel Refill Multiplier", new AcceptableValueRange<float>(min, max)));
fuelRefillMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureFuelTank(MultipliedObject<ModuleFuelTank> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_Capacity", fuelCapacityMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_RefillRate", fuelRefillMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.isObjectPlayerTank(obj);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnAttached")]
public static void PostfixCreate(ModuleFuelTank __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnDetaching")]
public static void PostfixDestroy(ModuleFuelTank __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleFuelTank: {0}", obj);
PostfixCreate(obj as ModuleFuelTank);
return true;
};
}
}

View File

@@ -0,0 +1,60 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleGyroManager {
private static readonly MultipliedObjectManager<ModuleGyro> Manager =
new MultipliedObjectManager<ModuleGyro>(ConfigureModuleGyro);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> activeSpeedMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Gyro", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
activeSpeedMultiplier = config.Bind(
"Gyro", "Active Speed Multiplier", 1f,
new ConfigDescription("Active Speed Multiplier", new AcceptableValueRange<float>(min, max)));
activeSpeedMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureModuleGyro(MultipliedObject<ModuleGyro> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_ActiveSpeed", activeSpeedMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleGyro), "OnAttached")]
public static void PostfixCreate(ModuleGyro __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleGyro), "OnDetaching")]
public static void PostfixDestroy(ModuleGyro __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleGyro: {0}", obj);
PostfixCreate(obj as ModuleGyro);
return true;
};
}
}

View File

@@ -0,0 +1,76 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleHeartManager {
private static readonly MultipliedObjectManager<ModuleHeart> Manager =
new MultipliedObjectManager<ModuleHeart>(ConfigureHeart);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> eventHorizonRadiusMultiplier;
private static ConfigEntry<float> setupTimeMultiplier;
private static ConfigEntry<float> startShrinkingRadiusMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Heart", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
eventHorizonRadiusMultiplier = config.Bind(
"Heart", "Event Horizon Radius Multiplier", 1f,
new ConfigDescription("Event Horizon Radius Multiplier", new AcceptableValueRange<float>(min, max)));
eventHorizonRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
setupTimeMultiplier =
config.Bind("Heart", "Setup Time Multiplier", 1f,
new ConfigDescription("Setup Time Multiplier", new AcceptableValueRange<float>(min, max)));
setupTimeMultiplier.SettingChanged += (sender, args) => DoPatch();
startShrinkingRadiusMultiplier = config.Bind(
"Heart", "Start Shrinking Radius Multiplier", 1f,
new ConfigDescription("Start Shrinking Radius Multiplier", new AcceptableValueRange<float>(min, max)));
startShrinkingRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureHeart(MultipliedObject<ModuleHeart> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_EventHorizonRadius", eventHorizonRadiusMultiplier,
ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_SetupTime", setupTimeMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_StartShrinkingRadius", startShrinkingRadiusMultiplier,
ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.isObjectPlayerTank(obj);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleHeart), "OnAttached")]
public static void PostfixCreate(ModuleHeart __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleHeart), "OnDetaching")]
public static void PostfixDestroy(ModuleHeart __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleHeart: {0}", obj);
PostfixCreate(obj as ModuleHeart);
return true;
};
}
}

View File

@@ -0,0 +1,164 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleItemHolderManager {
private static readonly MultipliedObjectManager<ModuleItemHolder> BeamManager =
new MultipliedObjectManager<ModuleItemHolder>(ConfigureBeam);
private static readonly MultipliedObjectManager<ModuleItemHolderBeam> BeamHolderManager =
new MultipliedObjectManager<ModuleItemHolderBeam>(ConfigureBeamHolder);
private static readonly MultipliedObjectManager<ModuleItemPickup> BeamPickupManager =
new MultipliedObjectManager<ModuleItemPickup>(ConfigureBeamPickup);
private static readonly MultipliedObjectManager<ModuleItemHolderMagnet> MagnetHolderManager =
new MultipliedObjectManager<ModuleItemHolderMagnet>(ConfigureMagnetHolder);
private static readonly MultipliedObjectManager<ModuleItemPickup> MagnetPickupManager =
new MultipliedObjectManager<ModuleItemPickup>(ConfigureMagnetPickup);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> capacityPerStackMultiplier;
private static ConfigEntry<float> beamStrengthMultiplier;
private static ConfigEntry<float> beamHeightIncrementScaleMultiplier;
private static ConfigEntry<float> beamPickupRangeMultiplier;
private static ConfigEntry<float> magnetStrengthMultiplier;
private static ConfigEntry<float> magnetPickupRangeMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Item Holder", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
capacityPerStackMultiplier = config.Bind(
"Item Holder", "Capacity Per Stack Multiplier", 1f,
new ConfigDescription("Capacity Per Stack Multiplier", new AcceptableValueRange<float>(min, max)));
capacityPerStackMultiplier.SettingChanged += (sender, args) => DoPatch();
beamStrengthMultiplier = config.Bind(
"Item Holder", "Beam Strength Multiplier", 1f,
new ConfigDescription("Beam Strength Multiplier", new AcceptableValueRange<float>(min, max)));
beamStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
beamHeightIncrementScaleMultiplier =
config.Bind("Item Holder", "Beam Height Increment Scale Multiplier", 1f,
new ConfigDescription("Beam Height Increment Scale Multiplier",
new AcceptableValueRange<float>(min, max)));
beamHeightIncrementScaleMultiplier.SettingChanged += (sender, args) => DoPatch();
beamPickupRangeMultiplier = config.Bind(
"Item Holder", "Beam Pickup Range Multiplier", 1f,
new ConfigDescription("Beam Pickup Range Multiplier", new AcceptableValueRange<float>(min, max)));
beamPickupRangeMultiplier.SettingChanged += (sender, args) => DoPatch();
magnetStrengthMultiplier = config.Bind(
"Item Holder", "Magnet Strength Multiplier", 1f,
new ConfigDescription("Magnet Strength Multiplier", new AcceptableValueRange<float>(min, max)));
magnetStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
magnetPickupRangeMultiplier = config.Bind(
"Item Holder", "Magnet Pickup Range Multiplier", 1f,
new ConfigDescription("Magnet Pickup Range Multiplier", new AcceptableValueRange<float>(min, max)));
magnetPickupRangeMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureBeam(MultipliedObject<ModuleItemHolder> obj) {
obj.AddField(
new FieldConfiguration<int, float>("m_CapacityPerStack", capacityPerStackMultiplier, ShouldApply));
}
private static void ConfigureBeamHolder(MultipliedObject<ModuleItemHolderBeam> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_BeamStrength", beamStrengthMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_HeightIncrementScale",
beamHeightIncrementScaleMultiplier, ShouldApply));
}
private static void ConfigureBeamPickup(MultipliedObject<ModuleItemPickup> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_PickupRange", beamPickupRangeMultiplier, ShouldApply));
}
private static void ConfigureMagnetHolder(MultipliedObject<ModuleItemHolderMagnet> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_Strength", magnetStrengthMultiplier, ShouldApply));
}
private static void ConfigureMagnetPickup(MultipliedObject<ModuleItemPickup> obj) {
obj.AddField(
new FieldConfiguration<float, float>("m_PickupRange", magnetPickupRangeMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolder), "OnAttached")]
public static void PostfixCreate(ModuleItemHolder __instance) {
BeamManager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolder), "OnDetaching")]
public static void PostfixDestroy(ModuleItemHolder __instance) {
BeamManager.OnObjectDetached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnAttached")]
public static void PostfixCreate(ModuleItemHolderBeam __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
BeamHolderManager.OnObjectAttached(__instance);
BeamPickupManager.OnObjectAttached(pickup);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnDetaching")]
public static void PostfixDestroy(ModuleItemHolderBeam __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
BeamHolderManager.OnObjectDetached(__instance);
BeamPickupManager.OnObjectDetached(pickup);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnAttached")]
public static void PostfixCreate(ModuleItemHolderMagnet __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
MagnetHolderManager.OnObjectAttached(__instance);
MagnetPickupManager.OnObjectAttached(pickup);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnDetaching")]
public static void PostfixDestroy(ModuleItemHolderMagnet __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
MagnetHolderManager.OnObjectDetached(__instance);
MagnetPickupManager.OnObjectDetached(pickup);
}
private static void DoPatch() {
BeamManager.ApplyAll();
BeamHolderManager.ApplyAll();
BeamPickupManager.ApplyAll();
MagnetHolderManager.ApplyAll();
MagnetPickupManager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleItemHolder: {0}", obj);
PostfixCreate(obj as ModuleItemHolder);
return true;
};
}
}

View File

@@ -0,0 +1,77 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleItemProducerManager {
private static readonly MultipliedObjectManager<ModuleItemProducer> Manager =
new MultipliedObjectManager<ModuleItemProducer>(ConfigureModuleItemProducer);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> resourceGroundRadiusMultiplier;
private static ConfigEntry<float> minDispenseIntervalMultiplier;
private static ConfigEntry<float> secPerItemProducedMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
playerOnly = config.Bind("Item Producer", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
resourceGroundRadiusMultiplier = config.Bind(
"Item Producer", "Resource Ground Radius Multiplier", 1f,
new ConfigDescription("Resource Ground Radius Multiplier", new AcceptableValueRange<float>(min, max)));
resourceGroundRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
minDispenseIntervalMultiplier = config.Bind(
"Item Producer", "Min Dispense Interval Multiplier", 1f,
new ConfigDescription("Min Dispense Interval Multiplier", new AcceptableValueRange<float>(min, max)));
minDispenseIntervalMultiplier.SettingChanged += (sender, args) => DoPatch();
secPerItemProducedMultiplier = config.Bind(
"Item Producer", "Sec Per Item Produced Multiplier", 1f,
new ConfigDescription("Sec Per Item Produced Multiplier", new AcceptableValueRange<float>(min, max)));
secPerItemProducedMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureModuleItemProducer(MultipliedObject<ModuleItemProducer> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_ResourceGroundRadius", resourceGroundRadiusMultiplier,
ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_MinDispenseInterval", minDispenseIntervalMultiplier,
ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_SecPerItemProduced", secPerItemProducedMultiplier,
ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemProducer), "GetClosestResourceReservoirInRange")]
public static void PostfixCreate(ModuleItemProducer __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")]
public static void PostfixDestroy(ModuleItemProducer __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleItemProducer: {0}", obj);
PostfixCreate(obj as ModuleItemProducer);
return true;
};
}
}

View File

@@ -0,0 +1,77 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleRemoteChargerManager {
private static readonly MultipliedObjectManager<ModuleRemoteCharger> Manager =
new MultipliedObjectManager<ModuleRemoteCharger>(ConfigureModuleRemoteCharger);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> arcFiringIntervalMultiplier;
private static ConfigEntry<float> chargingRadiusMultiplier;
private static ConfigEntry<float> powerTransferPerArcMultiplier;
public static void Setup(ConfigFile config) {
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("Remote Charger", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
arcFiringIntervalMultiplier = config.Bind(
"Remote Charger", "Arc Firing Interval Multiplier", 1f,
new ConfigDescription("Arc Firing Interval Multiplier", new AcceptableValueRange<float>(min, max)));
arcFiringIntervalMultiplier.SettingChanged += (sender, args) => DoPatch();
chargingRadiusMultiplier = config.Bind(
"Remote Charger", "Charging Radius Multiplier", 1f,
new ConfigDescription("Charging Radius Multiplier", new AcceptableValueRange<float>(min, max)));
chargingRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
powerTransferPerArcMultiplier = config.Bind(
"Remote Charger", "Power Transfer Per Arc Multiplier", 1f,
new ConfigDescription("Power Transfer Per Arc Multiplier", new AcceptableValueRange<float>(min, max)));
powerTransferPerArcMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureModuleRemoteCharger(MultipliedObject<ModuleRemoteCharger> obj) {
obj.AddField(
new FieldConfiguration<float, float>("m_ArcFiringInterval", arcFiringIntervalMultiplier, ShouldApply));
obj.AddField(
new FieldConfiguration<float, float>("m_ChargingRadius", chargingRadiusMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_PowerTransferPerArc", powerTransferPerArcMultiplier,
ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnAttached")]
public static void PostfixCreate(ModuleRemoteCharger __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnDetaching")]
public static void PostfixDestroy(ModuleRemoteCharger __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleRemoteCharger: {0}", obj);
PostfixCreate(obj as ModuleRemoteCharger);
return true;
};
}
}

View File

@@ -0,0 +1,88 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleShieldGeneratorManager {
private static readonly MultipliedObjectManager<ModuleShieldGenerator> Manager =
new MultipliedObjectManager<ModuleShieldGenerator>(ConfigureShieldGenerator);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> radiusMultiplier;
private static ConfigEntry<float> radiusMultiplierHealing;
private static ConfigEntry<float> heartbeatIntervalMultiplier;
private static ConfigEntry<float> powerUpDelayMultiplier;
public static void Setup(ConfigFile config) {
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("Shield", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
radiusMultiplier =
config.Bind("Shield", "Radius Multiplier", 1f,
new ConfigDescription("Radius Multiplier", new AcceptableValueRange<float>(min, max)));
radiusMultiplier.SettingChanged += (sender, args) => DoPatch();
heartbeatIntervalMultiplier = config.Bind(
"Shield", "Heartbeat Interval Multiplier", 1f,
new ConfigDescription("Heartbeat Interval Multiplier", new AcceptableValueRange<float>(min, max)));
heartbeatIntervalMultiplier.SettingChanged += (sender, args) => DoPatch();
powerUpDelayMultiplier = config.Bind(
"Shield", "Power Up Delay Multiplier", 1f,
new ConfigDescription("Power Up Delay Multiplier", new AcceptableValueRange<float>(min, max)));
powerUpDelayMultiplier.SettingChanged += (sender, args) => DoPatch();
radiusMultiplierHealing = config.Bind(
"Shield", "Radius Multiplier Healing", 1f,
new ConfigDescription("Radius Multiplier Healing", new AcceptableValueRange<float>(min, max)));
radiusMultiplierHealing.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureShieldGenerator(MultipliedObject<ModuleShieldGenerator> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_HealingHeartbeatInterval", heartbeatIntervalMultiplier,
ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_Radius", radiusMultiplier, __instance => {
if (!ShouldApply(__instance))
return radiusMultiplier;
var shield = (ModuleShieldGenerator)__instance;
return shield.m_Healing ? radiusMultiplierHealing : radiusMultiplier;
}));
obj.AddField(new FieldConfiguration<float, float>("m_PowerUpDelay", powerUpDelayMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")]
public static void PostfixCreate(ModuleShieldGenerator __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")]
public static void PostfixDestroy(ModuleShieldGenerator __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleShieldGenerator: {0}", obj);
PostfixCreate(obj as ModuleShieldGenerator);
return true;
};
}
}

View File

@@ -0,0 +1,121 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleWeaponGunManager {
private static readonly MultipliedObjectManager<ModuleWeaponGun> Manager =
new MultipliedObjectManager<ModuleWeaponGun>(ConfigureManager);
private static readonly MultipliedObjectManager<FireData> FireDataManager =
new MultipliedObjectManager<FireData>(ConfigureFireData);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> kickbackStrengthMultiplier;
private static ConfigEntry<float> muzzleVelocityMultiplier;
private static ConfigEntry<float> burstCooldownMultiplier;
private static ConfigEntry<float> burstShotCountMultiplier;
private static ConfigEntry<float> shotCooldownMultiplier;
private static ConfigEntry<bool> seekingRoundsAll;
private static ConfigEntry<bool> resetBurstOnInterruptAll;
public static void Setup(ConfigFile config) {
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("WeaponGun", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
kickbackStrengthMultiplier = config.Bind(
"FireData", "Kickback Strength Multiplier", 1f,
new ConfigDescription("Kickback Strength Multiplier", new AcceptableValueRange<float>(min, max)));
kickbackStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
muzzleVelocityMultiplier = config.Bind(
"FireData", "Muzzle Velocity Multiplier", 1f,
new ConfigDescription("Muzzle Velocity Multiplier", new AcceptableValueRange<float>(min, max)));
muzzleVelocityMultiplier.SettingChanged += (sender, args) => DoPatch();
burstCooldownMultiplier = config.Bind(
"FireData", "Burst Cooldown Multiplier", 1f,
new ConfigDescription("Burst Cooldown Multiplier", new AcceptableValueRange<float>(min, max)));
burstCooldownMultiplier.SettingChanged += (sender, args) => DoPatch();
burstShotCountMultiplier = config.Bind(
"FireData", "Burst Shot Count Multiplier", 1f,
new ConfigDescription("Burst Shot Count Multiplier", new AcceptableValueRange<float>(min, max)));
burstShotCountMultiplier.SettingChanged += (sender, args) => DoPatch();
shotCooldownMultiplier = config.Bind(
"FireData", "Shot Cooldown Multiplier", 1f,
new ConfigDescription("Shot Cooldown Multiplier", new AcceptableValueRange<float>(min, max)));
shotCooldownMultiplier.SettingChanged += (sender, args) => DoPatch();
seekingRoundsAll =
config.Bind("FireData", "Seeking Rounds All", false,
new ConfigDescription("Seeking Rounds All", new AcceptableValueRange<bool>(false, true)));
seekingRoundsAll.SettingChanged += (sender, args) => DoPatch();
resetBurstOnInterruptAll = config.Bind(
"FireData", "Reset Burst On Interrupt All", false,
new ConfigDescription("Reset Burst On Interrupt All", new AcceptableValueRange<bool>(false, true)));
resetBurstOnInterruptAll.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureManager(MultipliedObject<ModuleWeaponGun> obj) {
obj.AddBooleanField(new BooleanFieldConfiguration("m_SeekingRounds", seekingRoundsAll, ShouldApply));
obj.AddBooleanField(
new BooleanFieldConfiguration("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_BurstCooldown", burstCooldownMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<int, float>("m_BurstShotCount", burstShotCountMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_ShotCooldown", shotCooldownMultiplier, ShouldApply));
}
private static void ConfigureFireData(MultipliedObject<FireData> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_MuzzleVelocity", muzzleVelocityMultiplier));
obj.AddField(new FieldConfiguration<float, float>("m_KickbackStrength", kickbackStrengthMultiplier));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeaponGun), "OnAttached")]
public static void PostfixCreate(ModuleWeaponGun __instance) {
Manager.OnObjectAttached(__instance);
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
var trav = Traverse.Create(__instance);
var firingData = trav.Field("m_FiringData");
FireDataManager.OnObjectAttached(firingData.GetValue<FireData>());
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeaponGun), "OnDetaching")]
public static void PostfixDestroy(ModuleWeaponGun __instance) {
Manager.OnObjectAttached(__instance);
var trav = Traverse.Create(__instance);
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
var firingData = trav.Field("m_FiringData");
FireDataManager.OnObjectDetached(firingData.GetValue<FireData>());
}
private static void DoPatch() {
FireDataManager.ApplyAll();
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWeaponGun: {0}", obj);
PostfixCreate(obj as ModuleWeaponGun);
return true;
};
}
}

View File

@@ -0,0 +1,60 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleWeaponManager {
private static readonly MultipliedObjectManager<ModuleWeapon> Manager =
new MultipliedObjectManager<ModuleWeapon>(ConfigureManager);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> rotateSpeedMultiplier;
public static void Setup(ConfigFile config) {
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("ModuleWeapon", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
rotateSpeedMultiplier = config.Bind(
"ModuleWeapon", "Rotate Speed Multiplier", 1f,
new ConfigDescription("Rotate Speed Multiplier", new AcceptableValueRange<float>(min, max)));
rotateSpeedMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureManager(MultipliedObject<ModuleWeapon> obj) {
obj.AddField(new FieldConfiguration<float, float>("m_RotateSpeed", rotateSpeedMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeapon), "OnAttached")]
public static void PostfixCreate(ModuleWeapon __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeapon), "OnDetaching")]
public static void PostfixDestroy(ModuleWeapon __instance) {
Manager.OnObjectDetached(__instance);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWeapon: {0}", obj);
PostfixCreate(obj as ModuleWeapon);
return true;
};
}
}

View File

@@ -0,0 +1,71 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleWheelsManager {
private static readonly MultipliedObjectManager<ManWheels.TorqueParams> TorqueParamsManager =
new MultipliedObjectManager<ManWheels.TorqueParams>(ConfigureTorqueParams);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> torqueRpmMultiplier;
private static ConfigEntry<float> torqueMultiplier;
public static void Setup(ConfigFile config) {
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("TorqueParams", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
torqueRpmMultiplier =
config.Bind("TorqueParams", "Torque RPM Multiplier", 1f,
new ConfigDescription("Torque RPM Multiplier", new AcceptableValueRange<float>(min, max)));
torqueRpmMultiplier.SettingChanged += (sender, args) => DoPatch();
torqueMultiplier =
config.Bind("TorqueParams", "Torque Multiplier", 1f,
new ConfigDescription("Torque Multiplier", new AcceptableValueRange<float>(min, max)));
torqueMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureTorqueParams(MultipliedObject<ManWheels.TorqueParams> obj) {
obj.AddField(new FieldConfiguration<float, float>("torqueCurveMaxRpm", torqueRpmMultiplier, ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("torqueCurveMaxTorque", torqueMultiplier, ShouldApply));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWheels), "OnAttached")]
public static void PostfixCreate(ModuleWheels __instance) {
var trav = Traverse.Create(__instance);
var torqueParams = trav.Field("torqueParams");
TorqueParamsManager.OnObjectAttached(torqueParams.GetValue<ManWheels.TorqueParams>());
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWheels), "OnDetaching")]
public static void PostfixDestroy(ModuleWheels __instance) {
var trav = Traverse.Create(__instance);
var torqueParams = trav.Field("torqueParams");
TorqueParamsManager.OnObjectDetached(torqueParams.GetValue<ManWheels.TorqueParams>());
}
private static void DoPatch() {
TorqueParamsManager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWheels: {0}", obj);
PostfixCreate(obj as ModuleWheels);
return true;
};
}
}

View File

@@ -0,0 +1,83 @@
using System;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ModuleWingManager {
private static readonly MultipliedObjectManager<ModuleWing.Aerofoil> Manager =
new MultipliedObjectManager<ModuleWing.Aerofoil>(ConfigureAerofoil);
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> angleRangeMultiplier;
private static ConfigEntry<float> turnSpeedMultiplier;
private static ConfigEntry<float> liftStrengthMultiplier;
public static void Setup(ConfigFile config) {
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("Aerofoil", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
angleRangeMultiplier =
config.Bind("Aerofoil", "Angle Range Multiplier", 1f,
new ConfigDescription("Angle Range Multiplier", new AcceptableValueRange<float>(min, max)));
angleRangeMultiplier.SettingChanged += (sender, args) => DoPatch();
turnSpeedMultiplier =
config.Bind("Aerofoil", "Turn Speed Multiplier", 1f,
new ConfigDescription("Turn Speed Multiplier", new AcceptableValueRange<float>(min, max)));
turnSpeedMultiplier.SettingChanged += (sender, args) => DoPatch();
liftStrengthMultiplier = config.Bind(
"Aerofoil", "Lift Strength Multiplier", 1f,
new ConfigDescription("Lift Strength Multiplier", new AcceptableValueRange<float>(min, max)));
liftStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureAerofoil(MultipliedObject<ModuleWing.Aerofoil> obj) {
obj.AddField(new FieldConfiguration<float, float>("flapAngleRangeActual", angleRangeMultiplier));
obj.AddField(new FieldConfiguration<float, float>("flapAngleRangeVisual", angleRangeMultiplier));
obj.AddField(new FieldConfiguration<float, float>("flapTurnSpeed", turnSpeedMultiplier));
obj.AddField(new FieldConfiguration<float, float>("liftStrength", liftStrengthMultiplier));
}
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsPlayerTank(obj as Module);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWing), "OnAttached")]
public static void PostfixCreate(ModuleWing __instance) {
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
for (int i = 0; i < __instance.m_Aerofoils.Length; i++) {
var aerofoil = __instance.m_Aerofoils[i];
Manager.OnObjectAttached(aerofoil);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWing), "OnDetaching")]
public static void PostfixDestroy(ModuleWing __instance) {
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
foreach (var aerofoil in __instance.m_Aerofoils) Manager.OnObjectDetached(aerofoil);
}
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWing: {0}", obj);
PostfixCreate(obj as ModuleWing);
return true;
};
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Reflection;
using HarmonyLib;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Quasimorph {
[HarmonyPatch]
public class MultiBuy {
public static UIShopBlockSelect panel;
public static Traverse panelTraverse;
[HarmonyPostfix]
[HarmonyPatch(typeof(UIShopBlockSelect), "OnSpawn")]
public static void PostfixCreate(UIShopBlockSelect __instance) {
panel = __instance;
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance);
panelTraverse = Traverse.Create(__instance);
var placeButton = panelTraverse.Field("m_PurchaseBlockButton").GetValue<Button>();
placeButton.gameObject.AddComponent<MultiBuyRightClickHandler>();
}
}
class MultiBuyRightClickHandler : MonoBehaviour, IPointerClickHandler {
// private void Awake() {
// }
public void OnPointerClick(PointerEventData eventData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: {0} {1}", gameObject.name,
eventData.button);
try {
if (eventData.button == PointerEventData.InputButton.Right) {
UIBlockSelectGrid grid = MultiBuy.panelTraverse.Field("m_Grid").GetValue<UIBlockSelectGrid>();
BlockTypes blockTypes;
bool ok = grid.TryGetSelection(out blockTypes);
if (!ok) {
if (Main.debugBuyAll.Value)
Console.WriteLine(
"MultiBuyRightClickHandler.OnPointerClick: Failed to get block selection from grid");
return;
}
uint shopBlockPoolID = MultiBuy.panelTraverse.Field("m_ShopBlockPoolID").GetValue<uint>();
MethodInfo canPurchaseMethod =
AccessTools.Method(typeof(UIShopBlockSelect), "CanPurchaseBlock", new[] { typeof(BlockTypes) });
Func<BlockTypes, bool> canPurchase = (Func<BlockTypes, bool>)Delegate.CreateDelegate(
typeof(Func<BlockTypes, bool>), MultiBuy.panel, canPurchaseMethod);
for (int i = 0; i < Main.multiBuyAmount.Value; i++) {
if (!canPurchase.Invoke(blockTypes)) {
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Can purchase no more {0}",
blockTypes);
return;
}
Singleton.Manager<ManPurchases>.inst.RequestPurchaseBlock(shopBlockPoolID, blockTypes, 1);
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Purchased {0} block",
blockTypes);
}
}
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Exception occurred: {0}", e);
}
}
}
}

View File

@@ -0,0 +1,531 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
public interface IFieldModifier {
void CaptureOriginal();
void Apply();
void Restore();
void LogValue(string prefix);
}
/// <summary>
/// Represents a field that can be multiplied by a configurable value
/// </summary>
/// <typeparam name="TField">The type of the field value</typeparam>
/// <typeparam name="TMul">The type of the multiplier</typeparam>
public class FieldConfiguration<TField, TMul> {
private string _fieldName;
private ConfigEntry<TMul> _defaultMultiplier;
private Func<object, ConfigEntry<TMul>> _conditionalMultiplier;
private Func<object, bool> _applyCondition;
public string FieldName {
get { return _fieldName; }
set { _fieldName = value; }
}
public ConfigEntry<TMul> DefaultMultiplier {
get { return _defaultMultiplier; }
set { _defaultMultiplier = value; }
}
public Func<object, ConfigEntry<TMul>> ConditionalMultiplier {
get { return _conditionalMultiplier; }
set { _conditionalMultiplier = value; }
}
public Func<object, bool> ApplyCondition {
get { return _applyCondition; }
set { _applyCondition = value; }
}
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier) {
_fieldName = fieldName;
_defaultMultiplier = defaultMultiplier;
}
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier,
Func<object, ConfigEntry<TMul>> conditionalMultiplier) {
_fieldName = fieldName;
_defaultMultiplier = defaultMultiplier;
_conditionalMultiplier = conditionalMultiplier;
}
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier,
Func<object, bool> applyCondition) {
_fieldName = fieldName;
_defaultMultiplier = defaultMultiplier;
_applyCondition = applyCondition;
}
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier,
Func<object, ConfigEntry<TMul>> conditionalMultiplier,
Func<object, bool> applyCondition) {
_fieldName = fieldName;
_defaultMultiplier = defaultMultiplier;
_conditionalMultiplier = conditionalMultiplier;
_applyCondition = applyCondition;
}
public ConfigEntry<TMul> GetMultiplier(object __instance) {
if (_conditionalMultiplier == null) {
return _defaultMultiplier;
}
return _conditionalMultiplier(__instance);
}
public bool ShouldApply(object __instance) {
if (_applyCondition == null) {
return true;
}
return _applyCondition(__instance);
}
}
public class MultipliedField<TField, TMul> : IFieldModifier {
private readonly string _fieldName;
private readonly ConfigEntry<TMul> _multiplier;
private readonly Traverse _parentTraverse;
private readonly Func<object, bool> _applyCondition;
private TField _originalValue;
public string FieldName {
get { return _fieldName; }
}
public MultipliedField(string fieldName, ConfigEntry<TMul> multiplier, Traverse parentTraverse,
Func<object, bool> applyCondition = null) {
_fieldName = fieldName;
_multiplier = multiplier;
_parentTraverse = parentTraverse;
_applyCondition = applyCondition;
if (!parentTraverse.Field(fieldName).FieldExists()) {
throw new ArgumentException(
string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse));
}
// Verify TField is a numeric type
if (!IsNumericType(typeof(TField))) {
throw new ArgumentException(
string.Format("Field type {0} must be a numeric type", typeof(TField).Name));
}
// Verify TMul is a numeric type
if (!IsNumericType(typeof(TMul))) {
throw new ArgumentException(
string.Format("Multiplier type {0} must be a numeric type", typeof(TMul).Name));
}
}
private static bool IsNumericType(Type type) {
return type == typeof(byte) || type == typeof(sbyte) || type == typeof(short) || type == typeof(ushort) ||
type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) ||
type == typeof(float) || type == typeof(double) || type == typeof(decimal);
}
private TField MultiplyValues(TField fieldValue, TMul multiplierValue) {
// Convert both to double for the multiplication
double fieldDouble = Convert.ToDouble(fieldValue);
double multiplierDouble = Convert.ToDouble(multiplierValue);
double result = fieldDouble * multiplierDouble;
// Convert back to TField
return (TField)Convert.ChangeType(result, typeof(TField));
}
public TField GetValue() {
var value = _parentTraverse.Field(_fieldName).GetValue();
if (value == null)
throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName));
return (TField)value;
}
public void SetValue(TField value) {
_parentTraverse.Field(_fieldName).SetValue(value);
var verifyValue = GetValue();
if (!verifyValue.Equals(value))
throw new InvalidOperationException(
string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue));
}
public void CaptureOriginal() {
_originalValue = GetValue();
if (Main.debug.Value)
Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue);
}
public void Apply() {
try {
if (_applyCondition != null && !_applyCondition(_parentTraverse.GetValue())) {
if (Main.debug.Value)
Console.WriteLine("Skipping {0}: condition not met", _fieldName);
return;
}
var newValue = MultiplyValues(_originalValue, _multiplier.Value);
if (Main.debug.Value)
Console.WriteLine("Applying to {0}: {1} * {2} = {3}", _fieldName, _originalValue, _multiplier.Value,
newValue);
SetValue(newValue);
} catch (Exception e) {
throw new InvalidOperationException(string.Format("Failed to apply multiplication to {0}", _fieldName),
e);
}
}
public void Restore() {
if (Main.debug.Value)
Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue);
SetValue(_originalValue);
}
public void LogValue(string prefix) {
if (!Main.debug.Value)
return;
var currentValue = GetValue();
Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, multiplier: {5})", prefix, _parentTraverse, _fieldName,
currentValue, _originalValue, _multiplier.Value);
}
}
public class BooleanFieldConfiguration {
private string _fieldName;
private ConfigEntry<bool> _value;
private Func<object, ConfigEntry<bool>> _conditionalValue;
private Func<object, bool> _applyCondition;
public string FieldName {
get { return _fieldName; }
set { _fieldName = value; }
}
public ConfigEntry<bool> Value {
get { return _value; }
set { _value = value; }
}
public Func<object, ConfigEntry<bool>> ConditionalValue {
get { return _conditionalValue; }
set { _conditionalValue = value; }
}
public Func<object, bool> ApplyCondition {
get { return _applyCondition; }
set { _applyCondition = value; }
}
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value) {
_fieldName = fieldName;
_value = value;
}
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value,
Func<object, ConfigEntry<bool>> conditionalValue) {
_fieldName = fieldName;
_value = value;
_conditionalValue = conditionalValue;
}
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value, Func<object, bool> applyCondition) {
_fieldName = fieldName;
_value = value;
_applyCondition = applyCondition;
}
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value,
Func<object, ConfigEntry<bool>> conditionalValue,
Func<object, bool> applyCondition) {
_fieldName = fieldName;
_value = value;
_conditionalValue = conditionalValue;
_applyCondition = applyCondition;
}
public ConfigEntry<bool> GetValue(object __instance) {
if (_conditionalValue == null) {
return _value;
}
return _conditionalValue(__instance);
}
public bool ShouldApply(object __instance) {
if (_applyCondition == null) {
return true;
}
return _applyCondition(__instance);
}
}
public class BooleanField : IFieldModifier {
private readonly string _fieldName;
private readonly ConfigEntry<bool> _value;
private readonly Traverse _parentTraverse;
private readonly Func<object, bool> _applyCondition;
private bool _originalValue;
public string FieldName {
get { return _fieldName; }
}
public BooleanField(string fieldName, ConfigEntry<bool> value, Traverse parentTraverse,
Func<object, bool> applyCondition = null) {
_fieldName = fieldName;
_value = value;
_parentTraverse = parentTraverse;
_applyCondition = applyCondition;
if (!parentTraverse.Field(fieldName).FieldExists()) {
throw new ArgumentException(
string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse));
}
}
public bool GetValue() {
var value = _parentTraverse.Field(_fieldName).GetValue();
if (value == null)
throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName));
return (bool)value;
}
public void SetValue(bool value) {
_parentTraverse.Field(_fieldName).SetValue(value);
var verifyValue = GetValue();
if (verifyValue != value)
throw new InvalidOperationException(
string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue));
}
public void CaptureOriginal() {
_originalValue = GetValue();
if (Main.debug.Value)
Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue);
}
public void Apply() {
try {
if (_applyCondition != null && !_applyCondition(_parentTraverse.GetValue())) {
if (Main.debug.Value)
Console.WriteLine("Skipping {0}: condition not met", _fieldName);
return;
}
if (_value.Value) {
if (Main.debug.Value)
Console.WriteLine("Applying to {0}: forcing to true", _fieldName);
SetValue(true);
} else {
if (Main.debug.Value)
Console.WriteLine("Applying to {0}: leaving as {1} (config is false)", _fieldName, GetValue());
}
} catch (Exception e) {
throw new InvalidOperationException(string.Format("Failed to apply value to {0}", _fieldName), e);
}
}
public void Restore() {
if (Main.debug.Value)
Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue);
SetValue(_originalValue);
}
public void LogValue(string prefix) {
if (!Main.debug.Value)
return;
var currentValue = GetValue();
Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, config: {5})", prefix, _parentTraverse, _fieldName,
currentValue, _originalValue, _value.Value);
}
}
/// <summary>
/// Represents an object with multiple fields that can be multiplied
/// </summary>
/// <typeparam name="T">The type of the object being managed</typeparam>
public class MultipliedObject<T> {
private readonly T _instance;
private readonly Traverse _objectTraverse;
private readonly Dictionary<string, IFieldModifier> _fields;
public MultipliedObject(T __instance) {
_instance = __instance;
_objectTraverse = Traverse.Create(__instance);
_fields = new Dictionary<string, IFieldModifier>();
}
public void AddField<TField, TMul>(FieldConfiguration<TField, TMul> config) {
var multiplier = config.GetMultiplier(_instance);
_fields[config.FieldName] =
new MultipliedField<TField, TMul>(config.FieldName, multiplier, _objectTraverse, config.ShouldApply);
}
public void AddBooleanField(BooleanFieldConfiguration config) {
var value = config.GetValue(_instance);
_fields[config.FieldName] = new BooleanField(config.FieldName, value, _objectTraverse, config.ShouldApply);
}
public void CaptureFrom() {
foreach (var field in _fields.Values) {
field.CaptureOriginal();
}
}
public void ApplyTo(IEnumerable<string> fieldNames = null) {
IEnumerable<string> fieldsToApply = fieldNames ?? _fields.Keys;
foreach (var fieldName in fieldsToApply.Where(name => _fields.ContainsKey(name)))
_fields[fieldName].Apply();
}
public void RestoreTo(IEnumerable<string> fieldNames = null) {
IEnumerable<string> fieldsToRestore = fieldNames ?? _fields.Keys;
foreach (var fieldName in fieldsToRestore.Where(name => _fields.ContainsKey(name)))
_fields[fieldName].Restore();
}
public void LogValues(string prefix) {
if (!Main.debug.Value)
return;
foreach (var field in _fields.Values) {
field.LogValue(prefix);
}
}
}
/// <summary>
/// Manages a collection of objects whose fields can be multiplied
/// </summary>
/// <typeparam name="T">The type of objects being managed</typeparam>
public class MultipliedObjectManager<T> {
private readonly Dictionary<T, MultipliedObject<T>> _managedObjects;
private readonly Action<MultipliedObject<T>> _configureObject;
public MultipliedObjectManager(Action<MultipliedObject<T>> configureObject) {
if (configureObject == null)
throw new ArgumentNullException("configureObject");
_configureObject = configureObject;
_managedObjects = new Dictionary<T, MultipliedObject<T>>();
}
private void SafeRemove(T __instance) {
if (__instance == null)
return;
try {
_managedObjects.Remove(__instance);
} catch (Exception e) {
Console.WriteLine("Error removing __instance from _managedObjects: {0}", e);
}
}
public void OnObjectAttached(T __instance) {
if (Main.debug.Value)
Console.WriteLine("{0}.OnAttached", typeof(T).Name);
if (__instance == null) {
Console.WriteLine("Attempted to attach null __instance");
return;
}
try {
if (_managedObjects.ContainsKey(__instance)) {
if (Main.debug.Value)
Console.WriteLine("{0} already managed, skipping", typeof(T).Name);
return;
}
var multipliedObject = new MultipliedObject<T>(__instance);
_configureObject(multipliedObject);
multipliedObject.CaptureFrom();
_managedObjects.Add(__instance, multipliedObject);
multipliedObject.LogValues("Patching");
ApplyTo(__instance);
multipliedObject.LogValues("Patched");
} catch (Exception e) {
Console.WriteLine("Error in OnObjectAttached: {0}", e);
}
}
public void OnObjectDetached(T __instance) {
if (Main.debug.Value)
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
if (__instance == null) {
Console.WriteLine("Attempted to detach null __instance");
return;
}
try {
MultipliedObject<T> multipliedObject;
if (_managedObjects.TryGetValue(__instance, out multipliedObject)) {
if (Main.debug.Value)
multipliedObject.LogValues("Restoring");
try {
RestoreTo(__instance);
multipliedObject.LogValues("Restored");
} catch (Exception e) {
Console.WriteLine("Error restoring values: {0}", e);
}
SafeRemove(__instance);
}
} catch (Exception e) {
Console.WriteLine("Error in OnObjectDetached: {0}", e);
}
}
public void ApplyAll(IEnumerable<string> fieldNames = null) {
if (Main.debug.Value)
Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name);
// Make a copy of the keys to avoid modification during enumeration
var instances = _managedObjects.Keys.ToList();
foreach (var __instance in instances) {
try {
RestoreTo(__instance, fieldNames);
ApplyTo(__instance, fieldNames);
} catch (Exception e) {
Console.WriteLine("Error applying to __instance: {0}", e);
}
}
}
public void ApplyTo(T __instance, IEnumerable<string> fieldNames = null) {
if (Main.debug.Value)
Console.WriteLine("Applying {0}", typeof(T).Name);
if (__instance == null)
return;
try {
MultipliedObject<T> obj;
if (_managedObjects.TryGetValue(__instance, out obj))
obj.ApplyTo(fieldNames);
} catch (Exception e) {
Console.WriteLine("Error in ApplyTo: {0}", e);
}
}
public void RestoreTo(T __instance, IEnumerable<string> fieldNames = null) {
if (Main.debug.Value)
Console.WriteLine("Restoring {0}", typeof(T).Name);
if (__instance == null)
return;
try {
MultipliedObject<T> obj;
if (_managedObjects.TryGetValue(__instance, out obj))
obj.RestoreTo(fieldNames);
} catch (Exception e) {
Console.WriteLine("Error in RestoreTo: {0}", e);
}
}
}
}

View File

@@ -0,0 +1,24 @@
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class Patches {
[HarmonyPrefix]
[HarmonyPatch(typeof(ManLicenses), "AddXP")]
static void XpMulti(FactionSubTypes corporation, ref int xp, bool showUI = true) {
xp = (int)(xp * Main.xpMultiplier.Value);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ManPlayer), "AddMoney")]
static void MoneyMulti(ref int amount) {
amount = (int)(amount * Main.moneyMultiplier.Value);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TechHolders), "SetHeartbeatInterval")]
static void HeartbeatMulti(ref float interval) {
interval *= Main.heartbeatIntervalMultiplier.Value;
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class ProjectilePatch {
[HarmonyPrefix]
[HarmonyPatch(typeof(Projectile), "StickToObjectWithVisuals")]
static void Prefix(Projectile __instance) {
if (Main.debug.Value)
Console.WriteLine("Projectile created");
var trav = Traverse.Create(__instance);
var explodeOnStick = trav.Field("m_ExplodeOnStick");
if (!explodeOnStick.GetValue<bool>()) {
if (Main.debug.Value)
Console.WriteLine("Exploding on stick");
explodeOnStick.SetValue(Main.projectileExplodeOnStick.Value);
}
}
}
}

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("Quasimorph")]
[assembly:AssemblyDescription("")]
[assembly:AssemblyConfiguration("")]
[assembly:AssemblyCompany("")]
[assembly:AssemblyProduct("Quasimorph")]
[assembly:AssemblyCopyright("Copyright © 2023")]
[assembly:AssemblyTrademark("")]
[assembly:AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly:ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly:Guid("EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly:AssemblyVersion("1.0.0.0")]
[assembly:AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props"
Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<GAME_DIR>C:/Users/Administrator/scoop/apps/steam/current/steamapps/common/Quasimorph</GAME_DIR>
<GAME_MANAGED>$(GAME_DIR)/Quasimorph_Data/Managed</GAME_MANAGED>
<GAME_BEPINEX>$(GAME_DIR)/BepInEx</GAME_BEPINEX>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Quasimorph</RootNamespace>
<AssemblyName>Quasimorph</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<!-- <Compile Include="ModuleShieldGeneratorManager.cs" />
<Compile Include="ObjectFieldMultiplier.cs" />
<Compile Include="Patches.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SeekingProjectileManager.cs" />
<Compile Include="ModuleWingManager.cs" />
<Compile Include="ModuleBoosterManager.cs" />
<Compile Include="ModuleWeaponGunManager.cs" />
<Compile Include="ModuleEnergyManager.cs" />
<Compile Include="ModuleEnergyStoreManager.cs" />
<Compile Include="ModuleGyroManager.cs" />
<Compile Include="ModuleItemHolderManager.cs" />
<Compile Include="ModuleItemProducerManager.cs" />
<Compile Include="ModuleRemoteChargerManager.cs" />
<Compile Include="ModuleWheelsManager.cs" />
<Compile Include="TankBeamManager.cs" />
<Compile Include="ModuleWeaponManager.cs" />
<Compile Include="CykUtil.cs" />
<Compile Include="ModuleHeartManager.cs" />
<Compile Include="ModuleFuelTankManager.cs" />
<Compile Include="ProjectilePatch.cs" />
<Compile Include="TankManager.cs" />
<Compile Include="UISnapshotPanelBuyAll.cs" />
<Compile Include="MultiBuy.cs" /> -->
</ItemGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>$(GAME_BEPINEX)/core/0Harmony.dll</HintPath>
</Reference>
<Reference Include="BepInEx">
<HintPath>$(GAME_BEPINEX)/core/BepInEx.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>$(GAME_MANAGED)/UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(GAME_MANAGED)/UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>$(GAME_MANAGED)/UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>$(GAME_MANAGED)/Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="ConfigurationManager">
<HintPath>$(GAME_BEPINEX)/plugins/ConfigurationManager/ConfigurationManager.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,30 @@
using System;
using HarmonyLib;
namespace Quasimorph {
public class SeekingProjectileManager {
[HarmonyPatch(typeof(SeekingProjectile), "OnSpawn")]
class Patch {
public static void Postfix(SeekingProjectile __instance) {
if (Main.debug.Value)
Console.WriteLine("SeekingProjectile created");
SetField(
__instance, "m_VisionConeAngle",
Main.seekingProjectileVisionConeAngleMultiplier.Value * GetField(__instance, "m_VisionConeAngle"));
SetField(__instance, "m_VisionRange",
Main.seekingProjectileVisionRangeMultiplier.Value * GetField(__instance, "m_VisionRange"));
SetField(__instance, "m_TurnSpeed",
Main.seekingProjectileTurningSpeedMultiplier.Value * GetField(__instance, "m_TurnSpeed"));
}
}
private static float GetField(SeekingProjectile seekingProjectile, string field) {
return Traverse.Create(seekingProjectile).Field(field).GetValue() as float ? ?? 0f;
}
private static void SetField(SeekingProjectile seekingProjectile, string field, float value) {
Traverse.Create(seekingProjectile).Field(field).SetValue(value);
}
}
}

View File

@@ -0,0 +1,53 @@
using BepInEx.Configuration;
using HarmonyLib;
namespace Quasimorph {
[HarmonyPatch]
public class TankBeamManager {
private static readonly MultipliedObjectManager<TankBeam> Manager =
new MultipliedObjectManager<TankBeam>(ConfigureBeam);
public static ConfigEntry<float> hoverClearanceMultiplier;
public static ConfigEntry<float> nudgeSpeedForwardMultiplier;
public static ConfigEntry<float> nudgeSpeedRotateMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
hoverClearanceMultiplier = config.Bind(
"TankBeam", "Hover Clearance Multiplier", 1f,
new ConfigDescription("Hover Clearance Multiplier", new AcceptableValueRange<float>(min, max)));
hoverClearanceMultiplier.SettingChanged += (sender, args) => DoPatch();
nudgeSpeedForwardMultiplier = config.Bind(
"TankBeam", "Nudge Speed Forward Multiplier", 1f,
new ConfigDescription("Nudge Speed Forward Multiplier", new AcceptableValueRange<float>(min, max)));
nudgeSpeedForwardMultiplier.SettingChanged += (sender, args) => DoPatch();
nudgeSpeedRotateMultiplier = config.Bind(
"TankBeam", "Nudge Speed Rotate Multiplier", 1f,
new ConfigDescription("Nudge Speed Rotate Multiplier", new AcceptableValueRange<float>(min, max)));
nudgeSpeedRotateMultiplier.SettingChanged += (sender, args) => DoPatch();
}
private static void ConfigureBeam(MultipliedObject<TankBeam> obj) {
obj.AddField(new FieldConfiguration<float, float>("hoverClearance", hoverClearanceMultiplier));
obj.AddField(new FieldConfiguration<float, float>("nudgeSpeedForward", nudgeSpeedForwardMultiplier));
obj.AddField(new FieldConfiguration<float, float>("nudgeSpeedRotate", nudgeSpeedRotateMultiplier));
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TankBeam), "EnableBeam")]
public static void PostfixCreate(TankBeam __instance, ref bool enable) {
if (enable)
Manager.OnObjectAttached(__instance);
else
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
Manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
namespace Quasimorph {
[HarmonyPatch]
public class TankManager {
public static ConfigEntry<bool> recheck;
public static Dictionary<Type, Func<Module, bool>> moduleManagerMapper =
new Dictionary<Type, Func<Module, bool>>();
public static void Setup(ConfigFile config) {
recheck = config.Bind("Tank", "Recheck", false, new ConfigDescription("Recheck"));
moduleManagerMapper.Add(typeof(ModuleBooster), ModuleBoosterManager.Register);
moduleManagerMapper.Add(typeof(ModuleEnergy), ModuleEnergyManager.Register);
moduleManagerMapper.Add(typeof(ModuleEnergyStore), ModuleEnergyStoreManager.Register);
moduleManagerMapper.Add(typeof(ModuleFuelTank), ModuleFuelTankManager.Register);
moduleManagerMapper.Add(typeof(ModuleGyro), ModuleGyroManager.Register);
moduleManagerMapper.Add(typeof(ModuleHeart), ModuleHeartManager.Register);
moduleManagerMapper.Add(typeof(ModuleItemHolder), ModuleItemHolderManager.Register);
moduleManagerMapper.Add(typeof(ModuleItemProducer), ModuleItemProducerManager.Register);
moduleManagerMapper.Add(typeof(ModuleRemoteCharger), ModuleRemoteChargerManager.Register);
moduleManagerMapper.Add(typeof(ModuleShieldGenerator), ModuleShieldGeneratorManager.Register);
moduleManagerMapper.Add(typeof(ModuleWeaponGun), ModuleWeaponGunManager.Register);
moduleManagerMapper.Add(typeof(ModuleWeapon), ModuleWeaponManager.Register);
moduleManagerMapper.Add(typeof(ModuleWheels), ModuleWheelsManager.Register);
moduleManagerMapper.Add(typeof(ModuleWing), ModuleWingManager.Register);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Tank), "NotifyAnchor")]
public static void PostfixCreate(Tank __instance, ModuleAnchor anchor, bool anchored) {
if (Main.debug.Value)
Console.WriteLine("TankManager.NotifyAnchor: {0}", __instance);
if (!__instance.ControllableByLocalPlayer)
return;
if (!recheck.Value)
return;
foreach (Transform child in __instance.transform) {
GameObject childObj = child.gameObject;
Component[] components = childObj.GetComponents<Component>();
foreach (Component component in components) {
Func<Module, bool> manager;
if (moduleManagerMapper.TryGetValue(component.GetType(), out manager))
manager(component as Module);
}
}
}
}
}

View File

@@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
using Snapshots;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Quasimorph {
[HarmonyPatch]
public class UISnapshotPanelBuyAll {
public static UISnapshotPanel panel;
public static Traverse panelTraverse;
public static SnapshotLiveData selectedData;
[HarmonyPostfix]
[HarmonyPatch(typeof(UISnapshotPanel), "OnPool")]
public static void PostfixCreate(UISnapshotPanel __instance) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance);
panel = __instance;
panelTraverse = Traverse.Create(__instance);
var placeButton = panelTraverse.Field("m_PlaceButton").GetValue<Button>();
placeButton.gameObject.AddComponent<RightClickHandler>();
var swapButton = panelTraverse.Field("m_SwapButton").GetValue<Button>();
swapButton.gameObject.AddComponent<RightClickHandlerSwap>();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UISnapshotPanel), "OnSelectedChanged")]
public static void PostfixCreate(UISnapshotPanel __instance, ref SnapshotLiveData selectedData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnSelectedChanged: {0}", __instance);
UISnapshotPanelBuyAll.selectedData = selectedData;
}
}
public abstract class BaseRightClickHandler : MonoBehaviour, IPointerClickHandler {
protected static Traverse m_TechAvailLookupTraverse;
protected static Dictionary<Snapshot, TechDataAvailValidation> m_TechAvailLookup;
protected virtual void Awake() {
var trav = Traverse.Create(Singleton.Manager<ManSnapshots>.inst);
m_TechAvailLookupTraverse = trav.Field("m_TechAvailLookup");
m_TechAvailLookup = m_TechAvailLookupTraverse.GetValue<Dictionary<Snapshot, TechDataAvailValidation>>();
}
protected Dictionary<BlockTypes, int> CalculateMissingBlocks(
Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> blockAvailability, bool isSpawning) {
Dictionary<BlockTypes, int> missing = new Dictionary<BlockTypes, int>();
foreach (var kvp in blockAvailability) {
int numMissing;
if (isSpawning)
numMissing = kvp.Value.numRequired - kvp.Value.numInInventory;
else
numMissing = kvp.Value.numRequired - kvp.Value.numInInventory - kvp.Value.numOnPlayerTech;
}
if (missing.Count == 0)
foreach (var kvp in blockAvailability) missing.Add(kvp.Key, kvp.Value.numRequired);
return missing;
}
protected int CalculateTotalCost(Dictionary<BlockTypes, int> missingBlocks) {
int totalCost = 0;
RecipeManager recipeManager = Singleton.Manager<RecipeManager>.inst;
foreach (var kvp in missingBlocks) {
int cost = recipeManager.GetBlockBuyPrice(kvp.Key) * kvp.Value;
totalCost += cost;
if (Main.debugBuyAll.Value)
Console.WriteLine("{0} of {1} would cost {2}, total now {3}", kvp.Value, kvp.Key, cost, totalCost);
}
return totalCost;
}
protected bool TryPurchaseBlocks(Dictionary<BlockTypes, int> missingBlocks, int totalCost) {
ManPlayer player = Singleton.Manager<ManPlayer>.inst;
if (player.GetCurrentMoney() < totalCost) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Not enough money, have {0} but need {1}, nothing to do",
player.GetCurrentMoney(), totalCost);
return false;
}
player.PayMoney(totalCost);
foreach (var kvp in missingBlocks) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Buying {0} of {1}", kvp.Value, kvp.Key);
player.PlayerInventory.HostAddItem(kvp.Key, kvp.Value);
}
return true;
}
protected bool ProcessPurchase(
Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> blockAvailability, bool isSpawning) {
try {
if (blockAvailability == null) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Block availability is null (wtf?), nothing to do");
return false;
}
var missingBlocks = CalculateMissingBlocks(blockAvailability, isSpawning);
int totalCost = CalculateTotalCost(missingBlocks);
if (totalCost > 0) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Total cost: {0}", totalCost);
return TryPurchaseBlocks(missingBlocks, totalCost);
}
if (Main.debugBuyAll.Value)
Console.WriteLine("No blocks missing or no cost calculated");
return false;
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Error during purchase processing: {0}", e);
return false;
}
}
protected Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> GetCurrentBlockAvailability() {
SnapshotLiveData selectedSnapshotData = UISnapshotPanelBuyAll.selectedData;
Snapshot selectedSnapshot = selectedSnapshotData.m_Snapshot;
if (selectedSnapshot == null) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Selected snapshot is null wtf??: {0}", gameObject.name);
return null;
}
TechDataAvailValidation techDataAvail;
if (!m_TechAvailLookup.TryGetValue(selectedSnapshot, out techDataAvail)) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Failed to find TechDataAvailValidation for snapshot: {0}", selectedSnapshot);
return null;
}
var trav = Traverse.Create(techDataAvail);
var mBlockAvailabilityField = trav.Field("m_BlockAvailability");
var mBlockAvailability =
mBlockAvailabilityField
.GetValue<Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability>>();
return mBlockAvailability;
}
public abstract void OnPointerClick(PointerEventData eventData);
}
public class RightClickHandler : BaseRightClickHandler {
public override void OnPointerClick(PointerEventData eventData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPointerClick: {0} {1}", gameObject.name, eventData.button);
try {
if (eventData.button == PointerEventData.InputButton.Right)
ProcessPurchase(GetCurrentBlockAvailability(), true);
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Shit exploded fml: {0}", e);
}
}
}
public class RightClickHandlerSwap : BaseRightClickHandler {
public override void OnPointerClick(PointerEventData eventData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPointerClick: {0} {1}", gameObject.name, eventData.button);
try {
if (eventData.button == PointerEventData.InputButton.Right)
ProcessPurchase(GetCurrentBlockAvailability(), false);
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Shit exploded fml: {0}", e);
}
}
}
}

View File

@@ -0,0 +1,14 @@
static void Postfix(UIItemSelectGrid __instance) {
try {
StringBuilder sb = new StringBuilder();
sb.AppendLine("--------------------");
sb.AppendLine("void UIItemSelectGrid::Repopulate()");
sb.Append("- __instance: ").AppendLine(__instance.ToString());
foreach (var item in __instance.m_FilteredItemList) {
sb.Append("- item: ").AppendLine(item.ToString());
}
UnityExplorer.ExplorerCore.Log(sb.ToString());
} catch (System.Exception ex) {
UnityExplorer.ExplorerCore.LogWarning($"Exception in patch of void UIItemSelectGrid::Repopulate():\n{ex}");
}
}

View File

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

View File

@@ -0,0 +1,3 @@
- source: Quasimorph/obj/Release/Quasimorph.dll
target: ~/scoop/apps/steam/current/steamapps/common/Quasimorph/BepInEx/plugins/Quasimorph.dll
delete: true

View File

@@ -1 +0,0 @@
bin/Release/DavesPhatStore.dll,"C:\Games\Supermarket Simulator\BepInEx\plugins\DavesPhatStore.dll"

View File

@@ -0,0 +1,3 @@
- source: bin/Release/DavesPhatStore.dll
target: C:\Games\Supermarket Simulator\BepInEx\plugins\DavesPhatStore.dll
delete: true

View File

@@ -1 +0,0 @@
bin/Release/DavesPhatStore.dll,"C:/Program Files (x86)/Steam/steamapps/common/Supermarket Together/BepInEx/plugins/DavesPhatStore.dll"

View File

@@ -0,0 +1,3 @@
- source: bin/Release/DavesPhatStore.dll
target: C:/Program Files (x86)/Steam/steamapps/common/Supermarket Together/BepInEx/plugins/DavesPhatStore.dll
delete: true

View File

@@ -1 +0,0 @@
bin/Release/TavernDave.dll,"C:\Games\Tavern Master\BepInEx\plugins\TavernDave.dll"

View File

@@ -0,0 +1,3 @@
- source: bin/Release/TavernDave.dll
target: C:\Games\Tavern Master\BepInEx\plugins\TavernDave.dll
delete: true

View File

@@ -8,13 +8,17 @@ using HarmonyLib.Tools;
// TODO: Maybe make props faster, thrusters work fine
namespace TerraTech {
[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
public class Main : BaseUnityPlugin {
private const string pluginGuid = "CykaMod";
private const string pluginName = "CykaMod";
private const string pluginVersion = "1.0.0";
private const string PluginGuid = "CykaMod";
private const string PluginName = "CykaMod";
private const string PluginVersion = "1.0.0";
public static ConfigEntry<bool> debug;
public static ConfigEntry<bool> debugBuyAll;
public static ConfigEntry<bool> debugMultiBuy;
public static ConfigEntry<int> multiBuyAmount;
public static ConfigEntry<float> xpMultiplier;
public static ConfigEntry<float> moneyMultiplier;
public static ConfigEntry<float> heartbeatIntervalMultiplier;
@@ -25,6 +29,11 @@ namespace TerraTech {
public void Awake() {
debug = Config.Bind("General", "Debug", false);
debugBuyAll = Config.Bind("General", "Debug Buy All", false);
debugMultiBuy = Config.Bind("General", "Debug Multi Buy", false);
multiBuyAmount =
Config.Bind("General", "Multi Buy Amount", 10,
new ConfigDescription("Multi Buy Amount", new AcceptableValueRange<int>(1, 10000)));
float min = 0.01f;
float max = 32f;
@@ -43,6 +52,7 @@ namespace TerraTech {
ModuleWeaponManager.Setup(Config);
ModuleHeartManager.Setup(Config);
ModuleFuelTankManager.Setup(Config);
TankManager.Setup(Config);
xpMultiplier =
Config.Bind("General", "XP Multiplier", 1f,
@@ -72,7 +82,7 @@ namespace TerraTech {
Logger.LogInfo("Cyka mod loaded");
HarmonyFileLog.Enabled = true;
Harmony harmony = new Harmony(pluginGuid);
Harmony harmony = new Harmony(PluginGuid);
harmony.PatchAll();
var originalMethods = harmony.GetPatchedMethods();
Logger.LogInfo("Patched " + originalMethods.Count() + " methods");

View File

@@ -14,7 +14,7 @@ namespace TerraTech {
return tank.ControllableByLocalPlayer;
}
public static Func<object, bool> IsObjectPlayerTank = obj => {
public static Func<object, bool> isObjectPlayerTank = obj => {
if (obj == null)
return false;
try {

View File

@@ -6,14 +6,14 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleBoosterManager {
private static readonly MultipliedObjectManager<FanJet> fanManager =
private static readonly MultipliedObjectManager<FanJet> FanManager =
new MultipliedObjectManager<FanJet>(ConfigureFanThruster);
private static readonly MultipliedObjectManager<BoosterJet> jetManager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> fanThrustMultiplier;
private static ConfigEntry<float> jetThrustMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -44,34 +44,41 @@ namespace TerraTech {
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsObjectPlayerTank(obj);
return CykUtil.isObjectPlayerTank(obj);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleBooster), "OnAttached")]
static void PostfixCreate(ModuleBooster __instance) {
public static void PostfixCreate(ModuleBooster __instance) {
var trav = Traverse.Create(__instance);
var fans = trav.Field("fans").GetValue<List<FanJet>>();
var jets = trav.Field("jets").GetValue<List<BoosterJet>>();
foreach (var fan in fans) fanManager.OnObjectAttached(fan);
foreach (var jet in jets) jetManager.OnObjectAttached(jet);
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) {
public static void PostfixDestroy(ModuleBooster __instance) {
var trav = Traverse.Create(__instance);
var fans = trav.Field("fans").GetValue<List<FanJet>>();
var jets = trav.Field("jets").GetValue<List<BoosterJet>>();
foreach (var fan in fans) fanManager.OnObjectDetached(fan);
foreach (var jet in jets) jetManager.OnObjectDetached(jet);
foreach (var fan in fans) FanManager.OnObjectDetached(fan);
foreach (var jet in jets) JetManager.OnObjectDetached(jet);
}
public static void DoPatch() {
fanManager.ApplyAll();
jetManager.ApplyAll();
private static void DoPatch() {
FanManager.ApplyAll();
JetManager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleBooster: {0}", obj);
PostfixCreate(obj as ModuleBooster);
return true;
};
}
}

View File

@@ -5,12 +5,12 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleEnergyManager {
private static readonly MultipliedObjectManager<ModuleEnergy> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> outputMultiplier;
private static ConfigEntry<float> powerUpDelayMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -43,18 +43,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnAnchorStatusChanged")]
static void PostfixCreate(ModuleEnergy __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleEnergy __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")]
static void PostfixDestroy(ModuleEnergy __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleEnergy __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleEnergy: {0}", obj);
PostfixCreate(obj as ModuleEnergy);
return true;
};
}
}

View File

@@ -5,11 +5,11 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleEnergyStoreManager {
private static readonly MultipliedObjectManager<ModuleEnergyStore> manager =
private static readonly MultipliedObjectManager<ModuleEnergyStore> Manager =
new MultipliedObjectManager<ModuleEnergyStore>(ConfigureModuleEnergyStore);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> capacityMultiplier;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> capacityMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -36,18 +36,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergyStore), "OnAttached")]
static void PostfixCreate(ModuleEnergyStore __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleEnergyStore __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleEnergyStore), "OnDetaching")]
static void PostfixDestroy(ModuleEnergyStore __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleEnergyStore __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleEnergyStore: {0}", obj);
PostfixCreate(obj as ModuleEnergyStore);
return true;
};
}
}

View File

@@ -1,17 +1,16 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleFuelTankManager {
private static readonly MultipliedObjectManager<ModuleFuelTank> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> fuelCapacityMultiplier;
private static ConfigEntry<float> fuelRefillMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -39,23 +38,30 @@ namespace TerraTech {
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsObjectPlayerTank(obj);
return CykUtil.isObjectPlayerTank(obj);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnAttached")]
static void PostfixCreate(ModuleFuelTank __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleFuelTank __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleFuelTank), "OnDetaching")]
static void PostfixDestroy(ModuleFuelTank __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleFuelTank __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleFuelTank: {0}", obj);
PostfixCreate(obj as ModuleFuelTank);
return true;
};
}
}

View File

@@ -5,11 +5,11 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleGyroManager {
private static readonly MultipliedObjectManager<ModuleGyro> manager =
private static readonly MultipliedObjectManager<ModuleGyro> Manager =
new MultipliedObjectManager<ModuleGyro>(ConfigureModuleGyro);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> activeSpeedMultiplier;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> activeSpeedMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -36,18 +36,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleGyro), "OnAttached")]
static void PostfixCreate(ModuleGyro __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleGyro __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleGyro), "OnDetaching")]
static void PostfixDestroy(ModuleGyro __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleGyro __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleGyro: {0}", obj);
PostfixCreate(obj as ModuleGyro);
return true;
};
}
}

View File

@@ -1,18 +1,17 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleHeartManager {
private static readonly MultipliedObjectManager<ModuleHeart> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> eventHorizonRadiusMultiplier;
private static ConfigEntry<float> setupTimeMultiplier;
private static ConfigEntry<float> startShrinkingRadiusMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -48,23 +47,30 @@ namespace TerraTech {
private static readonly Func<object, bool> ShouldApply = obj => {
if (!playerOnly.Value)
return true;
return CykUtil.IsObjectPlayerTank(obj);
return CykUtil.isObjectPlayerTank(obj);
};
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleHeart), "OnAttached")]
static void PostfixCreate(ModuleHeart __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleHeart __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleHeart), "OnDetaching")]
static void PostfixDestroy(ModuleHeart __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleHeart __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleHeart: {0}", obj);
PostfixCreate(obj as ModuleHeart);
return true;
};
}
}

View File

@@ -5,25 +5,25 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleItemHolderManager {
private static readonly MultipliedObjectManager<ModuleItemHolder> beamManager =
private static readonly MultipliedObjectManager<ModuleItemHolder> BeamManager =
new MultipliedObjectManager<ModuleItemHolder>(ConfigureBeam);
private static readonly MultipliedObjectManager<ModuleItemHolderBeam> beamHolderManager =
private static readonly MultipliedObjectManager<ModuleItemHolderBeam> BeamHolderManager =
new MultipliedObjectManager<ModuleItemHolderBeam>(ConfigureBeamHolder);
private static readonly MultipliedObjectManager<ModuleItemPickup> beamPickupManager =
private static readonly MultipliedObjectManager<ModuleItemPickup> BeamPickupManager =
new MultipliedObjectManager<ModuleItemPickup>(ConfigureBeamPickup);
private static readonly MultipliedObjectManager<ModuleItemHolderMagnet> magnetHolderManager =
private static readonly MultipliedObjectManager<ModuleItemHolderMagnet> MagnetHolderManager =
new MultipliedObjectManager<ModuleItemHolderMagnet>(ConfigureMagnetHolder);
private static readonly MultipliedObjectManager<ModuleItemPickup> magnetPickupManager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> capacityPerStackMultiplier;
private static ConfigEntry<float> beamStrengthMultiplier;
private static ConfigEntry<float> beamHeightIncrementScaleMultiplier;
private static ConfigEntry<float> beamPickupRangeMultiplier;
private static ConfigEntry<float> magnetStrengthMultiplier;
private static ConfigEntry<float> magnetPickupRangeMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -96,62 +96,69 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolder), "OnAttached")]
static void PostfixCreate(ModuleItemHolder __instance) {
beamManager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleItemHolder __instance) {
BeamManager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolder), "OnDetaching")]
static void PostfixDestroy(ModuleItemHolder __instance) {
beamManager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleItemHolder __instance) {
BeamManager.OnObjectDetached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnAttached")]
static void PostfixCreate(ModuleItemHolderBeam __instance) {
public static void PostfixCreate(ModuleItemHolderBeam __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
beamHolderManager.OnObjectAttached(__instance);
beamPickupManager.OnObjectAttached(pickup);
BeamHolderManager.OnObjectAttached(__instance);
BeamPickupManager.OnObjectAttached(pickup);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnDetaching")]
static void PostfixDestroy(ModuleItemHolderBeam __instance) {
public static void PostfixDestroy(ModuleItemHolderBeam __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
beamHolderManager.OnObjectDetached(__instance);
beamPickupManager.OnObjectDetached(pickup);
BeamHolderManager.OnObjectDetached(__instance);
BeamPickupManager.OnObjectDetached(pickup);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnAttached")]
static void PostfixCreate(ModuleItemHolderMagnet __instance) {
public static void PostfixCreate(ModuleItemHolderMagnet __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
magnetHolderManager.OnObjectAttached(__instance);
magnetPickupManager.OnObjectAttached(pickup);
MagnetHolderManager.OnObjectAttached(__instance);
MagnetPickupManager.OnObjectAttached(pickup);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnDetaching")]
static void PostfixDestroy(ModuleItemHolderMagnet __instance) {
public static void PostfixDestroy(ModuleItemHolderMagnet __instance) {
var trav = Traverse.Create(__instance);
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
magnetHolderManager.OnObjectDetached(__instance);
magnetPickupManager.OnObjectDetached(pickup);
MagnetHolderManager.OnObjectDetached(__instance);
MagnetPickupManager.OnObjectDetached(pickup);
}
public static void DoPatch() {
beamManager.ApplyAll();
beamHolderManager.ApplyAll();
beamPickupManager.ApplyAll();
magnetHolderManager.ApplyAll();
magnetPickupManager.ApplyAll();
private static void DoPatch() {
BeamManager.ApplyAll();
BeamHolderManager.ApplyAll();
BeamPickupManager.ApplyAll();
MagnetHolderManager.ApplyAll();
MagnetPickupManager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleItemHolder: {0}", obj);
PostfixCreate(obj as ModuleItemHolder);
return true;
};
}
}

View File

@@ -5,13 +5,13 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleItemProducerManager {
private static readonly MultipliedObjectManager<ModuleItemProducer> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> resourceGroundRadiusMultiplier;
private static ConfigEntry<float> minDispenseIntervalMultiplier;
private static ConfigEntry<float> secPerItemProducedMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
@@ -53,18 +53,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemProducer), "GetClosestResourceReservoirInRange")]
static void PostfixCreate(ModuleItemProducer __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleItemProducer __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")]
static void PostfixDestroy(ModuleItemProducer __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleItemProducer __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleItemProducer: {0}", obj);
PostfixCreate(obj as ModuleItemProducer);
return true;
};
}
}

View File

@@ -5,17 +5,17 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleRemoteChargerManager {
private static readonly MultipliedObjectManager<ModuleRemoteCharger> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> arcFiringIntervalMultiplier;
private static ConfigEntry<float> chargingRadiusMultiplier;
private static ConfigEntry<float> powerTransferPerArcMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("Remote Charger", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
@@ -53,18 +53,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnAttached")]
static void PostfixCreate(ModuleRemoteCharger __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleRemoteCharger __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnDetaching")]
static void PostfixDestroy(ModuleRemoteCharger __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleRemoteCharger __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleRemoteCharger: {0}", obj);
PostfixCreate(obj as ModuleRemoteCharger);
return true;
};
}
}

View File

@@ -5,18 +5,18 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleShieldGeneratorManager {
private static readonly MultipliedObjectManager<ModuleShieldGenerator> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> radiusMultiplier;
private static ConfigEntry<float> radiusMultiplierHealing;
private static ConfigEntry<float> heartbeatIntervalMultiplier;
private static ConfigEntry<float> powerUpDelayMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("Shield", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
@@ -46,10 +46,10 @@ namespace TerraTech {
obj.AddField(new FieldConfiguration<float, float>("m_HealingHeartbeatInterval", heartbeatIntervalMultiplier,
ShouldApply));
obj.AddField(new FieldConfiguration<float, float>("m_Radius", radiusMultiplier, instance => {
if (!ShouldApply(instance))
obj.AddField(new FieldConfiguration<float, float>("m_Radius", radiusMultiplier, __instance => {
if (!ShouldApply(__instance))
return radiusMultiplier;
var shield = (ModuleShieldGenerator)instance;
var shield = (ModuleShieldGenerator)__instance;
return shield.m_Healing ? radiusMultiplierHealing : radiusMultiplier;
}));
@@ -64,18 +64,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")]
static void PostfixCreate(ModuleShieldGenerator __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleShieldGenerator __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")]
static void PostfixDestroy(ModuleShieldGenerator __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleShieldGenerator __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleShieldGenerator: {0}", obj);
PostfixCreate(obj as ModuleShieldGenerator);
return true;
};
}
}

View File

@@ -5,23 +5,23 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWeaponGunManager {
private static readonly MultipliedObjectManager<ModuleWeaponGun> manager =
private static readonly MultipliedObjectManager<ModuleWeaponGun> Manager =
new MultipliedObjectManager<ModuleWeaponGun>(ConfigureManager);
private static readonly MultipliedObjectManager<FireData> fireDataManager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> kickbackStrengthMultiplier;
private static ConfigEntry<float> muzzleVelocityMultiplier;
private static ConfigEntry<float> burstCooldownMultiplier;
private static ConfigEntry<float> burstShotCountMultiplier;
private static ConfigEntry<float> shotCooldownMultiplier;
private static ConfigEntry<bool> seekingRoundsAll;
private static ConfigEntry<bool> resetBurstOnInterruptAll;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("WeaponGun", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
@@ -84,31 +84,38 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeaponGun), "OnAttached")]
static void PostfixCreate(ModuleWeaponGun __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleWeaponGun __instance) {
Manager.OnObjectAttached(__instance);
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
var trav = Traverse.Create(__instance);
var firingData = trav.Field("m_FiringData");
fireDataManager.OnObjectAttached(firingData.GetValue<FireData>());
FireDataManager.OnObjectAttached(firingData.GetValue<FireData>());
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeaponGun), "OnDetaching")]
static void PostfixDestroy(ModuleWeaponGun __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixDestroy(ModuleWeaponGun __instance) {
Manager.OnObjectAttached(__instance);
var trav = Traverse.Create(__instance);
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
var firingData = trav.Field("m_FiringData");
fireDataManager.OnObjectDetached(firingData.GetValue<FireData>());
FireDataManager.OnObjectDetached(firingData.GetValue<FireData>());
}
public static void DoPatch() {
fireDataManager.ApplyAll();
manager.ApplyAll();
private static void DoPatch() {
FireDataManager.ApplyAll();
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWeaponGun: {0}", obj);
PostfixCreate(obj as ModuleWeaponGun);
return true;
};
}
}

View File

@@ -5,15 +5,15 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWeaponManager {
private static readonly MultipliedObjectManager<ModuleWeapon> manager =
private static readonly MultipliedObjectManager<ModuleWeapon> Manager =
new MultipliedObjectManager<ModuleWeapon>(ConfigureManager);
public static ConfigEntry<bool> playerOnly;
public static ConfigEntry<float> rotateSpeedMultiplier;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> rotateSpeedMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("ModuleWeapon", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
@@ -36,18 +36,25 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeapon), "OnAttached")]
static void PostfixCreate(ModuleWeapon __instance) {
manager.OnObjectAttached(__instance);
public static void PostfixCreate(ModuleWeapon __instance) {
Manager.OnObjectAttached(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWeapon), "OnDetaching")]
static void PostfixDestroy(ModuleWeapon __instance) {
manager.OnObjectDetached(__instance);
public static void PostfixDestroy(ModuleWeapon __instance) {
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWeapon: {0}", obj);
PostfixCreate(obj as ModuleWeapon);
return true;
};
}
}

View File

@@ -5,16 +5,16 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWheelsManager {
private static readonly MultipliedObjectManager<ManWheels.TorqueParams> torqueParamsManager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> torqueRpmMultiplier;
private static ConfigEntry<float> torqueMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("TorqueParams", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
@@ -43,22 +43,29 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWheels), "OnAttached")]
static void PostfixCreate(ModuleWheels __instance) {
public static void PostfixCreate(ModuleWheels __instance) {
var trav = Traverse.Create(__instance);
var torqueParams = trav.Field("torqueParams");
torqueParamsManager.OnObjectAttached(torqueParams.GetValue<ManWheels.TorqueParams>());
TorqueParamsManager.OnObjectAttached(torqueParams.GetValue<ManWheels.TorqueParams>());
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWheels), "OnDetaching")]
static void PostfixDestroy(ModuleWheels __instance) {
public static void PostfixDestroy(ModuleWheels __instance) {
var trav = Traverse.Create(__instance);
var torqueParams = trav.Field("torqueParams");
torqueParamsManager.OnObjectDetached(torqueParams.GetValue<ManWheels.TorqueParams>());
TorqueParamsManager.OnObjectDetached(torqueParams.GetValue<ManWheels.TorqueParams>());
}
public static void DoPatch() {
torqueParamsManager.ApplyAll();
private static void DoPatch() {
TorqueParamsManager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWheels: {0}", obj);
PostfixCreate(obj as ModuleWheels);
return true;
};
}
}

View File

@@ -5,17 +5,17 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class ModuleWingManager {
private static readonly MultipliedObjectManager<ModuleWing.Aerofoil> manager =
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;
private static ConfigEntry<bool> playerOnly;
private static ConfigEntry<float> angleRangeMultiplier;
private static ConfigEntry<float> turnSpeedMultiplier;
private static ConfigEntry<float> liftStrengthMultiplier;
public static void Setup(ConfigFile config) {
float min = 0.01f;
float max = 32f;
const float min = 0.01f;
const float max = 32f;
playerOnly = config.Bind("Aerofoil", "Player Only", false, new ConfigDescription("Player Only"));
playerOnly.SettingChanged += (sender, args) => DoPatch();
@@ -52,28 +52,32 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWing), "OnAttached")]
static void PostfixCreate(ModuleWing __instance) {
public static void PostfixCreate(ModuleWing __instance) {
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
return;
for (int i = 0; i < __instance.m_Aerofoils.Length; i++) {
var aerofoil = __instance.m_Aerofoils[i];
manager.OnObjectAttached(aerofoil);
Manager.OnObjectAttached(aerofoil);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ModuleWing), "OnDetaching")]
static void PostfixDestroy(ModuleWing __instance) {
public 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);
}
foreach (var aerofoil in __instance.m_Aerofoils) Manager.OnObjectDetached(aerofoil);
}
public static void DoPatch() {
manager.ApplyAll();
private static void DoPatch() {
Manager.ApplyAll();
}
public static readonly Func<Module, bool> Register = obj => {
if (Main.debug.Value)
Console.WriteLine("Registering ModuleWing: {0}", obj);
PostfixCreate(obj as ModuleWing);
return true;
};
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Reflection;
using HarmonyLib;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace TerraTech {
[HarmonyPatch]
public class MultiBuy {
public static UIShopBlockSelect panel;
public static Traverse panelTraverse;
[HarmonyPostfix]
[HarmonyPatch(typeof(UIShopBlockSelect), "OnSpawn")]
public static void PostfixCreate(UIShopBlockSelect __instance) {
panel = __instance;
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance);
panelTraverse = Traverse.Create(__instance);
var placeButton = panelTraverse.Field("m_PurchaseBlockButton").GetValue<Button>();
placeButton.gameObject.AddComponent<MultiBuyRightClickHandler>();
}
}
class MultiBuyRightClickHandler : MonoBehaviour, IPointerClickHandler {
// private void Awake() {
// }
public void OnPointerClick(PointerEventData eventData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: {0} {1}", gameObject.name,
eventData.button);
try {
if (eventData.button == PointerEventData.InputButton.Right) {
UIBlockSelectGrid grid = MultiBuy.panelTraverse.Field("m_Grid").GetValue<UIBlockSelectGrid>();
BlockTypes blockTypes;
bool ok = grid.TryGetSelection(out blockTypes);
if (!ok) {
if (Main.debugBuyAll.Value)
Console.WriteLine(
"MultiBuyRightClickHandler.OnPointerClick: Failed to get block selection from grid");
return;
}
uint shopBlockPoolID = MultiBuy.panelTraverse.Field("m_ShopBlockPoolID").GetValue<uint>();
MethodInfo canPurchaseMethod =
AccessTools.Method(typeof(UIShopBlockSelect), "CanPurchaseBlock", new[] { typeof(BlockTypes) });
Func<BlockTypes, bool> canPurchase = (Func<BlockTypes, bool>)Delegate.CreateDelegate(
typeof(Func<BlockTypes, bool>), MultiBuy.panel, canPurchaseMethod);
for (int i = 0; i < Main.multiBuyAmount.Value; i++) {
if (!canPurchase.Invoke(blockTypes)) {
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Can purchase no more {0}",
blockTypes);
return;
}
Singleton.Manager<ManPurchases>.inst.RequestPurchaseBlock(shopBlockPoolID, blockTypes, 1);
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Purchased {0} block",
blockTypes);
}
}
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Exception occurred: {0}", e);
}
}
}
}

View File

@@ -71,18 +71,18 @@ namespace TerraTech {
_applyCondition = applyCondition;
}
public ConfigEntry<TMul> GetMultiplier(object instance) {
public ConfigEntry<TMul> GetMultiplier(object __instance) {
if (_conditionalMultiplier == null) {
return _defaultMultiplier;
}
return _conditionalMultiplier(instance);
return _conditionalMultiplier(__instance);
}
public bool ShouldApply(object instance) {
public bool ShouldApply(object __instance) {
if (_applyCondition == null) {
return true;
}
return _applyCondition(instance);
return _applyCondition(__instance);
}
}
@@ -247,18 +247,18 @@ namespace TerraTech {
_applyCondition = applyCondition;
}
public ConfigEntry<bool> GetValue(object instance) {
public ConfigEntry<bool> GetValue(object __instance) {
if (_conditionalValue == null) {
return _value;
}
return _conditionalValue(instance);
return _conditionalValue(__instance);
}
public bool ShouldApply(object instance) {
public bool ShouldApply(object __instance) {
if (_applyCondition == null) {
return true;
}
return _applyCondition(instance);
return _applyCondition(__instance);
}
}
@@ -353,9 +353,9 @@ namespace TerraTech {
private readonly Traverse _objectTraverse;
private readonly Dictionary<string, IFieldModifier> _fields;
public MultipliedObject(T instance) {
_instance = instance;
_objectTraverse = Traverse.Create(instance);
public MultipliedObject(T __instance) {
_instance = __instance;
_objectTraverse = Traverse.Create(__instance);
_fields = new Dictionary<string, IFieldModifier>();
}
@@ -413,68 +413,68 @@ namespace TerraTech {
_managedObjects = new Dictionary<T, MultipliedObject<T>>();
}
private void SafeRemove(T instance) {
if (instance == null)
private void SafeRemove(T __instance) {
if (__instance == null)
return;
try {
_managedObjects.Remove(instance);
_managedObjects.Remove(__instance);
} catch (Exception e) {
Console.WriteLine("Error removing instance from _managedObjects: {0}", e);
Console.WriteLine("Error removing __instance from _managedObjects: {0}", e);
}
}
public void OnObjectAttached(T instance) {
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");
if (__instance == null) {
Console.WriteLine("Attempted to attach null __instance");
return;
}
try {
if (_managedObjects.ContainsKey(instance)) {
if (_managedObjects.ContainsKey(__instance)) {
if (Main.debug.Value)
Console.WriteLine("{0} already managed, skipping", typeof(T).Name);
return;
}
var multipliedObject = new MultipliedObject<T>(instance);
var multipliedObject = new MultipliedObject<T>(__instance);
_configureObject(multipliedObject);
multipliedObject.CaptureFrom();
_managedObjects.Add(instance, multipliedObject);
_managedObjects.Add(__instance, multipliedObject);
multipliedObject.LogValues("Patching");
ApplyTo(instance);
ApplyTo(__instance);
multipliedObject.LogValues("Patched");
} catch (Exception e) {
Console.WriteLine("Error in OnObjectAttached: {0}", e);
}
}
public void OnObjectDetached(T instance) {
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");
if (__instance == null) {
Console.WriteLine("Attempted to detach null __instance");
return;
}
try {
MultipliedObject<T> multipliedObject;
if (_managedObjects.TryGetValue(instance, out multipliedObject)) {
if (_managedObjects.TryGetValue(__instance, out multipliedObject)) {
if (Main.debug.Value)
multipliedObject.LogValues("Restoring");
try {
RestoreTo(instance);
RestoreTo(__instance);
multipliedObject.LogValues("Restored");
} catch (Exception e) {
Console.WriteLine("Error restoring values: {0}", e);
}
SafeRemove(instance);
SafeRemove(__instance);
}
} catch (Exception e) {
Console.WriteLine("Error in OnObjectDetached: {0}", e);
@@ -488,40 +488,40 @@ namespace TerraTech {
// Make a copy of the keys to avoid modification during enumeration
var instances = _managedObjects.Keys.ToList();
foreach (var instance in instances) {
foreach (var __instance in instances) {
try {
RestoreTo(instance, fieldNames);
ApplyTo(instance, fieldNames);
RestoreTo(__instance, fieldNames);
ApplyTo(__instance, fieldNames);
} catch (Exception e) {
Console.WriteLine("Error applying to instance: {0}", e);
Console.WriteLine("Error applying to __instance: {0}", e);
}
}
}
public void ApplyTo(T instance, IEnumerable<string> fieldNames = null) {
public void ApplyTo(T __instance, IEnumerable<string> fieldNames = null) {
if (Main.debug.Value)
Console.WriteLine("Applying {0}", typeof(T).Name);
if (instance == null)
if (__instance == null)
return;
try {
MultipliedObject<T> obj;
if (_managedObjects.TryGetValue(instance, out 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) {
public void RestoreTo(T __instance, IEnumerable<string> fieldNames = null) {
if (Main.debug.Value)
Console.WriteLine("Restoring {0}", typeof(T).Name);
if (instance == null)
if (__instance == null)
return;
try {
MultipliedObject<T> obj;
if (_managedObjects.TryGetValue(instance, out obj))
if (_managedObjects.TryGetValue(__instance, out obj))
obj.RestoreTo(fieldNames);
} catch (Exception e) {
Console.WriteLine("Error in RestoreTo: {0}", e);

View File

@@ -5,7 +5,7 @@ namespace TerraTech {
public class Patches {
[HarmonyPrefix]
[HarmonyPatch(typeof(ManLicenses), "AddXP")]
static void XPMulti(FactionSubTypes corporation, ref int xp, bool showUI = true) {
static void XpMulti(FactionSubTypes corporation, ref int xp, bool showUI = true) {
xp = (int)(xp * Main.xpMultiplier.Value);
}

View File

@@ -5,7 +5,7 @@ namespace TerraTech {
public class SeekingProjectileManager {
[HarmonyPatch(typeof(SeekingProjectile), "OnSpawn")]
class Patch {
static void Postfix(SeekingProjectile __instance) {
public static void Postfix(SeekingProjectile __instance) {
if (Main.debug.Value)
Console.WriteLine("SeekingProjectile created");

View File

@@ -4,7 +4,7 @@ using HarmonyLib;
namespace TerraTech {
[HarmonyPatch]
public class TankBeamManager {
private static readonly MultipliedObjectManager<TankBeam> manager =
private static readonly MultipliedObjectManager<TankBeam> Manager =
new MultipliedObjectManager<TankBeam>(ConfigureBeam);
public static ConfigEntry<float> hoverClearanceMultiplier;
@@ -39,15 +39,15 @@ namespace TerraTech {
[HarmonyPrefix]
[HarmonyPatch(typeof(TankBeam), "EnableBeam")]
static void PostfixCreate(TankBeam __instance, ref bool enable) {
public static void PostfixCreate(TankBeam __instance, ref bool enable) {
if (enable)
manager.OnObjectAttached(__instance);
Manager.OnObjectAttached(__instance);
else
manager.OnObjectDetached(__instance);
Manager.OnObjectDetached(__instance);
}
public static void DoPatch() {
manager.ApplyAll();
Manager.ApplyAll();
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
namespace TerraTech {
[HarmonyPatch]
public class TankManager {
public static ConfigEntry<bool> recheck;
public static Dictionary<Type, Func<Module, bool>> moduleManagerMapper =
new Dictionary<Type, Func<Module, bool>>();
public static void Setup(ConfigFile config) {
recheck = config.Bind("Tank", "Recheck", false, new ConfigDescription("Recheck"));
moduleManagerMapper.Add(typeof(ModuleBooster), ModuleBoosterManager.Register);
moduleManagerMapper.Add(typeof(ModuleEnergy), ModuleEnergyManager.Register);
moduleManagerMapper.Add(typeof(ModuleEnergyStore), ModuleEnergyStoreManager.Register);
moduleManagerMapper.Add(typeof(ModuleFuelTank), ModuleFuelTankManager.Register);
moduleManagerMapper.Add(typeof(ModuleGyro), ModuleGyroManager.Register);
moduleManagerMapper.Add(typeof(ModuleHeart), ModuleHeartManager.Register);
moduleManagerMapper.Add(typeof(ModuleItemHolder), ModuleItemHolderManager.Register);
moduleManagerMapper.Add(typeof(ModuleItemProducer), ModuleItemProducerManager.Register);
moduleManagerMapper.Add(typeof(ModuleRemoteCharger), ModuleRemoteChargerManager.Register);
moduleManagerMapper.Add(typeof(ModuleShieldGenerator), ModuleShieldGeneratorManager.Register);
moduleManagerMapper.Add(typeof(ModuleWeaponGun), ModuleWeaponGunManager.Register);
moduleManagerMapper.Add(typeof(ModuleWeapon), ModuleWeaponManager.Register);
moduleManagerMapper.Add(typeof(ModuleWheels), ModuleWheelsManager.Register);
moduleManagerMapper.Add(typeof(ModuleWing), ModuleWingManager.Register);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Tank), "NotifyAnchor")]
public static void PostfixCreate(Tank __instance, ModuleAnchor anchor, bool anchored) {
if (Main.debug.Value)
Console.WriteLine("TankManager.NotifyAnchor: {0}", __instance);
if (!__instance.ControllableByLocalPlayer)
return;
if (!recheck.Value)
return;
foreach (Transform child in __instance.transform) {
GameObject childObj = child.gameObject;
Component[] components = childObj.GetComponents<Component>();
foreach (Component component in components) {
Func<Module, bool> manager;
if (moduleManagerMapper.TryGetValue(component.GetType(), out manager))
manager(component as Module);
}
}
}
}
}

View File

@@ -59,6 +59,9 @@
<Compile Include="ModuleHeartManager.cs" />
<Compile Include="ModuleFuelTankManager.cs" />
<Compile Include="ProjectilePatch.cs" />
<Compile Include="TankManager.cs" />
<Compile Include="UISnapshotPanelBuyAll.cs" />
<Compile Include="MultiBuy.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="0Harmony">
@@ -73,6 +76,9 @@
<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="UnityEngine.Networking">
<HintPath>$(GAME_MANAGED)/UnityEngine.Networking.dll</HintPath>
</Reference>

View File

@@ -0,0 +1,181 @@
using System;
using System.Collections.Generic;
using HarmonyLib;
using Snapshots;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace TerraTech {
[HarmonyPatch]
public class UISnapshotPanelBuyAll {
public static UISnapshotPanel panel;
public static Traverse panelTraverse;
public static SnapshotLiveData selectedData;
[HarmonyPostfix]
[HarmonyPatch(typeof(UISnapshotPanel), "OnPool")]
public static void PostfixCreate(UISnapshotPanel __instance) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance);
panel = __instance;
panelTraverse = Traverse.Create(__instance);
var placeButton = panelTraverse.Field("m_PlaceButton").GetValue<Button>();
placeButton.gameObject.AddComponent<RightClickHandler>();
var swapButton = panelTraverse.Field("m_SwapButton").GetValue<Button>();
swapButton.gameObject.AddComponent<RightClickHandlerSwap>();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UISnapshotPanel), "OnSelectedChanged")]
public static void PostfixCreate(UISnapshotPanel __instance, ref SnapshotLiveData selectedData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnSelectedChanged: {0}", __instance);
UISnapshotPanelBuyAll.selectedData = selectedData;
}
}
public abstract class BaseRightClickHandler : MonoBehaviour, IPointerClickHandler {
protected static Traverse m_TechAvailLookupTraverse;
protected static Dictionary<Snapshot, TechDataAvailValidation> m_TechAvailLookup;
protected virtual void Awake() {
var trav = Traverse.Create(Singleton.Manager<ManSnapshots>.inst);
m_TechAvailLookupTraverse = trav.Field("m_TechAvailLookup");
m_TechAvailLookup = m_TechAvailLookupTraverse.GetValue<Dictionary<Snapshot, TechDataAvailValidation>>();
}
protected Dictionary<BlockTypes, int> CalculateMissingBlocks(
Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> blockAvailability, bool isSpawning) {
Dictionary<BlockTypes, int> missing = new Dictionary<BlockTypes, int>();
foreach (var kvp in blockAvailability) {
int numMissing;
if (isSpawning)
numMissing = kvp.Value.numRequired - kvp.Value.numInInventory;
else
numMissing = kvp.Value.numRequired - kvp.Value.numInInventory - kvp.Value.numOnPlayerTech;
}
if (missing.Count == 0)
foreach (var kvp in blockAvailability) missing.Add(kvp.Key, kvp.Value.numRequired);
return missing;
}
protected int CalculateTotalCost(Dictionary<BlockTypes, int> missingBlocks) {
int totalCost = 0;
RecipeManager recipeManager = Singleton.Manager<RecipeManager>.inst;
foreach (var kvp in missingBlocks) {
int cost = recipeManager.GetBlockBuyPrice(kvp.Key) * kvp.Value;
totalCost += cost;
if (Main.debugBuyAll.Value)
Console.WriteLine("{0} of {1} would cost {2}, total now {3}", kvp.Value, kvp.Key, cost, totalCost);
}
return totalCost;
}
protected bool TryPurchaseBlocks(Dictionary<BlockTypes, int> missingBlocks, int totalCost) {
ManPlayer player = Singleton.Manager<ManPlayer>.inst;
if (player.GetCurrentMoney() < totalCost) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Not enough money, have {0} but need {1}, nothing to do",
player.GetCurrentMoney(), totalCost);
return false;
}
player.PayMoney(totalCost);
foreach (var kvp in missingBlocks) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Buying {0} of {1}", kvp.Value, kvp.Key);
player.PlayerInventory.HostAddItem(kvp.Key, kvp.Value);
}
return true;
}
protected bool ProcessPurchase(
Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> blockAvailability, bool isSpawning) {
try {
if (blockAvailability == null) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Block availability is null (wtf?), nothing to do");
return false;
}
var missingBlocks = CalculateMissingBlocks(blockAvailability, isSpawning);
int totalCost = CalculateTotalCost(missingBlocks);
if (totalCost > 0) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Total cost: {0}", totalCost);
return TryPurchaseBlocks(missingBlocks, totalCost);
}
if (Main.debugBuyAll.Value)
Console.WriteLine("No blocks missing or no cost calculated");
return false;
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Error during purchase processing: {0}", e);
return false;
}
}
protected Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability> GetCurrentBlockAvailability() {
SnapshotLiveData selectedSnapshotData = UISnapshotPanelBuyAll.selectedData;
Snapshot selectedSnapshot = selectedSnapshotData.m_Snapshot;
if (selectedSnapshot == null) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Selected snapshot is null wtf??: {0}", gameObject.name);
return null;
}
TechDataAvailValidation techDataAvail;
if (!m_TechAvailLookup.TryGetValue(selectedSnapshot, out techDataAvail)) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Failed to find TechDataAvailValidation for snapshot: {0}", selectedSnapshot);
return null;
}
var trav = Traverse.Create(techDataAvail);
var mBlockAvailabilityField = trav.Field("m_BlockAvailability");
var mBlockAvailability =
mBlockAvailabilityField
.GetValue<Dictionary<BlockTypes, TechDataAvailValidation.BlockTypeAvailability>>();
return mBlockAvailability;
}
public abstract void OnPointerClick(PointerEventData eventData);
}
public class RightClickHandler : BaseRightClickHandler {
public override void OnPointerClick(PointerEventData eventData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPointerClick: {0} {1}", gameObject.name, eventData.button);
try {
if (eventData.button == PointerEventData.InputButton.Right)
ProcessPurchase(GetCurrentBlockAvailability(), true);
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Shit exploded fml: {0}", e);
}
}
}
public class RightClickHandlerSwap : BaseRightClickHandler {
public override void OnPointerClick(PointerEventData eventData) {
if (Main.debugBuyAll.Value)
Console.WriteLine("UISnapshotPanel.OnPointerClick: {0} {1}", gameObject.name, eventData.button);
try {
if (eventData.button == PointerEventData.InputButton.Right)
ProcessPurchase(GetCurrentBlockAvailability(), false);
} catch (Exception e) {
if (Main.debugBuyAll.Value)
Console.WriteLine("Shit exploded fml: {0}", e);
}
}
}
}

View File

@@ -0,0 +1,14 @@
static void Postfix(UIItemSelectGrid __instance) {
try {
StringBuilder sb = new StringBuilder();
sb.AppendLine("--------------------");
sb.AppendLine("void UIItemSelectGrid::Repopulate()");
sb.Append("- __instance: ").AppendLine(__instance.ToString());
foreach (var item in __instance.m_FilteredItemList) {
sb.Append("- item: ").AppendLine(item.ToString());
}
UnityExplorer.ExplorerCore.Log(sb.ToString());
} catch (System.Exception ex) {
UnityExplorer.ExplorerCore.LogWarning($"Exception in patch of void UIItemSelectGrid::Repopulate():\n{ex}");
}
}

View File

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

View File

@@ -0,0 +1,3 @@
- source: TerraTech/obj/Release/TerraTech.dll
target: ~/scoop/apps/steam/current/steamapps/common/TerraTech/BepInEx/plugins/TerraTech.dll
delete: true

View File

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

View File

@@ -0,0 +1,18 @@
<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/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005C0Harmony_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CAssembly_002DCSharp_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CBepInEx_002Edll/@EntryIndexedValue">True</s:Boolean>
<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_003AFunc_00602_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_003F105da1159ec9496ab9310694c7b11dd2532bb0_003F8e_003Fd9fe1d1e_003FFunc_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInt32_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_003F105da1159ec9496ab9310694c7b11dd2532bb0_003F2f_003Fc4c87fac_003FInt32_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AModuleEnergy_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_003F88c9fc29ca6844c7a78a6d5386efc5cfbd1c00_003F6a_003Ff8d470ed_003FModuleEnergy_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARecipeManager_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_003F88c9fc29ca6844c7a78a6d5386efc5cfbd1c00_003Fec_003F11004097_003FRecipeManager_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

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

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zompiercer", "Zompiercer\Zompiercer.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,17 @@
<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/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005C0Harmony_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CAssembly_002DCSharp_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CAdministrator_005CRiderProjects_005CBepinex_005CProjects_005CTerraTech_005Clibs_005CBepInEx_002Edll/@EntryIndexedValue">True</s:Boolean>
<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_003AFunc_00602_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_003F105da1159ec9496ab9310694c7b11dd2532bb0_003F8e_003Fd9fe1d1e_003FFunc_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInt32_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_003F105da1159ec9496ab9310694c7b11dd2532bb0_003F2f_003Fc4c87fac_003FInt32_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AModuleEnergy_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_003F88c9fc29ca6844c7a78a6d5386efc5cfbd1c00_003F6a_003Ff8d470ed_003FModuleEnergy_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARecipeManager_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_003F88c9fc29ca6844c7a78a6d5386efc5cfbd1c00_003Fec_003F11004097_003FRecipeManager_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

@@ -0,0 +1,32 @@
using System.Linq;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using HarmonyLib.Tools;
// TODO: Make shield and repair bigger
// TODO: Maybe make props faster, thrusters work fine
namespace Zompiercer {
[BepInPlugin(PluginGuid, PluginName, PluginVersion)]
public class Main : BaseUnityPlugin {
private const string PluginGuid = "CykPiercer";
private const string PluginName = "CykaPiercer";
private const string PluginVersion = "1.0.0";
public static ConfigEntry<bool> debug;
public static ConfigEntry<float> weightMultiplier;
public void Awake() {
debug = Config.Bind("General", "Debug", false);
weightMultiplier = Config.Bind("General", "Weight Multiplier", 1.0f, "Multiplier for the weight of the tank");
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");
}
}
}

View File

@@ -0,0 +1,35 @@
using System;
using HarmonyLib;
namespace Zompiercer {
[HarmonyPatch]
public class Patches {
[HarmonyPostfix]
[HarmonyPatch(typeof(InventoryItem), "GetWeight")]
static void GetWeight(ref float __result) {
if (Main.debug.Value)
Console.WriteLine("GetWeight: " + __result);
__result = __result * Main.weightMultiplier.Value;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(InventoryItem), "GetWeightOfOneItem")]
static void GetWeightOfOneItem(ref float __result) {
if (Main.debug.Value)
Console.WriteLine("GetWeightOfOneItem: " + __result);
__result = __result * Main.weightMultiplier.Value;
}
//[HarmonyPrefix]
//[HarmonyPatch(typeof(ManPlayer), "AddMoney")]
//static void MoneyMulti(ref int amount) {
// amount = (int)(amount * Main.moneyMultiplier.Value);
//}
//[HarmonyPrefix]
//[HarmonyPatch(typeof(TechHolders), "SetHeartbeatInterval")]
//static void HeartbeatMulti(ref float interval) {
// interval *= Main.heartbeatIntervalMultiplier.Value;
//}
}
}

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("Zompiercer")]
[assembly:AssemblyDescription("")]
[assembly:AssemblyConfiguration("")]
[assembly:AssemblyCompany("")]
[assembly:AssemblyProduct("Zompiercer")]
[assembly:AssemblyCopyright("Copyright © 2023")]
[assembly:AssemblyTrademark("")]
[assembly:AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly:ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly:Guid("EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly:AssemblyVersion("1.0.0.0")]
[assembly:AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props"
Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<GAME_DIR>C:/Games/Zompiercer.Build.16292544</GAME_DIR>
<GAME_MANAGED>$(GAME_DIR)/Zompiercer_Data/Managed</GAME_MANAGED>
<GAME_BEPINEX>$(GAME_DIR)/BepInEx</GAME_BEPINEX>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Zompiercer</RootNamespace>
<AssemblyName>Zompiercer</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" />
</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="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" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

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

View File

@@ -0,0 +1,2 @@
- source: Zompiercer/obj/Release/Zompiercer.dll
target: C:/Games/Zompiercer.Build.16292544/BepInEx/plugins/Zompiercer.dll