public static double getEnumeratedPowerFromSatelliteForAllVesssels(VesselMicrowavePersistence vmp)
        {
            double enumerated_power = 0;

            foreach (Vessel vess in FlightGlobals.Vessels)
            {
                List <MicrowavePowerReceiver> receivers = vess.FindPartModulesImplementing <MicrowavePowerReceiver>();
                foreach (MicrowavePowerReceiver receiver in receivers)
                {
                    enumerated_power += receiver.getPowerFromSatellite(vmp);
                }
            }
            return(enumerated_power);
        }
 protected double GetSatPower(VesselMicrowavePersistence transmitter, double efficiency)
 {
     double availablePower = transmitter.getAvailablePower();
     return availablePower * efficiency;
 }
        public static double getEnumeratedPowerFromSatelliteForAllVesssels(VesselMicrowavePersistence vmp)
        {

            double enumerated_power = 0;
            foreach (Vessel vess in FlightGlobals.Vessels)
            {
                List<MicrowavePowerReceiver> receivers = vess.FindPartModulesImplementing<MicrowavePowerReceiver>();
                foreach (MicrowavePowerReceiver receiver in receivers)
                {
                    enumerated_power += receiver.getPowerFromSatellite(vmp);
                }
            }
            return enumerated_power;
        }
 public double getPowerFromSatellite(VesselMicrowavePersistence vmp)
 {
     if (received_power.ContainsKey(vmp.getVessel()) && receiverIsEnabled)
     {
         return received_power[vmp.getVessel()];
     }
     return 0;
 }
        public override void OnStart(PartModule.StartState state)
        {
            String[] resources_to_supply = { FNResourceManager.FNRESOURCE_MEGAJOULES, FNResourceManager.FNRESOURCE_WASTEHEAT, FNResourceManager.FNRESOURCE_THERMALPOWER };
            this.resources_to_supply = resources_to_supply;
            base.OnStart(state);
            if (state == StartState.Editor) { return; }

            if (part.FindModulesImplementing<MicrowavePowerTransmitter>().Count == 1)
            {
                part_transmitter = part.FindModulesImplementing<MicrowavePowerTransmitter>().First();
                has_transmitter = true;
            }

            if (animTName != null)
            {
                animT = part.FindModelAnimators(animTName).FirstOrDefault();
                if (animT != null)
                {
                    animT[animTName].layer = 1;
                    animT[animTName].normalizedTime = 0f;
                    animT[animTName].speed = 0.001f;
                    animT.Play();
                }
            }

            if (animName != null)
            {
                anim = part.FindModelAnimators(animName).FirstOrDefault();
                if (anim != null)
                {
                    anim[animName].layer = 1;
                    if (connectedsatsi > 0 || connectedrelaysi > 0)
                    {
                        anim[animName].normalizedTime = 1f;
                        anim[animName].speed = -1f;

                    }
                    else
                    {
                        anim[animName].normalizedTime = 0f;
                        anim[animName].speed = 1f;

                    }
                    anim.Play();
                }
            }
            vmps = new List<VesselMicrowavePersistence>();
            vrps = new List<VesselRelayPersistence>();
            ConfigNode config = PluginHelper.getPluginSaveFile();
            foreach (Vessel vess in FlightGlobals.Vessels)
            {
                String vesselID = vess.id.ToString();

                if (vess.isActiveVessel == false && vess.vesselName.ToLower().IndexOf("debris") == -1)
                {
                    if (config.HasNode("VESSEL_MICROWAVE_POWER_" + vesselID))
                    {
                        ConfigNode power_node = config.GetNode("VESSEL_MICROWAVE_POWER_" + vesselID);
                        double nuclear_power = 0;
                        double solar_power = 0;
                        if (power_node.HasValue("nuclear_power"))
                        {
                            nuclear_power = double.Parse(power_node.GetValue("nuclear_power"));

                        }
                        if (power_node.HasValue("solar_power"))
                        {
                            solar_power = double.Parse(power_node.GetValue("solar_power"));
                        }
                        if (nuclear_power > 0 || solar_power > 0)
                        {
                            VesselMicrowavePersistence vmp = new VesselMicrowavePersistence(vess);
                            vmp.setSolarPower(solar_power);
                            vmp.setNuclearPower(nuclear_power);
                            vmps.Add(vmp);
                        }
                    }

                    if (config.HasNode("VESSEL_MICROWAVE_RELAY_" + vesselID))
                    {
                        ConfigNode relay_node = config.GetNode("VESSEL_MICROWAVE_RELAY_" + vesselID);
                        if (relay_node.HasValue("relay"))
                        {
                            bool relay = bool.Parse(relay_node.GetValue("relay"));
                            if (relay)
                            {
                                VesselRelayPersistence vrp = new VesselRelayPersistence(vess);
                                vrp.setActive(relay);
                                vrps.Add(vrp);
                            }
                        }
                    }
                }
            }
            penaltyFreeDistance = Math.Sqrt(1 / ((microwaveAngleTan * microwaveAngleTan) / collectorArea));

            this.part.force_activate();

        }
        protected double GetSatPower(VesselMicrowavePersistence transmitter, double efficiency)
        {
            double availablePower = transmitter.getAvailablePower();

            return(availablePower * efficiency);
        }
        public override void OnFixedUpdate()
        {
            int activeSatsIncr = 0;
            //int activeRelsIncr = 0;
            double total_power = 0;

            connectedsatsi   = 0;
            connectedrelaysi = 0;
            networkDepth     = 0;

            base.OnFixedUpdate();
            if (receiverIsEnabled)
            {
                if (getResourceBarRatio(FNResourceManager.FNRESOURCE_WASTEHEAT) >= 0.95 && !isThermalReceiver)
                {
                    receiverIsEnabled = false;
                    deactivate_timer++;
                    if (FlightGlobals.ActiveVessel == vessel && deactivate_timer > 2)
                    {
                        ScreenMessages.PostScreenMessage("Warning Dangerous Overheating Detected: Emergency microwave power shutdown occuring NOW!", 5.0f, ScreenMessageStyle.UPPER_CENTER);
                    }
                    return;
                }
                double atmosphericefficiency = Math.Exp(-FlightGlobals.getStaticPressure(vessel.transform.position) / 5);
                efficiency_d     = GameConstants.microwave_dish_efficiency * atmosphericefficiency;
                deactivate_timer = 0;


                HashSet <VesselRelayPersistence> usedRelays = new HashSet <VesselRelayPersistence>();
                //Transmitters power calculation
                foreach (var connectedTransmitterEntry in GetConnectedTransmitters())
                {
                    VesselMicrowavePersistence transmitter = connectedTransmitterEntry.Key;
                    Vessel transmitterVessel = connectedTransmitterEntry.Key.getVessel();
                    double routeEfficiency   = connectedTransmitterEntry.Value.Key;
                    IEnumerable <VesselRelayPersistence> relays = connectedTransmitterEntry.Value.Value;

                    received_power[transmitterVessel] = 0;

                    // calculate maximum power receivable from satellite
                    double satPowerCap           = transmitter.getAvailablePower() * efficiency_d;
                    double currentPowerFromSat   = MicrowavePowerReceiver.getEnumeratedPowerFromSatelliteForAllVesssels(transmitter);
                    double powerAvailableFromSat = (satPowerCap - currentPowerFromSat);
                    double satPower = Math.Min(GetSatPower(transmitter, routeEfficiency), powerAvailableFromSat); // get sat power and make sure we conserve enegy
                    received_power[transmitterVessel] = satPower * atmosphericefficiency;
                    total_power += satPower;
                    if (satPower > 0)
                    {
                        activeSatsIncr++;
                        if (relays != null)
                        {
                            foreach (var relay in relays)
                            {
                                usedRelays.Add(relay);
                            }
                            networkDepth = Math.Max(networkDepth, relays.Count());
                        }
                    }
                }


                connectedsatsi   = activeSatsIncr;
                connectedrelaysi = usedRelays.Count;

                double availPower = total_power / 1000.0 * GameConstants.microwave_dish_efficiency * atmosphericefficiency; // maximum available in network

                if (automode)
                {
                    // dynamicly configure power reception
                    List <Part> parts          = vessel.parts;                                                                   // lets find the maxPower in those part configs for each engine
                    double      eEnginePower   = 0;                                                                              //we'll save total electric engine power here
                    double      tEnginePower   = 0;                                                                              // and the thermal engine power here
                    double      vEnginePower   = 0;                                                                              // and now the vista engines
                    int         aRecieverCount = 0;                                                                              //count active recievers

                    var eEngines = FlightGlobals.ActiveVessel.FindPartModulesImplementing <ElectricEngineController>().ToList(); // Lets find the electric engines
                    foreach (ElectricEngineController engine in eEngines)
                    {
                        if (engine.isEnabled)                // if they are enabled
                        {
                            eEnginePower += engine.maxPower; // add thier demand together
                        }
                    }

                    var vEngines = FlightGlobals.ActiveVessel.FindPartModulesImplementing <VistaEngineController>().ToList(); // Lets find the vista engines
                    foreach (VistaEngineController vengine in vEngines)
                    {
                        if (vengine.isEnabled)                        // if they are enabled
                        {
                            vEnginePower += vengine.powerConsumption; // add thier demand together
                        }
                    }

                    var tEngines = FlightGlobals.ActiveVessel.FindPartModulesImplementing <FNNozzleController>().ToList(); // find the thermal nozzles
                    foreach (FNNozzleController engine in tEngines)
                    {
                        if (engine.IsEnabled)          // if they are enabled
                        {
                            tEnginePower = availPower; // max the power, since there is no power cap, and waste heat isn't an issue.
                        }
                    }

                    //var activeRecievers = FlightGlobals.ActiveVessel.FindPartModulesImplementing<MicrowavePowerReceiver>().ToList();
                    //foreach (MicrowavePowerReceiver receiver in activeRecievers)
                    //{
                    //    if (receiver)
                    //    {
                    //        aRecieverCount += 1; // count active recievers
                    //    }
                    //}

                    minDemand = getCurrentResourceDemand("Megajoules") + getCurrentResourceDemand("ElectricCharge"); // fallback for minimum demand
                    maxDemand = eEnginePower + vEnginePower + tEnginePower;                                          // the max draw of the engines

                    //if (aRecieverCount < 1) // handle divide by zero
                    //{
                    //    aRecieverCount = 1;
                    //}

                    // this needs to be fixed to only add power for one active reciever

                    //if throttled up, recieve the maximum of demand up to the maximum available power (ie. atmo, dist, angle, total supply)
                    if (FlightGlobals.ActiveVessel.ctrlState.mainThrottle > 0.0f)
                    {
                        powerInputMegajoules = ((Math.Min(maxDemand, availPower) - vEnginePower) * FlightGlobals.ActiveVessel.ctrlState.mainThrottle) + vEnginePower;
                    }
                    // else only recieve the minimum demand (just enough to keep the lights running) again, if enough available power
                    else
                    {
                        powerInputMegajoules = Math.Min(minDemand, availPower);
                    }
                }
                else
                {
                    powerInputMegajoules = availPower;
                }

                powerInput = powerInputMegajoules * 1000.0f * receiptPower / 100.0f;


                float animateTemp = (float)powerInputMegajoules / 3000;
                if (animateTemp > 1)
                {
                    animateTemp = 1;
                }

                if (animT != null)
                {
                    animT[animTName].speed          = 0.001f;
                    animT[animTName].normalizedTime = animateTemp;
                    animT.Blend(animTName, 2f);
                }

                if (!isThermalReceiver)
                {
                    supplyFNResource(powerInputMegajoules * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES);
                    double waste_head_production = powerInputMegajoules / GameConstants.microwave_dish_efficiency * (1.0f - GameConstants.microwave_dish_efficiency);
                    supplyFNResource(waste_head_production * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_WASTEHEAT);
                }
                else
                {
                    double cur_thermal_power = supplyFNResource(powerInputMegajoules * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_THERMALPOWER) / TimeWarp.fixedDeltaTime;
                    if (ThermalPower <= 0)
                    {
                        ThermalPower = (float)(cur_thermal_power);
                    }
                    else
                    {
                        ThermalPower = (float)(cur_thermal_power * GameConstants.microwave_alpha + (1.0f - GameConstants.microwave_alpha) * ThermalPower);
                    }
                }
            }
            else
            {
                received_power.Clear();
            }
        }
        public override void OnStart(PartModule.StartState state)
        {
            String[] resources_to_supply = { FNResourceManager.FNRESOURCE_MEGAJOULES, FNResourceManager.FNRESOURCE_WASTEHEAT, FNResourceManager.FNRESOURCE_THERMALPOWER };
            this.resources_to_supply = resources_to_supply;
            base.OnStart(state);
            if (state == StartState.Editor)
            {
                return;
            }

            if (part.FindModulesImplementing <MicrowavePowerTransmitter>().Count == 1)
            {
                part_transmitter = part.FindModulesImplementing <MicrowavePowerTransmitter>().First();
                has_transmitter  = true;
            }

            if (animTName != null)
            {
                animT = part.FindModelAnimators(animTName).FirstOrDefault();
                if (animT != null)
                {
                    animT[animTName].layer          = 1;
                    animT[animTName].normalizedTime = 0f;
                    animT[animTName].speed          = 0.001f;
                    animT.Play();
                }
            }

            if (animName != null)
            {
                anim = part.FindModelAnimators(animName).FirstOrDefault();
                if (anim != null)
                {
                    anim[animName].layer = 1;
                    if (connectedsatsi > 0 || connectedrelaysi > 0)
                    {
                        anim[animName].normalizedTime = 1f;
                        anim[animName].speed          = -1f;
                    }
                    else
                    {
                        anim[animName].normalizedTime = 0f;
                        anim[animName].speed          = 1f;
                    }
                    anim.Play();
                }
            }
            vmps = new List <VesselMicrowavePersistence>();
            vrps = new List <VesselRelayPersistence>();
            ConfigNode config = PluginHelper.getPluginSaveFile();

            foreach (Vessel vess in FlightGlobals.Vessels)
            {
                String vesselID = vess.id.ToString();

                if (vess.isActiveVessel == false && vess.vesselName.ToLower().IndexOf("debris") == -1)
                {
                    if (config.HasNode("VESSEL_MICROWAVE_POWER_" + vesselID))
                    {
                        ConfigNode power_node    = config.GetNode("VESSEL_MICROWAVE_POWER_" + vesselID);
                        double     nuclear_power = 0;
                        double     solar_power   = 0;
                        if (power_node.HasValue("nuclear_power"))
                        {
                            nuclear_power = double.Parse(power_node.GetValue("nuclear_power"));
                        }
                        if (power_node.HasValue("solar_power"))
                        {
                            solar_power = double.Parse(power_node.GetValue("solar_power"));
                        }
                        if (nuclear_power > 0 || solar_power > 0)
                        {
                            VesselMicrowavePersistence vmp = new VesselMicrowavePersistence(vess);
                            vmp.setSolarPower(solar_power);
                            vmp.setNuclearPower(nuclear_power);
                            vmps.Add(vmp);
                        }
                    }

                    if (config.HasNode("VESSEL_MICROWAVE_RELAY_" + vesselID))
                    {
                        ConfigNode relay_node = config.GetNode("VESSEL_MICROWAVE_RELAY_" + vesselID);
                        if (relay_node.HasValue("relay"))
                        {
                            bool relay = bool.Parse(relay_node.GetValue("relay"));
                            if (relay)
                            {
                                VesselRelayPersistence vrp = new VesselRelayPersistence(vess);
                                vrp.setActive(relay);
                                vrps.Add(vrp);
                            }
                        }
                    }
                }
            }
            penaltyFreeDistance = Math.Sqrt(1 / ((microwaveAngleTan * microwaveAngleTan) / collectorArea));

            this.part.force_activate();
        }