public override void OnStart(PartModule.StartState state)
        {
            if (state == StartState.Editor)
            {
                return;
            }

            generators = vessel.FindPartModulesImplementing <FNGenerator>();
            receivers  = vessel.FindPartModulesImplementing <MicrowavePowerReceiver>();
            panels     = vessel.FindPartModulesImplementing <ModuleDeployableSolarPanel>();
            if (part.FindModulesImplementing <MicrowavePowerReceiver>().Count == 1)
            {
                part_receiver = part.FindModulesImplementing <MicrowavePowerReceiver>().First();
                has_receiver  = true;
            }

            anim = part.FindModelAnimators(animName).FirstOrDefault();
            if (anim != null)
            {
                anim[animName].layer = 1;
                if (!IsEnabled)
                {
                    anim[animName].normalizedTime = 1f;
                    anim[animName].speed          = -1f;
                }
                else
                {
                    anim[animName].normalizedTime = 0f;
                    anim[animName].speed          = 1f;
                }
                anim.Play();
            }

            this.part.force_activate();
        }
        public override void OnStart(PartModule.StartState state) {
            if (state == StartState.Editor) { return; }

            generators = vessel.FindPartModulesImplementing<FNGenerator>();
            receivers = vessel.FindPartModulesImplementing<MicrowavePowerReceiver>();
            panels = vessel.FindPartModulesImplementing<ModuleDeployableSolarPanel>();
            if (part.FindModulesImplementing<MicrowavePowerReceiver>().Count == 1) {
                part_receiver = part.FindModulesImplementing<MicrowavePowerReceiver>().First();
                has_receiver = true;
            }

            anim = part.FindModelAnimators(animName).FirstOrDefault();
            if (anim != null) {
                anim[animName].layer = 1;
                if (!IsEnabled) {
                    anim[animName].normalizedTime = 1f;
                    anim[animName].speed = -1f;

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

                }
                anim.Play();
            }

            this.part.force_activate();
        }
        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();
            }
        }