Skip to content

Commit d1f8003

Browse files
committed
Added copy to clipboard buttons, improved mass info
1 parent 1f757a1 commit d1f8003

5 files changed

Lines changed: 112 additions & 20 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ build/
1717
bld/
1818
[Bb]in/
1919
[Oo]bj/
20+
.vs/
2021

2122
# Roslyn cache directories
2223
*.ide/

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
0.2.0
2+
-----
3+
- Part mass information now include dry and wet (if part contain any resources) mass.
4+
- Added buttons: "copy part name to clipboard" and "copy part CFF node to clipboard". Could be useful for debug purposes.
5+
- Code improvements.
6+
17
0.1.1
28
-----
39
- Information in PAW menu is now properly updated, then part variant (B9PartSwitch) is changed.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
@PART[*]:HAS[@MODULE[ModuleEngines*]]:FOR[PartInfoInPAW]
1+
@PART[*]:FOR[zzzzzzzzPartInfoInPAW]
22
{
33
MODULE
44
{
55
name = ModulePartInfoInPAW
6-
originalPartName = #$../name$
76
}
87
}

src/Modules/PartInfoInPAW.cs

Lines changed: 98 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
1+
using System;
2+
using System.Linq;
3+
using UnityEngine;
4+
15
namespace PartInfoInPAW
26
{
3-
public class ModulePartInfoInPAW: PartModule
7+
public class ModulePartInfoInPAW : PartModule
48
{
5-
[KSPField(isPersistant = true)]
6-
public string originalPartName = "";
7-
89
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Name", groupName = "partInfo", groupDisplayName = "Part info")]
910
public string partName = "";
1011

11-
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Dry mass", groupName = "partInfo", groupDisplayName = "Part info", guiFormat = "F3", guiUnits = " t")]
12-
public float partMass = 0.0f;
12+
[KSPEvent(guiActive = false, guiActiveEditor = true, guiName = "Copy part name", active = true, groupName = "partInfo", groupDisplayName = "Part info")]
13+
public void CopyPartName()
14+
{
15+
GUIUtility.systemCopyBuffer = partName;
16+
}
17+
18+
[KSPEvent(guiActive = false, guiActiveEditor = true, guiName = "Copy part CFG node", active = true, groupName = "partInfo", groupDisplayName = "Part info")]
19+
public void CopyPartConfigNode()
20+
{
21+
GUIUtility.systemCopyBuffer = GetConfigNodeText();
22+
}
23+
24+
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Dry mass", groupName = "partInfo", groupDisplayName = "Part info")]
25+
public string partMass = "0 kg";
1326

14-
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Cost", groupName = "partInfo", groupDisplayName = "Part info")]
27+
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Cost", guiFormat = "F0", groupName = "partInfo", groupDisplayName = "Part info")]
1528
public float partCost = 0.0f;
1629

1730
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Entry cost", groupName = "partInfo", groupDisplayName = "Part info")]
1831
public int partEntryCost = 0;
1932

20-
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Engine TWR", groupName = "partInfo", groupDisplayName = "Part info", guiFormat = "F2")]
33+
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Engine TWR", guiFormat = "F3", groupName = "partInfo", groupDisplayName = "Part info")]
2134
public float partTWR = 0.0f;
2235

2336
[KSPField(isPersistant = false, guiActiveEditor = true, guiActive = false, guiName = "Info", groupName = "engine1Info", groupDisplayName = "Engine #1 info")]
@@ -55,22 +68,34 @@ public void Update()
5568
}
5669
}
5770

