Skip to content

Commit

Permalink
Correct CommPower combination and apply UI and code improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
KSP-TaxiService committed Jul 15, 2017
1 parent ea716b2 commit 98b2dba
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 44 deletions.
49 changes: 34 additions & 15 deletions src/CommNetConstellation/CommNetLayer/CNCCommNetVessel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public void KSPEventVesselSetup()
{
new VesselSetupDialog("Vessel - <color=#00ff00>Communication</color>", this.vessel, null).launch();
}

//TODO: check if can spawn vesselsetupdialog with pure data?
}

/// <summary>
Expand Down Expand Up @@ -94,7 +96,7 @@ protected override void OnNetworkInitialized()
try
{
validateAndUpgrade(this.Vessel);
OnAntennaChange();
rebuildFreqList(true);
}
catch (Exception e)
{
Expand Down Expand Up @@ -198,31 +200,46 @@ protected List<CNCAntennaPartInfo> readAntennaData()
/// </summary>
protected Dictionary<short, double> buildFrequencyList(List<CNCAntennaPartInfo> antennas)
{
Dictionary<short, double> freqDict = new Dictionary<short, double>();
Dictionary<short, double[]> powerDict = new Dictionary<short, double[]>();

const int COMINDEX = 0;
const int MAXINDEX = 1;
Dictionary<short, List<double>> combinepowerFreqDict = new Dictionary<short, List<double>>();
Dictionary<short, List<double>> expoFreqDict = new Dictionary<short, List<double>>();
Dictionary<short, double> noncombinepowerDict = new Dictionary<short, double>();
List<short> allFreqs = new List<short>();

//read each antenna
for(int i=0; i<antennas.Count; i++)
for (int i=0; i<antennas.Count; i++)
{
if (!antennas[i].inUse || !antennas[i].canComm) // deselected or retracted
continue;

if(!powerDict.ContainsKey(antennas[i].frequency))//not found
powerDict.Add(antennas[i].frequency, new double[] { 0.0, 0.0 });
short thisFreq = antennas[i].frequency;

if (!allFreqs.Contains(thisFreq))//not found
{
allFreqs.Add(thisFreq);
combinepowerFreqDict.Add(thisFreq, new List<double> { });
expoFreqDict.Add(thisFreq, new List<double> { });
noncombinepowerDict.Add(thisFreq, 0.0);
}

if (antennas[i].antennaCombinable) // TODO: revise to best antenna power * (total power / best power) * avg(all expo)
powerDict[antennas[i].frequency][COMINDEX] += (powerDict[antennas[i].frequency][COMINDEX]==0.0) ? antennas[i].antennaPower : antennas[i].antennaCombinableExponent * antennas[i].antennaPower;
if (antennas[i].antennaCombinable)
{
expoFreqDict[thisFreq].Add(antennas[i].antennaPower*antennas[i].antennaCombinableExponent);
combinepowerFreqDict[thisFreq].Add(antennas[i].antennaPower);
}
else
powerDict[antennas[i].frequency][MAXINDEX] = Math.Max(powerDict[antennas[i].frequency][MAXINDEX], antennas[i].antennaPower);
{
noncombinepowerDict[thisFreq] = Math.Max(noncombinepowerDict[thisFreq], antennas[i].antennaPower);
}
}

//consolidate into vessel's list of frequencies and their com powers
foreach (short freq in powerDict.Keys)
Dictionary<short, double> freqDict = new Dictionary<short, double>();
foreach (short freq in allFreqs) // each freq
{
freqDict.Add(freq, powerDict[freq].Max());
//best antenna power * (total power / best power) ^ (sum(expo*power)/total power)
double weightedExpo = expoFreqDict[freq].Sum() / combinepowerFreqDict[freq].Sum();
double combinedPower = (combinepowerFreqDict[freq].Count == 0)? 0.0:combinepowerFreqDict[freq].Max() * Math.Pow((combinepowerFreqDict[freq].Sum() / combinepowerFreqDict[freq].Max()), weightedExpo);
freqDict.Add(freq, Math.Max(combinedPower, noncombinepowerDict[freq]));
}

return freqDict;
Expand Down Expand Up @@ -291,8 +308,9 @@ public bool isFreqListEditable()
if (this.FreqListOperation != CNCCommNetVessel.FrequencyListOperation.LockList)
return true;

ScreenMessage msg = new ScreenMessage("Note: Lock List mode is in effect.", CNCSettings.ScreenMessageDuration, ScreenMessageStyle.UPPER_LEFT);
ScreenMessage msg = new ScreenMessage(string.Format("CommNet Constellation: Frequency list of Vessel '{0}' is locked.", this.vessel.vesselName), CNCSettings.ScreenMessageDuration, ScreenMessageStyle.UPPER_LEFT);
ScreenMessages.PostScreenMessage(msg);

return false;
}

Expand All @@ -302,6 +320,7 @@ public bool isFreqListEditable()
public void OnAntennaChange()
{
this.vesselAntennas = readAntennaData();
isFreqListEditable();

switch (this.FreqListOperation)
{
Expand Down
29 changes: 15 additions & 14 deletions src/CommNetConstellation/CommNetLayer/CNCCommNetwork.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ public static bool AreSame(CommNode a, CommNode b)
/// </summary>
protected override bool SetNodeConnection(CommNode a, CommNode b)
{
//stop links between ground stations
if (a.isHome && b.isHome)
{
this.Disconnect(a, b, true);
return false;
}

List<short> aFreqs, bFreqs;

//each CommNode has at least frequency?
//each CommNode has at least some frequencies?
try
{
aFreqs = CNCCommNetScenario.Instance.getFrequencies(a);
Expand All @@ -50,23 +57,17 @@ protected override bool SetNodeConnection(CommNode a, CommNode b)
return false;
}

IRangeModel rangeModel = CNCCommNetScenario.RangeModel;
double longestRange = 0.0;

//update best comm power for each node
for (int i = 0; i < commonFreqs.Count(); i++)
{
short thisFreq = commonFreqs.ElementAt(i);
double thisRange = rangeModel.GetMaximumRange(CNCCommNetScenario.Instance.getCommPower(a, thisFreq), CNCCommNetScenario.Instance.getCommPower(b, thisFreq));
double aPower = CNCCommNetScenario.Instance.getCommPower(a, commonFreqs.ElementAt(i));
double bPower = CNCCommNetScenario.Instance.getCommPower(b, commonFreqs.ElementAt(i));

if (thisRange > longestRange)
longestRange = thisRange;
}
if (!a.isHome && a.antennaTransmit.power < aPower)
a.antennaTransmit.power = aPower;

//max range equal or exceed physical distance?
if (longestRange < Vector3.Distance(a.precisePosition, b.precisePosition))
{
this.Disconnect(a, b, true);
return false;
if (!b.isHome && b.antennaTransmit.power < bPower)
b.antennaTransmit.power = bPower;
}

return base.SetNodeConnection(a, b);
Expand Down
19 changes: 14 additions & 5 deletions src/CommNetConstellation/UI/UIUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,25 @@ public static string Concatenate<T>(IEnumerable<T> source, string delimiter)
/// <summary>
/// Round a given number to nearest metric factor
/// </summary>
public static string RoundToNearestMetricFactor(double number)
public static string RoundToNearestMetricFactor(double number, int decimalPlaces = 1)
{
string formatStr = "{0:0.0}";
if(decimalPlaces > 1)
{
formatStr = "{0:0.";
for (int i=0; i< decimalPlaces; i++)
formatStr += "0";
formatStr += "}";
}

if (number > Math.Pow(10, 9))
return string.Format("{0:0.0} G", number / Math.Pow(10, 9));
return string.Format(formatStr+" G", number / Math.Pow(10, 9));
else if (number > Math.Pow(10, 6))
return string.Format("{0:0.0} M", number / Math.Pow(10, 6));
return string.Format(formatStr+" M", number / Math.Pow(10, 6));
else if (number > Math.Pow(10, 3))
return string.Format("{0:0.0} k", number / Math.Pow(10, 3));
return string.Format(formatStr+" k", number / Math.Pow(10, 3));
else
return string.Format("{0:0.0}", number);
return string.Format(formatStr, number);
}
}
}
2 changes: 1 addition & 1 deletion src/CommNetConstellation/UI/VesselMgtTools/AntennaTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public override List<DialogGUIBase> getContentComponents()

DialogGUIToggle toggleBtn = new DialogGUIToggle(antennaInfo.inUse, "", delegate (bool b) { vesselAntennaSelected(b, antennaInfo); actionCallbacks[0](); }, 20, 32);
DialogGUILabel nameLabel = new DialogGUILabel(antennaInfo.name, style); nameLabel.size = new Vector2(160, 32);
DialogGUILabel comPowerLabel = new DialogGUILabel(string.Format("Com power: {0:0.00}", UIUtils.RoundToNearestMetricFactor(antennaInfo.antennaPower)), style); comPowerLabel.size = new Vector2(120, 32);
DialogGUILabel comPowerLabel = new DialogGUILabel(string.Format("Com power: {0}", UIUtils.RoundToNearestMetricFactor(antennaInfo.antennaPower, 2)), style); comPowerLabel.size = new Vector2(120, 32);
DialogGUILabel frequencyLabel = new DialogGUILabel(string.Format("(<color={0}>{1}</color>)", UIUtils.colorToHex(Constellation.getColor(antennaInfo.frequency)), antennaInfo.frequency), style); frequencyLabel.size = new Vector2(60, 32);
DialogGUILabel combinableLabel = new DialogGUILabel("Combinable: " + (antennaInfo.antennaCombinable ? "Yes" : "No") + "\nBroadcast: " + (antennaInfo.canComm ? "Yes" : "No"), style); combinableLabel.size = new Vector2(90, 32);

Expand Down
38 changes: 29 additions & 9 deletions src/CommNetConstellation/UI/VesselSetupDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public class VesselSetupDialog : AbstractDialog
private Vessel hostVessel; // could be null (in editor)
private string description = "Something";

private const string nofreqMessage = "No active frequency to broadcast!";
private UIStyle nofreqMessageStyle;

private Callback<Vessel> updateCallback;
private DialogGUIVerticalLayout frequencyRowLayout;
private ToolContentManagement toolMgt;
Expand All @@ -39,14 +42,17 @@ public VesselSetupDialog(string title, Vessel vessel, Callback<Vessel> updateCa
VanillaFreqTool vanillaTool = new VanillaFreqTool(this.hostVessel.connection, refreshFrequencyRows);
this.toolMgt.add(vanillaTool);

this.nofreqMessageStyle = new UIStyle();
this.nofreqMessageStyle.alignment = TextAnchor.MiddleCenter;
this.nofreqMessageStyle.fontStyle = FontStyle.Bold;
this.nofreqMessageStyle.normal = HighLogic.UISkin.label.normal;

this.GetInputLocks();
}

protected override void OnPreDismiss()
{
if(this.updateCallback != null)
this.updateCallback(this.hostVessel);

this.updateCallback?.Invoke(this.hostVessel);
this.ReleaseInputLocks();
}

Expand All @@ -61,13 +67,22 @@ protected override List<DialogGUIBase> drawContentComponents()

//frequency list
listComponments.Add(new DialogGUILabel("<b>Active frequencies</b>", false, false));
DialogGUIBase[] frequencyRows = new DialogGUIBase[vesselFrequencyList.Count + 1];
frequencyRows[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);
for (int i = 0; i < vesselFrequencyList.Count; i++)
DialogGUIBase[] frequencyRows;
if (vesselFrequencyList.Count == 0)
{
frequencyRows[i + 1] = createFrequencyRow(vesselFrequencyList[i]);
frequencyRows = new DialogGUIBase[2];
frequencyRows[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);
frequencyRows[1] = new DialogGUILabel(nofreqMessage, nofreqMessageStyle, true, false);
}
else
{
frequencyRows = new DialogGUIBase[vesselFrequencyList.Count + 1];
frequencyRows[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);
for (int i = 0; i < vesselFrequencyList.Count; i++)
{
frequencyRows[i + 1] = createFrequencyRow(vesselFrequencyList[i]);
}
}

frequencyRowLayout = new DialogGUIVerticalLayout(10, 100, 4, new RectOffset(5, 25, 5, 5), TextAnchor.UpperLeft, frequencyRows);
listComponments.Add(new DialogGUIScrollList(Vector2.one, false, true, frequencyRowLayout));

Expand All @@ -86,7 +101,7 @@ private DialogGUIHorizontalLayout createFrequencyRow(short freq)
DialogGUIImage colorImage = new DialogGUIImage(new Vector2(32, 32), Vector2.one, color, colorTexture);
DialogGUILabel nameLabel = new DialogGUILabel(name, 160, 12);
DialogGUILabel eachFreqLabel = new DialogGUILabel(string.Format("(<color={0}>{1}</color>)", UIUtils.colorToHex(color), freq), 70, 12);
DialogGUILabel freqPowerLabel = new DialogGUILabel(string.Format("Combined Comm Power: {0}", UIUtils.RoundToNearestMetricFactor(cncVessel.getMaxComPower(freq))), 180, 12);
DialogGUILabel freqPowerLabel = new DialogGUILabel(string.Format("Combined Comm Power: {0}", UIUtils.RoundToNearestMetricFactor(cncVessel.getMaxComPower(freq), 2)), 180, 12);
return new DialogGUIHorizontalLayout(true, false, 0, new RectOffset(), TextAnchor.MiddleLeft, new DialogGUIBase[] { colorImage, nameLabel, eachFreqLabel, freqPowerLabel });
}

Expand All @@ -101,6 +116,11 @@ private void refreshFrequencyRows()
frequencyRowLayout.AddChild(createFrequencyRow(vesselFrequencyList[i]));
}

if (vesselFrequencyList.Count == 0)
{
frequencyRowLayout.AddChild(new DialogGUILabel(nofreqMessage, nofreqMessageStyle, true, false));
}

registerLayoutComponents(frequencyRowLayout);
}
}
Expand Down

0 comments on commit 98b2dba

Please sign in to comment.