Compare commits
3 Commits
793fc2b48d
...
87dc60763c
Author | SHA1 | Date | |
---|---|---|---|
87dc60763c | |||
b54210ec69 | |||
dcc039afcb |
BIN
BepInEx.Patcher.exe
Normal file
BIN
BepInEx.Patcher.exe
Normal file
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
bin/Release/DaveCEO.dll,"C:\Games\Airport CEO\BepInEx\plugins\DaveCEO.dll"
|
|
3
Projects/AirportCEO/AirportCEO/sync.yml
Normal file
3
Projects/AirportCEO/AirportCEO/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/DaveCEO.dll
|
||||||
|
target: C:\Games\Airport CEO\BepInEx\plugins\DaveCEO.dll
|
||||||
|
delete: true
|
@@ -1 +0,0 @@
|
|||||||
bin/Release/CykaOfIndustry.dll,"C:\Program Files (x86)\Steam\steamapps\common\Captain of Industry\BepInEx\plugins\CykaOfIndustry.dll"
|
|
3
Projects/CaptainOfIndustry/CykaOfIndustry/sync.yml
Normal file
3
Projects/CaptainOfIndustry/CykaOfIndustry/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/CykaOfIndustry.dll
|
||||||
|
target: C:\Program Files (x86)\Steam\steamapps\common\Captain of Industry\BepInEx\plugins\CykaOfIndustry.dll
|
||||||
|
delete: true
|
@@ -1 +0,0 @@
|
|||||||
bin/Release/CykaOfQud.dll,"C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll"
|
|
3
Projects/CykaOfQud/sync.yml
Normal file
3
Projects/CykaOfQud/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/CykaOfQud.dll
|
||||||
|
target: C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll
|
||||||
|
delete: true
|
@@ -1 +0,0 @@
|
|||||||
InfectionFreeZone/bin/Release/InfectionFreeZone.dll,"C:\Games\Infection.Free.Zone.v0.24.8.21a\BepInEx\plugins\InfectionFreeZone.dll"
|
|
3
Projects/InfectionFreeZone/sync.yml
Normal file
3
Projects/InfectionFreeZone/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/InfectionFreeZone.dll
|
||||||
|
target: C:\Games\Infection.Free.Zone.v0.24.8.21a\BepInEx\plugins\InfectionFreeZone.dll
|
||||||
|
delete: true
|
@@ -1 +0,0 @@
|
|||||||
bin/Release/CykaRaider.dll,"C:/Games/NightRaider/BepInEx/plugins/CykaRaider.dll"
|
|
3
Projects/NightRaider/sync.yml
Normal file
3
Projects/NightRaider/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/CykaRaider.dll
|
||||||
|
target: C:/Games/NightRaider/BepInEx/plugins/CykaRaider.dll
|
||||||
|
delete: true
|
3
Projects/Quasimorph/.clang-format
Normal file
3
Projects/Quasimorph/.clang-format
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
|
ColumnLimit: 120
|
BIN
Projects/Quasimorph/.vs/Quasimorph/v16/.suo
Normal file
BIN
Projects/Quasimorph/.vs/Quasimorph/v16/.suo
Normal file
Binary file not shown.
16
Projects/Quasimorph/Quasimorph.sln
Normal file
16
Projects/Quasimorph/Quasimorph.sln
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quasimorph", "Quasimorph\Quasimorph.csproj", "{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
33
Projects/Quasimorph/Quasimorph/Class1.cs
Normal file
33
Projects/Quasimorph/Quasimorph/Class1.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
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 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 void Awake() {
|
||||||
|
debug = Config.Bind("General", "Debug", false);
|
||||||
|
scrappingMultiplier = Config.Bind("General", "Scrapping Multiplier", 1,
|
||||||
|
new ConfigDescription("Scrapping Multiplier", new AcceptableValueRange<int>(1, 10000)));
|
||||||
|
|
||||||
|
Logger.LogInfo("Quasicyka loaded");
|
||||||
|
HarmonyFileLog.Enabled = true;
|
||||||
|
Harmony harmony = new Harmony(PluginGuid);
|
||||||
|
harmony.PatchAll();
|
||||||
|
var originalMethods = harmony.GetPatchedMethods();
|
||||||
|
Logger.LogInfo("Patched " + originalMethods.Count() + " methods");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
Projects/Quasimorph/Quasimorph/CykUtil.cs
Normal file
28
Projects/Quasimorph/Quasimorph/CykUtil.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
public class CykUtil {
|
||||||
|
public static bool IsPlayerTank(Module module) {
|
||||||
|
if (module == null)
|
||||||
|
return false;
|
||||||
|
TankBlock block = module.block;
|
||||||
|
if (block == null)
|
||||||
|
return false;
|
||||||
|
Tank tank = block.tank;
|
||||||
|
if (tank == null)
|
||||||
|
return false;
|
||||||
|
return tank.ControllableByLocalPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Func<object, bool> isObjectPlayerTank = obj => {
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
return IsPlayerTank(obj as Module);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Failed to check if object is a player tank: " + e.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
84
Projects/Quasimorph/Quasimorph/ModuleBoosterManager.cs
Normal file
84
Projects/Quasimorph/Quasimorph/ModuleBoosterManager.cs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleBoosterManager {
|
||||||
|
private static readonly MultipliedObjectManager<FanJet> FanManager =
|
||||||
|
new MultipliedObjectManager<FanJet>(ConfigureFanThruster);
|
||||||
|
private static readonly MultipliedObjectManager<BoosterJet> JetManager =
|
||||||
|
new MultipliedObjectManager<BoosterJet>(ConfigureJetThruster);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> fanThrustMultiplier;
|
||||||
|
private static ConfigEntry<float> jetThrustMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Booster", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
fanThrustMultiplier =
|
||||||
|
config.Bind("Booster", "Fan Thrust Multiplier", 1f,
|
||||||
|
new ConfigDescription("Fan Thrust Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
fanThrustMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
jetThrustMultiplier =
|
||||||
|
config.Bind("Booster", "Jet Thrust Multiplier", 1f,
|
||||||
|
new ConfigDescription("Jet Thrust Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
jetThrustMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureFanThruster(MultipliedObject<FanJet> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_Force", fanThrustMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureJetThruster(MultipliedObject<BoosterJet> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_Force", jetThrustMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.isObjectPlayerTank(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleBooster), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleBooster __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var fans = trav.Field("fans").GetValue<List<FanJet>>();
|
||||||
|
var jets = trav.Field("jets").GetValue<List<BoosterJet>>();
|
||||||
|
|
||||||
|
foreach (var fan in fans) FanManager.OnObjectAttached(fan);
|
||||||
|
foreach (var jet in jets) JetManager.OnObjectAttached(jet);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleBooster), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleBooster __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var fans = trav.Field("fans").GetValue<List<FanJet>>();
|
||||||
|
var jets = trav.Field("jets").GetValue<List<BoosterJet>>();
|
||||||
|
|
||||||
|
foreach (var fan in fans) FanManager.OnObjectDetached(fan);
|
||||||
|
foreach (var jet in jets) JetManager.OnObjectDetached(jet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
FanManager.ApplyAll();
|
||||||
|
JetManager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleBooster: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleBooster);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
67
Projects/Quasimorph/Quasimorph/ModuleEnergyManager.cs
Normal file
67
Projects/Quasimorph/Quasimorph/ModuleEnergyManager.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleEnergyManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleEnergy> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleEnergy>(ConfigureModuleEnergy);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> outputMultiplier;
|
||||||
|
private static ConfigEntry<float> powerUpDelayMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Energy", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
outputMultiplier =
|
||||||
|
config.Bind("Energy", "Output Multiplier", 1f,
|
||||||
|
new ConfigDescription("Output Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
outputMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
powerUpDelayMultiplier = config.Bind(
|
||||||
|
"Energy", "Power Up Delay Multiplier", 1f,
|
||||||
|
new ConfigDescription("Power Up Delay Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
powerUpDelayMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureModuleEnergy(MultipliedObject<ModuleEnergy> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_OutputPerSecond", outputMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_PowerUpDelay", powerUpDelayMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleEnergy), "OnAnchorStatusChanged")]
|
||||||
|
public static void PostfixCreate(ModuleEnergy __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleEnergy), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleEnergy __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleEnergy: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleEnergy);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
60
Projects/Quasimorph/Quasimorph/ModuleEnergyStoreManager.cs
Normal file
60
Projects/Quasimorph/Quasimorph/ModuleEnergyStoreManager.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleEnergyStoreManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleEnergyStore> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleEnergyStore>(ConfigureModuleEnergyStore);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> capacityMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Energy", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
capacityMultiplier =
|
||||||
|
config.Bind("Energy", "Capacity Multiplier", 1f,
|
||||||
|
new ConfigDescription("Capacity Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
capacityMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureModuleEnergyStore(MultipliedObject<ModuleEnergyStore> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_Capacity", capacityMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleEnergyStore), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleEnergyStore __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleEnergyStore), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleEnergyStore __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleEnergyStore: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleEnergyStore);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
67
Projects/Quasimorph/Quasimorph/ModuleFuelTankManager.cs
Normal file
67
Projects/Quasimorph/Quasimorph/ModuleFuelTankManager.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleFuelTankManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleFuelTank> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleFuelTank>(ConfigureFuelTank);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> fuelCapacityMultiplier;
|
||||||
|
private static ConfigEntry<float> fuelRefillMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("FuelTank", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
fuelCapacityMultiplier = config.Bind(
|
||||||
|
"FuelTank", "Fuel Capacity Multiplier", 1f,
|
||||||
|
new ConfigDescription("Fuel Capacity Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
fuelCapacityMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
fuelRefillMultiplier =
|
||||||
|
config.Bind("FuelTank", "Fuel Refill Multiplier", 1f,
|
||||||
|
new ConfigDescription("Fuel Refill Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
fuelRefillMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureFuelTank(MultipliedObject<ModuleFuelTank> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_Capacity", fuelCapacityMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_RefillRate", fuelRefillMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.isObjectPlayerTank(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleFuelTank), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleFuelTank __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleFuelTank), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleFuelTank __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleFuelTank: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleFuelTank);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
60
Projects/Quasimorph/Quasimorph/ModuleGyroManager.cs
Normal file
60
Projects/Quasimorph/Quasimorph/ModuleGyroManager.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleGyroManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleGyro> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleGyro>(ConfigureModuleGyro);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> activeSpeedMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Gyro", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
activeSpeedMultiplier = config.Bind(
|
||||||
|
"Gyro", "Active Speed Multiplier", 1f,
|
||||||
|
new ConfigDescription("Active Speed Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
activeSpeedMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureModuleGyro(MultipliedObject<ModuleGyro> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_ActiveSpeed", activeSpeedMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleGyro), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleGyro __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleGyro), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleGyro __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleGyro: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleGyro);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
76
Projects/Quasimorph/Quasimorph/ModuleHeartManager.cs
Normal file
76
Projects/Quasimorph/Quasimorph/ModuleHeartManager.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleHeartManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleHeart> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleHeart>(ConfigureHeart);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> eventHorizonRadiusMultiplier;
|
||||||
|
private static ConfigEntry<float> setupTimeMultiplier;
|
||||||
|
private static ConfigEntry<float> startShrinkingRadiusMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Heart", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
eventHorizonRadiusMultiplier = config.Bind(
|
||||||
|
"Heart", "Event Horizon Radius Multiplier", 1f,
|
||||||
|
new ConfigDescription("Event Horizon Radius Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
eventHorizonRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
setupTimeMultiplier =
|
||||||
|
config.Bind("Heart", "Setup Time Multiplier", 1f,
|
||||||
|
new ConfigDescription("Setup Time Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
setupTimeMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
startShrinkingRadiusMultiplier = config.Bind(
|
||||||
|
"Heart", "Start Shrinking Radius Multiplier", 1f,
|
||||||
|
new ConfigDescription("Start Shrinking Radius Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
startShrinkingRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureHeart(MultipliedObject<ModuleHeart> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_EventHorizonRadius", eventHorizonRadiusMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_SetupTime", setupTimeMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_StartShrinkingRadius", startShrinkingRadiusMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.isObjectPlayerTank(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleHeart), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleHeart __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleHeart), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleHeart __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleHeart: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleHeart);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
164
Projects/Quasimorph/Quasimorph/ModuleItemHolderManager.cs
Normal file
164
Projects/Quasimorph/Quasimorph/ModuleItemHolderManager.cs
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleItemHolderManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleItemHolder> BeamManager =
|
||||||
|
new MultipliedObjectManager<ModuleItemHolder>(ConfigureBeam);
|
||||||
|
private static readonly MultipliedObjectManager<ModuleItemHolderBeam> BeamHolderManager =
|
||||||
|
new MultipliedObjectManager<ModuleItemHolderBeam>(ConfigureBeamHolder);
|
||||||
|
private static readonly MultipliedObjectManager<ModuleItemPickup> BeamPickupManager =
|
||||||
|
new MultipliedObjectManager<ModuleItemPickup>(ConfigureBeamPickup);
|
||||||
|
|
||||||
|
private static readonly MultipliedObjectManager<ModuleItemHolderMagnet> MagnetHolderManager =
|
||||||
|
new MultipliedObjectManager<ModuleItemHolderMagnet>(ConfigureMagnetHolder);
|
||||||
|
private static readonly MultipliedObjectManager<ModuleItemPickup> MagnetPickupManager =
|
||||||
|
new MultipliedObjectManager<ModuleItemPickup>(ConfigureMagnetPickup);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> capacityPerStackMultiplier;
|
||||||
|
private static ConfigEntry<float> beamStrengthMultiplier;
|
||||||
|
private static ConfigEntry<float> beamHeightIncrementScaleMultiplier;
|
||||||
|
private static ConfigEntry<float> beamPickupRangeMultiplier;
|
||||||
|
private static ConfigEntry<float> magnetStrengthMultiplier;
|
||||||
|
private static ConfigEntry<float> magnetPickupRangeMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Item Holder", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
capacityPerStackMultiplier = config.Bind(
|
||||||
|
"Item Holder", "Capacity Per Stack Multiplier", 1f,
|
||||||
|
new ConfigDescription("Capacity Per Stack Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
capacityPerStackMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
beamStrengthMultiplier = config.Bind(
|
||||||
|
"Item Holder", "Beam Strength Multiplier", 1f,
|
||||||
|
new ConfigDescription("Beam Strength Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
beamStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
beamHeightIncrementScaleMultiplier =
|
||||||
|
config.Bind("Item Holder", "Beam Height Increment Scale Multiplier", 1f,
|
||||||
|
new ConfigDescription("Beam Height Increment Scale Multiplier",
|
||||||
|
new AcceptableValueRange<float>(min, max)));
|
||||||
|
beamHeightIncrementScaleMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
beamPickupRangeMultiplier = config.Bind(
|
||||||
|
"Item Holder", "Beam Pickup Range Multiplier", 1f,
|
||||||
|
new ConfigDescription("Beam Pickup Range Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
beamPickupRangeMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
magnetStrengthMultiplier = config.Bind(
|
||||||
|
"Item Holder", "Magnet Strength Multiplier", 1f,
|
||||||
|
new ConfigDescription("Magnet Strength Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
magnetStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
magnetPickupRangeMultiplier = config.Bind(
|
||||||
|
"Item Holder", "Magnet Pickup Range Multiplier", 1f,
|
||||||
|
new ConfigDescription("Magnet Pickup Range Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
magnetPickupRangeMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureBeam(MultipliedObject<ModuleItemHolder> obj) {
|
||||||
|
obj.AddField(
|
||||||
|
new FieldConfiguration<int, float>("m_CapacityPerStack", capacityPerStackMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureBeamHolder(MultipliedObject<ModuleItemHolderBeam> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_BeamStrength", beamStrengthMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_HeightIncrementScale",
|
||||||
|
beamHeightIncrementScaleMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureBeamPickup(MultipliedObject<ModuleItemPickup> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_PickupRange", beamPickupRangeMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureMagnetHolder(MultipliedObject<ModuleItemHolderMagnet> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_Strength", magnetStrengthMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureMagnetPickup(MultipliedObject<ModuleItemPickup> obj) {
|
||||||
|
obj.AddField(
|
||||||
|
new FieldConfiguration<float, float>("m_PickupRange", magnetPickupRangeMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemHolder), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleItemHolder __instance) {
|
||||||
|
BeamManager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemHolder), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleItemHolder __instance) {
|
||||||
|
BeamManager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleItemHolderBeam __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
|
||||||
|
|
||||||
|
BeamHolderManager.OnObjectAttached(__instance);
|
||||||
|
BeamPickupManager.OnObjectAttached(pickup);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemHolderBeam), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleItemHolderBeam __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
|
||||||
|
|
||||||
|
BeamHolderManager.OnObjectDetached(__instance);
|
||||||
|
BeamPickupManager.OnObjectDetached(pickup);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleItemHolderMagnet __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
|
||||||
|
|
||||||
|
MagnetHolderManager.OnObjectAttached(__instance);
|
||||||
|
MagnetPickupManager.OnObjectAttached(pickup);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemHolderMagnet), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleItemHolderMagnet __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var pickup = trav.Field("m_Pickup").GetValue<ModuleItemPickup>();
|
||||||
|
|
||||||
|
MagnetHolderManager.OnObjectDetached(__instance);
|
||||||
|
MagnetPickupManager.OnObjectDetached(pickup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
BeamManager.ApplyAll();
|
||||||
|
BeamHolderManager.ApplyAll();
|
||||||
|
BeamPickupManager.ApplyAll();
|
||||||
|
MagnetHolderManager.ApplyAll();
|
||||||
|
MagnetPickupManager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleItemHolder: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleItemHolder);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
77
Projects/Quasimorph/Quasimorph/ModuleItemProducerManager.cs
Normal file
77
Projects/Quasimorph/Quasimorph/ModuleItemProducerManager.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleItemProducerManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleItemProducer> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleItemProducer>(ConfigureModuleItemProducer);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> resourceGroundRadiusMultiplier;
|
||||||
|
private static ConfigEntry<float> minDispenseIntervalMultiplier;
|
||||||
|
private static ConfigEntry<float> secPerItemProducedMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
float min = 0.01f;
|
||||||
|
float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Item Producer", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
resourceGroundRadiusMultiplier = config.Bind(
|
||||||
|
"Item Producer", "Resource Ground Radius Multiplier", 1f,
|
||||||
|
new ConfigDescription("Resource Ground Radius Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
resourceGroundRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
minDispenseIntervalMultiplier = config.Bind(
|
||||||
|
"Item Producer", "Min Dispense Interval Multiplier", 1f,
|
||||||
|
new ConfigDescription("Min Dispense Interval Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
minDispenseIntervalMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
secPerItemProducedMultiplier = config.Bind(
|
||||||
|
"Item Producer", "Sec Per Item Produced Multiplier", 1f,
|
||||||
|
new ConfigDescription("Sec Per Item Produced Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
secPerItemProducedMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureModuleItemProducer(MultipliedObject<ModuleItemProducer> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_ResourceGroundRadius", resourceGroundRadiusMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_MinDispenseInterval", minDispenseIntervalMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_SecPerItemProduced", secPerItemProducedMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemProducer), "GetClosestResourceReservoirInRange")]
|
||||||
|
public static void PostfixCreate(ModuleItemProducer __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleItemProducer), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleItemProducer __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleItemProducer: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleItemProducer);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
77
Projects/Quasimorph/Quasimorph/ModuleRemoteChargerManager.cs
Normal file
77
Projects/Quasimorph/Quasimorph/ModuleRemoteChargerManager.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleRemoteChargerManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleRemoteCharger> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleRemoteCharger>(ConfigureModuleRemoteCharger);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> arcFiringIntervalMultiplier;
|
||||||
|
private static ConfigEntry<float> chargingRadiusMultiplier;
|
||||||
|
private static ConfigEntry<float> powerTransferPerArcMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
const float min = 0.01f;
|
||||||
|
const float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Remote Charger", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
arcFiringIntervalMultiplier = config.Bind(
|
||||||
|
"Remote Charger", "Arc Firing Interval Multiplier", 1f,
|
||||||
|
new ConfigDescription("Arc Firing Interval Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
arcFiringIntervalMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
chargingRadiusMultiplier = config.Bind(
|
||||||
|
"Remote Charger", "Charging Radius Multiplier", 1f,
|
||||||
|
new ConfigDescription("Charging Radius Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
chargingRadiusMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
powerTransferPerArcMultiplier = config.Bind(
|
||||||
|
"Remote Charger", "Power Transfer Per Arc Multiplier", 1f,
|
||||||
|
new ConfigDescription("Power Transfer Per Arc Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
powerTransferPerArcMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureModuleRemoteCharger(MultipliedObject<ModuleRemoteCharger> obj) {
|
||||||
|
obj.AddField(
|
||||||
|
new FieldConfiguration<float, float>("m_ArcFiringInterval", arcFiringIntervalMultiplier, ShouldApply));
|
||||||
|
obj.AddField(
|
||||||
|
new FieldConfiguration<float, float>("m_ChargingRadius", chargingRadiusMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_PowerTransferPerArc", powerTransferPerArcMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleRemoteCharger __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleRemoteCharger), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleRemoteCharger __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleRemoteCharger: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleRemoteCharger);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleShieldGeneratorManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleShieldGenerator> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleShieldGenerator>(ConfigureShieldGenerator);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> radiusMultiplier;
|
||||||
|
private static ConfigEntry<float> radiusMultiplierHealing;
|
||||||
|
private static ConfigEntry<float> heartbeatIntervalMultiplier;
|
||||||
|
private static ConfigEntry<float> powerUpDelayMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
const float min = 0.01f;
|
||||||
|
const float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Shield", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
radiusMultiplier =
|
||||||
|
config.Bind("Shield", "Radius Multiplier", 1f,
|
||||||
|
new ConfigDescription("Radius Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
radiusMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
heartbeatIntervalMultiplier = config.Bind(
|
||||||
|
"Shield", "Heartbeat Interval Multiplier", 1f,
|
||||||
|
new ConfigDescription("Heartbeat Interval Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
heartbeatIntervalMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
powerUpDelayMultiplier = config.Bind(
|
||||||
|
"Shield", "Power Up Delay Multiplier", 1f,
|
||||||
|
new ConfigDescription("Power Up Delay Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
powerUpDelayMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
radiusMultiplierHealing = config.Bind(
|
||||||
|
"Shield", "Radius Multiplier Healing", 1f,
|
||||||
|
new ConfigDescription("Radius Multiplier Healing", new AcceptableValueRange<float>(min, max)));
|
||||||
|
radiusMultiplierHealing.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureShieldGenerator(MultipliedObject<ModuleShieldGenerator> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_HealingHeartbeatInterval", heartbeatIntervalMultiplier,
|
||||||
|
ShouldApply));
|
||||||
|
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_Radius", radiusMultiplier, __instance => {
|
||||||
|
if (!ShouldApply(__instance))
|
||||||
|
return radiusMultiplier;
|
||||||
|
var shield = (ModuleShieldGenerator)__instance;
|
||||||
|
return shield.m_Healing ? radiusMultiplierHealing : radiusMultiplier;
|
||||||
|
}));
|
||||||
|
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_PowerUpDelay", powerUpDelayMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleShieldGenerator __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleShieldGenerator), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleShieldGenerator __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleShieldGenerator: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleShieldGenerator);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
121
Projects/Quasimorph/Quasimorph/ModuleWeaponGunManager.cs
Normal file
121
Projects/Quasimorph/Quasimorph/ModuleWeaponGunManager.cs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleWeaponGunManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleWeaponGun> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleWeaponGun>(ConfigureManager);
|
||||||
|
private static readonly MultipliedObjectManager<FireData> FireDataManager =
|
||||||
|
new MultipliedObjectManager<FireData>(ConfigureFireData);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> kickbackStrengthMultiplier;
|
||||||
|
private static ConfigEntry<float> muzzleVelocityMultiplier;
|
||||||
|
private static ConfigEntry<float> burstCooldownMultiplier;
|
||||||
|
private static ConfigEntry<float> burstShotCountMultiplier;
|
||||||
|
private static ConfigEntry<float> shotCooldownMultiplier;
|
||||||
|
private static ConfigEntry<bool> seekingRoundsAll;
|
||||||
|
private static ConfigEntry<bool> resetBurstOnInterruptAll;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
const float min = 0.01f;
|
||||||
|
const float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("WeaponGun", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
kickbackStrengthMultiplier = config.Bind(
|
||||||
|
"FireData", "Kickback Strength Multiplier", 1f,
|
||||||
|
new ConfigDescription("Kickback Strength Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
kickbackStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
muzzleVelocityMultiplier = config.Bind(
|
||||||
|
"FireData", "Muzzle Velocity Multiplier", 1f,
|
||||||
|
new ConfigDescription("Muzzle Velocity Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
muzzleVelocityMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
burstCooldownMultiplier = config.Bind(
|
||||||
|
"FireData", "Burst Cooldown Multiplier", 1f,
|
||||||
|
new ConfigDescription("Burst Cooldown Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
burstCooldownMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
burstShotCountMultiplier = config.Bind(
|
||||||
|
"FireData", "Burst Shot Count Multiplier", 1f,
|
||||||
|
new ConfigDescription("Burst Shot Count Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
burstShotCountMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
shotCooldownMultiplier = config.Bind(
|
||||||
|
"FireData", "Shot Cooldown Multiplier", 1f,
|
||||||
|
new ConfigDescription("Shot Cooldown Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
shotCooldownMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
seekingRoundsAll =
|
||||||
|
config.Bind("FireData", "Seeking Rounds All", false,
|
||||||
|
new ConfigDescription("Seeking Rounds All", new AcceptableValueRange<bool>(false, true)));
|
||||||
|
seekingRoundsAll.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
resetBurstOnInterruptAll = config.Bind(
|
||||||
|
"FireData", "Reset Burst On Interrupt All", false,
|
||||||
|
new ConfigDescription("Reset Burst On Interrupt All", new AcceptableValueRange<bool>(false, true)));
|
||||||
|
resetBurstOnInterruptAll.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureManager(MultipliedObject<ModuleWeaponGun> obj) {
|
||||||
|
obj.AddBooleanField(new BooleanFieldConfiguration("m_SeekingRounds", seekingRoundsAll, ShouldApply));
|
||||||
|
obj.AddBooleanField(
|
||||||
|
new BooleanFieldConfiguration("m_ResetBurstOnInterrupt", resetBurstOnInterruptAll, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_BurstCooldown", burstCooldownMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<int, float>("m_BurstShotCount", burstShotCountMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_ShotCooldown", shotCooldownMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureFireData(MultipliedObject<FireData> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_MuzzleVelocity", muzzleVelocityMultiplier));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_KickbackStrength", kickbackStrengthMultiplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWeaponGun), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleWeaponGun __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var firingData = trav.Field("m_FiringData");
|
||||||
|
FireDataManager.OnObjectAttached(firingData.GetValue<FireData>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWeaponGun), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleWeaponGun __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var firingData = trav.Field("m_FiringData");
|
||||||
|
FireDataManager.OnObjectDetached(firingData.GetValue<FireData>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
FireDataManager.ApplyAll();
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleWeaponGun: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleWeaponGun);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
60
Projects/Quasimorph/Quasimorph/ModuleWeaponManager.cs
Normal file
60
Projects/Quasimorph/Quasimorph/ModuleWeaponManager.cs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleWeaponManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleWeapon> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleWeapon>(ConfigureManager);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> rotateSpeedMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
const float min = 0.01f;
|
||||||
|
const float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("ModuleWeapon", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
rotateSpeedMultiplier = config.Bind(
|
||||||
|
"ModuleWeapon", "Rotate Speed Multiplier", 1f,
|
||||||
|
new ConfigDescription("Rotate Speed Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
rotateSpeedMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureManager(MultipliedObject<ModuleWeapon> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("m_RotateSpeed", rotateSpeedMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWeapon), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleWeapon __instance) {
|
||||||
|
Manager.OnObjectAttached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWeapon), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleWeapon __instance) {
|
||||||
|
Manager.OnObjectDetached(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleWeapon: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleWeapon);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
71
Projects/Quasimorph/Quasimorph/ModuleWheelsManager.cs
Normal file
71
Projects/Quasimorph/Quasimorph/ModuleWheelsManager.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleWheelsManager {
|
||||||
|
private static readonly MultipliedObjectManager<ManWheels.TorqueParams> TorqueParamsManager =
|
||||||
|
new MultipliedObjectManager<ManWheels.TorqueParams>(ConfigureTorqueParams);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> torqueRpmMultiplier;
|
||||||
|
private static ConfigEntry<float> torqueMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
const float min = 0.01f;
|
||||||
|
const float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("TorqueParams", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
torqueRpmMultiplier =
|
||||||
|
config.Bind("TorqueParams", "Torque RPM Multiplier", 1f,
|
||||||
|
new ConfigDescription("Torque RPM Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
torqueRpmMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
torqueMultiplier =
|
||||||
|
config.Bind("TorqueParams", "Torque Multiplier", 1f,
|
||||||
|
new ConfigDescription("Torque Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
torqueMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureTorqueParams(MultipliedObject<ManWheels.TorqueParams> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("torqueCurveMaxRpm", torqueRpmMultiplier, ShouldApply));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("torqueCurveMaxTorque", torqueMultiplier, ShouldApply));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWheels), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleWheels __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var torqueParams = trav.Field("torqueParams");
|
||||||
|
TorqueParamsManager.OnObjectAttached(torqueParams.GetValue<ManWheels.TorqueParams>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWheels), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleWheels __instance) {
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var torqueParams = trav.Field("torqueParams");
|
||||||
|
TorqueParamsManager.OnObjectDetached(torqueParams.GetValue<ManWheels.TorqueParams>());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
TorqueParamsManager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleWheels: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleWheels);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
83
Projects/Quasimorph/Quasimorph/ModuleWingManager.cs
Normal file
83
Projects/Quasimorph/Quasimorph/ModuleWingManager.cs
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ModuleWingManager {
|
||||||
|
private static readonly MultipliedObjectManager<ModuleWing.Aerofoil> Manager =
|
||||||
|
new MultipliedObjectManager<ModuleWing.Aerofoil>(ConfigureAerofoil);
|
||||||
|
|
||||||
|
private static ConfigEntry<bool> playerOnly;
|
||||||
|
private static ConfigEntry<float> angleRangeMultiplier;
|
||||||
|
private static ConfigEntry<float> turnSpeedMultiplier;
|
||||||
|
private static ConfigEntry<float> liftStrengthMultiplier;
|
||||||
|
|
||||||
|
public static void Setup(ConfigFile config) {
|
||||||
|
const float min = 0.01f;
|
||||||
|
const float max = 32f;
|
||||||
|
|
||||||
|
playerOnly = config.Bind("Aerofoil", "Player Only", false, new ConfigDescription("Player Only"));
|
||||||
|
playerOnly.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
angleRangeMultiplier =
|
||||||
|
config.Bind("Aerofoil", "Angle Range Multiplier", 1f,
|
||||||
|
new ConfigDescription("Angle Range Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
angleRangeMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
turnSpeedMultiplier =
|
||||||
|
config.Bind("Aerofoil", "Turn Speed Multiplier", 1f,
|
||||||
|
new ConfigDescription("Turn Speed Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
turnSpeedMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
|
||||||
|
liftStrengthMultiplier = config.Bind(
|
||||||
|
"Aerofoil", "Lift Strength Multiplier", 1f,
|
||||||
|
new ConfigDescription("Lift Strength Multiplier", new AcceptableValueRange<float>(min, max)));
|
||||||
|
liftStrengthMultiplier.SettingChanged += (sender, args) => DoPatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureAerofoil(MultipliedObject<ModuleWing.Aerofoil> obj) {
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("flapAngleRangeActual", angleRangeMultiplier));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("flapAngleRangeVisual", angleRangeMultiplier));
|
||||||
|
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("flapTurnSpeed", turnSpeedMultiplier));
|
||||||
|
obj.AddField(new FieldConfiguration<float, float>("liftStrength", liftStrengthMultiplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Func<object, bool> ShouldApply = obj => {
|
||||||
|
if (!playerOnly.Value)
|
||||||
|
return true;
|
||||||
|
return CykUtil.IsPlayerTank(obj as Module);
|
||||||
|
};
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWing), "OnAttached")]
|
||||||
|
public static void PostfixCreate(ModuleWing __instance) {
|
||||||
|
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
|
||||||
|
return;
|
||||||
|
for (int i = 0; i < __instance.m_Aerofoils.Length; i++) {
|
||||||
|
var aerofoil = __instance.m_Aerofoils[i];
|
||||||
|
Manager.OnObjectAttached(aerofoil);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ModuleWing), "OnDetaching")]
|
||||||
|
public static void PostfixDestroy(ModuleWing __instance) {
|
||||||
|
if (playerOnly.Value && !CykUtil.IsPlayerTank(__instance))
|
||||||
|
return;
|
||||||
|
foreach (var aerofoil in __instance.m_Aerofoils) Manager.OnObjectDetached(aerofoil);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DoPatch() {
|
||||||
|
Manager.ApplyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly Func<Module, bool> Register = obj => {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Registering ModuleWing: {0}", obj);
|
||||||
|
PostfixCreate(obj as ModuleWing);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
71
Projects/Quasimorph/Quasimorph/MultiBuy.cs
Normal file
71
Projects/Quasimorph/Quasimorph/MultiBuy.cs
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class MultiBuy {
|
||||||
|
public static UIShopBlockSelect panel;
|
||||||
|
public static Traverse panelTraverse;
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
[HarmonyPatch(typeof(UIShopBlockSelect), "OnSpawn")]
|
||||||
|
public static void PostfixCreate(UIShopBlockSelect __instance) {
|
||||||
|
panel = __instance;
|
||||||
|
if (Main.debugBuyAll.Value)
|
||||||
|
Console.WriteLine("UISnapshotPanel.OnPool: {0}", __instance);
|
||||||
|
panelTraverse = Traverse.Create(__instance);
|
||||||
|
var placeButton = panelTraverse.Field("m_PurchaseBlockButton").GetValue<Button>();
|
||||||
|
placeButton.gameObject.AddComponent<MultiBuyRightClickHandler>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MultiBuyRightClickHandler : MonoBehaviour, IPointerClickHandler {
|
||||||
|
// private void Awake() {
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void OnPointerClick(PointerEventData eventData) {
|
||||||
|
if (Main.debugBuyAll.Value)
|
||||||
|
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: {0} {1}", gameObject.name,
|
||||||
|
eventData.button);
|
||||||
|
try {
|
||||||
|
if (eventData.button == PointerEventData.InputButton.Right) {
|
||||||
|
UIBlockSelectGrid grid = MultiBuy.panelTraverse.Field("m_Grid").GetValue<UIBlockSelectGrid>();
|
||||||
|
BlockTypes blockTypes;
|
||||||
|
bool ok = grid.TryGetSelection(out blockTypes);
|
||||||
|
if (!ok) {
|
||||||
|
if (Main.debugBuyAll.Value)
|
||||||
|
Console.WriteLine(
|
||||||
|
"MultiBuyRightClickHandler.OnPointerClick: Failed to get block selection from grid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint shopBlockPoolID = MultiBuy.panelTraverse.Field("m_ShopBlockPoolID").GetValue<uint>();
|
||||||
|
|
||||||
|
MethodInfo canPurchaseMethod =
|
||||||
|
AccessTools.Method(typeof(UIShopBlockSelect), "CanPurchaseBlock", new[] { typeof(BlockTypes) });
|
||||||
|
Func<BlockTypes, bool> canPurchase = (Func<BlockTypes, bool>)Delegate.CreateDelegate(
|
||||||
|
typeof(Func<BlockTypes, bool>), MultiBuy.panel, canPurchaseMethod);
|
||||||
|
|
||||||
|
for (int i = 0; i < Main.multiBuyAmount.Value; i++) {
|
||||||
|
if (!canPurchase.Invoke(blockTypes)) {
|
||||||
|
if (Main.debugBuyAll.Value)
|
||||||
|
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Can purchase no more {0}",
|
||||||
|
blockTypes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Singleton.Manager<ManPurchases>.inst.RequestPurchaseBlock(shopBlockPoolID, blockTypes, 1);
|
||||||
|
if (Main.debugBuyAll.Value)
|
||||||
|
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Purchased {0} block",
|
||||||
|
blockTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (Main.debugBuyAll.Value)
|
||||||
|
Console.WriteLine("MultiBuyRightClickHandler.OnPointerClick: Exception occurred: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
531
Projects/Quasimorph/Quasimorph/ObjectFieldMultiplier.cs
Normal file
531
Projects/Quasimorph/Quasimorph/ObjectFieldMultiplier.cs
Normal file
@@ -0,0 +1,531 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using BepInEx.Configuration;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
public interface IFieldModifier {
|
||||||
|
void CaptureOriginal();
|
||||||
|
void Apply();
|
||||||
|
void Restore();
|
||||||
|
void LogValue(string prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a field that can be multiplied by a configurable value
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TField">The type of the field value</typeparam>
|
||||||
|
/// <typeparam name="TMul">The type of the multiplier</typeparam>
|
||||||
|
public class FieldConfiguration<TField, TMul> {
|
||||||
|
private string _fieldName;
|
||||||
|
private ConfigEntry<TMul> _defaultMultiplier;
|
||||||
|
private Func<object, ConfigEntry<TMul>> _conditionalMultiplier;
|
||||||
|
private Func<object, bool> _applyCondition;
|
||||||
|
|
||||||
|
public string FieldName {
|
||||||
|
get { return _fieldName; }
|
||||||
|
set { _fieldName = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigEntry<TMul> DefaultMultiplier {
|
||||||
|
get { return _defaultMultiplier; }
|
||||||
|
set { _defaultMultiplier = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func<object, ConfigEntry<TMul>> ConditionalMultiplier {
|
||||||
|
get { return _conditionalMultiplier; }
|
||||||
|
set { _conditionalMultiplier = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func<object, bool> ApplyCondition {
|
||||||
|
get { return _applyCondition; }
|
||||||
|
set { _applyCondition = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_defaultMultiplier = defaultMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier,
|
||||||
|
Func<object, ConfigEntry<TMul>> conditionalMultiplier) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_defaultMultiplier = defaultMultiplier;
|
||||||
|
_conditionalMultiplier = conditionalMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier,
|
||||||
|
Func<object, bool> applyCondition) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_defaultMultiplier = defaultMultiplier;
|
||||||
|
_applyCondition = applyCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldConfiguration(string fieldName, ConfigEntry<TMul> defaultMultiplier,
|
||||||
|
Func<object, ConfigEntry<TMul>> conditionalMultiplier,
|
||||||
|
Func<object, bool> applyCondition) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_defaultMultiplier = defaultMultiplier;
|
||||||
|
_conditionalMultiplier = conditionalMultiplier;
|
||||||
|
_applyCondition = applyCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigEntry<TMul> GetMultiplier(object __instance) {
|
||||||
|
if (_conditionalMultiplier == null) {
|
||||||
|
return _defaultMultiplier;
|
||||||
|
}
|
||||||
|
return _conditionalMultiplier(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShouldApply(object __instance) {
|
||||||
|
if (_applyCondition == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return _applyCondition(__instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultipliedField<TField, TMul> : IFieldModifier {
|
||||||
|
private readonly string _fieldName;
|
||||||
|
private readonly ConfigEntry<TMul> _multiplier;
|
||||||
|
private readonly Traverse _parentTraverse;
|
||||||
|
private readonly Func<object, bool> _applyCondition;
|
||||||
|
private TField _originalValue;
|
||||||
|
|
||||||
|
public string FieldName {
|
||||||
|
get { return _fieldName; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipliedField(string fieldName, ConfigEntry<TMul> multiplier, Traverse parentTraverse,
|
||||||
|
Func<object, bool> applyCondition = null) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_multiplier = multiplier;
|
||||||
|
_parentTraverse = parentTraverse;
|
||||||
|
_applyCondition = applyCondition;
|
||||||
|
|
||||||
|
if (!parentTraverse.Field(fieldName).FieldExists()) {
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify TField is a numeric type
|
||||||
|
if (!IsNumericType(typeof(TField))) {
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("Field type {0} must be a numeric type", typeof(TField).Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify TMul is a numeric type
|
||||||
|
if (!IsNumericType(typeof(TMul))) {
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("Multiplier type {0} must be a numeric type", typeof(TMul).Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsNumericType(Type type) {
|
||||||
|
return type == typeof(byte) || type == typeof(sbyte) || type == typeof(short) || type == typeof(ushort) ||
|
||||||
|
type == typeof(int) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong) ||
|
||||||
|
type == typeof(float) || type == typeof(double) || type == typeof(decimal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TField MultiplyValues(TField fieldValue, TMul multiplierValue) {
|
||||||
|
// Convert both to double for the multiplication
|
||||||
|
double fieldDouble = Convert.ToDouble(fieldValue);
|
||||||
|
double multiplierDouble = Convert.ToDouble(multiplierValue);
|
||||||
|
double result = fieldDouble * multiplierDouble;
|
||||||
|
// Convert back to TField
|
||||||
|
return (TField)Convert.ChangeType(result, typeof(TField));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TField GetValue() {
|
||||||
|
var value = _parentTraverse.Field(_fieldName).GetValue();
|
||||||
|
if (value == null)
|
||||||
|
throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName));
|
||||||
|
return (TField)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(TField value) {
|
||||||
|
_parentTraverse.Field(_fieldName).SetValue(value);
|
||||||
|
var verifyValue = GetValue();
|
||||||
|
if (!verifyValue.Equals(value))
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CaptureOriginal() {
|
||||||
|
_originalValue = GetValue();
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() {
|
||||||
|
try {
|
||||||
|
if (_applyCondition != null && !_applyCondition(_parentTraverse.GetValue())) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Skipping {0}: condition not met", _fieldName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newValue = MultiplyValues(_originalValue, _multiplier.Value);
|
||||||
|
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Applying to {0}: {1} * {2} = {3}", _fieldName, _originalValue, _multiplier.Value,
|
||||||
|
newValue);
|
||||||
|
|
||||||
|
SetValue(newValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidOperationException(string.Format("Failed to apply multiplication to {0}", _fieldName),
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore() {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue);
|
||||||
|
SetValue(_originalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogValue(string prefix) {
|
||||||
|
if (!Main.debug.Value)
|
||||||
|
return;
|
||||||
|
var currentValue = GetValue();
|
||||||
|
Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, multiplier: {5})", prefix, _parentTraverse, _fieldName,
|
||||||
|
currentValue, _originalValue, _multiplier.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BooleanFieldConfiguration {
|
||||||
|
private string _fieldName;
|
||||||
|
private ConfigEntry<bool> _value;
|
||||||
|
private Func<object, ConfigEntry<bool>> _conditionalValue;
|
||||||
|
private Func<object, bool> _applyCondition;
|
||||||
|
|
||||||
|
public string FieldName {
|
||||||
|
get { return _fieldName; }
|
||||||
|
set { _fieldName = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigEntry<bool> Value {
|
||||||
|
get { return _value; }
|
||||||
|
set { _value = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func<object, ConfigEntry<bool>> ConditionalValue {
|
||||||
|
get { return _conditionalValue; }
|
||||||
|
set { _conditionalValue = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Func<object, bool> ApplyCondition {
|
||||||
|
get { return _applyCondition; }
|
||||||
|
set { _applyCondition = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value,
|
||||||
|
Func<object, ConfigEntry<bool>> conditionalValue) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_value = value;
|
||||||
|
_conditionalValue = conditionalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value, Func<object, bool> applyCondition) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_value = value;
|
||||||
|
_applyCondition = applyCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanFieldConfiguration(string fieldName, ConfigEntry<bool> value,
|
||||||
|
Func<object, ConfigEntry<bool>> conditionalValue,
|
||||||
|
Func<object, bool> applyCondition) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_value = value;
|
||||||
|
_conditionalValue = conditionalValue;
|
||||||
|
_applyCondition = applyCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigEntry<bool> GetValue(object __instance) {
|
||||||
|
if (_conditionalValue == null) {
|
||||||
|
return _value;
|
||||||
|
}
|
||||||
|
return _conditionalValue(__instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShouldApply(object __instance) {
|
||||||
|
if (_applyCondition == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return _applyCondition(__instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BooleanField : IFieldModifier {
|
||||||
|
private readonly string _fieldName;
|
||||||
|
private readonly ConfigEntry<bool> _value;
|
||||||
|
private readonly Traverse _parentTraverse;
|
||||||
|
private readonly Func<object, bool> _applyCondition;
|
||||||
|
private bool _originalValue;
|
||||||
|
|
||||||
|
public string FieldName {
|
||||||
|
get { return _fieldName; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BooleanField(string fieldName, ConfigEntry<bool> value, Traverse parentTraverse,
|
||||||
|
Func<object, bool> applyCondition = null) {
|
||||||
|
_fieldName = fieldName;
|
||||||
|
_value = value;
|
||||||
|
_parentTraverse = parentTraverse;
|
||||||
|
_applyCondition = applyCondition;
|
||||||
|
|
||||||
|
if (!parentTraverse.Field(fieldName).FieldExists()) {
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("Field {0} does not exist on {1}", fieldName, parentTraverse));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetValue() {
|
||||||
|
var value = _parentTraverse.Field(_fieldName).GetValue();
|
||||||
|
if (value == null)
|
||||||
|
throw new InvalidOperationException(string.Format("Field {0} returned null", _fieldName));
|
||||||
|
return (bool)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue(bool value) {
|
||||||
|
_parentTraverse.Field(_fieldName).SetValue(value);
|
||||||
|
var verifyValue = GetValue();
|
||||||
|
if (verifyValue != value)
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
string.Format("Field {0} set to {1} but read back as {2}", _fieldName, value, verifyValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CaptureOriginal() {
|
||||||
|
_originalValue = GetValue();
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Captured original value for {0}: {1}", _fieldName, _originalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply() {
|
||||||
|
try {
|
||||||
|
if (_applyCondition != null && !_applyCondition(_parentTraverse.GetValue())) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Skipping {0}: condition not met", _fieldName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_value.Value) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Applying to {0}: forcing to true", _fieldName);
|
||||||
|
|
||||||
|
SetValue(true);
|
||||||
|
} else {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Applying to {0}: leaving as {1} (config is false)", _fieldName, GetValue());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidOperationException(string.Format("Failed to apply value to {0}", _fieldName), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Restore() {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Restoring {0} to original value: {1}", _fieldName, _originalValue);
|
||||||
|
SetValue(_originalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogValue(string prefix) {
|
||||||
|
if (!Main.debug.Value)
|
||||||
|
return;
|
||||||
|
var currentValue = GetValue();
|
||||||
|
Console.WriteLine("{0} {1}; {2}: {3} (original: {4}, config: {5})", prefix, _parentTraverse, _fieldName,
|
||||||
|
currentValue, _originalValue, _value.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an object with multiple fields that can be multiplied
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the object being managed</typeparam>
|
||||||
|
public class MultipliedObject<T> {
|
||||||
|
private readonly T _instance;
|
||||||
|
private readonly Traverse _objectTraverse;
|
||||||
|
private readonly Dictionary<string, IFieldModifier> _fields;
|
||||||
|
|
||||||
|
public MultipliedObject(T __instance) {
|
||||||
|
_instance = __instance;
|
||||||
|
_objectTraverse = Traverse.Create(__instance);
|
||||||
|
_fields = new Dictionary<string, IFieldModifier>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddField<TField, TMul>(FieldConfiguration<TField, TMul> config) {
|
||||||
|
var multiplier = config.GetMultiplier(_instance);
|
||||||
|
_fields[config.FieldName] =
|
||||||
|
new MultipliedField<TField, TMul>(config.FieldName, multiplier, _objectTraverse, config.ShouldApply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddBooleanField(BooleanFieldConfiguration config) {
|
||||||
|
var value = config.GetValue(_instance);
|
||||||
|
_fields[config.FieldName] = new BooleanField(config.FieldName, value, _objectTraverse, config.ShouldApply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CaptureFrom() {
|
||||||
|
foreach (var field in _fields.Values) {
|
||||||
|
field.CaptureOriginal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyTo(IEnumerable<string> fieldNames = null) {
|
||||||
|
IEnumerable<string> fieldsToApply = fieldNames ?? _fields.Keys;
|
||||||
|
foreach (var fieldName in fieldsToApply.Where(name => _fields.ContainsKey(name)))
|
||||||
|
_fields[fieldName].Apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RestoreTo(IEnumerable<string> fieldNames = null) {
|
||||||
|
IEnumerable<string> fieldsToRestore = fieldNames ?? _fields.Keys;
|
||||||
|
foreach (var fieldName in fieldsToRestore.Where(name => _fields.ContainsKey(name)))
|
||||||
|
_fields[fieldName].Restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LogValues(string prefix) {
|
||||||
|
if (!Main.debug.Value)
|
||||||
|
return;
|
||||||
|
foreach (var field in _fields.Values) {
|
||||||
|
field.LogValue(prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manages a collection of objects whose fields can be multiplied
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of objects being managed</typeparam>
|
||||||
|
public class MultipliedObjectManager<T> {
|
||||||
|
private readonly Dictionary<T, MultipliedObject<T>> _managedObjects;
|
||||||
|
private readonly Action<MultipliedObject<T>> _configureObject;
|
||||||
|
|
||||||
|
public MultipliedObjectManager(Action<MultipliedObject<T>> configureObject) {
|
||||||
|
if (configureObject == null)
|
||||||
|
throw new ArgumentNullException("configureObject");
|
||||||
|
|
||||||
|
_configureObject = configureObject;
|
||||||
|
_managedObjects = new Dictionary<T, MultipliedObject<T>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SafeRemove(T __instance) {
|
||||||
|
if (__instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
_managedObjects.Remove(__instance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error removing __instance from _managedObjects: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnObjectAttached(T __instance) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("{0}.OnAttached", typeof(T).Name);
|
||||||
|
|
||||||
|
if (__instance == null) {
|
||||||
|
Console.WriteLine("Attempted to attach null __instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (_managedObjects.ContainsKey(__instance)) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("{0} already managed, skipping", typeof(T).Name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var multipliedObject = new MultipliedObject<T>(__instance);
|
||||||
|
_configureObject(multipliedObject);
|
||||||
|
multipliedObject.CaptureFrom();
|
||||||
|
_managedObjects.Add(__instance, multipliedObject);
|
||||||
|
multipliedObject.LogValues("Patching");
|
||||||
|
|
||||||
|
ApplyTo(__instance);
|
||||||
|
multipliedObject.LogValues("Patched");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error in OnObjectAttached: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnObjectDetached(T __instance) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
|
||||||
|
if (__instance == null) {
|
||||||
|
Console.WriteLine("Attempted to detach null __instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
MultipliedObject<T> multipliedObject;
|
||||||
|
if (_managedObjects.TryGetValue(__instance, out multipliedObject)) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
multipliedObject.LogValues("Restoring");
|
||||||
|
|
||||||
|
try {
|
||||||
|
RestoreTo(__instance);
|
||||||
|
multipliedObject.LogValues("Restored");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error restoring values: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeRemove(__instance);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error in OnObjectDetached: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyAll(IEnumerable<string> fieldNames = null) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name);
|
||||||
|
|
||||||
|
// Make a copy of the keys to avoid modification during enumeration
|
||||||
|
var instances = _managedObjects.Keys.ToList();
|
||||||
|
|
||||||
|
foreach (var __instance in instances) {
|
||||||
|
try {
|
||||||
|
RestoreTo(__instance, fieldNames);
|
||||||
|
ApplyTo(__instance, fieldNames);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error applying to __instance: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyTo(T __instance, IEnumerable<string> fieldNames = null) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Applying {0}", typeof(T).Name);
|
||||||
|
if (__instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MultipliedObject<T> obj;
|
||||||
|
if (_managedObjects.TryGetValue(__instance, out obj))
|
||||||
|
obj.ApplyTo(fieldNames);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error in ApplyTo: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RestoreTo(T __instance, IEnumerable<string> fieldNames = null) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Restoring {0}", typeof(T).Name);
|
||||||
|
if (__instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MultipliedObject<T> obj;
|
||||||
|
if (_managedObjects.TryGetValue(__instance, out obj))
|
||||||
|
obj.RestoreTo(fieldNames);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine("Error in RestoreTo: {0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
Projects/Quasimorph/Quasimorph/Patches.cs
Normal file
24
Projects/Quasimorph/Quasimorph/Patches.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class Patches {
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ManLicenses), "AddXP")]
|
||||||
|
static void XpMulti(FactionSubTypes corporation, ref int xp, bool showUI = true) {
|
||||||
|
xp = (int)(xp * Main.xpMultiplier.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(ManPlayer), "AddMoney")]
|
||||||
|
static void MoneyMulti(ref int amount) {
|
||||||
|
amount = (int)(amount * Main.moneyMultiplier.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(TechHolders), "SetHeartbeatInterval")]
|
||||||
|
static void HeartbeatMulti(ref float interval) {
|
||||||
|
interval *= Main.heartbeatIntervalMultiplier.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
Projects/Quasimorph/Quasimorph/ProjectilePatch.cs
Normal file
22
Projects/Quasimorph/Quasimorph/ProjectilePatch.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
namespace Quasimorph {
|
||||||
|
[HarmonyPatch]
|
||||||
|
public class ProjectilePatch {
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(Projectile), "StickToObjectWithVisuals")]
|
||||||
|
static void Prefix(Projectile __instance) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Projectile created");
|
||||||
|
var trav = Traverse.Create(__instance);
|
||||||
|
var explodeOnStick = trav.Field("m_ExplodeOnStick");
|
||||||
|
|
||||||
|
if (!explodeOnStick.GetValue<bool>()) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("Exploding on stick");
|
||||||
|
explodeOnStick.SetValue(Main.projectileExplodeOnStick.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
Projects/Quasimorph/Quasimorph/Properties/AssemblyInfo.cs
Normal file
35
Projects/Quasimorph/Quasimorph/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly:AssemblyTitle("Quasimorph")]
|
||||||
|
[assembly:AssemblyDescription("")]
|
||||||
|
[assembly:AssemblyConfiguration("")]
|
||||||
|
[assembly:AssemblyCompany("")]
|
||||||
|
[assembly:AssemblyProduct("Quasimorph")]
|
||||||
|
[assembly:AssemblyCopyright("Copyright © 2023")]
|
||||||
|
[assembly:AssemblyTrademark("")]
|
||||||
|
[assembly:AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly:ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly:Guid("EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly:AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly:AssemblyFileVersion("1.0.0.0")]
|
97
Projects/Quasimorph/Quasimorph/Quasimorph.csproj
Normal file
97
Projects/Quasimorph/Quasimorph/Quasimorph.csproj
Normal 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>
|
30
Projects/Quasimorph/Quasimorph/SeekingProjectileManager.cs
Normal file
30
Projects/Quasimorph/Quasimorph/SeekingProjectileManager.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
Projects/Quasimorph/Quasimorph/TankBeamManager.cs
Normal file
53
Projects/Quasimorph/Quasimorph/TankBeamManager.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
Projects/Quasimorph/Quasimorph/TankManager.cs
Normal file
53
Projects/Quasimorph/Quasimorph/TankManager.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
181
Projects/Quasimorph/Quasimorph/UISnapshotPanelBuyAll.cs
Normal file
181
Projects/Quasimorph/Quasimorph/UISnapshotPanelBuyAll.cs
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using HarmonyLib;
|
||||||
|
using Snapshots;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
Projects/Quasimorph/Quasimorph/log.cs
Normal file
14
Projects/Quasimorph/Quasimorph/log.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
static void Postfix(UIItemSelectGrid __instance) {
|
||||||
|
try {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine("--------------------");
|
||||||
|
sb.AppendLine("void UIItemSelectGrid::Repopulate()");
|
||||||
|
sb.Append("- __instance: ").AppendLine(__instance.ToString());
|
||||||
|
foreach (var item in __instance.m_FilteredItemList) {
|
||||||
|
sb.Append("- item: ").AppendLine(item.ToString());
|
||||||
|
}
|
||||||
|
UnityExplorer.ExplorerCore.Log(sb.ToString());
|
||||||
|
} catch (System.Exception ex) {
|
||||||
|
UnityExplorer.ExplorerCore.LogWarning($"Exception in patch of void UIItemSelectGrid::Repopulate():\n{ex}");
|
||||||
|
}
|
||||||
|
}
|
1
Projects/Quasimorph/format.sh
Normal file
1
Projects/Quasimorph/format.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
clang-format -i TerraTech/*.cs
|
3
Projects/Quasimorph/sync.yml
Normal file
3
Projects/Quasimorph/sync.yml
Normal 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
|
@@ -1 +0,0 @@
|
|||||||
bin/Release/DavesPhatStore.dll,"C:\Games\Supermarket Simulator\BepInEx\plugins\DavesPhatStore.dll"
|
|
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/DavesPhatStore.dll
|
||||||
|
target: C:\Games\Supermarket Simulator\BepInEx\plugins\DavesPhatStore.dll
|
||||||
|
delete: true
|
@@ -1 +0,0 @@
|
|||||||
bin/Release/DavesPhatStore.dll,"C:/Program Files (x86)/Steam/steamapps/common/Supermarket Together/BepInEx/plugins/DavesPhatStore.dll"
|
|
@@ -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
|
@@ -1 +0,0 @@
|
|||||||
bin/Release/TavernDave.dll,"C:\Games\Tavern Master\BepInEx\plugins\TavernDave.dll"
|
|
3
Projects/TavernMaster/TavernMaster/sync.yml
Normal file
3
Projects/TavernMaster/TavernMaster/sync.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
- source: bin/Release/TavernDave.dll
|
||||||
|
target: C:\Games\Tavern Master\BepInEx\plugins\TavernDave.dll
|
||||||
|
delete: true
|
@@ -1 +0,0 @@
|
|||||||
TerraTech/obj/Release/TerraTech.dll,~/scoop/apps/steam/current/steamapps/common/TerraTech/BepInEx/plugins/TerraTech.dll
|
|
3
Projects/TerraTech/sync.yml
Normal file
3
Projects/TerraTech/sync.yml
Normal 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
|
Reference in New Issue
Block a user