public void ProcessPacket(PowerTowerUserLoadingResponse packet, NebulaConnection conn)
        {
            PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;

            if (factory != null && factory.powerSystem != null)
            {
                PowerNetwork pNet = factory.powerSystem.netPool[packet.NetId];

                if (packet.Charging)
                {
                    PowerTowerManager.AddExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId, packet.PowerAmount);
                    if (PowerTowerManager.DidRequest(packet.PlanetId, packet.NetId, packet.NodeId))
                    {
                        int   baseDemand = factory.powerSystem.nodePool[packet.NodeId].workEnergyPerTick - factory.powerSystem.nodePool[packet.NodeId].idleEnergyPerTick;
                        float mult       = factory.powerSystem.networkServes[packet.NetId];
                        PowerTowerManager.PlayerChargeAmount = (int)(mult * (float)baseDemand);
                    }
                }
                else
                {
                    PowerTowerManager.RemExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId);
                }

                pNet.energyCapacity    = packet.EnergyCapacity;
                pNet.energyRequired    = packet.EnergyRequired;
                pNet.energyAccumulated = packet.EnergyAccumulated;
                pNet.energyExchanged   = packet.EnergyExchanged;
                pNet.energyServed      = packet.EnergyServed;
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Calls the update functions on the systems that are updated on a fixed frequency.
 /// </summary>
 /// <param name="deltaTime">Delta time.</param>
 private void TickFixedFrequency(float deltaTime)
 {
     // Progress temperature modelling
     temperature.Update(deltaTime);
     PowerNetwork.Update(deltaTime);
     FluidNetwork.Update(deltaTime);
 }
Esempio n. 3
0
    private void SetupWorld(int width, int height, int depth)
    {
        // Set the current world to be this world.
        // TODO: Do we need to do any cleanup of the old world?
        Current = this;

        Width  = width;
        Height = height;
        Depth  = depth;

        tiles = new Tile[Width, Height, Depth];

        RoomManager           = new RoomManager();
        RoomManager.Adding   += (room) => roomGraph = null;
        RoomManager.Removing += (room) => roomGraph = null;

        FillTilesArray();

        FurnitureManager          = new FurnitureManager();
        FurnitureManager.Created += OnFurnitureCreated;

        UtilityManager   = new UtilityManager();
        CharacterManager = new CharacterManager();
        InventoryManager = new InventoryManager();
        jobQueue         = new JobQueue();
        GameEventManager = new GameEventManager();
        PowerNetwork     = new PowerNetwork();
        temperature      = new Temperature();
        ShipManager      = new ShipManager();
        Wallet           = new Wallet();
        CameraData       = new CameraData();

        LoadSkybox();
        AddEventListeners();
    }
Esempio n. 4
0
        public override void ProcessPacket(PowerTowerUserLoadingRequest packet, NebulaConnection conn)
        {
            if (IsClient)
            {
                return;
            }

            PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;

            if (factory?.powerSystem != null)
            {
                PowerNetwork pNet = factory.powerSystem.netPool[packet.NetId];

                if (packet.Charging)
                {
                    Multiplayer.Session.PowerTowers.AddExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId, packet.PowerAmount);
                }
                else
                {
                    Multiplayer.Session.PowerTowers.RemExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId);
                }

                Multiplayer.Session.Network.SendPacketToStar(new PowerTowerUserLoadingResponse(packet.PlanetId,
                                                                                               packet.NetId,
                                                                                               packet.NodeId,
                                                                                               packet.PowerAmount,
                                                                                               pNet.energyCapacity,
                                                                                               pNet.energyRequired,
                                                                                               pNet.energyServed,
                                                                                               pNet.energyAccumulated,
                                                                                               pNet.energyExchanged,
                                                                                               packet.Charging),
                                                             GameMain.galaxy.PlanetById(packet.PlanetId).star.id);
            }
        }
Esempio n. 5
0
        public void ProcessPacket(PowerTowerUserLoadingRequest packet, NebulaConnection conn)
        {
            PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;

            if (factory != null && factory.powerSystem != null)
            {
                PowerNetwork pNet = factory.powerSystem.netPool[packet.NetId];

                if (packet.Charging)
                {
                    PowerTowerManager.AddExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId, packet.PowerAmount);
                }
                else
                {
                    PowerTowerManager.RemExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId);
                }

                LocalPlayer.SendPacketToStar(new PowerTowerUserLoadingResponse(packet.PlanetId,
                                                                               packet.NetId,
                                                                               packet.NodeId,
                                                                               packet.PowerAmount,
                                                                               pNet.energyCapacity,
                                                                               pNet.energyRequired,
                                                                               pNet.energyServed,
                                                                               pNet.energyAccumulated,
                                                                               pNet.energyExchanged,
                                                                               packet.Charging),
                                             GameMain.galaxy.PlanetById(packet.PlanetId).star.id);
            }
        }
