diff --git a/Projects/CykaOfQud/CavesOfQud.csproj b/Projects/CykaOfQud/CavesOfQud.csproj
new file mode 100644
index 0000000..ad2edf1
--- /dev/null
+++ b/Projects/CykaOfQud/CavesOfQud.csproj
@@ -0,0 +1,57 @@
+
+
+
+
+ C:/Games/Caves.of.Qud.Build.16668101
+ $(GAME_DIR)/CoQ_Data/Managed
+ $(GAME_DIR)/BepInEx
+ Debug
+ AnyCPU
+ {EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}
+ Library
+ Properties
+ CykaOfQud
+ CykaOfQud
+ v4.8.1
+ 512
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+ $(GAME_BEPINEX)/core/0Harmony.dll
+
+
+ $(GAME_BEPINEX)/core/BepInEx.dll
+
+
+ $(GAME_MANAGED)/UnityEngine.dll
+
+
+ $(GAME_MANAGED)/UnityEngine.CoreModule.dll
+
+
+
+
\ No newline at end of file
diff --git a/Projects/CykaOfQud/Class1.cs b/Projects/CykaOfQud/Class1.cs
new file mode 100644
index 0000000..a3d87e6
--- /dev/null
+++ b/Projects/CykaOfQud/Class1.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using BepInEx;
+using BepInEx.Configuration;
+using HarmonyLib;
+using HarmonyLib.Tools;
+
+namespace CykaOfQud {
+ [BepInPlugin(pluginGuid, pluginName, pluginVersion)]
+ public class Main : BaseUnityPlugin {
+ private const string pluginGuid = "CykaOfQud";
+ private const string pluginName = "CykaOfQud";
+ private const string pluginVersion = "1.0.0";
+
+ public static ConfigEntry excavatorCapacityMultiplier;
+ public static ConfigEntry excavatorMineTileIterationsMultiplier;
+ public static ConfigEntry truckCapacityMultiplier;
+ public static ConfigEntry cargoShipCapacityMultiplier;
+ public static ConfigEntry excavatorMiningCapacityMultiplier;
+ public static ConfigEntry excavatorMiningAreaMultiplier;
+ public static ConfigEntry excavatorMinReachMultiplier;
+ public static ConfigEntry excavatorMaxReachMultiplier;
+ public static ConfigEntry bufferCapacityMultiplier;
+ public static ConfigEntry unityGenerationMultiplier;
+ public static ConfigEntry depotTransferSpeedMultiplier;
+ public static ConfigEntry worldMineSpeedMultiplier;
+ public static ConfigEntry housingCapacityMultiplier;
+ public static ConfigEntry dumpDelayMultiplier;
+ public static ConfigEntry transportSpeedMultiplier;
+ public static ConfigEntry shipyardCargoMultiplier;
+ public static ConfigEntry autosaveInterval;
+ public static ConfigEntry recipeMultipliers;
+ public static Dictionary recipeMultipliersDict;
+
+ public static ConfigEntry debugMode;
+
+ public void Awake() {
+ excavatorCapacityMultiplier = Config.Bind("General", "Excavator Capacity Multiplier", 1,
+ new ConfigDescription("Excavator Capacity Multiplier"));
+ excavatorMineTileIterationsMultiplier = Config.Bind("General", "Excavator Mine Tile Iterations Multiplier",
+ 1f,
+ new ConfigDescription("Excavator Mine Tile Iterations Multiplier"));
+ truckCapacityMultiplier = Config.Bind("General", "Truck Capacity Multiplier", 1,
+ new ConfigDescription("Truck Capacity Multiplier"));
+ cargoShipCapacityMultiplier = Config.Bind("General", "Cargo Ship Capacity Multiplier", 1,
+ new ConfigDescription("Cargo Ship Capacity Multiplier"));
+ excavatorMiningAreaMultiplier = Config.Bind("General", "Excavator Mining Area Multiplier", 1,
+ new ConfigDescription("Excavator Mining Area Multiplier"));
+ excavatorMiningCapacityMultiplier = Config.Bind("General", "Excavator Mining Capacity Multiplier", 1f,
+ new ConfigDescription("Excavator Mining Capacity Multiplier"));
+ excavatorMinReachMultiplier = Config.Bind("General", "Excavator Min Reach Multiplier", 1f,
+ new ConfigDescription("Excavator Min Reach Multiplier"));
+ excavatorMaxReachMultiplier = Config.Bind("General", "Excavator Max Reach Multiplier", 1f,
+ new ConfigDescription("Excavator Max Reach Multiplier"));
+ bufferCapacityMultiplier = Config.Bind("General", "Buffer Capacity Multiplier", 1f,
+ new ConfigDescription("Buffer Capacity Multiplier"));
+ storageCapacityMultiplier = Config.Bind("General", "Storage Capacity Multiplier", 1f,
+ new ConfigDescription("Storage Capacity Multiplier"));
+ unityGenerationMultiplier = Config.Bind("General", "Unity Generation Multiplier", 1f,
+ new ConfigDescription("Unity Generation Multiplier"));
+ depotTransferSpeedMultiplier = Config.Bind("General", "Depot Transfer Speed Multiplier", 1f,
+ new ConfigDescription("Depot Transfer Speed Multiplier"));
+ worldMineSpeedMultiplier = Config.Bind("General", "World Mine Speed Multiplier", 1f,
+ new ConfigDescription("World Mine Speed Multiplier"));
+ housingCapacityMultiplier = Config.Bind("General", "Housing Capacity Multiplier", 1f,
+ new ConfigDescription("Housing Capacity Multiplier"));
+ dumpDelayMultiplier = Config.Bind("General", "Dump Delay Multiplier", 1f,
+ new ConfigDescription("Dump Delay Multiplier"));
+ transportSpeedMultiplier = Config.Bind("General", "Transport Speed Multiplier", 1f,
+ new ConfigDescription("Transport Speed Multiplier"));
+ shipyardCargoMultiplier = Config.Bind("General", "Shipyard Cargo Multiplier", 1f,
+ new ConfigDescription("Shipyard Cargo Multiplier"));
+ autosaveInterval = Config.Bind("General", "Autosave Interval", 1,
+ new ConfigDescription("Autosave Interval in minutes"));
+ recipeMultipliers = Config.Bind("General", "Recipe Multipliers", "dirt:4",
+ new ConfigDescription("Recipe Multipliers"));
+
+ recipeMultipliersDict = recipeMultipliers.Value.Split(',')
+ .ToDictionary(x => x.Split(':')[0], x => int.Parse(x.Split(':')[1]));
+ recipeMultipliers.SettingChanged += (sender, args) => {
+ recipeMultipliersDict = recipeMultipliers.Value.Split(',')
+ .ToDictionary(x => x.Split(':')[0], x => int.Parse(x.Split(':')[1]));
+ Console.WriteLine("IndustrialCyka: Recipe multipliers parsed as:");
+ foreach (var kvp in recipeMultipliersDict)
+ Console.WriteLine("\tIndustrialCyka: {0} x {1}", kvp.Key, kvp.Value);
+ };
+
+ debugMode = Config.Bind("General", "Debug Mode", false, new ConfigDescription("Debug Mode"));
+
+ // shootingSpeedMultiplier.SettingChanged += (sender, args) => WeaponPropertiesManager.DoPatch();
+ // energyGenMultiplier.SettingChanged += (sender, args) => GeneratorPropertiesManager.DoPatch();
+ // magnetStrenghtMultiplier.SettingChanged += (sender, args) => MagnetPropertiesManager.DoPatch();
+ // magnetRadiusMultiplier.SettingChanged += (sender, args) => MagnetPropertiesManager.DoPatch();
+ // beamStrenghtMultiplier.SettingChanged += (sender, args) => BeamPropertiesManager.DoPatch();
+ // beamRadiusMultiplier.SettingChanged += (sender, args) => BeamPropertiesManager.DoPatch();
+ // fuelTankRefillMultiplier.SettingChanged += (sender, args) => FuelPropertiesManager.DoPatch();
+ // fuelTankCapacityMultiplier.SettingChanged += (sender, args) => FuelPropertiesManager.DoPatch();
+ // wheelTorqueMultiplier.SettingChanged += (sender, args) => WheelPropertiesManager.DoPatch();
+ // wheelSpeedMultiplier.SettingChanged += (sender, args) => WheelPropertiesManager.DoPatch();
+ // jetThrustMultiplier.SettingChanged += (sender, args) => ThrusterPropertiesManager.DoPatch();
+ // minerGroundArea.SettingChanged += (sender, args) => MinerPropertiesManager.DoPatch();
+ // minerMiningSpeed.SettingChanged += (sender, args) => MinerPropertiesManager.DoPatch();
+ // wirelessChargingPowerPerArcMultiplier.SettingChanged += (sender, args) => WirelessChargerPropertiesManager.DoPatch();
+ // wirelessChargingArcFiringIntervalMultiplier.SettingChanged += (sender, args) => WirelessChargerPropertiesManager.DoPatch();
+ // wirelessChargingRadiusMultiplier.SettingChanged += (sender, args) => WirelessChargerPropertiesManager.DoPatch();
+
+ Logger.LogInfo("Cyka mod loaded");
+ HarmonyFileLog.Enabled = true;
+ Harmony harmony = new Harmony(pluginGuid);
+ harmony.PatchAll();
+ var originalMethods = harmony.GetPatchedMethods();
+ Logger.LogInfo("Patched " + originalMethods.Count() + " methods");
+ foreach (var method in originalMethods) {
+ Logger.LogInfo("Patched " + method.Name);
+ }
+ }
+
+ public static ConfigEntry storageCapacityMultiplier;
+ }
+}
\ No newline at end of file
diff --git a/Projects/CykaOfQud/CykaOfQud.sln b/Projects/CykaOfQud/CykaOfQud.sln
new file mode 100644
index 0000000..111ba7b
--- /dev/null
+++ b/Projects/CykaOfQud/CykaOfQud.sln
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CavesOfQud", "CavesOfQud.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
diff --git a/Projects/CykaOfQud/Patches.cs b/Projects/CykaOfQud/Patches.cs
new file mode 100644
index 0000000..1ac58b5
--- /dev/null
+++ b/Projects/CykaOfQud/Patches.cs
@@ -0,0 +1,621 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection.Emit;
+using HarmonyLib;
+using Mafi;
+using Mafi.Collections.ImmutableCollections;
+using Mafi.Core;
+using Mafi.Core.Buildings.Cargo.Modules;
+using Mafi.Core.Buildings.Cargo.Ships.Modules;
+using Mafi.Core.Buildings.Settlements;
+using Mafi.Core.Buildings.Shipyard;
+using Mafi.Core.Buildings.Storages;
+using Mafi.Core.Entities;
+using Mafi.Core.Entities.Dynamic;
+using Mafi.Core.Entities.Static;
+using Mafi.Core.Entities.Static.Layout;
+using Mafi.Core.Factory.Machines;
+using Mafi.Core.Factory.Recipes;
+using Mafi.Core.Factory.Transports;
+using Mafi.Core.Population;
+using Mafi.Core.Ports.Io;
+using Mafi.Core.Products;
+using Mafi.Core.Prototypes;
+using Mafi.Core.SaveGame;
+using Mafi.Core.Terrain;
+using Mafi.Core.Vehicles.Excavators;
+using Mafi.Core.World.Entities;
+
+namespace CykaOfIndustry {
+ [HarmonyPatch]
+ public class Patches {
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(ExcavatorProtoBuilder.ExcavatorProtoBuilderState), "SetCapacity")]
+ static void excavatorCapacityMultiplier(ref int quantity) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old excavator capacity {0}", quantity);
+ quantity *= Main.excavatorCapacityMultiplier.Value;
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New excavator capacity {0}", quantity);
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(ExcavatorProtoBuilder.ExcavatorProtoBuilderState), "SetMinedThicknessByDistanceMeters")]
+ static void excavatorMiningAreaMultiplier(ref float[] thicknessMeters) {
+ for (int i = 0; i < thicknessMeters.Length; i++) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old mining area {0}", thicknessMeters[i]);
+ thicknessMeters[i] *= Main.excavatorMiningCapacityMultiplier.Value;
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New mining area {0}", thicknessMeters[i]);
+ }
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(ExcavatorProtoBuilder.ExcavatorProtoBuilderState), "SetMaxMiningDistance")]
+ static void excavatorReachMultiplier(ref RelTile1i minMiningDistance, ref RelTile1i maxMiningDistance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old min mining distance {0}, max mining distance {1}",
+ minMiningDistance, maxMiningDistance);
+ minMiningDistance = new RelTile1i((int)(minMiningDistance.Value * Main.excavatorMinReachMultiplier.Value));
+ maxMiningDistance = new RelTile1i((int)(maxMiningDistance.Value * Main.excavatorMaxReachMultiplier.Value));
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New min mining distance {0}, max mining distance {1}",
+ minMiningDistance, maxMiningDistance);
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(TruckProtoBuilder.TruckProtoBuilderState), "SetCapacity")]
+ static void truckCapacityMultiplier(ref int quantity) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old truck capacity {0}", quantity);
+ quantity *= Main.truckCapacityMultiplier.Value;
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New truck capacity {0}", quantity);
+ }
+
+ // [HarmonyPrefix]
+ // [HarmonyPatch(typeof(StorageProtoBuilder.State), "SetCapacity")]
+ // static void storageCapacityMultiplier(ref int capacity) {
+// // Console.WriteLine("IndustrialCyka: Old storage capacity: {0}", capacity);
+ // capacity = (int)(capacity * Main.storageCapacityMultiplier.Value);
+// // Console.WriteLine("IndustrialCyka: New storage capacity: {0}", capacity);
+ // }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CargoShipModuleProto), MethodType.Constructor,
+ new[] {
+ typeof(Proto.ID), typeof(Proto.Str), typeof(ProductType), typeof(Quantity),
+ typeof(CargoShipModuleProto.Gfx)
+ })]
+ static void cargoShipCapacityMultiplier(CargoShipModuleProto __instance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old ship capacity {0}", __instance.Capacity);
+ __instance.Capacity = new Quantity(__instance.Capacity.Value * Main.cargoShipCapacityMultiplier.Value);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New ship capacity {0}", __instance.Capacity);
+ }
+
+ // No workey... idk how it's supposed to work, speed is always 1 or 100%
+ // [HarmonyPrefix]
+ // [HarmonyPatch(typeof(DrivingEntity), "SetSpeedFactor")]
+ // static void vehicleSpeedMultiplier(ref Percent speedFactor) {
+// // Console.WriteLine("IndustrialCyka: Old speed: {0}", speedFactor.ToString());
+ // // typeof(Percent)
+ // // .GetField("RawValue",BindingFlags.Instance|BindingFlags.NonPublic)
+ // // .SetValue(speedFactor,speedFactor.ToFloat() / Main.vehicleSpeedMultiplier.Value);
+ // Percent newSpeedFactor = Percent.FromFloat(speedFactor.ToFloat() / Main.vehicleSpeedMultiplier.Value);
+ // speedFactor = newSpeedFactor;
+// // Console.WriteLine("IndustrialCyka: New speed: {1}", newSpeedFactor.RawValue.ToString());
+ // }
+
+// [HarmonyPostfix]
+// [HarmonyPatch(typeof(SmoothDriver), "SetSpeedFactor")]
+// static void vehicleSpeedMultiplier(SmoothDriver __instance) {
+// Fix32 speedMulti = Fix32.FromFloat(Main.vehicleSpeedMultiplier.Value);
+//
+// Traverse traverse = Traverse.Create(__instance);
+// Traverse maxForwardsSpeedField = traverse.Field("m_maxForwardsSpeed");
+// Traverse maxBackwardsSpeedField = traverse.Field("m_maxBackwardsSpeed");
+// Traverse maxAccelerationField = traverse.Field("m_maxAcceleration");
+//
+// // Console.WriteLine("IndustrialCyka: Old speeds: (F) {0}, (B) {1}, (A) {2}", maxForwardsSpeedField.GetValue(),
+// // maxBackwardsSpeedField.GetValue(), maxAccelerationField.GetValue());
+//
+// maxForwardsSpeedField.SetValue((Fix32)maxForwardsSpeedField.GetValue() * speedMulti);
+// maxBackwardsSpeedField.SetValue((Fix32)maxBackwardsSpeedField.GetValue() * speedMulti);
+// maxAccelerationField.SetValue((Fix32)maxAccelerationField.GetValue() * speedMulti);
+//
+// // Console.WriteLine("IndustrialCyka: New speeds: (F) {0}, (B) {1}, (A) {2}", maxForwardsSpeedField.GetValue(),
+// // maxBackwardsSpeedField.GetValue(), maxAccelerationField.GetValue());
+// }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(StorageBaseProto), MethodType.Constructor,
+ new[] {
+ typeof(StaticEntityProto.ID),
+ typeof(Proto.Str),
+ typeof(EntityLayout),
+ typeof(Quantity),
+ typeof(EntityCosts),
+ typeof(LayoutEntityProto.Gfx),
+ typeof(Quantity),
+ typeof(Duration),
+ typeof(IEnumerable)
+ })]
+ static void storageCapacityMultiplier(StorageProto __instance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old storage capacity {0}", __instance.Capacity);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old storage transfer limit {0}", __instance.TransferLimit);
+ Traverse traverse = Traverse.Create(__instance);
+
+ traverse.Field("Capacity")
+ .SetValue(new Quantity((int)(__instance.Capacity.Value * Main.storageCapacityMultiplier.Value)));
+ traverse.Field("TransferLimit").SetValue(new Quantity(10000));
+ traverse.Field("TransferLimitDuration").SetValue(Duration.FromTicks(1));
+
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New storage capacity {0}", __instance.Capacity);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New storage transfer limit {0}", __instance.TransferLimit);
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(UpointsManager), "GenerateUnity")]
+ static void unityGenerationMultiplier(Proto.ID categoryId, ref Upoints generated) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old generated {0} unity", generated.Value);
+ Fix32 multi = Fix32.FromFloat(Main.unityGenerationMultiplier.Value);
+ generated = new Upoints(generated.Value * multi);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New generated {0} unity", generated.Value);
+ }
+
+ [HarmonyTranspiler]
+ [HarmonyPatch(typeof(Machine), "updateWorkOnRecipes")]
+ static IEnumerable unityBooster(IEnumerable instructions) {
+ Dictionary matchTable = new Dictionary();
+ matchTable[0] = OpCodes.Ldsfld;
+ matchTable[1] = OpCodes.Br;
+ matchTable[2] = OpCodes.Ldc_I4_2;
+ int matches = 0;
+ int totalMatch = matchTable.Count;
+
+ var codes = new List(instructions);
+ for (int i = 0; i < codes.Count; i++) {
+ if (matches >= totalMatch) {
+ break;
+ }
+
+ if (codes[i].opcode.Equals(matchTable[matches])) {
+ if (matches == totalMatch - 1) {
+ codes[i].opcode = OpCodes.Ldc_I4_6;
+ }
+
+ matches++;
+ }
+ }
+
+ // for (int i = 0; i < codes.Count; i++) {
+ // Console.WriteLine(codes[i].ToString());
+ // }
+
+ return codes.AsEnumerable();
+ }
+
+ // Could not make this work either... idk why... Doesn't make sense...
+ // [HarmonyPostfix]
+ // [HarmonyPatch(typeof(SimpleVirtualResource), "MineResourceAt")]
+ // static void infiniteGroundResources(SimpleVirtualResource __instance) {
+// // Console.WriteLine("IndustrialCyka: Patching ground resources (Capacity)");
+ // Traverse traverse = Traverse.Create(__instance);
+ // Traverse capacityField = traverse.Field("Capacity");
+ // capacityField.SetValue(1000000000);
+ // Traverse quantityField = traverse.Field("Quantity");
+ // quantityField.SetValue(1000000000);
+ // }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(ProductBuffer), "ForceNewCapacityTo")]
+ static void bufferCapacityMultiplier(ref Quantity newCapacity) {
+ if (newCapacity.Value <= 0) {
+ return;
+ }
+
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old buffer capacity {0}", newCapacity);
+ Quantity newNewCapacity = new Quantity((int)(newCapacity.Value * Main.bufferCapacityMultiplier.Value));
+ newCapacity = newNewCapacity;
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New buffer capacity {0}", newCapacity);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(CargoDepotModuleProto), MethodType.Constructor,
+ new[] {
+ typeof(CargoDepotModuleProto.ID),
+ typeof(Proto.Str),
+ typeof(EntityLayout),
+ typeof(ProductType),
+ typeof(Option),
+ typeof(Quantity),
+ typeof(Quantity),
+ typeof(Duration),
+ typeof(Electricity),
+ typeof(bool),
+ typeof(Percent),
+ typeof(EntityCosts),
+ typeof(CargoDepotModuleProto.Gfx),
+ typeof(IEnumerable),
+ })]
+ static void depotTransferSpeedMultiplier(CargoDepotModuleProto __instance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old depot transfer speed {0}", __instance.QuantityPerExchange);
+ Traverse traverse = Traverse.Create(__instance);
+
+ traverse.Field("QuantityPerExchange")
+ .SetValue(new Quantity((int)(__instance.QuantityPerExchange.Value *
+ Main.depotTransferSpeedMultiplier.Value)));
+
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New depot transfer speed {0}", __instance.QuantityPerExchange);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
+ new[] {
+ typeof(EntityProto.ID),
+ typeof(Proto.Str),
+ typeof(ProductQuantity),
+ typeof(Duration),
+ typeof(Upoints),
+ typeof(UpointsCategoryProto),
+ typeof(EntityCosts),
+ typeof(Func),
+ typeof(int),
+ typeof(Quantity),
+ typeof(WorldMapEntityProto.Gfx),
+ typeof(int),
+ typeof(int),
+ typeof(IEnumerable),
+ })]
+ static void worldMineSpeedMultiplier(WorldMapMineProto __instance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old world mine speed {0}",
+ __instance.ProducedProductPerStep.Quantity);
+ ProductQuantity newProductQuantity = new ProductQuantity(__instance.ProducedProductPerStep.Product,
+ new Quantity((int)(__instance.ProducedProductPerStep.Quantity.Value *
+ Main.worldMineSpeedMultiplier.Value)));
+
+ Traverse.Create(__instance)
+ .Field("ProducedProductPerStep")
+ .SetValue(newProductQuantity);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New world mine speed {0}",
+ __instance.ProducedProductPerStep.Quantity);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
+ new[] {
+ typeof(EntityProto.ID),
+ typeof(Proto.Str),
+ typeof(ProductQuantity),
+ typeof(Duration),
+ typeof(Upoints),
+ typeof(UpointsCategoryProto),
+ typeof(EntityCosts),
+ typeof(Func),
+ typeof(int),
+ typeof(Quantity),
+ typeof(WorldMapEntityProto.Gfx),
+ typeof(int),
+ typeof(int),
+ typeof(IEnumerable),
+ })]
+ static void worldMineLevelIncrementMultiplier(WorldMapMineProto __instance) {
+ Traverse traverse = Traverse.Create(__instance);
+
+ // int level = traverse.Field("Level").GetValue();
+ int maxLevel = traverse.Field("MaxLevel").GetValue();
+ // int levelsPerUpgrade = traverse.Field("LevelsPerUpgrade").GetValue();
+
+ int newLevelsPerUpgrade = 10;
+ int newMaxLevel = (int)Math.Ceiling((double)maxLevel / newLevelsPerUpgrade) * newLevelsPerUpgrade;
+
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old max level {0}, new max level {1}", maxLevel, newMaxLevel);
+ traverse.Field("MaxLevel").SetValue(newMaxLevel);
+ traverse.Field("LevelsPerUpgrade").SetValue(newLevelsPerUpgrade);
+ }
+
+ [HarmonyTranspiler]
+ [HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
+ new[] {
+ typeof(EntityProto.ID),
+ typeof(Proto.Str),
+ typeof(ProductQuantity),
+ typeof(Duration),
+ typeof(Upoints),
+ typeof(UpointsCategoryProto),
+ typeof(EntityCosts),
+ typeof(Func),
+ typeof(int),
+ typeof(Quantity),
+ typeof(WorldMapEntityProto.Gfx),
+ typeof(int),
+ typeof(int),
+ typeof(IEnumerable),
+ })]
+ static IEnumerable cookWorldMineLevelIncrementMultiplier(
+ IEnumerable instructions) {
+ Dictionary matchTable = new Dictionary();
+ matchTable[0] = OpCodes.Rem;
+ matchTable[1] = OpCodes.Ldfld;
+ matchTable[2] = OpCodes.Ldarg_0;
+ matchTable[3] = OpCodes.Ldfld;
+ matchTable[4] = OpCodes.Ldarg_0;
+ int matches = 0;
+ int totalMatch = matchTable.Count;
+
+ var codes = new List(instructions);
+ for (int i = codes.Count - 1; i >= 0; i--) {
+ if (matches >= totalMatch) {
+ break;
+ }
+
+ if (codes[i].opcode.Equals(matchTable[matches])) {
+ if (matches == totalMatch - 1) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Patching world mine level increment");
+ codes[i + 4].opcode = OpCodes.Add;
+ codes[i + 5].opcode = OpCodes.Brtrue_S;
+ break;
+ }
+
+ matches++;
+ }
+ else {
+ matches = 0;
+ }
+ }
+
+ return codes.AsEnumerable();
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(SettlementHousingModuleProto), MethodType.Constructor, new[] {
+ typeof(StaticEntityProto.ID),
+ typeof(Proto.Str),
+ typeof(EntityLayout),
+ typeof(EntityCosts),
+ typeof(int),
+ typeof(Upoints),
+ typeof(ImmutableArray, Percent>>),
+ typeof(IReadOnlyDictionary),
+ typeof(Option),
+ typeof(SettlementHousingModuleProto.Gfx),
+ })]
+ static void housingCapacityMultiplier(SettlementHousingModuleProto __instance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old housing capacity {0}", __instance.Capacity);
+ Traverse.Create(__instance).Field("Capacity").Value =
+ (int)(__instance.Capacity * Main.housingCapacityMultiplier.Value);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New housing capacity {0}", __instance.Capacity);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(StackerProto), MethodType.Constructor, new[] {
+ typeof(StaticEntityProto.ID),
+ typeof(Proto.Str),
+ typeof(EntityLayout),
+ typeof(EntityCosts),
+ typeof(Electricity),
+ typeof(ThicknessTilesI),
+ typeof(RelTile3i),
+ typeof(Duration),
+ typeof(Duration),
+ typeof(StackerProto.Gfx),
+ typeof(ThicknessTilesI),
+ typeof(IEnumerable),
+ })]
+ static void dumpDelayMultiplier(StackerProto __instance) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old dumpDelay {0}", __instance.DumpDelay);
+ Duration newDelay =
+ new Duration(Math.Max((int)(__instance.DumpDelay.Ticks * Main.dumpDelayMultiplier.Value), 1));
+ Traverse.Create(__instance).Field("DumpDelay").SetValue(newDelay);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New dumpDelay {0}", __instance.DumpDelay);
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(TransportProto), MethodType.Constructor, new[] {
+ typeof(StaticEntityProto.ID),
+ typeof(Proto.Str),
+ typeof(ThicknessTilesF),
+ typeof(Quantity),
+ typeof(RelTile1f),
+ typeof(RelTile1f),
+ typeof(RelTile1i),
+ typeof(bool),
+ typeof(bool),
+ typeof(Option),
+ typeof(RelTile1i),
+ typeof(IoPortShapeProto),
+ typeof(Electricity),
+ typeof(Percent),
+ typeof(bool),
+ typeof(bool),
+ typeof(EntityCosts),
+ typeof(RelTile1i),
+ typeof(Duration),
+ typeof(Option),
+ typeof(VirtualProductProto),
+ typeof(Quantity),
+ typeof(TransportProto.Gfx),
+ })]
+ static void transportSpeedMultiplier(ref StaticEntityProto.ID id, ref Proto.Str strings,
+ ref ThicknessTilesF surfaceRelativeHeight, ref Quantity maxQuantityPerTransportedProduct,
+ ref RelTile1f transportedProductsSpacing, ref RelTile1f speedPerTick, ref RelTile1i zStepLength,
+ ref bool needsPillarsAtGround, ref bool canBeBuried,
+ ref Option tileSurfaceWhenOnGround, ref RelTile1i maxPillarSupportRadius,
+ ref IoPortShapeProto portsShape, ref Electricity baseElectricityCost, ref Percent cornersSharpnessPercent,
+ ref bool allowMixedProducts, ref bool isBuildable, ref EntityCosts costs, ref RelTile1i lengthPerCost,
+ ref Duration constructionDurationPerProduct, ref Option nextTier,
+ ref VirtualProductProto maintenanceProduct, Quantity maintenancePerTile, ref TransportProto.Gfx graphics) {
+ if (TransportPillarProto.MAX_PILLAR_HEIGHT.Value < 25)
+ typeof(TransportPillarProto).GetField("MAX_PILLAR_HEIGHT").SetValue(null, new ThicknessTilesI(25));
+ if (IoPort.MAX_TRANSFER_PER_TICK.Value < 10000)
+ typeof(IoPort).GetField("MAX_TRANSFER_PER_TICK").SetValue(null, new Quantity(10000));
+
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Old maxQuantityPerTransportedProduct {0}",
+ maxQuantityPerTransportedProduct);
+ maxQuantityPerTransportedProduct *= 1000;
+ maxQuantityPerTransportedProduct = maxQuantityPerTransportedProduct.Min(new Quantity(10000));
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: New maxQuantityPerTransportedProduct {0}",
+ maxQuantityPerTransportedProduct);
+
+ speedPerTick *= 10;
+ transportedProductsSpacing = speedPerTick;
+ zStepLength = RelTile1i.One;
+ canBeBuried = true;
+ maxPillarSupportRadius = new RelTile1i(8);
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(ShipyardProto), MethodType.Constructor, new[] {
+ typeof(StaticEntityProto.ID),
+ typeof(Proto.Str),
+ typeof(EntityLayout),
+ typeof(EntityCosts),
+ typeof(bool),
+ typeof(Quantity),
+ typeof(Option),
+ typeof(ImmutableArray>),
+ typeof(StackerProto.Gfx),
+ typeof(ImmutableArray),
+ typeof(bool),
+ })]
+ static void shipyardCargoMultiplier(ShipyardProto __instance) {
+ Traverse.Create(__instance).Field("CargoCapacity").SetValue(new Quantity(
+ (int)(__instance.CargoCapacity.Value * Main.shipyardCargoMultiplier.Value)));
+ }
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(SaveManager), "isTimeForAutoSave")]
+ static void autosaveInterval(ref bool __result, SaveManager __instance) {
+ if (Main.autosaveInterval.Value <= 0) {
+ __result = false;
+ return;
+ }
+
+ var trav = Traverse.Create(__instance);
+ var lastSaveTime = trav.Field("m_lastSaveTime").GetValue();
+ var num = (Environment.TickCount - lastSaveTime).Abs() / 1000L;
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Autosave interval: {0}", num);
+ __result = num > Main.autosaveInterval.Value;
+ }
+
+ [HarmonyPrefix]
+ [HarmonyPatch(typeof(MachineProto), nameof(MachineProto.AddRecipe))]
+ static void machineProtoAddRecipe(MachineProto __instance, ref RecipeProto recipe) {
+ Console.WriteLine("Recipe outputs for {0}:", __instance.Id);
+ recipe.AllOutputs.ForEach(o => {
+ var id = o.Product.Id.ToString();
+ Console.WriteLine("\tIndustrialCyka: Recipe output {0} x {1}", id, o.Quantity);
+ if (!Main.recipeMultipliersDict.ContainsKey(id)) {
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Recipe output {0} not found in multipliers, nothing to do", id);
+ return;
+ }
+ var multiplier = Main.recipeMultipliersDict[id];
+ var trav = Traverse.Create(o);
+ trav.Field("Quantity").SetValue(new Quantity(trav.Field("Quantity").GetValue().Value * multiplier));
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Recipe output {0} changed to {1}", id, trav.Field("Quantity").GetValue());
+ });
+ }
+ }
+
+ [HarmonyPatch(typeof(Excavator), "MineMixedAt")]
+ public class MineMixedAtPatch {
+ public static Dictionary
+ originalCapacity = new Dictionary();
+
+ public static Dictionary> originalMinedThicknessByDistance =
+ new Dictionary>();
+
+ public static Dictionary originalMineTileIterations =
+ new Dictionary();
+
+ public static Dictionary originalMaxMiningDistance =
+ new Dictionary();
+
+ static void Prefix(ref Excavator __instance) {
+ if (!originalCapacity.ContainsKey(__instance.Prototype)) {
+ originalCapacity.Add(__instance.Prototype, __instance.Prototype.Capacity);
+ }
+
+ var trav = Traverse.Create(__instance.Prototype);
+ trav.Field("Capacity")
+ .SetValue(new Quantity(originalCapacity[__instance.Prototype].Value *
+ Main.excavatorCapacityMultiplier.Value));
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Excavator capacity: {0}", __instance.Prototype.Capacity.Value);
+
+ if (!originalMinedThicknessByDistance.ContainsKey(__instance.Prototype)) {
+ originalMinedThicknessByDistance.Add(__instance.Prototype,
+ trav.Field("MinedThicknessByDistance").GetValue>());
+ }
+
+ trav.Field("MinedThicknessByDistance")
+ .SetValue(originalMinedThicknessByDistance[__instance.Prototype]
+ .SelectMany(t => Enumerable.Repeat(t, Main.excavatorMiningAreaMultiplier.Value))
+ .Select(t =>
+ new ThicknessTilesF((int)(t.Value.ToFloat() * Main.excavatorMiningCapacityMultiplier.Value)))
+ .ToImmutableArray());
+ if (Main.debugMode.Value)
+ originalMinedThicknessByDistance[__instance.Prototype].ForEach(t => Console.WriteLine(t.Value));
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Excavator mined thickness: {0}",
+ __instance.Prototype.MinedThicknessByDistance);
+
+ if (!originalMaxMiningDistance.ContainsKey(__instance.Prototype)) {
+ originalMaxMiningDistance.Add(__instance.Prototype,
+ trav.Field("MaxMiningDistance").GetValue());
+ }
+
+ var value = originalMaxMiningDistance[__instance.Prototype];
+ var newValueMiningDistance = new RelTile1i((int)(value.Value * Main.excavatorMaxReachMultiplier.Value));
+ trav.Field("MaxMiningDistance")
+ .SetValue(newValueMiningDistance);
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Excavator max mining distance: {0}",
+ __instance.Prototype.MaxMiningDistance);
+
+ var trav2 = Traverse.Create(__instance.Prototype.MineTimings);
+ if (!originalMineTileIterations.ContainsKey(__instance.Prototype.MineTimings)) {
+ originalMineTileIterations.Add(__instance.Prototype.MineTimings,
+ trav2.Field("MineTileIterations").GetValue());
+ }
+
+ var newValue = (int)(originalMineTileIterations[__instance.Prototype.MineTimings] *
+ Main.excavatorMineTileIterationsMultiplier.Value);
+ trav2.Field("MineTileIterations").SetValue(newValue);
+ trav2.Field("PrepareToMineDuration").SetValue(new Duration(1));
+ trav2.Field("MineDuration").SetValue(new Duration(1));
+ trav2.Field("PrepareToDumpDuration").SetValue(new Duration(1));
+ trav2.Field("DumpDuration").SetValue(new Duration(1));
+ if (Main.debugMode.Value)
+ Console.WriteLine("IndustrialCyka: Excavator mine tile iterations 2: {0}",
+ trav2.Field("MineTileIterations").GetValue());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Projects/CykaOfQud/Properties/AssemblyInfo.cs b/Projects/CykaOfQud/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6cff8c4
--- /dev/null
+++ b/Projects/CykaOfQud/Properties/AssemblyInfo.cs
@@ -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("CykaOfQud")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CykaOfQud")]
+[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")]
diff --git a/Projects/CykaOfQud/sync b/Projects/CykaOfQud/sync
new file mode 100644
index 0000000..55d037e
--- /dev/null
+++ b/Projects/CykaOfQud/sync
@@ -0,0 +1 @@
+bin/Release/CykaOfQud.dll,"C:/Games/Caves.of.Qud.Build.16668101/BepInEx/plugins/CykaOfQud.dll"
\ No newline at end of file