58-
public void UpdateInfo()
71+
private void UpdateInfo()
5972
{
73+
if (partName == "")
74+
{
75+
partName = GetPartName();
76+
}
6077
ModuleEngines[] engines;
6178
MultiModeEngine[] isMultimode;
6279
float totalThrust = 0.0f;
6380

64-
if (originalPartName != "")
81+
float prefabMass = part.partInfo.partPrefab.mass;
82+
float dryMass = prefabMass + part.GetModuleMass(prefabMass);
83+
float resMass = part.GetResourceMass();
84+
float wetMass = dryMass + resMass;
85+
if (Math.Abs(resMass) <= float.Epsilon)
6586
{
66-
partName = originalPartName;
87+
// Dry mass only
88+
Fields["partMass"].guiName = "Dry mass";
89+
partMass = FormatMass(dryMass);
6790
}
6891
else
6992
{
70-
partName = part.partInfo.name;
93+
// Dry mass / wet mass
94+
Fields["partMass"].guiName = "Dry / wet mass";
95+
partMass = FormatMass(dryMass) + " / " + FormatMass(wetMass);
7196
}
72-
partMass = part.mass;
73-
partCost = part.partInfo.cost;
97+
98+
partCost = part.partInfo.cost + part.GetModuleCosts(part.partInfo.cost);
7499
partEntryCost = part.partInfo.entryCost;
75100

76101
engines = part.GetComponents<ModuleEngines>();
@@ -104,9 +129,9 @@ public void UpdateInfo()
104129
if (ShowTWR)
105130
{
106131
partTWR = 0.0f;
107-
if (partMass > 0)
132+
if (wetMass > 0)
108133
{
109-
partTWR = totalThrust / (partMass * 9.81f);
134+
partTWR = totalThrust / (wetMass * 9.81f);
110135
}
111136
Fields["partTWR"].guiActiveEditor = true;
112137
}
@@ -117,6 +142,63 @@ public void UpdateInfo()
117142
InfoUpdated = true;
118143
}
119144

145+
private string FormatMass(float mass)
146+
{
147+
string result;
148+
if (mass < 1.0f)
149+
{
150+
result = (mass * 1000.0f).ToString("F0") + " kg";
151+
}
152+
else
153+
{
154+
result = mass.ToString("F3") + " t";
155+
}
156+
return result;
157+
}
158+
159+
private string GetPartName()
160+
{
161+
string pName = "";
162+
try
163+
{
164+
pName = GameDatabase.Instance.GetConfigs("PART").
165+
Single(c => part.partInfo.name.Replace('_', '.') == c.name.Replace('_', '.')).name;
166+
}
167+
catch (Exception)
168+
{
169+
Debug.LogError(String.Format($"[PartInfoInPAW] Couldn't get config value name for part {part.partInfo.name}"));
170+
}
171+
return pName;
172+
}
173+
174+
private string GetConfigNodeText()
175+
{
176+
string node = "";
177+
try
178+
{
179+
ConfigNode cfg = GameDatabase.Instance.GetConfigNode(part.partInfo.partUrl);
180+
node = cfg.ToString();
181+
if (cfg != null && !cfg.HasValue("name") && (partName != ""))
182+
{
183+
// node.Replace($"PART{Environment.NewLine}" + "{" + $"{Environment.NewLine}", $"PART{Environment.NewLine}" + "{" + $"{Environment.NewLine}\tname = " + partName + $"{Environment.NewLine}");
184+
// node.Replace("PART\n{\n", "PART\n{" + $"\n\tname = {partName}\n");
185+
node = ReplaceFirstOccurrence(node, "{", "{" + $"{Environment.NewLine}\tname = {partName}");
186+
}
187+
}
188+
catch (Exception)
189+
{
190+
Debug.LogError(String.Format($"[PartInfoInPAW] Couldn't get config node for part {part.partInfo.name}"));
191+
}
192+
return node;
193+
}
194+
195+
public static string ReplaceFirstOccurrence(string Source, string Find, string Replace)
196+
{
197+
int Place = Source.IndexOf(Find);
198+
string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
199+
return result;
200+
}
201+
120202
[KSPEvent]
121203
public void ModuleDataChanged(BaseEventDetails details)
122204
{

src/PartInfoInPAW.csproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<PropertyGroup>
44
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
55
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -10,7 +10,7 @@
1010
<AppDesignerFolder>Properties</AppDesignerFolder>
1111
<RootNamespace>PartInfoInPAW</RootNamespace>
1212
<AssemblyName>PartInfoInPAW</AssemblyName>
13-
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
13+
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
1414
<FileAlignment>512</FileAlignment>
1515
<TargetFrameworkProfile />
1616
</PropertyGroup>
@@ -57,6 +57,10 @@
5757
<SpecificVersion>False</SpecificVersion>
5858
<HintPath>..\..\..\..\..\..\KSP 1.8.1\KSP_x64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
5959
</Reference>
60+
<Reference Include="UnityEngine.IMGUIModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
61+
<SpecificVersion>False</SpecificVersion>
62+
<HintPath>bin\Release\UnityEngine.IMGUIModule.dll</HintPath>
63+
</Reference>
6064
</ItemGroup>
6165
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
6266
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

0 commit comments

Comments
 (0)