Esempio n. 6
0
    private void SetupWorld(int width, int height)
    {
        // Set the current world to be this world.
        // TODO: Do we need to do any cleanup of the old world?
        Current = this;


        RoomManager           = new RoomManager();
        RoomManager.Adding   += (room) => roomGraph = null;
        RoomManager.Removing += (room) => roomGraph = null;

        FillTilesArray();

        FurnitureManager          = new FurnitureManager();
        FurnitureManager.Created += OnFurnitureCreated;

        UtilityManager   = new UtilityManager();
        CharacterManager = new CharacterManager();
        InventoryManager = new InventoryManager();
        jobQueue         = new JobQueue();
        GameEventManager = new GameEventManager();
        PowerNetwork     = new PowerNetwork();
        FluidNetwork     = new FluidNetwork();
        temperature      = new TemperatureDiffusion(this);
        Wallet           = new Wallet();
        CameraData       = new CameraData();

        LoadSkybox();
        AddEventListeners();

        holder.Start();
        biomes.RandomBiome();
        mapData.SetupWorld(width, height, biome.maxHeight);
    }
Esempio n. 7
0
            void FinishRemovingPowerNets()
            {
                for (int i = 0; i < powerSystem.netCursor; i++)
                {
                    PowerNetwork network = powerSystem.netPool[i];
                    if (network == null || network.id != i)
                    {
                        continue;
                    }
                    if (network.id >= powerConRemoval.Count)
                    {
                        continue;
                    }

                    HashSet <int> consumersToRemove = powerConRemoval[network.id];
                    foreach (Node node in network.nodes)
                    {
                        node.consumers.RemoveAll(x => consumersToRemove.Contains(x));
                    }
                    network.consumers.RemoveAll(x => consumersToRemove.Contains(x));
                }

                if (factory.planet.factoryModel != null)
                {
                    factory.planet.factoryModel.RefreshPowerConsumers();
                }
            }
Esempio n. 8
0
    /// <summary>
    /// Calls the update functions on the systems that are updated on a fixed frequency.
    /// </summary>
    /// <param name="deltaTime">Delta time.</param>
    private void TickFixedFrequency(float deltaTime)
    {
        FurnitureManager.TickFixedFrequency(deltaTime);

        // Progress temperature modelling
        temperature.Update();
        PowerNetwork.Update(deltaTime);
    }
Esempio n. 9
0
    public void Init()
    {
        powerNetwork = new PowerNetwork();
        Type      livePowerSystemType = typeof(PowerNetwork);
        FieldInfo field = livePowerSystemType.GetField("powerGrids", BindingFlags.NonPublic | BindingFlags.Instance);

        Assert.IsNotNull(field);
        powerGrids = field.GetValue(powerNetwork) as HashSet <UtilityGrid>;
        Assert.IsNotNull(powerGrids);
        Assert.AreEqual(0, powerGrids.Count);
    }
Esempio n. 10
0
 public static void PowerSystem_GameTick_Postfix(PowerSystem __instance, long time, bool isActive, bool isMultithreadMode)
 {
     if (SimulatedWorld.Initialized)
     {
         for (int i = 1; i < __instance.netCursor; i++)
         {
             PowerNetwork pNet = __instance.netPool[i];
             pNet.energyRequired += PowerTowerManager.GetExtraDemand(__instance.planet.id, i);
         }
         PowerTowerManager.GivePlayerPower();
         PowerTowerManager.UpdateAllAnimations(__instance.planet.id);
     }
 }
