using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using HarmonyLib.Tools; using Pathfinding; namespace CykaMod { [BepInPlugin(pluginGuid, pluginName, pluginVersion)] public class Main : BaseUnityPlugin { private const string pluginGuid = "CykaMod"; private const string pluginName = "CykaMod"; private const string pluginVersion = "1.0.0"; public static ConfigEntry skillCap; public static ConfigEntry workSpeed; public static ConfigEntry workResult; public static ConfigEntry alwaysCritical; public static ConfigEntry gameSpeed; public static ConfigEntry fans; public static ConfigEntry money; // // private void Awake() // { // configGreeting = Config.Bind("General", // The section under which the option is shown // "GreetingText", // The key of the configuration option in the configuration file // "Hello, world!", // The default value // "A greeting text to show when the game is launched"); // Description of the option to show in the config file // public void Awake() { skillCap = Config.Bind("General", "Skill Cap", 100f); workSpeed = Config.Bind("General", "Work Speed Multiplier", 4f); workResult = Config.Bind("General", "Work Result Multiplier", 4f); alwaysCritical = Config.Bind("General", "Work Always Critical", false); gameSpeed = Config.Bind("General", "Game Speed Multiplier", 3f); fans = Config.Bind("General", "Fans Multiplier", 2); money = Config.Bind("General", "Money Multiplier", 2L); 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"); } public static bool IsMatch(List codes, int index, List matcher) { for (var i = 0; i < matcher.Count; i++) { if (codes[index + i].opcode != matcher[i].opcode) { return false; } } return true; } public static void InsertAt(List codes, int index, List toInsert) { for (var i = 0; i < toInsert.Count; i++) { codes.Insert(index + i, toInsert[i]); } } } [HarmonyPatch(typeof(characterScript), "GetSkillCap")] public class SkillCapPatch { static void Postfix(ref float __result) { // Console.WriteLine("GetSkillCap Postfix! Result is " + __result); __result = Main.skillCap.Value; } } [HarmonyPatch(typeof(characterScript), "GetSkillCap_Skill")] public class SkillCapSkillPatch { static void Postfix(ref float __result) { // Console.WriteLine("GetSkillCap_Skill Postfix! Result is " + __result); __result = Main.skillCap.Value; } } [HarmonyPatch(typeof(characterScript), "GetWorkSpeed")] public class GetWorkSpeedPatch { static void Postfix(ref float __result) { // Console.WriteLine("GetWorkSpeed Postfix! Result is " + __result); __result *= Main.workSpeed.Value; } } [HarmonyPatch(typeof(characterScript), "GetWorkResult")] public class GetWorkResultPatch { static void Prefix(ref float f) { // Console.WriteLine("GetWorkResult Postfix! f is " + f); f *= Main.workResult.Value; } } [HarmonyPatch(typeof(characterScript), "GetCritic")] public class GetCriticPatch { static void Postfix(ref bool __result) { // Console.WriteLine("GetWorkResult Postfix! f is " + f); if (Main.alwaysCritical.Value) { __result = true; } } } [HarmonyPatch(typeof(mainScript), "SetGameSpeed")] public class GameSpeedPatch { static void Prefix(ref float f) { // Console.WriteLine("SetGameSpeed Prefix! Argument is " + f); if (f > 1) { f *= Main.gameSpeed.Value; // Console.WriteLine("Argument modified to " + f); } } } [HarmonyPatch(typeof(characterScript), "Learn")] public static class LearnManyPatch { static IEnumerable Transpiler(IEnumerable instructions) { var codes = new List(instructions); for (var i = 0; i < 5; i++) { if (codes[i].opcode == OpCodes.Ldc_R4) { Console.WriteLine("Changing " + codes[i]); codes[i].operand = (float)codes[i].operand * 64; Console.WriteLine("Changed " + codes[i]); } } return codes.AsEnumerable(); } } [HarmonyPatch(typeof(arbeitsmarkt), "ArbeitsmarktUpdaten")] public static class ManyEmployeesPatch { static IEnumerable Transpiler(IEnumerable instructions) { var codes = new List(instructions); for (var i = codes.Count - 1; i > 0; i--) { if (codes[i].opcode == OpCodes.Ldc_I4_3) { Console.WriteLine("Changing " + codes[i]); codes[i] = new CodeInstruction(OpCodes.Ldc_I4, 64); Console.WriteLine("Changed " + codes[i]); break; } } return codes.AsEnumerable(); } } // [HarmonyPatch(typeof(AILerp), "MovementUpdate")] public class MovementSpeedPatch { static void Prefix(ref float deltaTime) { Console.WriteLine("MovementUpdate Prefix! deltaTime is " + deltaTime); deltaTime *= 16f; } } // [HarmonyPatch(typeof(movementScript), "Move")] public static class EmployeeMovementSpeedPatch { static IEnumerable Transpiler(IEnumerable instructions) { var codes = new List(instructions); List matcher = new List(); matcher.Add(new CodeInstruction(OpCodes.Ldarg_0, null)); matcher.Add(new CodeInstruction(OpCodes.Ldfld, null)); matcher.Add(new CodeInstruction(OpCodes.Ldarg_0, null)); matcher.Add(new CodeInstruction(OpCodes.Ldfld, null)); matcher.Add(new CodeInstruction(OpCodes.Mul, null)); List patch = new List(); patch.Add(new CodeInstruction(OpCodes.Ldc_R4, 8)); patch.Add(new CodeInstruction(OpCodes.Mul, null)); for (var i = codes.Count - 1; i > 0; i--) { if (Main.IsMatch(codes, i, matcher)) { Main.InsertAt(codes, i + 5, patch); Console.WriteLine("Movement speed patched"); for (var j = 0; j < 15; j++) { Console.WriteLine(codes[i + j]); } break; } } Console.WriteLine("Return"); return codes.AsEnumerable(); } } [HarmonyPatch(typeof(mainScript), "WochenUpdates")] public static class ContractWorkAmount { static IEnumerable Transpiler(IEnumerable instructions) { var codes = new List(instructions); int methodIndex = -1; List pattern = new List(); List matcher = new List(); matcher.Add(new CodeInstruction(OpCodes.Ldarg_0, null)); matcher.Add(new CodeInstruction(OpCodes.Ldfld, null)); matcher.Add(new CodeInstruction(OpCodes.Ldc_I4_0, null)); matcher.Add(new CodeInstruction(OpCodes.Callvirt, null)); for (var i = 0; i < codes.Count; i++) { if (codes[i].operand != null) { if (codes[i].operand.ToString().Contains("UpdateContractWork")) { methodIndex = i; pattern.Add(codes[i - 3]); pattern.Add(codes[i - 2]); pattern.Add(codes[i - 1]); pattern.Add(codes[i]); break; } } } pattern[2].opcode = OpCodes.Ldc_I4_1; for (int i = 0; i < 16; i++) { for (int j = 0; j < pattern.Count; j++) { codes.Insert(methodIndex + i + j, pattern[j]); } } return codes.AsEnumerable(); } } [HarmonyPatch(typeof(platformScript), "SellPlayer")] public static class ConsoleProductionReductionPatch { static IEnumerable Transpiler(IEnumerable instructions) { var codes = new List(instructions); List matcher = new List(); matcher.Add(new CodeInstruction(OpCodes.Ldarg_0, null)); matcher.Add(new CodeInstruction(OpCodes.Ldarg_0, null)); matcher.Add(new CodeInstruction(OpCodes.Ldfld, null)); matcher.Add(new CodeInstruction(OpCodes.Ldc_R4, null)); matcher.Add(new CodeInstruction(OpCodes.Ldc_R4, null)); matcher.Add(new CodeInstruction(OpCodes.Call, null)); matcher.Add(new CodeInstruction(OpCodes.Add, null)); matcher.Add(new CodeInstruction(OpCodes.Stfld, null)); for (var i = 0; i < codes.Count; i++) { if (Main.IsMatch(codes, i, matcher)) { codes[i + 3].operand = (float)codes[i + 3].operand * 8f; codes[i + 4].operand = (float)codes[i + 4].operand * 8f; Console.WriteLine("ConsoleProductionReductionPatch patched"); break; } } return codes.AsEnumerable(); } } [HarmonyPatch(typeof(mainScript), "AddFans")] public static class AddFansPatch { static void Prefix(ref int i) { // Console.WriteLine("GetWorkResult Postfix! f is " + f); i *= Main.fans.Value; } } [HarmonyPatch(typeof(mainScript), "Earn")] public static class AddMoneyPatch { static void Prefix(ref long amount) { // Console.WriteLine("GetWorkResult Postfix! f is " + f); amount *= Main.money.Value; } } }