ModuleLimitedDataTransmitter: Scale packetResource with the throttle.
[AntennaRange.git] / ModuleLimitedDataTransmitter.cs
blob:a/ModuleLimitedDataTransmitter.cs -> blob:b/ModuleLimitedDataTransmitter.cs
--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -54,6 +54,10 @@
 	 * */
 	public class ModuleLimitedDataTransmitter : ModuleDataTransmitter, IScienceDataTransmitter, IAntennaRelay
 	{
+		// If true, use a fixed power cost at the configured value and degrade data rates instead of increasing power
+		// requirements.
+		public static bool fixedPowerCost;
+
 		// Stores the packetResourceCost as defined in the .cfg file.
 		protected float _basepacketResourceCost;
 
@@ -73,6 +77,9 @@
 		// and packetSize.
 		[KSPField(isPersistant = false)]
 		public float nominalRange;
+
+		[KSPField(isPersistant = false, guiActive = true, guiName = "Relay")]
+		public string UIrelayStatus;
 
 		[KSPField(isPersistant = false, guiActive = true, guiName = "Transmission Distance")]
 		public string UItransmitDistance;
@@ -291,7 +298,7 @@
 		// transmission fails (see CanTransmit).
 		protected void PreTransmit_SetPacketResourceCost()
 		{
-			if (this.transmitDistance <= this.nominalRange)
+			if (fixedPowerCost || this.transmitDistance <= this.nominalRange)
 			{
 				base.packetResourceCost = this._basepacketResourceCost;
 			}
@@ -308,7 +315,7 @@
 		// distance.  packetSize maxes out at _basepacketSize * maxDataFactor.
 		protected void PreTransmit_SetPacketSize()
 		{
-			if (this.transmitDistance >= this.nominalRange)
+			if (!fixedPowerCost && this.transmitDistance >= this.nominalRange)
 			{
 				base.packetSize = this._basepacketSize;
 			}
@@ -334,6 +341,11 @@
 		// Override ModuleDataTransmitter.CanTransmit to return false when transmission is not possible.
 		public new bool CanTransmit()
 		{
+			if (this.part == null || this.relay == null)
+			{
+				return false;
+			}
+
 			PartStates partState = this.part.State;
 			if (partState == PartStates.DEAD || partState == PartStates.DEACTIVATED)
 			{
@@ -382,6 +394,75 @@
 			}
 			else
 			{
+				Tools.PostDebugMessage(this, "{0} unable to transmit during TransmitData.", this.part.partInfo.title);
+
+				var logger = Tools.DebugLogger.New(this);
+
+				foreach (ModuleScienceContainer	scienceContainer in this.vessel.getModulesOfType<ModuleScienceContainer>())
+				{
+					logger.AppendFormat("Checking ModuleScienceContainer in {0}\n",
+						scienceContainer.part.partInfo.title);
+
+					if (
+						scienceContainer.capacity != 0 &&
+						scienceContainer.GetScienceCount() >= scienceContainer.capacity
+					)
+					{
+						logger.Append("\tInsufficient capacity, skipping.\n");
+						continue;
+					}
+
+					List<ScienceData> dataStored = new List<ScienceData>();
+
+					foreach (ScienceData data in dataQueue)
+					{
+						if (!scienceContainer.allowRepeatedSubjects && scienceContainer.HasData(data))
+						{
+							logger.Append("\tAlready contains subject and repeated subjects not allowed, skipping.\n");
+							continue;
+						}
+
+						logger.AppendFormat("\tAcceptable, adding data on subject {0}... ", data.subjectID);
+						if (scienceContainer.AddData(data))
+						{
+							logger.Append("done, removing from queue.\n");
+
+							dataStored.Add(data);
+						}
+						#if DEBUG
+						else
+						{
+							logger.Append("failed.\n");
+						}
+						#endif
+					}
+
+					dataQueue.RemoveAll(i => dataStored.Contains(i));
+
+					logger.AppendFormat("\t{0} data left in queue.", dataQueue.Count);
+				}
+
+				logger.Print();
+
+				if (dataQueue.Count > 0)
+				{
+					StringBuilder msg = new StringBuilder();
+
+					msg.Append('[');
+					msg.Append(this.part.partInfo.title);
+					msg.AppendFormat("]: {0} data items could not be saved: no space available in data containers.\n");
+					msg.Append("Data to be discarded:\n");
+
+					foreach (ScienceData data in dataQueue)
+					{
+						msg.AppendFormat("\n{0}\n", data.title);
+					}
+
+					ScreenMessages.PostScreenMessage(msg.ToString(), 4f, ScreenMessageStyle.UPPER_LEFT);
+
+					Tools.PostDebugMessage(msg.ToString());
+				}
+
 				this.PostCannotTransmitError ();
 			}
 
@@ -439,9 +520,36 @@
 		{
 			if (this.actionUIUpdate)
 			{
-				this.UItransmitDistance = Tools.MuMech_ToSI(this.transmitDistance) + "m";
-				this.UIpacketSize = this.CanTransmit() ? Tools.MuMech_ToSI(this.DataRate) + "MiT" : "N/A";
-				this.UIpacketCost = this.CanTransmit() ? Tools.MuMech_ToSI(this.DataResourceCost) + "E" : "N/A";
+				if (this.CanTransmit())
+				{
+					this.UIrelayStatus = string.Format("Connected via {0}", this.relay);
+					this.UItransmitDistance = Tools.MuMech_ToSI(this.transmitDistance) + "m";
+					this.UIpacketSize = Tools.MuMech_ToSI(this.DataRate) + "MiT";
+					this.UIpacketCost = Tools.MuMech_ToSI(this.DataResourceCost) + "E";
+				}
+				else
+				{
+					if (this.relay.firstOccludingBody == null)
+					{
+						this.UIrelayStatus = string.Intern("Out of range");
+					}
+					else
+					{
+						if (this.relay.losStatus == LineOfSightStatus.Blocked)
+						{
+							this.UIrelayStatus =
+								string.Format("Blocked by {0}", this.relay.firstOccludingBody.bodyName);
+						}
+						else if (this.relay.losStatus == LineOfSightStatus.Marginal)
+						{
+							this.UIrelayStatus =
+								string.Format("Almost blocked by {0}", this.relay.firstOccludingBody.bodyName);
+						}
+					}
+					this.UImaxTransmitDistance = "N/A";
+					this.UIpacketSize = "N/A";
+					this.UIpacketCost = "N/A";
+				}
 			}
 		}