public MicrowaveRoute(double efficiency, double distance, double facingFactor, VesselRelayPersistence previousRelay=null) { Efficiency = efficiency; Distance = distance; FacingFactor = facingFactor; PreviousRelay = previousRelay; }
public static VesselRelayPersistence getVesselRelayPersistenceForVessel(Vessel vessel) { // find all active tranmitters configured for relay List <MicrowavePowerTransmitter> relays = vessel.FindPartModulesImplementing <MicrowavePowerTransmitter>().Where(m => m.IsRelay && m.IsEnabled).ToList(); var relay = new VesselRelayPersistence(vessel); relay.IsActive = relays.Count > 0; if (!relay.IsActive) { return(relay); } // Add guid if missing relays.ForEach(m => m.partId = string.IsNullOrEmpty(m.partId) ? Guid.NewGuid().ToString() : m.partId); relay.SupportedTransmitWavelengths.AddRange(relays.Select(m => new WaveLengthData() { partId = new Guid(m.partId), wavelength = m.Wavelength, isMirror = m.isMirror, atmosphericAbsorption = m.CombinedAtmosphericAbsorption }) .Distinct()); relay.Aperture = relays.Average(m => m.aperture) * Math.Sqrt(relays.Count); relay.PowerCapacity = relays.Sum(m => m.getPowerCapacity()); relay.MinimumRelayWavelenght = relays.Min(m => m.minimumRelayWavelenght); relay.MaximumRelayWavelenght = relays.Max(m => m.maximumRelayWavelenght); return(relay); }
protected double ComputeVisibilityAndDistance(VesselRelayPersistence r, Vessel v) { //return r.lineOfSightTo(v) ? Vector3d.Distance(PluginHelper.getVesselPos(r.getVessel()), PluginHelper.getVesselPos(v)) : -1; return(PluginHelper.HasLineOfSightWith(r.getVessel(), v, 0) ? Vector3d.Distance(PluginHelper.getVesselPos(r.getVessel()), PluginHelper.getVesselPos(v)) : -1); }
public MicrowaveRoute(double efficiency, double distance, double facingFactor, VesselRelayPersistence previousRelay = null) { Efficiency = efficiency; Distance = distance; FacingFactor = facingFactor; PreviousRelay = previousRelay; }
public static VesselRelayPersistence getVesselRelayPersistenceForVessel(Vessel vessel) { // find all active tranmitters configured for relay var relays = vessel.FindPartModulesImplementing <MicrowavePowerTransmitter>().Where(m => m.IsRelay || m.mergingBeams).ToList(); if (relays.Count == 0) { return(null); } var relayPersistance = new VesselRelayPersistence(vessel); relayPersistance.IsActive = true; if (relayPersistance.IsActive) { return(relayPersistance); } foreach (var relay in relays) { var transmitData = relayPersistance.SupportedTransmitWavelengths.FirstOrDefault(m => m.wavelength == relay.wavelength); if (transmitData == null) { // Add guid if missing relay.partId = string.IsNullOrEmpty(relay.partId) ? Guid.NewGuid().ToString() : relay.partId; relayPersistance.SupportedTransmitWavelengths.Add(new WaveLengthData() { partId = new Guid(relay.partId), count = 1, apertureSum = relay.aperture, powerCapacity = relay.power_capacity, wavelength = relay.Wavelength, minWavelength = relay.minimumRelayWavelenght, maxWavelength = relay.maximumRelayWavelenght, isMirror = relay.isMirror, atmosphericAbsorption = relay.CombinedAtmosphericAbsorption }); } else { transmitData.count++; transmitData.apertureSum += relay.aperture; transmitData.powerCapacity += relay.power_capacity; } } relayPersistance.Aperture = relays.Average(m => m.aperture) * Math.Sqrt(relays.Count); relayPersistance.PowerCapacity = relays.Sum(m => m.getPowerCapacity()); relayPersistance.MinimumRelayWavelenght = relays.Min(m => m.minimumRelayWavelenght); relayPersistance.MaximumRelayWavelenght = relays.Max(m => m.maximumRelayWavelenght); return(relayPersistance); }
public MicrowaveRoute(double efficiency, double distance, double facingFactor, double spotsize, double wavelength, VesselRelayPersistence previousRelay = null) { Efficiency = efficiency; Distance = distance; FacingFactor = facingFactor; PreviousRelay = previousRelay; Spotsize = spotsize; WaveLength = wavelength; }
public static VesselRelayPersistence getVesselRelayPersistanceForProtoVessel(Vessel vessel) { var relayVessel = new VesselRelayPersistence(vessel); int totalCount = 0; double totalAperture = 0; double totalPowerCapacity = 0; double minimumRelayWavelength = 1; double maximumRelayWavelenght = 0; foreach (var protopart in vessel.protoVessel.protoPartSnapshots) { foreach (var protomodule in protopart.modules) { if (protomodule.moduleName != "MicrowavePowerTransmitter") { continue; } bool inRelayMode = bool.Parse(protomodule.moduleValues.GetValue("relay")); bool isMergingBeams = false; if (protomodule.moduleValues.HasValue("mergingBeams")) { try { bool.TryParse(protomodule.moduleValues.GetValue("mergingBeams"), out isMergingBeams); } catch (Exception e) { UnityEngine.Debug.LogError("[KSPI] - Exception while reading mergingBeams" + e.Message); } } // filter on transmitters if (inRelayMode || isMergingBeams) { var wavelength = double.Parse(protomodule.moduleValues.GetValue("wavelength")); var isMirror = bool.Parse(protomodule.moduleValues.GetValue("isMirror")); var aperture = double.Parse(protomodule.moduleValues.GetValue("aperture")); var powerCapacity = double.Parse(protomodule.moduleValues.GetValue("power_capacity")); totalCount++; totalAperture += aperture; totalPowerCapacity += powerCapacity; var relayWavelenghtMin = double.Parse(protomodule.moduleValues.GetValue("minimumRelayWavelenght")); if (relayWavelenghtMin < minimumRelayWavelength) { minimumRelayWavelength = relayWavelenghtMin; } var relayWavelenghtMax = double.Parse(protomodule.moduleValues.GetValue("maximumRelayWavelenght")); if (relayWavelenghtMax > maximumRelayWavelenght) { maximumRelayWavelenght = relayWavelenghtMax; } var relayData = relayVessel.SupportedTransmitWavelengths.FirstOrDefault(m => m.wavelength == wavelength); if (relayData == null) { string partId = protomodule.moduleValues.GetValue("partId"); relayVessel.SupportedTransmitWavelengths.Add(new WaveLengthData() { partId = new Guid(partId), count = 1, apertureSum = aperture, powerCapacity = powerCapacity, wavelength = wavelength, minWavelength = relayWavelenghtMin, maxWavelength = relayWavelenghtMax, isMirror = isMirror, atmosphericAbsorption = double.Parse(protomodule.moduleValues.GetValue("atmosphericAbsorption")) }); } else { relayData.count++; relayData.apertureSum += aperture; relayData.powerCapacity += powerCapacity; } } } } relayVessel.Aperture = totalAperture; relayVessel.PowerCapacity = totalPowerCapacity; relayVessel.IsActive = totalCount > 0; relayVessel.MinimumRelayWavelenght = minimumRelayWavelength; relayVessel.MaximumRelayWavelenght = maximumRelayWavelenght; return(relayVessel); }
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 ComputeVisibilityAndDistance(VesselRelayPersistence r, Vessel v) { return r.lineOfSightTo(v) ? Vector3d.Distance(r.getVessel().transform.position, v.transform.position) : -1; }
/// <summary> /// Returns transmitters which to which this vessel can connect, route efficiency and relays used for each one. /// </summary> /// <param name="maxHops">Maximum number of relays which can be used for connection to transmitter</param> protected IDictionary <VesselMicrowavePersistence, KeyValuePair <double, IEnumerable <VesselRelayPersistence> > > GetConnectedTransmitters(int maxHops = 25) { //these two dictionaries store transmitters and relays and best currently known route to them which is replaced if better one is found. var transmitterRouteDictionary = new Dictionary <VesselMicrowavePersistence, MicrowaveRoute>(); var relayRouteDictionary = new Dictionary <VesselRelayPersistence, MicrowaveRoute>(); var transmittersToCheck = new List <VesselMicrowavePersistence>();//stores all transmiters to which we want to connect foreach (VesselMicrowavePersistence transmitter in MicrowaveSources.instance.transmitters.Values) { //first check for direct connection from current vessel to transmitters, will always be optimal if (transmitter.getAvailablePower() > 0) { //ignore if no power or transmitter is on the same vessel if (!isInlineReceiver || transmitter.getVessel() != vessel) { if (lineOfSightTo(transmitter.getVessel())) { double distance = ComputeDistance(vessel, transmitter.getVessel()); double facingFactor = ComputeFacingFactor(transmitter.getVessel()); double efficiency = ComputeTransmissionEfficiency(distance, facingFactor); transmitterRouteDictionary[transmitter] = new MicrowaveRoute(efficiency, distance, facingFactor); //store in dictionary that optimal route to this transmitter is direct connection, can be replaced if better route is found } transmittersToCheck.Add(transmitter); } } } //this algorithm processes relays in groups in which elements of the first group must be visible from receiver, //elements from the second group must be visible by at least one element from previous group and so on... var relaysToCheck = new List <VesselRelayPersistence>(); //relays which we have to check - all active relays will be here var currentRelayGroup = new List <KeyValuePair <VesselRelayPersistence, int> >(); //relays which are in line of sight, and we have not yet checked what they can see. Their index in relaysToCheck is also stored int relayIndex = 0; foreach (VesselRelayPersistence relay in MicrowaveSources.instance.relays.Values) { if (relay.isActive()) { if (lineOfSightTo(relay.getVessel())) { double distance = ComputeDistance(vessel, relay.getVessel()); double facingFactor = ComputeFacingFactor(relay.getVessel()); double efficiency = ComputeTransmissionEfficiency(distance, facingFactor); relayRouteDictionary[relay] = new MicrowaveRoute(efficiency, distance, facingFactor);//store in dictionary that optimal route to this relay is direct connection, can be replaced if better route is found currentRelayGroup.Add(new KeyValuePair <VesselRelayPersistence, int>(relay, relayIndex)); } relaysToCheck.Add(relay); relayIndex++; } } int hops = 0; //number of hops between relays //pre-compute distances and visibility thus limiting number of checks to (Nr^2)/2 + NrNt +Nr + Nt if (hops < maxHops && transmittersToCheck.Any()) { double[,] relayToRelayDistances = new double[relaysToCheck.Count, relaysToCheck.Count]; double[,] relayToTransmitterDistances = new double[relaysToCheck.Count, transmittersToCheck.Count]; for (int i = 0; i < relaysToCheck.Count; i++) { var relay = relaysToCheck[i]; for (int j = i + 1; j < relaysToCheck.Count; j++) { double visibilityAndDistance = ComputeVisibilityAndDistance(relay, relaysToCheck[j].getVessel()); relayToRelayDistances[i, j] = visibilityAndDistance; relayToRelayDistances[j, i] = visibilityAndDistance; } for (int t = 0; t < transmittersToCheck.Count; t++) { relayToTransmitterDistances[i, t] = ComputeVisibilityAndDistance(relay, transmittersToCheck[t]. getVessel()); } } HashSet <int> coveredRelays = new HashSet <int>(); //runs as long as there is any relay to which we can connect and maximum number of hops have not been breached while (hops < maxHops && currentRelayGroup.Any()) { var nextRelayGroup = new List <KeyValuePair <VesselRelayPersistence, int> >(); //will put every relay which is in line of sight of any relay from currentRelayGroup here foreach (var relayEntry in currentRelayGroup) //relays visible from receiver in first iteration, then relays visible from them etc.... { var relay = relayEntry.Key; MicrowaveRoute relayRoute = relayRouteDictionary[relay]; // current best route for this relay double relayRouteFacingFactor = relayRoute.FacingFactor; // it's always facing factor from the beggining of the route for (int t = 0; t < transmittersToCheck.Count; t++) //check if this relay can connect to transmitters { var transmitter = transmittersToCheck[t]; double transmitterDistance = relayToTransmitterDistances[relayEntry.Value, t]; if (transmitterDistance > 0) //it's >0 if it can see { double newDistance = relayRoute.Distance + transmitterDistance; // total distance from receiver by this relay to transmitter double efficiencyByThisRelay = ComputeTransmissionEfficiency(newDistance, relayRouteFacingFactor); //efficiency MicrowaveRoute currentOptimalRoute; //this will return true if there is already a route to this transmitter if (transmitterRouteDictionary.TryGetValue(transmitter, out currentOptimalRoute)) { if (currentOptimalRoute.Efficiency < efficiencyByThisRelay) { //if route using this relay is better then replace the old route transmitterRouteDictionary[transmitter] = new MicrowaveRoute(efficiencyByThisRelay, newDistance, relayRouteFacingFactor, relay); } } else { //there is no other route to this transmitter yet known so algorithm puts this one as optimal transmitterRouteDictionary[transmitter] = new MicrowaveRoute(efficiencyByThisRelay, newDistance, relayRouteFacingFactor, relay); } } } for (int r = 0; r < relaysToCheck.Count; r++) { var nextRelay = relaysToCheck[r]; if (nextRelay == relay) { continue; } double distanceToNextRelay = relayToRelayDistances[relayEntry.Value, r]; if (distanceToNextRelay > 0) //any relay which is in LOS of this relay { double relayToNextRelayDistance = relayRoute.Distance + distanceToNextRelay; double efficiencyByThisRelay = ComputeTransmissionEfficiency(relayToNextRelayDistance, relayRouteFacingFactor); MicrowaveRoute currentOptimalPredecessor; if (relayRouteDictionary.TryGetValue(nextRelay, out currentOptimalPredecessor)) //this will return true if there is already a route to next relay { if (currentOptimalPredecessor.Efficiency < efficiencyByThisRelay) { //if route using this relay is better relayRouteDictionary[nextRelay] = new MicrowaveRoute(efficiencyByThisRelay, relayToNextRelayDistance, relayRoute.FacingFactor, relay); } //we put it in dictionary as optimal } else //there is no other route to this relay yet known so we put this one as optimal { relayRouteDictionary[nextRelay] = new MicrowaveRoute(efficiencyByThisRelay, relayToNextRelayDistance, relayRoute.FacingFactor, relay); } if (!coveredRelays.Contains(r)) { nextRelayGroup.Add(new KeyValuePair <VesselRelayPersistence, int>(nextRelay, r)); //in next iteration we will check what next relay can see coveredRelays.Add(r); } } } } currentRelayGroup = nextRelayGroup; //we don't have to check old relays so we just replace whole List hops++; } } //building final result var resultDictionary = new Dictionary <VesselMicrowavePersistence, KeyValuePair <double, IEnumerable <VesselRelayPersistence> > >(); foreach (var transmitterEntry in transmitterRouteDictionary) { Stack <VesselRelayPersistence> relays = new Stack <VesselRelayPersistence>();//Last in, first out so relay visible from receiver will always be first VesselRelayPersistence relay = transmitterEntry.Value.PreviousRelay; while (relay != null) { relays.Push(relay); relay = relayRouteDictionary[relay].PreviousRelay; } resultDictionary.Add(transmitterEntry.Key, new KeyValuePair <double, IEnumerable <VesselRelayPersistence> >(transmitterEntry.Value.Efficiency, relays)); } return(resultDictionary); //connectedTransmitters; }
protected double ComputeVisibilityAndDistance(VesselRelayPersistence r, Vessel v) { //return r.lineOfSightTo(v) ? Vector3d.Distance(PluginHelper.getVesselPos(r.getVessel()), PluginHelper.getVesselPos(v)) : -1; return PluginHelper.HasLineOfSightWith(r.getVessel(), v, 0) ? Vector3d.Distance(PluginHelper.getVesselPos(r.getVessel()), PluginHelper.getVesselPos(v)) : -1; }
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 ComputeVisibilityAndDistance(VesselRelayPersistence r, Vessel v) { return(r.lineOfSightTo(v) ? Vector3d.Distance(r.getVessel().transform.position, v.transform.position) : -1); }
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); } } } }
public static VesselRelayPersistence getVesselRelayPersistanceForProtoVessel(Vessel vessel) { var relay = new VesselRelayPersistence(vessel); int totalCount = 0; double totalAperture = 0; double totalPowerCapacity = 0; double minimumRelayWavelength = 1; double maximumRelayWavelenght = 0; foreach (var protopart in vessel.protoVessel.protoPartSnapshots) { foreach (var protomodule in protopart.modules) { if (protomodule.moduleName == "MicrowavePowerTransmitter") { bool isRelay = bool.Parse(protomodule.moduleValues.GetValue("relay")); bool IsEnabled = bool.Parse(protomodule.moduleValues.GetValue("IsEnabled")); // filter on transmitters if (IsEnabled && isRelay) { totalCount++; totalAperture += double.Parse(protomodule.moduleValues.GetValue("aperture")); totalPowerCapacity += double.Parse(protomodule.moduleValues.GetValue("power_capacity")); var relayWavelenghtMin = double.Parse(protomodule.moduleValues.GetValue("minimumRelayWavelenght")); if (relayWavelenghtMin < minimumRelayWavelength) { minimumRelayWavelength = relayWavelenghtMin; } var relayWavelenghtMax = double.Parse(protomodule.moduleValues.GetValue("maximumRelayWavelenght")); if (relayWavelenghtMax > maximumRelayWavelenght) { maximumRelayWavelenght = relayWavelenghtMax; } var wavelength = double.Parse(protomodule.moduleValues.GetValue("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); } if (!relay.SupportedTransmitWavelengths.Any(m => m.wavelength == wavelength)) { string partId = null; try { partId = 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); } } relay.SupportedTransmitWavelengths.Add(new WaveLengthData() { partId = partId == null ? Guid.Empty : new Guid(partId), wavelength = wavelength, isMirror = isMirror, atmosphericAbsorption = double.Parse(protomodule.moduleValues.GetValue("atmosphericAbsorption")) }); } } } } } relay.Aperture = totalAperture; relay.PowerCapacity = totalPowerCapacity; relay.IsActive = totalCount > 0; relay.MinimumRelayWavelenght = minimumRelayWavelength; relay.MaximumRelayWavelenght = maximumRelayWavelenght; return(relay); }