Esempio n. 11
0
 public static void PowerSystem_GameTick_Postfix(PowerSystem __instance, long time, bool isActive, bool isMultithreadMode)
 {
     if (Multiplayer.IsActive)
     {
         for (int i = 1; i < __instance.netCursor; i++)
         {
             PowerNetwork pNet = __instance.netPool[i];
             pNet.energyRequired += Multiplayer.Session.PowerTowers.GetExtraDemand(__instance.planet.id, i);
         }
         Multiplayer.Session.PowerTowers.GivePlayerPower();
         Multiplayer.Session.PowerTowers.UpdateAllAnimations(__instance.planet.id);
     }
 }
        public override void ProcessPacket(PowerTowerUserLoadingResponse packet, NebulaConnection conn)
        {
            PlanetFactory factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;

            if (factory != null && factory.powerSystem != null)
            {
                PowerNetwork pNet = factory.powerSystem.netPool[packet.NetId];

                if (packet.Charging)
                {
                    Multiplayer.Session.PowerTowers.AddExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId, packet.PowerAmount);
                    if (IsClient)
                    {
                        if (Multiplayer.Session.PowerTowers.DidRequest(packet.PlanetId, packet.NetId, packet.NodeId))
                        {
                            int   baseDemand = factory.powerSystem.nodePool[packet.NodeId].workEnergyPerTick - factory.powerSystem.nodePool[packet.NodeId].idleEnergyPerTick;
                            float mult       = factory.powerSystem.networkServes[packet.NetId];
                            Multiplayer.Session.PowerTowers.PlayerChargeAmount += (int)(mult * baseDemand);
                        }
                    }
                }
                else
                {
                    Multiplayer.Session.PowerTowers.RemExtraDemand(packet.PlanetId, packet.NetId, packet.NodeId);
                }

                if (IsHost)
                {
                    Multiplayer.Session.Network.SendPacketToStar(new PowerTowerUserLoadingResponse(packet.PlanetId,
                                                                                                   packet.NetId,
                                                                                                   packet.NodeId,
                                                                                                   packet.PowerAmount,
                                                                                                   pNet.energyCapacity,
                                                                                                   pNet.energyRequired,
                                                                                                   pNet.energyServed,
                                                                                                   pNet.energyAccumulated,
                                                                                                   pNet.energyExchanged,
                                                                                                   packet.Charging),
                                                                 GameMain.galaxy.PlanetById(packet.PlanetId).star.id);
                }
                else
                {
                    pNet.energyCapacity    = packet.EnergyCapacity;
                    pNet.energyRequired    = packet.EnergyRequired;
                    pNet.energyAccumulated = packet.EnergyAccumulated;
                    pNet.energyExchanged   = packet.EnergyExchanged;
                    pNet.energyServed      = packet.EnergyServed;
                }
            }
        }
Esempio n. 13
0
    private void SetupWorld(int width, int height, int depth)
    {
        // Set the current world to be this world.
        // TODO: Do we need to do any cleanup of the old world?
        Current = this;

        Width  = width;
        Height = height;
        Depth  = depth;

        tiles = new Tile[Width, Height, Depth];

        RoomManager           = new RoomManager();
        RoomManager.Adding   += (room) => roomGraph = null;
        RoomManager.Removing += (room) => roomGraph = null;

        for (int x = 0; x < Width; x++)
        {
            for (int y = 0; y < Height; y++)
            {
                for (int z = 0; z < Depth; z++)
                {
                    tiles[x, y, z]                  = new Tile(x, y, z);
                    tiles[x, y, z].TileChanged     += OnTileChangedCallback;
                    tiles[x, y, z].TileTypeChanged += OnTileTypeChangedCallback;
                    tiles[x, y, z].Room             = RoomManager.OutsideRoom; // Rooms 0 is always going to be outside, and that is our default room
                }
            }
        }

        FurnitureManager          = new FurnitureManager();
        FurnitureManager.Created += OnFurnitureCreated;

        UtilityManager   = new UtilityManager();
        CharacterManager = new CharacterManager();
        InventoryManager = new InventoryManager();
        jobQueue         = new JobQueue();
        GameEventManager = new GameEventManager();
        PowerNetwork     = new PowerNetwork();
        temperature      = new Temperature();
        ShipManager      = new ShipManager();
        Wallet           = new Wallet();
        CameraData       = new CameraData();

        LoadSkybox();
        AddEventListeners();
    }
