621 lines
25 KiB
C#
621 lines
25 KiB
C#
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>());
|
|
}
|
|
}
|
|
} |