Changed to a direct set of the ModuleDataTransmitter packetSize and packetResourceCost instead of our previous attempt at a dynamic overload that wasn't working.
Changed to a direct set of the ModuleDataTransmitter packetSize and packetResourceCost instead of our previous attempt at a dynamic overload that wasn't working.

It seems to be working now!

/* /*
* AntennaRange © 2013 toadicus * AntennaRange © 2013 toadicus
* *
* AntennaRange provides incentive and requirements for the use of the various antenna parts. * AntennaRange provides incentive and requirements for the use of the various antenna parts.
* Nominally, the breakdown is as follows: * Nominally, the breakdown is as follows:
* *
* Communotron 16 - Suitable up to Kerbalsynchronous Orbit * Communotron 16 - Suitable up to Kerbalsynchronous Orbit
* Comms DTS-M1 - Suitable throughout the Kerbin subsystem * Comms DTS-M1 - Suitable throughout the Kerbin subsystem
* Communotron 88-88 - Suitable throughout the Kerbol system. * Communotron 88-88 - Suitable throughout the Kerbol system.
* *
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
* copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ * copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
* *
* This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike * This software uses the ModuleManager library © 2013 ialdabaoth, used under a Creative Commons Attribution-ShareAlike 3.0 Uported License.
* 3.0 Uported License.  
* *
*/ */
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using KSP; using KSP;
namespace AntennaRange namespace AntennaRange
{ {
/* /*
* ModuleLimitedDataTransmitter is designed as a drop-in replacement for ModuleDataTransmitter, and handles range- * ModuleLimitedDataTransmitter is designed as a drop-in replacement for ModuleDataTransmitter, and handles range-
* finding, power scaling, and data scaling for antennas during science transmission. Its functionality varies with * finding, power scaling, and data scaling for antennas during science transmission. Its functionality varies with
* three tunables: nominalRange, maxPowerFactor, and maxDataFactor, set in .cfg files. * three tunables: nominalRange, maxPowerFactor, and maxDataFactor, set in .cfg files.
* *
* In general, the scaling functions assume the following relation: * In general, the scaling functions assume the following relation:
* *
* D² α P/R, * D² α P/R,
* *
* where D is the total transmission distance, P is the transmission power, and R is the data rate. * where D is the total transmission distance, P is the transmission power, and R is the data rate.
* *
* */ * */
public class ModuleLimitedDataTransmitter : PartModule, IScienceDataTransmitter public class ModuleLimitedDataTransmitter : ModuleDataTransmitter, IScienceDataTransmitter
{ {
protected ModuleDataTransmitter dataTransmitter = null;  
   
// Stores the packetResourceCost as defined in the .cfg file. // Stores the packetResourceCost as defined in the .cfg file.
protected float _basepacketResourceCost; protected float _basepacketResourceCost;
// Stores the packetSize as defined in the .cfg file. // Stores the packetSize as defined in the .cfg file.
protected float _basepacketSize; protected float _basepacketSize;
// We don't have a Bard, so we're hiding Kerbin here. // We don't have a Bard, so we're hiding Kerbin here.
protected CelestialBody _Kerbin = null; protected CelestialBody _Kerbin;
// Returns the current distance to the center of Kerbin, which is totally where the Kerbals keep their radioes. // Returns the current distance to the center of Kerbin, which is totally where the Kerbals keep their radioes.
protected double transmitDistance protected double transmitDistance
{ {
get get
{ {
Vector3d KerbinPos = this._Kerbin.position; Vector3d KerbinPos = this._Kerbin.position;
Vector3d ActivePos = base.vessel.GetWorldPos3D(); Vector3d ActivePos = base.vessel.GetWorldPos3D();
return (ActivePos - KerbinPos).magnitude; return (ActivePos - KerbinPos).magnitude;
} }
} }
// Returns the maximum distance this module can transmit // Returns the maximum distance this module can transmit
public double maxTransmitDistance public double maxTransmitDistance
{ {
get get
{ {
return Math.Sqrt (this.maxPowerFactor) * this.nominalRange; return Math.Sqrt (this.maxPowerFactor) * this.nominalRange;
} }
} }
// The distance from Kerbin at which the antenna will perform exactly as prescribed by packetResourceCost // The distance from Kerbin at which the antenna will perform exactly as prescribed by packetResourceCost
// and packetSize. // and packetSize.
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public double nominalRange = 1500000d; public double nominalRange = 1500000d;
// The multiplier on packetResourceCost that defines the maximum power output of the antenna. When the power // The multiplier on packetResourceCost that defines the maximum power output of the antenna. When the power
// cost exceeds packetResourceCost * maxPowerFactor, transmission will fail. // cost exceeds packetResourceCost * maxPowerFactor, transmission will fail.
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public float maxPowerFactor = 8f; public float maxPowerFactor = 8f;
// The multipler on packetSize that defines the maximum data bandwidth of the antenna. // The multipler on packetSize that defines the maximum data bandwidth of the antenna.
[KSPField(isPersistant = false)] [KSPField(isPersistant = false)]
public float maxDataFactor = 4f; public float maxDataFactor = 4f;
public float DataRate  
{  
get  
{  
return dataTransmitter.DataRate;  
}  
}  
   
public double DataResourceCost  
{  
get  
{  
return dataTransmitter.DataRate;  
}  
}  
   
// Build ALL the objects. // Build ALL the objects.
public ModuleLimitedDataTransmitter () : base() public ModuleLimitedDataTransmitter () : base() { }
{  
dataTransmitter = new ModuleDataTransmitter (); public override void OnStart (StartState state)
} {
  base.OnStart (state);
public override void OnStart(PartModule.StartState state)  
{ if (state >= StartState.PreLaunch && this._Kerbin == null)
if (state >= PartModule.StartState.PreLaunch && this._Kerbin == null)  
{ {
// Go fetch Kerbin, because it is tricksy and hides from us. // Go fetch Kerbin, because it is tricksy and hides from us.
List<CelestialBody> bodies = FlightGlobals.Bodies; List<CelestialBody> bodies = FlightGlobals.Bodies;
foreach (CelestialBody body in bodies) foreach (CelestialBody body in bodies)
{ {
if (body.name == "Kerbin") if (body.name == "Kerbin")
{ {
this._Kerbin = body; this._Kerbin = body;
break; break;
} }
} }
} }
} }
public override void OnLoad(ConfigNode node) public override void OnLoad(ConfigNode node)
{ {
dataTransmitter.OnLoad (node); base.OnLoad (node);
this._basepacketSize = dataTransmitter.packetSize; this._basepacketSize = base.packetSize;
this._basepacketResourceCost = dataTransmitter.packetResourceCost; this._basepacketResourceCost = base.packetResourceCost;
} }
// Post an error in the communication messages describing the reason transmission has failed. Currently there // Post an error in the communication messages describing the reason transmission has failed. Currently there
// is only one reason for this. // is only one reason for this.
protected void PostCannotTransmitError() protected void PostCannotTransmitError()
{ {
string ErrorText = String.Format( string ErrorText = string.Format (
"Unable to transmit: out of range! Maximum range = {0}; Current range = {1}.", "Unable to transmit: out of range! Maximum range = {0}; Current range = {1}.",
this.maxTransmitDistance, this.maxTransmitDistance,
this.transmitDistance this.transmitDistance);
);  
ScreenMessages.PostScreenMessage (new ScreenMessage (ErrorText, 4f, ScreenMessageStyle.UPPER_LEFT)); ScreenMessages.PostScreenMessage (new ScreenMessage (ErrorText, 4f, ScreenMessageStyle.UPPER_LEFT));
} }
protected void PreTransmit_SetpacketSize() protected void PreTransmit_SetPacketResourceCost()
  {
  if (this.transmitDistance <= this.nominalRange)
  {
  base.packetResourceCost = this._basepacketResourceCost;
  }
  else
  {
  base.packetResourceCost = this._basepacketResourceCost
  * (float)Math.Pow (this.transmitDistance / this.nominalRange, 2);
  }
  }
   
  protected void PreTransmit_SetPacketSize()
{ {
if (this.transmitDistance >= this.nominalRange) if (this.transmitDistance >= this.nominalRange)
{ {
dataTransmitter.packetSize = this._basepacketSize; base.packetSize = this._basepacketSize;
} }
else else
{ {
// From above, data rate increases with the inverse square of the distance. base.packetSize = Math.Min (
dataTransmitter.packetSize = Math.Min(this._basepacketSize this._basepacketSize * (float)Math.Pow (this.nominalRange / this.transmitDistance, 2),
* (float)Math.Pow(this.nominalRange / this.transmitDistance, 2), this._basepacketSize * this.maxDataFactor);
this._basepacketSize * this.maxDataFactor);  
}  
}  
   
protected void PreTransmit_SetpacketResourceCost()  
{  
if (this.transmitDistance <= this.nominalRange)  
{  
dataTransmitter.packetResourceCost = this._basepacketResourceCost;  
}  
else  
{  
// From above, power increases with the square of the distance.  
dataTransmitter.packetResourceCost = this._basepacketResourceCost  
* (float)Math.Pow (this.transmitDistance / this.nominalRange, 2);  
} }
} }
// Override ModuleDataTransmitter.GetInfo to add nominal and maximum range to the VAB description. // Override ModuleDataTransmitter.GetInfo to add nominal and maximum range to the VAB description.
public override string GetInfo() public override string GetInfo()
{ {
string text = dataTransmitter.GetInfo(); string text = base.GetInfo();
text += "Nominal Range: " + this.nominalRange.ToString() + "\n"; text += "Nominal Range: " + this.nominalRange.ToString() + "\n";
text += "Maximum Range: " + this.maxTransmitDistance.ToString() + "\n"; text += "Maximum Range: " + this.maxTransmitDistance.ToString() + "\n";
return text; return text;
} }
// Override ModuleDataTransmitter.CanTransmit to return false when transmission is not possible. // Override ModuleDataTransmitter.CanTransmit to return false when transmission is not possible.
public bool CanTransmit() public new bool CanTransmit()
{ {
if (this.transmitDistance > this.maxTransmitDistance) if (this.transmitDistance > this.maxTransmitDistance)
{ {
return false; return false;
} }
return true; return true;
}  
   
public bool IsBusy()  
{  
return dataTransmitter.IsBusy ();  
} }
// Override ModuleDataTransmitter.TransmitData to check against CanTransmit and fail out when CanTransmit // Override ModuleDataTransmitter.TransmitData to check against CanTransmit and fail out when CanTransmit
// returns false. // returns false.
public void TransmitData(List<ScienceData> dataQueue) public new void TransmitData(List<ScienceData> dataQueue)
{ {
dataTransmitter.TransmitData(dataQueue); PreTransmit_SetPacketSize ();
// this.PreTransmit_SetpacketSize (); PreTransmit_SetPacketResourceCost ();
// this.PreTransmit_SetpacketResourceCost ();  
// Tools.PostDebugMessage (
// Tools.PostDebugMessage( "distance: " + this.transmitDistance
// "Attempting to TransmitData. Distance: " + this.transmitDistance.ToString() + " packetSize: " + this.packetSize
// + " packetSize: " + this.packetSize.ToString() + " packetResourceCost: " + this.packetResourceCost
// + " packetResourceCost: " + this.packetResourceCost.ToString() );
// ); if (this.CanTransmit())
// if (this.CanTransmit()) {
// { base.TransmitData(dataQueue);
// base.TransmitData(dataQueue); }
// } else
// else {
// { this.PostCannotTransmitError ();
// this.PostCannotTransmitError (); }
// }  
} }
// Override ModuleDataTransmitter.StartTransmission to check against CanTransmit and fail out when CanTransmit // Override ModuleDataTransmitter.StartTransmission to check against CanTransmit and fail out when CanTransmit
// returns false. // returns false.
[KSPEvent (guiName = "Transmit Data", active = true, guiActive = true)] public new void StartTransmission()
public void StartTransmission() {
{ PreTransmit_SetPacketSize ();
dataTransmitter.StartTransmission (); PreTransmit_SetPacketResourceCost ();
// this.PreTransmit_SetpacketSize ();  
// this.PreTransmit_SetpacketResourceCost (); Tools.PostDebugMessage (
// "distance: " + this.transmitDistance
// Tools.PostDebugMessage( + " packetSize: " + this.packetSize
// "Attempting to TransmitData. Distance: " + this.transmitDistance.ToString() + " packetResourceCost: " + this.packetResourceCost
// + " packetSize: " + this.packetSize.ToString() );
// + " packetResourceCost: " + this.packetResourceCost.ToString() if (this.CanTransmit())
// ); {
// if (this.CanTransmit()) base.StartTransmission();
// { }
// base.StartTransmission(); else
// } {
// else this.PostCannotTransmitError ();
// { }
// this.PostCannotTransmitError (); }
// }  
} #if DEBUG
  [KSPEvent (guiName = "Show Debug Info", active = true, guiActive = true)]
[KSPEvent (guiName = "Stop Transmitting", active = true, guiActive = true)] public void DebugInfo()
public void StopTransmission() {
{ PreTransmit_SetPacketSize ();
dataTransmitter.StopTransmission (); PreTransmit_SetPacketResourceCost ();
}  
  string msg = string.Format(
  "'{0}'\n" +
  "_basepacketSize: {1}\n" +
  "packetSize: {2}\n" +
  "_basepacketResourceCost: {3}\n" +
  "packetResourceCost: {4}\n" +
  "maxTransmitDistance: {5}\n" +
  "transmitDistance: {6}\n" +
  "nominalRange: {7}\n" +
  "CanTransmit: {8}",
  this.name,
  this._basepacketSize,
  base.packetSize,
  this._basepacketResourceCost,
  base.packetResourceCost,
  this.maxTransmitDistance,
  this.transmitDistance,
  this.nominalRange,
  this.CanTransmit()
  );
  ScreenMessages.PostScreenMessage (new ScreenMessage (msg, 30f, ScreenMessageStyle.UPPER_RIGHT));
  }
  #endif
} }
public static class Tools public static class Tools
{ {
[System.Diagnostics.Conditional("DEBUG")] [System.Diagnostics.Conditional("DEBUG")]
public static void PostDebugMessage(string Str) public static void PostDebugMessage(string Str)
{ {
ScreenMessage Message = new ScreenMessage (Str, 4f, ScreenMessageStyle.UPPER_RIGHT); ScreenMessage Message = new ScreenMessage (Str, 4f, ScreenMessageStyle.UPPER_RIGHT);
ScreenMessages.PostScreenMessage (Message); ScreenMessages.PostScreenMessage (Message);
} }
} }
} }