/// <summary> /// Fixes the graphical bug where the enemy ship is "spawned" beneath the player ship after it is destroyed. /// </summary> private void Structures_resetShipDataCoroutine_Fix() { ModuleDefinition unityModule = Injector.GetModuleZ("UnityEngine.dll"); TypeDefinition structuresDef = GameModule.GetTypeByName("Structures"); TypeDefinition resetShipDataCoroutine = structuresDef.NestedTypes.Where(t => t.Name.Contains("resetShipDataCoroutine")).FirstOrDefault(); MethodDefinition toggleShipVisual = structuresDef.GetMethodByName("toggleShipVisual"); MethodDefinition moveNextMethod = resetShipDataCoroutine.GetMethodByName("MoveNext"); FieldDefinition f_thisField = resetShipDataCoroutine.GetFieldByName("<>f__this"); MethodDefinition gameObjectGetMethod = unityModule.GetTypeByName("Component").GetPropertyByName("gameObject").GetMethod; Instruction[] instructions = new Instruction[] { Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldfld, GameModule.Import(f_thisField)), Instruction.Create(OpCodes.Ldc_I4_0), Instruction.Create(OpCodes.Callvirt, GameModule.Import(toggleShipVisual)) }; ILProcessor processor = moveNextMethod.Body.GetILProcessor(); Instruction lastInstruction = moveNextMethod.Body.Instructions.Where(i => i.OpCode == OpCodes.Callvirt && ((MethodReference)i.Operand).Name.Contains("set_position")).FirstOrDefault(); foreach (Instruction ins in instructions) { processor.InsertAfter(lastInstruction, ins); lastInstruction = ins; } }
/// <summary> /// Fixes the graphical bug where the enemy ship is "spawned" beneath the player ship after it is destroyed. /// </summary> private void ManagerOptions_flyEnemyOutOfSceneCR_Fix() { TypeDefinition managerOptions = GameModule.GetTypeByName("ManagerOptions"); TypeDefinition flyEnemyOutOfSceneCR = managerOptions.NestedTypes.Where(t => t.Name.Contains("flyEnemyOutOfSceneCR")).FirstOrDefault(); TypeDefinition bugFixes = ModLibModule.GetTypeByName("__BugFixes"); MethodDefinition toggleShipVisual = bugFixes.GetMethodByName("ToggleShipVisual"); MethodDefinition moveNextMethod = flyEnemyOutOfSceneCR.GetMethodByName("MoveNext"); FieldDefinition f_thisField = flyEnemyOutOfSceneCR.GetFieldByName("<>f__this"); FieldDefinition enemyShipField = f_thisField.FieldType.Resolve().GetFieldByName("EnemyShip"); Instruction[] instructions = new Instruction[] { Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldfld, GameModule.Import(f_thisField)), Instruction.Create(OpCodes.Ldfld, GameModule.Import(enemyShipField)), Instruction.Create(OpCodes.Ldc_I4_0), Instruction.Create(OpCodes.Callvirt, GameModule.Import(toggleShipVisual)) }; ILProcessor processor = moveNextMethod.Body.GetILProcessor(); Instruction lastInstruction = moveNextMethod.Body.Instructions.Where(i => i.OpCode == OpCodes.Callvirt && ((MethodReference)i.Operand).Name.Contains("playSoundEnemyWarpOut")).FirstOrDefault(); foreach (Instruction ins in instructions) { processor.InsertAfter(lastInstruction, ins); lastInstruction = ins; } }
public override void Inject() { TypeDefinition ManagerDef = GameModule.GetTypeByName("ManagerOptions"); ChangeGameTitle(); NewPanelOpened(); }
/// <summary> /// Fixes a bug where crewmembers tries to find a tile outside the tile map (Position -444, -444). /// </summary> private void AI_anyPartOnFire_Fix() { TypeDefinition AIDef = GameModule.GetTypeByName("AI"); MethodDefinition anyPartOnFireDef = AIDef.GetMethodByName("anyPartOnFire"); ILProcessor il = anyPartOnFireDef.Body.GetILProcessor(); Instruction[] ending = new Instruction[] { Instruction.Create(OpCodes.Ldc_I4_0), Instruction.Create(OpCodes.Ret) }; il.Append(ending[0]); il.Append(ending[1]); Instruction[] beginning = new Instruction[] { Instruction.Create(OpCodes.Ldarg_1), Instruction.Create(OpCodes.Ldarg_2), Instruction.Create(OpCodes.Add), Instruction.Create(OpCodes.Ldc_I4, -888), Instruction.Create(OpCodes.Ceq), Instruction.Create(OpCodes.Brtrue, ending[0]) }; Instruction last = il.Body.Instructions[0]; for (int i = beginning.Length - 1; i >= 0; i--) { il.InsertBefore(last, beginning[i]); last = beginning[i]; } }
public override void Inject() { TypeDefinition ManagerDef = GameModule.GetTypeByName("ManagerOptions"); TypeDefinition ModGUIDef = ModLibModule.GetTypeByName("ModGUI"); MethodDefinition CreateModGUIMethod = ModGUIDef.GetMethodByName("__Create"); MethodDefinition ManagerStartMethod = ManagerDef.GetMethodByName("Start"); ManagerStartMethod.Body.GetILProcessor().InjectInstructionsToEnd(new Instruction[] { Instruction.Create(OpCodes.Callvirt, GameModule.Import(CreateModGUIMethod)), }); }
public override void Inject() { TypeDefinition ModLoaderDef = ModLibModule.GetTypeByName("ModLoader"); TypeDefinition ManagerDef = GameModule.GetTypeByName("ManagerOptions"); TypeDefinition GameEventsDef = ModLibModule.GetTypeByName("GameEvents"); InjectModLoaderField(ModLoaderDef, ManagerDef); InjectModLoaderLoadMods(ModLoaderDef, ManagerDef); InjectModLoaderGameStarted(GameEventsDef, ManagerDef); InjectModLoaderGameLoaded(GameEventsDef, ManagerDef); InjectModLoaderGameSaved(GameEventsDef, ManagerDef); }
private void ChangeGameTitle() { TypeDefinition ManagerMenuDef = GameModule.GetTypeByName("ManagerMenu"); MethodDefinition Method = ManagerMenuDef.GetMethodByName("createMainMenuBackground"); foreach (Instruction I in Method.Body.Instructions) { if (I.OpCode == OpCodes.Ldstr && I.Operand.ToString() == "STARSHIP THEORY") { I.Operand = "STARSHIP THEORY - MODDED"; break; } } }
public override void Inject() { TypeDefinition saveLoadDataType = ModLibModule.GetTypeByName("SaveLoadData"); MethodDefinition saveLoadInitMethod = saveLoadDataType.GetMethodByName("__Init"); TypeDefinition ES2InitType = GameModule.GetTypeByName("ES2Init"); MethodDefinition ES2InitMethod = ES2InitType.GetMethodByName("Init"); Instruction insertAfter = ES2InitMethod.Body.Instructions[ES2InitMethod.Body.Instructions.Count - 4]; ES2InitMethod.Body.GetILProcessor().InsertAfter(insertAfter, new Instruction[] { Instruction.Create(OpCodes.Callvirt, GameModule.Import(saveLoadInitMethod)) }); }
private void NewPanelOpened() { TypeDefinition MenuEventsDef = ModLibModule.GetTypeByName("MenuEvents"); MethodDefinition OnNewGamePanelOpened = MenuEventsDef.GetMethodByName("__OnNewGamePanelOpened"); TypeDefinition ManagerMenuDef = GameModule.GetTypeByName("ManagerMenu"); MethodDefinition Method = ManagerMenuDef.GetMethodByName("createNewGamePanel"); FieldDefinition rightMenuFieldDef = ManagerMenuDef.GetFieldByName("mainMenuRight"); Instruction[] instructions = new Instruction[] { Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldfld, GameModule.Import(rightMenuFieldDef)), Instruction.Create(OpCodes.Callvirt, GameModule.Import(OnNewGamePanelOpened)) }; Method.Body.GetILProcessor().InjectInstructionsToEnd(instructions); }
public override void Inject() { TypeDefinition CostsDef = ModLibModule.GetTypeByName("Costs"); MethodDefinition CostsCtor = CostsDef.GetMethodByName(".ctor"); MethodDefinition CostsGetResourceRequirementsMethod = CostsDef.GetMethodByName("GetResourceRequirements"); GameModule.Import(ModLibModule.GetTypeByName("EntityCost")); TypeDefinition ManagerDef = GameModule.GetTypeByName("ManagerResources"); MethodDefinition ManagerGetResourceRequirementsMethod = ManagerDef.GetMethodByName("getResourcesRequirement"); FieldDefinition CostsFieldDef = new FieldDefinition("Costs", FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly, GameModule.Import(CostsDef)); ManagerDef.Fields.Add(CostsFieldDef); MethodDefinition ManagerCtor = ManagerDef.GetMethodByName(".ctor"); ManagerCtor.Body.GetILProcessor().InjectInstructionsToEnd(new Instruction[] { Instruction.Create(OpCodes.Newobj, GameModule.Import(CostsCtor)), Instruction.Create(OpCodes.Stsfld, GameModule.Import(CostsFieldDef)) }); MethodDefinition logMethod = Injector.GetModuleZ("UnityEngine.dll").GetTypeByName("Debug").GetMethodByName("Log", 1); TypeDefinition stringType = Injector.GetModuleZ("mscorlib.dll").GetTypeByName("String"); MethodDefinition isNullOrEmptyMethod = stringType.GetMethodByName("IsNullOrEmpty"); MethodDefinition concatMethod = stringType.GetMethodByName("Concat", 4, GameModule.Import(stringType)); ManagerGetResourceRequirementsMethod.Body.Instructions.Clear(); ManagerGetResourceRequirementsMethod.Body.GetILProcessor().InjectInstructionsToEnd(new Instruction[] { Instruction.Create(OpCodes.Ldsfld, CostsFieldDef), Instruction.Create(OpCodes.Ldarg_1), Instruction.Create(OpCodes.Ldarg_2), Instruction.Create(OpCodes.Callvirt, GameModule.Import(CostsGetResourceRequirementsMethod)), Instruction.Create(OpCodes.Ret) }); /*ManagerGetResourceRequirementsMethod.Body.Instructions.Clear(); * * ManagerGetResourceRequirementsMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); * ManagerGetResourceRequirementsMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_2)); * ManagerGetResourceRequirementsMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Callvirt, GameModule.Import(CostsGetResourceRequirementsMethod))); * ManagerGetResourceRequirementsMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));*/ }