Esempio n. 14
0
        public static IEnumerable <CodeInstruction> PowerSystem_GameTick_Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            CodeMatcher codeMatcher = new CodeMatcher(instructions)
                                      .MatchForward(true,
                                                    new CodeMatch(OpCodes.Ldarg_0),
                                                    new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), nameof(PowerSystem.nodePool))),
                                                    new CodeMatch(OpCodes.Ldloc_S),
                                                    new CodeMatch(OpCodes.Ldelema),
                                                    new CodeMatch(OpCodes.Ldarg_0),
                                                    new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), nameof(PowerSystem.nodePool))),
                                                    new CodeMatch(OpCodes.Ldloc_S),
                                                    new CodeMatch(OpCodes.Ldelema),
                                                    new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerNodeComponent), nameof(PowerNodeComponent.workEnergyPerTick))),
                                                    new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(PowerNodeComponent), nameof(PowerNodeComponent.requiredEnergy))));

            if (codeMatcher.IsInvalid)
            {
                NebulaModel.Logger.Log.Error("PowerSystem_GameTick_Transpiler 1 failed. Mod version not compatible with game version.");
                return(instructions);
            }

            codeMatcher = codeMatcher
                          .Advance(1)
                          .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0))
                          .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 59))
                          .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 22))
                          .Insert(HarmonyLib.Transpilers.EmitDelegate <PlayerChargesAtTower>((PowerSystem _this, int powerNodeId, int powerNetId) =>
            {
                if (Multiplayer.IsActive)
                {
                    if (!Multiplayer.Session.LocalPlayer.IsHost)
                    {
                        _this.nodePool[powerNodeId].requiredEnergy = _this.nodePool[powerNodeId].idleEnergyPerTick;     // this gets added onto the known required energy by Multiplayer.Session.PowerTowers. and PowerSystem_Patch
                        if (Multiplayer.Session.PowerTowers.AddRequested(_this.planet.id, powerNetId, powerNodeId, true, false))
                        {
                            Multiplayer.Session.Network.SendPacket(new PowerTowerUserLoadingRequest(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick, true));
                        }
                    }
                    else
                    {
                        PowerNetwork pNet = _this.netPool[powerNetId];
                        if (Multiplayer.Session.PowerTowers.AddRequested(_this.planet.id, powerNetId, powerNodeId, true, false))
                        {
                            Multiplayer.Session.PowerTowers.AddExtraDemand(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick);
                            Multiplayer.Session.Network.SendPacketToLocalStar(new PowerTowerUserLoadingResponse(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick,
                                                                                                                pNet.energyCapacity,
                                                                                                                pNet.energyRequired,
                                                                                                                pNet.energyServed,
                                                                                                                pNet.energyAccumulated,
                                                                                                                pNet.energyExchanged,
                                                                                                                true));
                        }
                    }
                }
            }))
                          // now search for where its set back to idle after player leaves radius / has charged fully
                          .MatchForward(true,
                                        new CodeMatch(OpCodes.Ldarg_0),
                                        new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), nameof(PowerSystem.nodePool))),
                                        new CodeMatch(OpCodes.Ldloc_S),
                                        new CodeMatch(OpCodes.Ldelema),
                                        new CodeMatch(OpCodes.Ldarg_0),
                                        new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), nameof(PowerSystem.nodePool))),
                                        new CodeMatch(OpCodes.Ldloc_S),
                                        new CodeMatch(OpCodes.Ldelema),
                                        new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerNodeComponent), nameof(PowerNodeComponent.idleEnergyPerTick))),
                                        new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(PowerNodeComponent), nameof(PowerNodeComponent.requiredEnergy))));

            if (codeMatcher.IsInvalid)
            {
                NebulaModel.Logger.Log.Error("PowerSystem_GameTick_Transpiler 2 failed. Mod version not compatible with game version.");
                return(codeMatcher.InstructionEnumeration());
            }

            return(codeMatcher
                   .Repeat(matcher =>
            {
                matcher
                .Advance(1)
                .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0))
                .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 59))
                .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 22))
                .Insert(HarmonyLib.Transpilers.EmitDelegate <PlayerChargesAtTower>((PowerSystem _this, int powerNodeId, int powerNetId) =>
                {
                    if (Multiplayer.IsActive)
                    {
                        if (!Multiplayer.Session.LocalPlayer.IsHost)
                        {
                            if (Multiplayer.Session.PowerTowers.AddRequested(_this.planet.id, powerNetId, powerNodeId, false, false))
                            {
                                Multiplayer.Session.Network.SendPacket(new PowerTowerUserLoadingRequest(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick, false));
                            }
                        }
                        else
                        {
                            PowerNetwork pNet = _this.netPool[powerNetId];
                            if (Multiplayer.Session.PowerTowers.AddRequested(_this.planet.id, powerNetId, powerNodeId, false, false))
                            {
                                Multiplayer.Session.PowerTowers.RemExtraDemand(_this.planet.id, powerNetId, powerNodeId);
                                Multiplayer.Session.Network.SendPacketToLocalStar(new PowerTowerUserLoadingResponse(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick,
                                                                                                                    pNet.energyCapacity,
                                                                                                                    pNet.energyRequired,
                                                                                                                    pNet.energyServed,
                                                                                                                    pNet.energyAccumulated,
                                                                                                                    pNet.energyExchanged,
                                                                                                                    false));
                            }
                        }
                    }
                }));
            })
                   .InstructionEnumeration());
        }
