Add cykaOfqud

This commit is contained in:
2024-12-08 23:22:46 +01:00
parent 059c8a53a4
commit a40cb99745
6 changed files with 851 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<GAME_DIR>C:/Games/Caves.of.Qud.Build.16668101</GAME_DIR>
<GAME_MANAGED>$(GAME_DIR)/CoQ_Data/Managed</GAME_MANAGED>
<GAME_BEPINEX>$(GAME_DIR)/BepInEx</GAME_BEPINEX>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EE5EFB7F-A4DC-44F0-967B-F71ECA2D46AE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CykaOfQud</RootNamespace>
<AssemblyName>CykaOfQud</AssemblyName>
<TargetFrameworkVersion>v4.8.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Patches.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>$(GAME_BEPINEX)/core/0Harmony.dll</HintPath>
</Reference>
<Reference Include="BepInEx">
<HintPath>$(GAME_BEPINEX)/core/BepInEx.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>$(GAME_MANAGED)/UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>$(GAME_MANAGED)/UnityEngine.CoreModule.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>
</Project>

View File

@@ -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<int> excavatorCapacityMultiplier;
public static ConfigEntry<float> excavatorMineTileIterationsMultiplier;
public static ConfigEntry<int> truckCapacityMultiplier;
public static ConfigEntry<int> cargoShipCapacityMultiplier;
public static ConfigEntry<float> excavatorMiningCapacityMultiplier;
public static ConfigEntry<int> excavatorMiningAreaMultiplier;
public static ConfigEntry<float> excavatorMinReachMultiplier;
public static ConfigEntry<float> excavatorMaxReachMultiplier;
public static ConfigEntry<float> bufferCapacityMultiplier;
public static ConfigEntry<float> unityGenerationMultiplier;
public static ConfigEntry<float> depotTransferSpeedMultiplier;
public static ConfigEntry<float> worldMineSpeedMultiplier;
public static ConfigEntry<float> housingCapacityMultiplier;
public static ConfigEntry<float> dumpDelayMultiplier;
public static ConfigEntry<float> transportSpeedMultiplier;
public static ConfigEntry<float> shipyardCargoMultiplier;
public static ConfigEntry<int> autosaveInterval;
public static ConfigEntry<string> recipeMultipliers;
public static Dictionary<string, int> recipeMultipliersDict;
public static ConfigEntry<bool> 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<float> storageCapacityMultiplier;
}
}

View File

@@ -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

View File

