From 98b2dba84a18d7facb095ec6c6e615e615e13e97 Mon Sep 17 00:00:00 2001 From: KSP-TaxiService Date: Sun, 16 Jul 2017 00:30:09 +0800 Subject: [PATCH] Correct CommPower combination and apply UI and code improvements --- .../CommNetLayer/CNCCommNetVessel.cs | 49 +++++++++++++------ .../CommNetLayer/CNCCommNetwork.cs | 29 +++++------ src/CommNetConstellation/UI/UIUtils.cs | 19 +++++-- .../UI/VesselMgtTools/AntennaTool.cs | 2 +- .../UI/VesselSetupDialog.cs | 38 ++++++++++---- 5 files changed, 93 insertions(+), 44 deletions(-) diff --git a/src/CommNetConstellation/CommNetLayer/CNCCommNetVessel.cs b/src/CommNetConstellation/CommNetLayer/CNCCommNetVessel.cs index d3409e7..fa85527 100644 --- a/src/CommNetConstellation/CommNetLayer/CNCCommNetVessel.cs +++ b/src/CommNetConstellation/CommNetLayer/CNCCommNetVessel.cs @@ -18,6 +18,8 @@ public void KSPEventVesselSetup() { new VesselSetupDialog("Vessel - Communication", this.vessel, null).launch(); } + + //TODO: check if can spawn vesselsetupdialog with pure data? } /// @@ -94,7 +96,7 @@ protected override void OnNetworkInitialized() try { validateAndUpgrade(this.Vessel); - OnAntennaChange(); + rebuildFreqList(true); } catch (Exception e) { @@ -198,31 +200,46 @@ protected List readAntennaData() /// protected Dictionary buildFrequencyList(List antennas) { - Dictionary freqDict = new Dictionary(); - Dictionary powerDict = new Dictionary(); - - const int COMINDEX = 0; - const int MAXINDEX = 1; + Dictionary> combinepowerFreqDict = new Dictionary>(); + Dictionary> expoFreqDict = new Dictionary>(); + Dictionary noncombinepowerDict = new Dictionary(); + List allFreqs = new List(); //read each antenna - for(int i=0; i { }); + expoFreqDict.Add(thisFreq, new List { }); + 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 freqDict = new Dictionary(); + 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; @@ -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; } @@ -302,6 +320,7 @@ public bool isFreqListEditable() public void OnAntennaChange() { this.vesselAntennas = readAntennaData(); + isFreqListEditable(); switch (this.FreqListOperation) { diff --git a/src/CommNetConstellation/CommNetLayer/CNCCommNetwork.cs b/src/CommNetConstellation/CommNetLayer/CNCCommNetwork.cs index 788a803..b3ee888 100644 --- a/src/CommNetConstellation/CommNetLayer/CNCCommNetwork.cs +++ b/src/CommNetConstellation/CommNetLayer/CNCCommNetwork.cs @@ -28,9 +28,16 @@ public static bool AreSame(CommNode a, CommNode b) /// 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 aFreqs, bFreqs; - //each CommNode has at least frequency? + //each CommNode has at least some frequencies? try { aFreqs = CNCCommNetScenario.Instance.getFrequencies(a); @@ -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); diff --git a/src/CommNetConstellation/UI/UIUtils.cs b/src/CommNetConstellation/UI/UIUtils.cs index 3d94260..22e6e49 100644 --- a/src/CommNetConstellation/UI/UIUtils.cs +++ b/src/CommNetConstellation/UI/UIUtils.cs @@ -177,16 +177,25 @@ public static string Concatenate(IEnumerable source, string delimiter) /// /// Round a given number to nearest metric factor /// - 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); } } } diff --git a/src/CommNetConstellation/UI/VesselMgtTools/AntennaTool.cs b/src/CommNetConstellation/UI/VesselMgtTools/AntennaTool.cs index 30d5e92..9ee9137 100644 --- a/src/CommNetConstellation/UI/VesselMgtTools/AntennaTool.cs +++ b/src/CommNetConstellation/UI/VesselMgtTools/AntennaTool.cs @@ -38,7 +38,7 @@ public override List 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("({1})", 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); diff --git a/src/CommNetConstellation/UI/VesselSetupDialog.cs b/src/CommNetConstellation/UI/VesselSetupDialog.cs index 9ca6544..b493e2e 100644 --- a/src/CommNetConstellation/UI/VesselSetupDialog.cs +++ b/src/CommNetConstellation/UI/VesselSetupDialog.cs @@ -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 updateCallback; private DialogGUIVerticalLayout frequencyRowLayout; private ToolContentManagement toolMgt; @@ -39,14 +42,17 @@ public VesselSetupDialog(string title, Vessel vessel, Callback 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(); } @@ -61,13 +67,22 @@ protected override List drawContentComponents() //frequency list listComponments.Add(new DialogGUILabel("Active frequencies", 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)); @@ -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("({1})", 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 }); } @@ -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); } }