Skip to content

Commit b2bb206

Browse files
committed
Fixes #2666 - see comments in the code to explain how.
1 parent b56c1b5 commit b2bb206

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

src/kOS.Safe/Exceptions/KOSLookupFailException.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22

33
namespace kOS.Safe.Exceptions
44
{
@@ -30,7 +30,7 @@ public class KOSLookupFailException: KOSException
3030
/// <param name="exist">True if the reason for the message is that the thing exists at
3131
/// other times, but is just not available at the moment.</param>
3232
public KOSLookupFailException(string category, string lookupName, object obj, bool exist = false) :
33-
base(String.Format( (exist ? TERSE_NOT_EXIST_MSG_FMT : TERSE_NOT_EXIST_MSG_FMT), category, lookupName.ToUpper(), obj.ToString()) )
33+
base(String.Format( (exist ? TERSE_DOES_EXIST_MSG_FMT : TERSE_NOT_EXIST_MSG_FMT), category, lookupName.ToUpper(), obj.ToString()) )
3434
{
3535
this.category = category;
3636
this.lookupName = lookupName;

src/kOS/Suffixed/PartModuleField/PartModuleFields.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,23 @@ public virtual BooleanValue HasField(StringValue fieldName)
235235
/// <returns>a BaseField - a KSP type that can be used to get the value, or its GUI name or its reflection info.</returns>
236236
protected BaseField GetField(string cookedGuiName)
237237
{
238-
return partModule.Fields.Cast<BaseField>().
239-
FirstOrDefault(field => string.Equals(GetFieldName(field), cookedGuiName, StringComparison.CurrentCultureIgnoreCase));
238+
// Conceptually this should be a FirstOrDefault(), because there should only be one Field
239+
// with the given GUI name. But Issue #2666 forced kOS to change it to a list of hits
240+
// because KSP started naming two fields with the same gui name, only one of which is visible
241+
// at a time:
242+
IEnumerable<BaseField> allMatches = partModule.Fields.Cast<BaseField>().
243+
Where(field => string.Equals(GetFieldName(field), cookedGuiName, StringComparison.CurrentCultureIgnoreCase));
244+
// When KSP is *not* doing the weird thing of two fields with the same name, there's just one hit and it's simple:
245+
if (allMatches.Count() == 1)
246+
return allMatches.First();
247+
if (allMatches.Count() == 0)
248+
return null;
249+
250+
// Issue #2666 is handled here. kOS should not return the invisible field when there's
251+
// a visible one of the same name it could have picked instead. Only return an invisible
252+
// field if there's no visible one to pick.
253+
BaseField preferredMatch = allMatches.FirstOrDefault(field => FieldIsVisible(field));
254+
return preferredMatch ?? allMatches.First();
240255
}
241256

242257
/// <summary>

0 commit comments

Comments
 (0)