Esempio n. 15
0
 /// <summary>
 /// Calls the update functions on the systems that are updated on a fixed frequency.
 /// </summary>
 /// <param name="deltaTime">Delta time.</param>
 private void TickFixedFrequency(float deltaTime)
 {
     PowerNetwork.Update(deltaTime);
     FluidNetwork.Update(deltaTime);
 }
Esempio n. 16
0
        public bool MinerComponent_InternalUpdate(PlanetFactory factory, VeinData[] veinPool, PowerNetwork powerNetwork, float power, float miningRate, float miningSpeed, int[] productRegister, MinerComponent minerComponent)
        {
            if (minerComponent.type != EMinerType.Vein)
            {
                return(false);
            }

            var plantPosition = factory.entityPool[minerComponent.entityId].pos;

            int      vpNum      = ((minerComponent.veinCount != 0) ? minerComponent.veins[minerComponent.currentVeinIndex] : 0);
            VeinData veinData   = veinPool[vpNum];
            string   veinName   = veinData.type.ToString();
            int      veinAmount = DSPStatisticsHelper.GetTotalVeinAmountForMineComponent(minerComponent, veinPool);

            var       signData  = factory.entitySignPool[minerComponent.entityId];
            ItemProto itemProto = signData.iconId0 != 0 ? LDB.items.Select((int)signData.iconId0) : null;

            var time = (int)(power * (float)minerComponent.speed * miningSpeed * (float)minerComponent.veinCount);

            float consumerRatio = ((powerNetwork == null || powerNetwork.id <= 0) ? 0f : ((float)powerNetwork.consumerRatio));

            // Debug.Log(factory.planet.displayName + " - " + __instance.entityId + ", " + veinName + ", " + __instance.workstate + ", VeinCount: " + __instance.veinCount + " VeinAmount: " + veinAmount + " | " + latlon);

            Texture2D texture = null;

            if (itemProto != null)
            {
                texture  = itemProto.iconSprite.texture;
                veinName = itemProto.name.Translate();
            }

            float  minutesToEmptyVein;
            string minutesToEmptyVeinTxt;
            var    miningRatePerMin = 0f;

            if (time == 0 || veinAmount == 0 || minerComponent.period == 0)
            {
                minutesToEmptyVeinTxt = (veinAmount == 0) ? "Empty" : "Infinity";
                minutesToEmptyVein    = (veinAmount == 0) ? 0 : float.PositiveInfinity;
            }
            else
            {
                var miningTimePerSec          = minerComponent.period / (MineralExhaustionNotifier.timeStepsSecond);
                var secondsPerMiningOperation = (float)miningTimePerSec / (float)time;
                miningRatePerMin      = 60 / secondsPerMiningOperation;
                minutesToEmptyVein    = (float)Math.Round((float)veinAmount / miningRatePerMin, 0);
                minutesToEmptyVeinTxt = minutesToEmptyVein.ToString();
                if (minerComponent.workstate == EWorkState.Full)
                {
                    minutesToEmptyVeinTxt += " to ∞";
                }
                minutesToEmptyVeinTxt += " min"; // .ToString("0.0") + "每分钟".Translate();
            }
            var minerStat = new MinerNotificationDetail()
            {
                minerComponent        = minerComponent,
                entityId              = minerComponent.entityId,
                planetName            = factory.planet.displayName,
                itemProto             = itemProto,
                signType              = signData.signType,
                veinName              = veinName,
                veinAmount            = veinAmount,
                plantPosition         = plantPosition,
                factory               = factory,
                miningRate            = miningRate,
                time                  = time,
                period                = minerComponent.period,
                veinCount             = minerComponent.veinCount,
                miningRatePerMin      = miningRatePerMin,
                minutesToEmptyVein    = minutesToEmptyVein,
                minutesToEmptyVeinTxt = minutesToEmptyVeinTxt,
                resourceTexture       = texture,
                powerNetwork          = powerNetwork,
                consumerRatio         = consumerRatio
            };

            minerStats.Add(minerStat);

            return(true);
        }