@@ -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<Tag>)
})]
static void storageCapacityMultiplier(StorageProto __instance) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old storage capacity {0}", __instance.Capacity);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old storage transfer limit {0}", __instance.TransferLimit);
Traverse traverse = Traverse.Create(__instance);
traverse.Field("Capacity")
.SetValue(new Quantity((int)(__instance.Capacity.Value * Main.storageCapacityMultiplier.Value)));
traverse.Field("TransferLimit").SetValue(new Quantity(10000));
traverse.Field("TransferLimitDuration").SetValue(Duration.FromTicks(1));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New storage capacity {0}", __instance.Capacity);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New storage transfer limit {0}", __instance.TransferLimit);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(UpointsManager), "GenerateUnity")]
static void unityGenerationMultiplier(Proto.ID categoryId, ref Upoints generated) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old generated {0} unity", generated.Value);
Fix32 multi = Fix32.FromFloat(Main.unityGenerationMultiplier.Value);
generated = new Upoints(generated.Value * multi);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New generated {0} unity", generated.Value);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(Machine), "updateWorkOnRecipes")]
static IEnumerable<CodeInstruction> unityBooster(IEnumerable<CodeInstruction> instructions) {
Dictionary<int, OpCode> matchTable = new Dictionary<int, OpCode>();
matchTable[0] = OpCodes.Ldsfld;
matchTable[1] = OpCodes.Br;
matchTable[2] = OpCodes.Ldc_I4_2;
int matches = 0;
int totalMatch = matchTable.Count;
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++) {
if (matches >= totalMatch) {
break;
}
if (codes[i].opcode.Equals(matchTable[matches])) {
if (matches == totalMatch - 1) {
codes[i].opcode = OpCodes.Ldc_I4_6;
}
matches++;
}
}
// for (int i = 0; i < codes.Count; i++) {
// Console.WriteLine(codes[i].ToString());
// }
return codes.AsEnumerable();
}
// Could not make this work either... idk why... Doesn't make sense...
// [HarmonyPostfix]
// [HarmonyPatch(typeof(SimpleVirtualResource), "MineResourceAt")]
// static void infiniteGroundResources(SimpleVirtualResource __instance) {
// // Console.WriteLine("IndustrialCyka: Patching ground resources (Capacity)");
// Traverse traverse = Traverse.Create(__instance);
// Traverse capacityField = traverse.Field("Capacity");
// capacityField.SetValue(1000000000);
// Traverse quantityField = traverse.Field("Quantity");
// quantityField.SetValue(1000000000);
// }
[HarmonyPrefix]
[HarmonyPatch(typeof(ProductBuffer), "ForceNewCapacityTo")]
static void bufferCapacityMultiplier(ref Quantity newCapacity) {
if (newCapacity.Value <= 0) {
return;
}
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old buffer capacity {0}", newCapacity);
Quantity newNewCapacity = new Quantity((int)(newCapacity.Value * Main.bufferCapacityMultiplier.Value));
newCapacity = newNewCapacity;
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New buffer capacity {0}", newCapacity);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CargoDepotModuleProto), MethodType.Constructor,
new[] {
typeof(CargoDepotModuleProto.ID),
typeof(Proto.Str),
typeof(EntityLayout),
typeof(ProductType),
typeof(Option<CargoDepotModuleProto>),
typeof(Quantity),
typeof(Quantity),
typeof(Duration),
typeof(Electricity),
typeof(bool),
typeof(Percent),
typeof(EntityCosts),
typeof(CargoDepotModuleProto.Gfx),
typeof(IEnumerable<Tag>),
})]
static void depotTransferSpeedMultiplier(CargoDepotModuleProto __instance) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old depot transfer speed {0}", __instance.QuantityPerExchange);
Traverse traverse = Traverse.Create(__instance);
traverse.Field("QuantityPerExchange")
.SetValue(new Quantity((int)(__instance.QuantityPerExchange.Value *
Main.depotTransferSpeedMultiplier.Value)));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New depot transfer speed {0}", __instance.QuantityPerExchange);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
new[] {
typeof(EntityProto.ID),
typeof(Proto.Str),
typeof(ProductQuantity),
typeof(Duration),
typeof(Upoints),
typeof(UpointsCategoryProto),
typeof(EntityCosts),
typeof(Func<int, EntityCosts>),
typeof(int),
typeof(Quantity),
typeof(WorldMapEntityProto.Gfx),
typeof(int),
typeof(int),
typeof(IEnumerable<Tag>),
})]
static void worldMineSpeedMultiplier(WorldMapMineProto __instance) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old world mine speed {0}",
__instance.ProducedProductPerStep.Quantity);
ProductQuantity newProductQuantity = new ProductQuantity(__instance.ProducedProductPerStep.Product,
new Quantity((int)(__instance.ProducedProductPerStep.Quantity.Value *
Main.worldMineSpeedMultiplier.Value)));
Traverse.Create(__instance)
.Field("ProducedProductPerStep")
.SetValue(newProductQuantity);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New world mine speed {0}",
__instance.ProducedProductPerStep.Quantity);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
new[] {
typeof(EntityProto.ID),
typeof(Proto.Str),
typeof(ProductQuantity),
typeof(Duration),
typeof(Upoints),
typeof(UpointsCategoryProto),
typeof(EntityCosts),
typeof(Func<int, EntityCosts>),
typeof(int),
typeof(Quantity),
typeof(WorldMapEntityProto.Gfx),
typeof(int),
typeof(int),
typeof(IEnumerable<Tag>),
})]
static void worldMineLevelIncrementMultiplier(WorldMapMineProto __instance) {
Traverse traverse = Traverse.Create(__instance);
// int level = traverse.Field("Level").GetValue<int>();
int maxLevel = traverse.Field("MaxLevel").GetValue<int>();
// int levelsPerUpgrade = traverse.Field("LevelsPerUpgrade").GetValue<int>();
int newLevelsPerUpgrade = 10;
int newMaxLevel = (int)Math.Ceiling((double)maxLevel / newLevelsPerUpgrade) * newLevelsPerUpgrade;
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old max level {0}, new max level {1}", maxLevel, newMaxLevel);
traverse.Field("MaxLevel").SetValue(newMaxLevel);
traverse.Field("LevelsPerUpgrade").SetValue(newLevelsPerUpgrade);
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(WorldMapMineProto), MethodType.Constructor,
new[] {
typeof(EntityProto.ID),
typeof(Proto.Str),
typeof(ProductQuantity),
typeof(Duration),
typeof(Upoints),
typeof(UpointsCategoryProto),
typeof(EntityCosts),
typeof(Func<int, EntityCosts>),
typeof(int),
typeof(Quantity),
typeof(WorldMapEntityProto.Gfx),
typeof(int),
typeof(int),
typeof(IEnumerable<Tag>),
})]
static IEnumerable<CodeInstruction> cookWorldMineLevelIncrementMultiplier(
IEnumerable<CodeInstruction> instructions) {
Dictionary<int, OpCode> matchTable = new Dictionary<int, OpCode>();
matchTable[0] = OpCodes.Rem;
matchTable[1] = OpCodes.Ldfld;
matchTable[2] = OpCodes.Ldarg_0;
matchTable[3] = OpCodes.Ldfld;
matchTable[4] = OpCodes.Ldarg_0;
int matches = 0;
int totalMatch = matchTable.Count;
var codes = new List<CodeInstruction>(instructions);
for (int i = codes.Count - 1; i >= 0; i--) {
if (matches >= totalMatch) {
break;
}
if (codes[i].opcode.Equals(matchTable[matches])) {
if (matches == totalMatch - 1) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Patching world mine level increment");
codes[i + 4].opcode = OpCodes.Add;
codes[i + 5].opcode = OpCodes.Brtrue_S;
break;
}
matches++;
}
else {
matches = 0;
}
}
return codes.AsEnumerable();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SettlementHousingModuleProto), MethodType.Constructor, new[] {
typeof(StaticEntityProto.ID),
typeof(Proto.Str),
typeof(EntityLayout),
typeof(EntityCosts),
typeof(int),
typeof(Upoints),
typeof(ImmutableArray<KeyValuePair<ImmutableArray<PopNeedProto>, Percent>>),
typeof(IReadOnlyDictionary<PopNeedProto, Percent>),
typeof(Option<SettlementHousingModuleProto>),
typeof(SettlementHousingModuleProto.Gfx),
})]
static void housingCapacityMultiplier(SettlementHousingModuleProto __instance) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old housing capacity {0}", __instance.Capacity);
Traverse.Create(__instance).Field<int>("Capacity").Value =
(int)(__instance.Capacity * Main.housingCapacityMultiplier.Value);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New housing capacity {0}", __instance.Capacity);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(StackerProto), MethodType.Constructor, new[] {
typeof(StaticEntityProto.ID),
typeof(Proto.Str),
typeof(EntityLayout),
typeof(EntityCosts),
typeof(Electricity),
typeof(ThicknessTilesI),
typeof(RelTile3i),
typeof(Duration),
typeof(Duration),
typeof(StackerProto.Gfx),
typeof(ThicknessTilesI),
typeof(IEnumerable<Tag>),
})]
static void dumpDelayMultiplier(StackerProto __instance) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old dumpDelay {0}", __instance.DumpDelay);
Duration newDelay =
new Duration(Math.Max((int)(__instance.DumpDelay.Ticks * Main.dumpDelayMultiplier.Value), 1));
Traverse.Create(__instance).Field("DumpDelay").SetValue(newDelay);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New dumpDelay {0}", __instance.DumpDelay);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(TransportProto), MethodType.Constructor, new[] {
typeof(StaticEntityProto.ID),
typeof(Proto.Str),
typeof(ThicknessTilesF),
typeof(Quantity),
typeof(RelTile1f),
typeof(RelTile1f),
typeof(RelTile1i),
typeof(bool),
typeof(bool),
typeof(Option<TerrainTileSurfaceProto>),
typeof(RelTile1i),
typeof(IoPortShapeProto),
typeof(Electricity),
typeof(Percent),
typeof(bool),
typeof(bool),
typeof(EntityCosts),
typeof(RelTile1i),
typeof(Duration),
typeof(Option<TransportProto>),
typeof(VirtualProductProto),
typeof(Quantity),
typeof(TransportProto.Gfx),
})]
static void transportSpeedMultiplier(ref StaticEntityProto.ID id, ref Proto.Str strings,
ref ThicknessTilesF surfaceRelativeHeight, ref Quantity maxQuantityPerTransportedProduct,
ref RelTile1f transportedProductsSpacing, ref RelTile1f speedPerTick, ref RelTile1i zStepLength,
ref bool needsPillarsAtGround, ref bool canBeBuried,
ref Option<TerrainTileSurfaceProto> tileSurfaceWhenOnGround, ref RelTile1i maxPillarSupportRadius,
ref IoPortShapeProto portsShape, ref Electricity baseElectricityCost, ref Percent cornersSharpnessPercent,
ref bool allowMixedProducts, ref bool isBuildable, ref EntityCosts costs, ref RelTile1i lengthPerCost,
ref Duration constructionDurationPerProduct, ref Option<TransportProto> nextTier,
ref VirtualProductProto maintenanceProduct, Quantity maintenancePerTile, ref TransportProto.Gfx graphics) {
if (TransportPillarProto.MAX_PILLAR_HEIGHT.Value < 25)
typeof(TransportPillarProto).GetField("MAX_PILLAR_HEIGHT").SetValue(null, new ThicknessTilesI(25));
if (IoPort.MAX_TRANSFER_PER_TICK.Value < 10000)
typeof(IoPort).GetField("MAX_TRANSFER_PER_TICK").SetValue(null, new Quantity(10000));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Old maxQuantityPerTransportedProduct {0}",
maxQuantityPerTransportedProduct);
maxQuantityPerTransportedProduct *= 1000;
maxQuantityPerTransportedProduct = maxQuantityPerTransportedProduct.Min(new Quantity(10000));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: New maxQuantityPerTransportedProduct {0}",
maxQuantityPerTransportedProduct);
speedPerTick *= 10;
transportedProductsSpacing = speedPerTick;
zStepLength = RelTile1i.One;
canBeBuried = true;
maxPillarSupportRadius = new RelTile1i(8);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ShipyardProto), MethodType.Constructor, new[] {
typeof(StaticEntityProto.ID),
typeof(Proto.Str),
typeof(EntityLayout),
typeof(EntityCosts),
typeof(bool),
typeof(Quantity),
typeof(Option<ShipyardProto>),
typeof(ImmutableArray<ImmutableArray<RectangleTerrainArea2iRelative>>),
typeof(StackerProto.Gfx),
typeof(ImmutableArray<String>),
typeof(bool),
})]
static void shipyardCargoMultiplier(ShipyardProto __instance) {
Traverse.Create(__instance).Field("CargoCapacity").SetValue(new Quantity(
(int)(__instance.CargoCapacity.Value * Main.shipyardCargoMultiplier.Value)));
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SaveManager), "isTimeForAutoSave")]
static void autosaveInterval(ref bool __result, SaveManager __instance) {
if (Main.autosaveInterval.Value <= 0) {
__result = false;
return;
}
var trav = Traverse.Create(__instance);
var lastSaveTime = trav.Field("m_lastSaveTime").GetValue<long>();
var num = (Environment.TickCount - lastSaveTime).Abs() / 1000L;
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Autosave interval: {0}", num);
__result = num > Main.autosaveInterval.Value;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MachineProto), nameof(MachineProto.AddRecipe))]
static void machineProtoAddRecipe(MachineProto __instance, ref RecipeProto recipe) {
Console.WriteLine("Recipe outputs for {0}:", __instance.Id);
recipe.AllOutputs.ForEach(o => {
var id = o.Product.Id.ToString();
Console.WriteLine("\tIndustrialCyka: Recipe output {0} x {1}", id, o.Quantity);
if (!Main.recipeMultipliersDict.ContainsKey(id)) {
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Recipe output {0} not found in multipliers, nothing to do", id);
return;
}
var multiplier = Main.recipeMultipliersDict[id];
var trav = Traverse.Create(o);
trav.Field("Quantity").SetValue(new Quantity(trav.Field("Quantity").GetValue<Quantity>().Value * multiplier));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Recipe output {0} changed to {1}", id, trav.Field("Quantity").GetValue<Quantity>());
});
}
}
[HarmonyPatch(typeof(Excavator), "MineMixedAt")]
public class MineMixedAtPatch {
public static Dictionary<ExcavatorProto, Quantity>
originalCapacity = new Dictionary<ExcavatorProto, Quantity>();
public static Dictionary<ExcavatorProto, ImmutableArray<ThicknessTilesF>> originalMinedThicknessByDistance =
new Dictionary<ExcavatorProto, ImmutableArray<ThicknessTilesF>>();
public static Dictionary<ExcavatorProto.Timings, int> originalMineTileIterations =
new Dictionary<ExcavatorProto.Timings, int>();
public static Dictionary<ExcavatorProto, RelTile1i> originalMaxMiningDistance =
new Dictionary<ExcavatorProto, RelTile1i>();
static void Prefix(ref Excavator __instance) {
if (!originalCapacity.ContainsKey(__instance.Prototype)) {
originalCapacity.Add(__instance.Prototype, __instance.Prototype.Capacity);
}
var trav = Traverse.Create(__instance.Prototype);
trav.Field("Capacity")
.SetValue(new Quantity(originalCapacity[__instance.Prototype].Value *
Main.excavatorCapacityMultiplier.Value));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Excavator capacity: {0}", __instance.Prototype.Capacity.Value);
if (!originalMinedThicknessByDistance.ContainsKey(__instance.Prototype)) {
originalMinedThicknessByDistance.Add(__instance.Prototype,
trav.Field("MinedThicknessByDistance").GetValue<ImmutableArray<ThicknessTilesF>>());
}
trav.Field("MinedThicknessByDistance")
.SetValue(originalMinedThicknessByDistance[__instance.Prototype]
.SelectMany(t => Enumerable.Repeat(t, Main.excavatorMiningAreaMultiplier.Value))
.Select(t =>
new ThicknessTilesF((int)(t.Value.ToFloat() * Main.excavatorMiningCapacityMultiplier.Value)))
.ToImmutableArray());
if (Main.debugMode.Value)
originalMinedThicknessByDistance[__instance.Prototype].ForEach(t => Console.WriteLine(t.Value));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Excavator mined thickness: {0}",
__instance.Prototype.MinedThicknessByDistance);
if (!originalMaxMiningDistance.ContainsKey(__instance.Prototype)) {
originalMaxMiningDistance.Add(__instance.Prototype,
trav.Field("MaxMiningDistance").GetValue<RelTile1i>());
}
var value = originalMaxMiningDistance[__instance.Prototype];
var newValueMiningDistance = new RelTile1i((int)(value.Value * Main.excavatorMaxReachMultiplier.Value));
trav.Field("MaxMiningDistance")
.SetValue(newValueMiningDistance);
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Excavator max mining distance: {0}",
__instance.Prototype.MaxMiningDistance);
var trav2 = Traverse.Create(__instance.Prototype.MineTimings);
if (!originalMineTileIterations.ContainsKey(__instance.Prototype.MineTimings)) {
originalMineTileIterations.Add(__instance.Prototype.MineTimings,
trav2.Field("MineTileIterations").GetValue<int>());
}
var newValue = (int)(originalMineTileIterations[__instance.Prototype.MineTimings] *
Main.excavatorMineTileIterationsMultiplier.Value);
trav2.Field("MineTileIterations").SetValue(newValue);
trav2.Field("PrepareToMineDuration").SetValue(new Duration(1));
trav2.Field("MineDuration").SetValue(new Duration(1));
trav2.Field("PrepareToDumpDuration").SetValue(new Duration(1));
trav2.Field("DumpDuration").SetValue(new Duration(1));
if (Main.debugMode.Value)
Console.WriteLine("IndustrialCyka: Excavator mine tile iterations 2: {0}",
trav2.Field("MineTileIterations").GetValue<int>());
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("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")]

1
Projects/CykaOfQud/sync Normal file
View File

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