double penaltyFreeDistance = 1; //should be set to proper value by OnStart method #endregion Fields #region Methods 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 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); }
/// <summary> /// Collect anything that can act like a transmitter, including relays /// </summary> /// <param name="vessel"></param> /// <returns></returns> public static VesselMicrowavePersistence getVesselMicrowavePersistanceForProtoVessel(Vessel vessel) { var transmitter = new VesselMicrowavePersistence(vessel); int totalCount = 0; double totalAperture = 0.0; double totalNuclearPower = 0.0; double totalSolarPower = 0.0; double totalPowerCapacity = 0.0; foreach (var protopart in vessel.protoVessel.protoPartSnapshots) { foreach (var protomodule in protopart.modules) { if (protomodule.moduleName != "MicrowavePowerTransmitter") { continue; } // filter on active transmitters bool transmitterIsEnabled = bool.Parse(protomodule.moduleValues.GetValue("IsEnabled")); if (!transmitterIsEnabled) { continue; } var aperture = double.Parse(protomodule.moduleValues.GetValue("aperture")); var nuclearPower = double.Parse(protomodule.moduleValues.GetValue("nuclear_power")); var solarPower = double.Parse(protomodule.moduleValues.GetValue("solar_power")); var powerCapacity = double.Parse(protomodule.moduleValues.GetValue("power_capacity")); var wavelength = double.Parse(protomodule.moduleValues.GetValue("wavelength")); totalCount++; totalAperture += aperture; totalNuclearPower += nuclearPower; totalSolarPower += solarPower; totalPowerCapacity += powerCapacity; var transmitData = transmitter.SupportedTransmitWavelengths.FirstOrDefault(m => m.wavelength == wavelength); if (transmitData == null) { bool isMirror = bool.Parse(protomodule.moduleValues.GetValue("isMirror")); string partId = protomodule.moduleValues.GetValue("partId"); transmitter.SupportedTransmitWavelengths.Add(new WaveLengthData() { partId = new Guid(partId), count = 1, apertureSum = aperture, wavelength = wavelength, minWavelength = wavelength * 0.99, maxWavelength = wavelength * 1.01, isMirror = isMirror, nuclearPower = nuclearPower, solarPower = solarPower, powerCapacity = powerCapacity, atmosphericAbsorption = double.Parse(protomodule.moduleValues.GetValue("atmosphericAbsorption")) }); } else { transmitData.count++; transmitData.apertureSum += aperture; transmitData.nuclearPower += nuclearPower; transmitData.solarPower += solarPower; transmitData.powerCapacity += powerCapacity; } } } transmitter.Aperture = totalAperture; transmitter.NuclearPower = totalNuclearPower; transmitter.SolarPower = totalSolarPower; transmitter.PowerCapacity = totalPowerCapacity; transmitter.IsActive = totalCount > 0; return(transmitter); }
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>(); foreach (Vessel vess in FlightGlobals.Vessels) { String vesselID = vess.id.ToString(); if (vess.isActiveVessel == false && vess.vesselName.ToLower().IndexOf("debris") == -1) { ConfigNode config = PluginHelper.getPluginSaveFile(); 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 double getPowerFromSatellite(VesselMicrowavePersistence vmp) { if (received_power.ContainsKey(vmp.getVessel()) && receiverIsEnabled) { return received_power[vmp.getVessel()]; } return 0; }
protected double GetSatPower(VesselMicrowavePersistence transmitter, double efficiency) { double availablePower = transmitter.getAvailablePower(); return(availablePower * efficiency); }
uint counter = 0; // OnFixedUpdate cycle counter public override void OnFixedUpdate() { 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; } if (++counter % 10 == 1) // recalculate input once per 10 physics cycles. Relay route algorythm is too expensive { double total_power = 0; int activeSatsIncr = 0; connectedsatsi = 0; connectedrelaysi = 0; networkDepth = 0; 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; powerInputMegajoules = total_power / 1000.0 * GameConstants.microwave_dish_efficiency * atmosphericefficiency * receiptPower / 100.0f; powerInput = powerInputMegajoules * 1000.0f; } float animateTemp = (float)powerInputMegajoules / 3000; if (animateTemp > 1) { animateTemp = 1; } if (animT != null) { animT[animTName].normalizedTime = animateTemp; animT.Sample(); } if (!isThermalReceiver) { supplyFNResource(powerInputMegajoules * TimeWarp.fixedDeltaTime, FNResourceManager.FNRESOURCE_MEGAJOULES); double waste_heat_production = powerInputMegajoules / GameConstants.microwave_dish_efficiency * (1.0f - GameConstants.microwave_dish_efficiency); supplyFNResource(waste_heat_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 { connectedsatsi = 0; connectedrelaysi = 0; 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>(); foreach (Vessel vess in FlightGlobals.Vessels) { String vesselID = vess.id.ToString(); if (vess.isActiveVessel == false && vess.vesselName.ToLower().IndexOf("debris") == -1) { ConfigNode config = PluginHelper.getPluginSaveFile(); 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(); }
public void calculateTransmitters() { unloaded_counter++; foreach (var vessel in FlightGlobals.Vessels) { // if vessek is offloaded to rails, parse file system if (vessel.state == Vessel.State.INACTIVE) { if (unloaded_counter % 100 != 1) // sometimes rebuild unloaded vessels as transmitters and relays continue; // parse transmitter var trans_pers = new VesselMicrowavePersistence(vessel); trans_pers.setNuclearPower(MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel.protoVessel)); trans_pers.setSolarPower(MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel.protoVessel)); if (trans_pers.getAvailablePower() > 1.0) transmitters[vessel] = trans_pers; else transmitters.Remove(vessel); // parse relay var persistence = new VesselRelayPersistence(vessel); persistence.setActive(MicrowavePowerTransmitter.vesselIsRelay(vessel.protoVessel)); if (persistence.isActive()) relays[vessel] = persistence; else relays.Remove(vessel); continue; } // if vessel is dead if (vessel.state == Vessel.State.DEAD) { transmitters.Remove(vessel); relays.Remove(vessel); continue; } // if vessel is loaded var transes = vessel.FindPartModulesImplementing<MicrowavePowerTransmitter>(); if (transes.Count > 0) { var persistence = new VesselMicrowavePersistence(vessel); persistence.setNuclearPower(MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel)); persistence.setSolarPower(MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel)); if (persistence.getAvailablePower() > 1.0) transmitters[vessel] = persistence; else transmitters.Remove(vessel); } if (MicrowavePowerTransmitter.vesselIsRelay(vessel)) { var persistence = new VesselRelayPersistence(vessel); persistence.setActive(true); if (persistence.isActive()) relays[vessel] = persistence; else relays.Remove(vessel); } } }
public void calculateTransmitters() { unloaded_counter++; foreach (var vessel in FlightGlobals.Vessels) { // if vessek is offloaded to rails, parse file system if (vessel.state == Vessel.State.INACTIVE) { if (unloaded_counter % 100 != 1) // sometimes rebuild unloaded vessels as transmitters and relays { continue; } // parse transmitter var trans_pers = new VesselMicrowavePersistence(vessel); trans_pers.setNuclearPower(MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel.protoVessel)); trans_pers.setSolarPower(MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel.protoVessel)); if (trans_pers.getAvailablePower() > 1.0) { transmitters[vessel] = trans_pers; } else { transmitters.Remove(vessel); } // parse relay var persistence = new VesselRelayPersistence(vessel); persistence.setActive(MicrowavePowerTransmitter.vesselIsRelay(vessel.protoVessel)); if (persistence.isActive()) { relays[vessel] = persistence; } else { relays.Remove(vessel); } continue; } // if vessel is dead if (vessel.state == Vessel.State.DEAD) { transmitters.Remove(vessel); relays.Remove(vessel); continue; } // if vessel is loaded var transes = vessel.FindPartModulesImplementing <MicrowavePowerTransmitter>(); if (transes.Count > 0) { var persistence = new VesselMicrowavePersistence(vessel); persistence.setNuclearPower(MicrowavePowerTransmitter.getEnumeratedNuclearPowerForVessel(vessel)); persistence.setSolarPower(MicrowavePowerTransmitter.getEnumeratedSolarPowerForVessel(vessel)); if (persistence.getAvailablePower() > 1.0) { transmitters[vessel] = persistence; } else { transmitters.Remove(vessel); } } if (MicrowavePowerTransmitter.vesselIsRelay(vessel)) { var persistence = new VesselRelayPersistence(vessel); persistence.setActive(true); if (persistence.isActive()) { relays[vessel] = persistence; } else { relays.Remove(vessel); } } } }
/// <summary> /// Collect anything that can act like a transmitter, including relays /// </summary> /// <param name="vessel"></param> /// <returns></returns> public static VesselMicrowavePersistence getVesselMicrowavePersistanceForProtoVessel(Vessel vessel) { var transmitter = new VesselMicrowavePersistence(vessel); var totalCount = 0; var totalAperture = 0.0; var totalNuclearPower = 0.0; var totalSolarPower = 0.0; var totalPowerCapacity = 0.0; foreach (var protopart in vessel.protoVessel.protoPartSnapshots) { foreach (var protomodule in protopart.modules) { if (protomodule.moduleName == "MicrowavePowerTransmitter") { bool transmitterIsEnabled = bool.Parse(protomodule.moduleValues.GetValue("IsEnabled")); // filter on active transmitters if (transmitterIsEnabled) { totalCount++; totalAperture += double.Parse(protomodule.moduleValues.GetValue("aperture")); totalNuclearPower += double.Parse(protomodule.moduleValues.GetValue("nuclear_power")); totalSolarPower += double.Parse(protomodule.moduleValues.GetValue("solar_power")); totalPowerCapacity += double.Parse(protomodule.moduleValues.GetValue("power_capacity")); double wavelength = double.Parse(protomodule.moduleValues.GetValue("wavelength")); if (!transmitter.SupportedTransmitWavelengths.Any(m => m.wavelength == wavelength)) { bool isMirror = false; try { bool.TryParse(protomodule.moduleValues.GetValue("isMirror"), out isMirror); } catch (Exception e) { UnityEngine.Debug.LogError("[KSPI] - Exception while reading isMirror" + e.Message); } string partId = null; try { protomodule.moduleValues.GetValue("partId"); } catch (Exception e) { UnityEngine.Debug.LogError("[KSPI] - Exception while reading partId" + e.Message); } if (String.IsNullOrEmpty(partId)) { try { partId = Guid.NewGuid().ToString(); protomodule.moduleValues.SetValue("partId", partId, true); //UnityEngine.Debug.Log("[KSPI] - Writen partId " + partId); } catch (Exception e) { UnityEngine.Debug.LogError("[KSPI] - Exception while writing partId" + e.Message); } } transmitter.SupportedTransmitWavelengths.Add(new WaveLengthData() { partId = partId == null ? Guid.Empty : new Guid(partId), wavelength = wavelength, isMirror = isMirror, atmosphericAbsorption = double.Parse(protomodule.moduleValues.GetValue("atmosphericAbsorption")) }); } } } } } transmitter.Aperture = totalAperture; transmitter.NuclearPower = totalNuclearPower; transmitter.SolarPower = totalSolarPower; transmitter.PowerCapacity = totalPowerCapacity; transmitter.IsActive = totalCount > 0; return(transmitter); }