diff --git a/NebulaPatcher/Patches/Dynamic/ACH_BroadcastStar_Patch.cs b/NebulaPatcher/Patches/Dynamic/ACH_BroadcastStar_Patch.cs new file mode 100644 index 000000000..8f979a1ee --- /dev/null +++ b/NebulaPatcher/Patches/Dynamic/ACH_BroadcastStar_Patch.cs @@ -0,0 +1,25 @@ +#region + +using HarmonyLib; +using NebulaWorld; + +#endregion + +namespace NebulaPatcher.Patches.Dynamic; + +[HarmonyPatch(typeof(ACH_BroadcastStar))] +internal class ACH_BroadcastStar_Patch +{ + [HarmonyPrefix] + [HarmonyPatch(nameof(ACH_BroadcastStar.OnGameTick))] + [HarmonyPatch(nameof(ACH_BroadcastStar.TryAlterEntity))] + public static bool Block_On_Client_Prefix() + { + // ACH_BroadcastStar is for the achievement "Let there be light!" + // which needs to light up Artificial Star (2210) on certain planets + // Clients only have partial factories loaded so they won't get the correct stats. + // Therefore it's disabled to prevent errors. + // TODO: Try to handle global achievements syncing? + return !Multiplayer.IsActive || Multiplayer.Session.IsServer; + } +} diff --git a/NebulaPatcher/Patches/Transpilers/ACH_BroadcastStar_Transpiler.cs b/NebulaPatcher/Patches/Transpilers/ACH_BroadcastStar_Transpiler.cs deleted file mode 100644 index dac10a763..000000000 --- a/NebulaPatcher/Patches/Transpilers/ACH_BroadcastStar_Transpiler.cs +++ /dev/null @@ -1,69 +0,0 @@ -#region - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using HarmonyLib; -using NebulaModel.Logger; -using NebulaWorld; - -#endregion - -namespace NebulaPatcher.Patches.Transpilers; - -[HarmonyPatch(typeof(ACH_BroadcastStar))] -internal class ACH_BroadcastStar_Transpiler -{ - /* - * Returns early if - * instance.gameData.factories[factoryId]?.powerSystem?.genPool[generatorId] == null || instance.gameData.factories[factoryId].index == -1 - * while in a multiplayer session as a client - */ - [HarmonyTranspiler] - [HarmonyPatch(nameof(ACH_BroadcastStar.OnGameTick))] - private static IEnumerable OnGameTick_Transpiler(IEnumerable instructions, ILGenerator il) - { - var codeInstructions = instructions as CodeInstruction[] ?? instructions.ToArray(); - try - { - var codeMatcher = new CodeMatcher(codeInstructions, il) - .MatchForward(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "gameData"), - new CodeMatch(i => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "factories"), - new CodeMatch(i => i.IsLdloc()), - new CodeMatch(OpCodes.Ldelem_Ref) - ); - - var factoryIdInstruction = codeMatcher.InstructionAt(3); - var generatorIdInstruction = codeMatcher.InstructionAt(7); - - return codeMatcher - .CreateLabel(out var label) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0)) - .InsertAndAdvance(factoryIdInstruction) - .InsertAndAdvance(generatorIdInstruction) - .InsertAndAdvance(HarmonyLib.Transpilers.EmitDelegate>( - (instance, factoryId, generatorId) => - { - if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost) - { - return true; - } - - return instance.gameData.factories[factoryId]?.powerSystem?.genPool[generatorId] != null && - instance.gameData.factories[factoryId].index != -1; - })) - .InsertAndAdvance(new CodeInstruction(OpCodes.Brtrue, label)) - .InsertAndAdvance(new CodeInstruction(OpCodes.Ret)) - .InstructionEnumeration(); - } - catch - { - Log.Error("ACH_BroadcastStar.OnGameTick_Transpiler failed. Mod version not compatible with game version."); - return codeInstructions; - } - } -}