Skip to content

Commit 98b2dba

Browse files
Correct CommPower combination and apply UI and code improvements
1 parent ea716b2 commit 98b2dba

File tree

5 files changed

+93
-44
lines changed

5 files changed

+93
-44
lines changed

src/CommNetConstellation/CommNetLayer/CNCCommNetVessel.cs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public void KSPEventVesselSetup()
1818
{
1919
new VesselSetupDialog("Vessel - <color=#00ff00>Communication</color>", this.vessel, null).launch();
2020
}
21+
22+
//TODO: check if can spawn vesselsetupdialog with pure data?
2123
}
2224

2325
/// <summary>
@@ -94,7 +96,7 @@ protected override void OnNetworkInitialized()
9496
try
9597
{
9698
validateAndUpgrade(this.Vessel);
97-
OnAntennaChange();
99+
rebuildFreqList(true);
98100
}
99101
catch (Exception e)
100102
{
@@ -198,31 +200,46 @@ protected List<CNCAntennaPartInfo> readAntennaData()
198200
/// </summary>
199201
protected Dictionary<short, double> buildFrequencyList(List<CNCAntennaPartInfo> antennas)
200202
{
201-
Dictionary<short, double> freqDict = new Dictionary<short, double>();
202-
Dictionary<short, double[]> powerDict = new Dictionary<short, double[]>();
203-
204-
const int COMINDEX = 0;
205-
const int MAXINDEX = 1;
203+
Dictionary<short, List<double>> combinepowerFreqDict = new Dictionary<short, List<double>>();
204+
Dictionary<short, List<double>> expoFreqDict = new Dictionary<short, List<double>>();
205+
Dictionary<short, double> noncombinepowerDict = new Dictionary<short, double>();
206+
List<short> allFreqs = new List<short>();
206207

207208
//read each antenna
208-
for(int i=0; i<antennas.Count; i++)
209+
for (int i=0; i<antennas.Count; i++)
209210
{
210211
if (!antennas[i].inUse || !antennas[i].canComm) // deselected or retracted
211212
continue;
212213

213-
if(!powerDict.ContainsKey(antennas[i].frequency))//not found
214-
powerDict.Add(antennas[i].frequency, new double[] { 0.0, 0.0 });
214+
short thisFreq = antennas[i].frequency;
215+
216+
if (!allFreqs.Contains(thisFreq))//not found
217+
{
218+
allFreqs.Add(thisFreq);
219+
combinepowerFreqDict.Add(thisFreq, new List<double> { });
220+
expoFreqDict.Add(thisFreq, new List<double> { });
221+
noncombinepowerDict.Add(thisFreq, 0.0);
222+
}
215223

216-
if (antennas[i].antennaCombinable) // TODO: revise to best antenna power * (total power / best power) * avg(all expo)
217-
powerDict[antennas[i].frequency][COMINDEX] += (powerDict[antennas[i].frequency][COMINDEX]==0.0) ? antennas[i].antennaPower : antennas[i].antennaCombinableExponent * antennas[i].antennaPower;
224+
if (antennas[i].antennaCombinable)
225+
{
226+
expoFreqDict[thisFreq].Add(antennas[i].antennaPower*antennas[i].antennaCombinableExponent);
227+
combinepowerFreqDict[thisFreq].Add(antennas[i].antennaPower);
228+
}
218229
else
219-
powerDict[antennas[i].frequency][MAXINDEX] = Math.Max(powerDict[antennas[i].frequency][MAXINDEX], antennas[i].antennaPower);
230+
{
231+
noncombinepowerDict[thisFreq] = Math.Max(noncombinepowerDict[thisFreq], antennas[i].antennaPower);
232+
}
220233
}
221234

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

228245
return freqDict;
@@ -291,8 +308,9 @@ public bool isFreqListEditable()
291308
if (this.FreqListOperation != CNCCommNetVessel.FrequencyListOperation.LockList)
292309
return true;
293310

294-
ScreenMessage msg = new ScreenMessage("Note: Lock List mode is in effect.", CNCSettings.ScreenMessageDuration, ScreenMessageStyle.UPPER_LEFT);
311+
ScreenMessage msg = new ScreenMessage(string.Format("CommNet Constellation: Frequency list of Vessel '{0}' is locked.", this.vessel.vesselName), CNCSettings.ScreenMessageDuration, ScreenMessageStyle.UPPER_LEFT);
295312
ScreenMessages.PostScreenMessage(msg);
313+
296314
return false;
297315
}
298316

@@ -302,6 +320,7 @@ public bool isFreqListEditable()
302320
public void OnAntennaChange()
303321
{
304322
this.vesselAntennas = readAntennaData();
323+
isFreqListEditable();
305324

306325
switch (this.FreqListOperation)
307326
{

src/CommNetConstellation/CommNetLayer/CNCCommNetwork.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,16 @@ public static bool AreSame(CommNode a, CommNode b)
2828
/// </summary>
2929
protected override bool SetNodeConnection(CommNode a, CommNode b)
3030
{
31+
//stop links between ground stations
32+
if (a.isHome && b.isHome)
33+
{
34+
this.Disconnect(a, b, true);
35+
return false;
36+
}
37+
3138
List<short> aFreqs, bFreqs;
3239

33-
//each CommNode has at least frequency?
40+
//each CommNode has at least some frequencies?
3441
try
3542
{
3643
aFreqs = CNCCommNetScenario.Instance.getFrequencies(a);
@@ -50,23 +57,17 @@ protected override bool SetNodeConnection(CommNode a, CommNode b)
5057
return false;
5158
}
5259

53-
IRangeModel rangeModel = CNCCommNetScenario.RangeModel;
54-
double longestRange = 0.0;
55-
60+
//update best comm power for each node
5661
for (int i = 0; i < commonFreqs.Count(); i++)
5762
{
58-
short thisFreq = commonFreqs.ElementAt(i);
59-
double thisRange = rangeModel.GetMaximumRange(CNCCommNetScenario.Instance.getCommPower(a, thisFreq), CNCCommNetScenario.Instance.getCommPower(b, thisFreq));
63+
double aPower = CNCCommNetScenario.Instance.getCommPower(a, commonFreqs.ElementAt(i));
64+
double bPower = CNCCommNetScenario.Instance.getCommPower(b, commonFreqs.ElementAt(i));
6065

61-
if (thisRange > longestRange)
62-
longestRange = thisRange;
63-
}
66+
if (!a.isHome && a.antennaTransmit.power < aPower)
67+
a.antennaTransmit.power = aPower;
6468

65-
//max range equal or exceed physical distance?
66-
if (longestRange < Vector3.Distance(a.precisePosition, b.precisePosition))
67-
{
68-
this.Disconnect(a, b, true);
69-
return false;
69+
if (!b.isHome && b.antennaTransmit.power < bPower)
70+
b.antennaTransmit.power = bPower;
7071
}
7172

7273
return base.SetNodeConnection(a, b);

src/CommNetConstellation/UI/UIUtils.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,25 @@ public static string Concatenate<T>(IEnumerable<T> source, string delimiter)
177177
/// <summary>
178178
/// Round a given number to nearest metric factor
179179
/// </summary>
180-
public static string RoundToNearestMetricFactor(double number)
180+
public static string RoundToNearestMetricFactor(double number, int decimalPlaces = 1)
181181
{
182+
string formatStr = "{0:0.0}";
183+
if(decimalPlaces > 1)
184+
{
185+
formatStr = "{0:0.";
186+
for (int i=0; i< decimalPlaces; i++)
187+
formatStr += "0";
188+
formatStr += "}";
189+
}
190+
182191
if (number > Math.Pow(10, 9))
183-
return string.Format("{0:0.0} G", number / Math.Pow(10, 9));
192+
return string.Format(formatStr+" G", number / Math.Pow(10, 9));
184193
else if (number > Math.Pow(10, 6))
185-
return string.Format("{0:0.0} M", number / Math.Pow(10, 6));
194+
return string.Format(formatStr+" M", number / Math.Pow(10, 6));
186195
else if (number > Math.Pow(10, 3))
187-
return string.Format("{0:0.0} k", number / Math.Pow(10, 3));
196+
return string.Format(formatStr+" k", number / Math.Pow(10, 3));
188197
else
189-
return string.Format("{0:0.0}", number);
198+
return string.Format(formatStr, number);
190199
}
191200
}
192201
}

src/CommNetConstellation/UI/VesselMgtTools/AntennaTool.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public override List<DialogGUIBase> getContentComponents()
3838

3939
DialogGUIToggle toggleBtn = new DialogGUIToggle(antennaInfo.inUse, "", delegate (bool b) { vesselAntennaSelected(b, antennaInfo); actionCallbacks[0](); }, 20, 32);
4040
DialogGUILabel nameLabel = new DialogGUILabel(antennaInfo.name, style); nameLabel.size = new Vector2(160, 32);
41-
DialogGUILabel comPowerLabel = new DialogGUILabel(string.Format("Com power: {0:0.00}", UIUtils.RoundToNearestMetricFactor(antennaInfo.antennaPower)), style); comPowerLabel.size = new Vector2(120, 32);
41+
DialogGUILabel comPowerLabel = new DialogGUILabel(string.Format("Com power: {0}", UIUtils.RoundToNearestMetricFactor(antennaInfo.antennaPower, 2)), style); comPowerLabel.size = new Vector2(120, 32);
4242
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);
4343
DialogGUILabel combinableLabel = new DialogGUILabel("Combinable: " + (antennaInfo.antennaCombinable ? "Yes" : "No") + "\nBroadcast: " + (antennaInfo.canComm ? "Yes" : "No"), style); combinableLabel.size = new Vector2(90, 32);
4444

src/CommNetConstellation/UI/VesselSetupDialog.cs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ public class VesselSetupDialog : AbstractDialog
1414
private Vessel hostVessel; // could be null (in editor)
1515
private string description = "Something";
1616

17+
private const string nofreqMessage = "No active frequency to broadcast!";
18+
private UIStyle nofreqMessageStyle;
19+
1720
private Callback<Vessel> updateCallback;
1821
private DialogGUIVerticalLayout frequencyRowLayout;
1922
private ToolContentManagement toolMgt;
@@ -39,14 +42,17 @@ public VesselSetupDialog(string title, Vessel vessel, Callback<Vessel> updateCa
3942
VanillaFreqTool vanillaTool = new VanillaFreqTool(this.hostVessel.connection, refreshFrequencyRows);
4043
this.toolMgt.add(vanillaTool);
4144

45+
this.nofreqMessageStyle = new UIStyle();
46+
this.nofreqMessageStyle.alignment = TextAnchor.MiddleCenter;
47+
this.nofreqMessageStyle.fontStyle = FontStyle.Bold;
48+
this.nofreqMessageStyle.normal = HighLogic.UISkin.label.normal;
49+
4250
this.GetInputLocks();
4351
}
4452

4553
protected override void OnPreDismiss()
4654
{
47-
if(this.updateCallback != null)
48-
this.updateCallback(this.hostVessel);
49-
55+
this.updateCallback?.Invoke(this.hostVessel);
5056
this.ReleaseInputLocks();
5157
}
5258

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

6268
//frequency list
6369
listComponments.Add(new DialogGUILabel("<b>Active frequencies</b>", false, false));
64-
DialogGUIBase[] frequencyRows = new DialogGUIBase[vesselFrequencyList.Count + 1];
65-
frequencyRows[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);
66-
for (int i = 0; i < vesselFrequencyList.Count; i++)
70+
DialogGUIBase[] frequencyRows;
71+
if (vesselFrequencyList.Count == 0)
6772
{
68-
frequencyRows[i + 1] = createFrequencyRow(vesselFrequencyList[i]);
73+
frequencyRows = new DialogGUIBase[2];
74+
frequencyRows[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);
75+
frequencyRows[1] = new DialogGUILabel(nofreqMessage, nofreqMessageStyle, true, false);
76+
}
77+
else
78+
{
79+
frequencyRows = new DialogGUIBase[vesselFrequencyList.Count + 1];
80+
frequencyRows[0] = new DialogGUIContentSizer(ContentSizeFitter.FitMode.Unconstrained, ContentSizeFitter.FitMode.PreferredSize, true);
81+
for (int i = 0; i < vesselFrequencyList.Count; i++)
82+
{
83+
frequencyRows[i + 1] = createFrequencyRow(vesselFrequencyList[i]);
84+
}
6985
}
70-
7186
frequencyRowLayout = new DialogGUIVerticalLayout(10, 100, 4, new RectOffset(5, 25, 5, 5), TextAnchor.UpperLeft, frequencyRows);
7287
listComponments.Add(new DialogGUIScrollList(Vector2.one, false, true, frequencyRowLayout));
7388

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

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

119+
if (vesselFrequencyList.Count == 0)
120+
{
121+
frequencyRowLayout.AddChild(new DialogGUILabel(nofreqMessage, nofreqMessageStyle, true, false));
122+
}
123+
104124
registerLayoutComponents(frequencyRowLayout);
105125
}
106126
}

0 commit comments

Comments
 (0)