Esempio n. 17
0
        public static IEnumerable <CodeInstruction> PowerSystem_GameTick_Transpiler(IEnumerable <CodeInstruction> instructions)
        {
            instructions = new CodeMatcher(instructions)
                           .MatchForward(true,
                                         new CodeMatch(OpCodes.Ldarg_0),
                                         new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), "nodePool")),
                                         new CodeMatch(OpCodes.Ldloc_S),
                                         new CodeMatch(OpCodes.Ldelema),
                                         new CodeMatch(OpCodes.Ldarg_0),
                                         new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), "nodePool")),
                                         new CodeMatch(OpCodes.Ldloc_S),
                                         new CodeMatch(OpCodes.Ldelema),
                                         new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerNodeComponent), "workEnergyPerTick")),
                                         new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(PowerNodeComponent), "requiredEnergy")))
                           .Advance(1)
                           .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0))
                           .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 58))
                           .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 22))
                           .Insert(HarmonyLib.Transpilers.EmitDelegate <PlayerChargesAtTower>((PowerSystem _this, int powerNodeId, int powerNetId) =>
            {
                if (SimulatedWorld.Initialized)
                {
                    if (!LocalPlayer.IsMasterClient)
                    {
                        _this.nodePool[powerNodeId].requiredEnergy = _this.nodePool[powerNodeId].idleEnergyPerTick;     // this gets added onto the known required energy by PowerTowerManager and PowerSystem_Patch
                        if (PowerTowerManager.AddRequested(_this.planet.id, powerNetId, powerNodeId, true, false))
                        {
                            LocalPlayer.SendPacket(new PowerTowerUserLoadingRequest(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick, true));
                        }
                    }
                    else
                    {
                        PowerNetwork pNet = _this.netPool[powerNetId];
                        if (PowerTowerManager.AddRequested(_this.planet.id, powerNetId, powerNodeId, true, false))
                        {
                            PowerTowerManager.AddExtraDemand(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick);
                            LocalPlayer.SendPacketToLocalStar(new PowerTowerUserLoadingResponse(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick,
                                                                                                pNet.energyCapacity,
                                                                                                pNet.energyRequired,
                                                                                                pNet.energyServed,
                                                                                                pNet.energyAccumulated,
                                                                                                pNet.energyExchanged,
                                                                                                true));
                        }
                    }
                }
            }))
                           // now search for where its set back to idle after player leaves radius / has charged fully
                           .MatchForward(true,
                                         new CodeMatch(OpCodes.Ldarg_0),
                                         new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), "nodePool")),
                                         new CodeMatch(OpCodes.Ldloc_S),
                                         new CodeMatch(OpCodes.Ldelema),
                                         new CodeMatch(OpCodes.Ldarg_0),
                                         new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerSystem), "nodePool")),
                                         new CodeMatch(OpCodes.Ldloc_S),
                                         new CodeMatch(OpCodes.Ldelema),
                                         new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PowerNodeComponent), "idleEnergyPerTick")),
                                         new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(PowerNodeComponent), "requiredEnergy")))
                           .Repeat(matcher =>
            {
                matcher
                .Advance(1)
                .InsertAndAdvance(new CodeInstruction(OpCodes.Ldarg_0))
                .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 58))
                .InsertAndAdvance(new CodeInstruction(OpCodes.Ldloc_S, 22))
                .Insert(HarmonyLib.Transpilers.EmitDelegate <PlayerChargesAtTower>((PowerSystem _this, int powerNodeId, int powerNetId) =>
                {
                    if (SimulatedWorld.Initialized)
                    {
                        if (!LocalPlayer.IsMasterClient)
                        {
                            if (PowerTowerManager.AddRequested(_this.planet.id, powerNetId, powerNodeId, false, false))
                            {
                                LocalPlayer.SendPacket(new PowerTowerUserLoadingRequest(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick, false));
                            }
                        }
                        else
                        {
                            PowerNetwork pNet = _this.netPool[powerNetId];
                            if (PowerTowerManager.AddRequested(_this.planet.id, powerNetId, powerNodeId, false, false))
                            {
                                PowerTowerManager.RemExtraDemand(_this.planet.id, powerNetId, powerNodeId);
                                LocalPlayer.SendPacketToLocalStar(new PowerTowerUserLoadingResponse(_this.planet.id, powerNetId, powerNodeId, _this.nodePool[powerNodeId].workEnergyPerTick,
                                                                                                    pNet.energyCapacity,
                                                                                                    pNet.energyRequired,
                                                                                                    pNet.energyServed,
                                                                                                    pNet.energyAccumulated,
                                                                                                    pNet.energyExchanged,
                                                                                                    false));
                            }
                        }
                    }
                }));
            })
                           .InstructionEnumeration();

            return(instructions);
        }