private static IEnumerable <CodeInstruction> InternalUpdate_Transpiler(IEnumerable <CodeInstruction> instructions) { // Store projectile data after swarm.AddBullet(sailBullet, orbitId) if IsUpdateNeeded == true try { CodeMatcher matcher = new CodeMatcher(instructions) .MatchForward(false, new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(SailBullet), nameof(SailBullet.lBegin))) //IL#638 ); CodeInstruction loadInstruction = matcher.InstructionAt(-1); matcher.MatchForward(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(DysonSwarm), nameof(DysonSwarm.AddBullet))) //IL#679 ) .Advance(2) .InsertAndAdvance( new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.planetId))), loadInstruction, new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.orbitId))), HarmonyLib.Transpilers.EmitDelegate <Action <int, Vector3, int> >((planetId, localPos, orbitId) => { // If the dyson sphere has no subscribers anymore, skip this data if (!Multiplayer.IsActive || !Multiplayer.Session.Launch.Snapshots.ContainsKey(planetId / 100 - 1)) { return; } // Assume orbitId < 65536 DysonLaunchData.Projectile data = new DysonLaunchData.Projectile { PlanetId = planetId, TargetId = (ushort)orbitId, LocalPos = localPos }; Multiplayer.Session.Launch.ProjectileBag.Add(data); }) ); return(matcher.InstructionEnumeration()); } catch { NebulaModel.Logger.Log.Error("EjectorComponent.InternalUpdate_Transpiler failed. Mod version not compatible with game version."); return(instructions); } }
private static IEnumerable <CodeInstruction> InternalUpdate_Transpiler(IEnumerable <CodeInstruction> instructions) { // Store projectile data after sphere.AddDysonRocket(dysonRocket, autoDysonNode) if IsUpdateNeeded == true try { CodeMatcher matcher = new CodeMatcher(instructions) .MatchForward(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(DysonSphere), nameof(DysonSphere.AddDysonRocket))) //IL#310 ); CodeInstruction loadInstruction = matcher.InstructionAt(-1); //autoDysonNode matcher.Advance(2) .InsertAndAdvance( new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(SiloComponent), nameof(SiloComponent.planetId))), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(SiloComponent), nameof(SiloComponent.localPos))), loadInstruction, HarmonyLib.Transpilers.EmitDelegate <Action <int, Vector3, DysonNode> >((planetId, localPos, autoDysonNode) => { // If the dyson sphere has no subscribers anymore, skip this data if (!Multiplayer.IsActive || !Multiplayer.Session.Launch.Snapshots.ContainsKey(planetId / 100 - 1)) { return; } // Assume layerId < 16, nodeId < 4096 DysonLaunchData.Projectile data = new DysonLaunchData.Projectile { PlanetId = planetId, TargetId = (ushort)((autoDysonNode.layerId << 12) | (autoDysonNode.id & 0x0FFF)), LocalPos = localPos }; Multiplayer.Session.Launch.ProjectileBag.Add(data); }) ); return(matcher.InstructionEnumeration()); } catch { NebulaModel.Logger.Log.Error("SiloComponent.InternalUpdate_Transpiler failed. Mod version not compatible with game version."); return(instructions); } }