@@ -12,6 +12,7 @@ public class NotInMyBackYard : MonoBehaviour
12
12
protected Button . ButtonClickedEvent originalCallback ;
13
13
14
14
public List < IBeacon > StaticBeacons { get ; set ; } = new List < IBeacon > ( ) ;
15
+ public static double MobileBeaconRange { get ; set ; } = 2000 ;
15
16
16
17
public void Start ( )
17
18
{
@@ -53,25 +54,27 @@ protected void NewRecoveryFunction(Vessel vessel)
53
54
IBeacon closestBeacon = null ; //Used for if we're not in range of any beacons
54
55
double shortestDistance = double . PositiveInfinity ;
55
56
56
-
57
-
58
57
foreach ( IBeacon beacon in GetAllBeacons ( ) )
59
58
{
60
- if ( ! beacon . Active )
59
+ if ( ! beacon . Active || beacon . Range <= 0 )
61
60
{
62
61
continue ;
63
62
}
64
63
double distance = beacon . GreatCircleDistance ( vessel ) ;
64
+ double adjustedDistance = distance - beacon . Range ;
65
+
66
+ Debug . Log ( $ "[NIMBY] { beacon . Name } is { ( distance / 1000 ) . ToString ( "N2" ) } ({ ( adjustedDistance / 1000 ) . ToString ( "N2" ) } )km away.") ;
67
+
65
68
if ( beacon . CanRecoverVessel ( vessel ) )
66
69
{
67
70
originalCallback . Invoke ( ) ;
68
71
return ;
69
72
}
70
73
else
71
74
{
72
- if ( distance > 0 && distance < shortestDistance ) //the > 0 checks that it isn't the active vessel
75
+ if ( distance > 0 && adjustedDistance < shortestDistance ) //the > 0 checks that it isn't the active vessel
73
76
{
74
- shortestDistance = distance ;
77
+ shortestDistance = adjustedDistance ;
75
78
closestBeacon = beacon ;
76
79
}
77
80
}
@@ -84,7 +87,8 @@ protected void NewRecoveryFunction(Vessel vessel)
84
87
string closestMessage = "There are no Recovery Beacons nearby." ;
85
88
if ( closestBeacon != null )
86
89
{
87
- closestMessage = $ "Closest Recovery Beacon is { closestBeacon . Name } and is { ( shortestDistance / 1000 ) . ToString ( "N2" ) } km away.";
90
+ double dist = closestBeacon . GreatCircleDistance ( vessel ) / 1000 ;
91
+ closestMessage = $ "Closest Recovery Beacon is { closestBeacon . Name } and is { ( dist ) . ToString ( "N2" ) } km away ({ ( dist - closestBeacon . Range / 1000 ) . ToString ( "N2" ) } km to edge of Beacon's range).";
88
92
}
89
93
90
94
PopupDialog . SpawnPopupDialog ( new Vector2 ( ) , new Vector2 ( ) , "tooFarPopup" ,
@@ -99,18 +103,25 @@ public IList<IBeacon> GetAllBeacons()
99
103
100
104
101
105
//find all vessels that have a mobile beacon module
102
- foreach ( Vessel vessel in FlightGlobals . Vessels . Where ( v => v . Parts . Exists ( p => p . Modules . Contains ( nameof ( ModuleMobileRecoveryBeacon ) ) ) ) ) //this all requires it to be loaded to function. Ideally we wouldn't require that
106
+ foreach ( Vessel vessel in FlightGlobals . Vessels )
103
107
{
104
108
//make sure it's active
105
109
IEnumerable < ModuleMobileRecoveryBeacon > modules ;
106
- if ( ( modules = vessel . Parts . Select ( p => p . Modules . GetModule < ModuleMobileRecoveryBeacon > ( ) ) ) != null )
110
+ if ( vessel . loaded && ( modules = vessel . Parts . Select ( p => p . Modules . GetModule < ModuleMobileRecoveryBeacon > ( ) ) ) != null )
107
111
{
112
+ Debug . Log ( $ "[NIMBY] { vessel . GetDisplayName ( ) } has module") ;
108
113
IBeacon active = modules . FirstOrDefault ( m => m . Active ) ;
109
114
if ( active != null )
110
115
{
116
+ Debug . Log ( $ "[NIMBY] Module is Active.") ;
111
117
beacons . Add ( active ) ;
112
118
}
113
119
}
120
+ else if ( MobileBeaconRequirementsMet ( vessel ) )
121
+ {
122
+ Debug . Log ( $ "[NIMBY] Adding unloaded Beacon for { vessel . GetDisplayName ( ) } .") ;
123
+ beacons . Add ( new UnloadedMobileBeacon ( vessel ) ) ;
124
+ }
114
125
}
115
126
Debug . Log ( $ "[NIMBY] Counting { staticBeacons } static beacons and { beacons . Count - staticBeacons } mobile beacons.") ;
116
127
return beacons ;
@@ -130,6 +141,40 @@ public static double DefaultGreatCircleDistance(double radius, double latitude1,
130
141
131
142
return Math . Sqrt ( d * d ) ;
132
143
}
144
+
145
+ public static bool MobileBeaconRequirementsMet ( Vessel vessel )
146
+ {
147
+ //Check that it's on Kerbin/Earth/whatever
148
+ if ( vessel . mainBody != Planetarium . fetch . Home )
149
+ {
150
+ return false ;
151
+ }
152
+ //check for the module on the vessel
153
+ if ( ! vessel . protoVessel . protoPartSnapshots . Exists ( p => p . modules . Exists ( m => m . moduleName == nameof ( ModuleMobileRecoveryBeacon ) ) ) )
154
+ {
155
+ //Debug.Log($"[NIMBY] {vessel.GetDisplayName()} doesn't have a recovery module.");
156
+ return false ;
157
+ }
158
+ //check for a lab on the vessel
159
+ if ( ! vessel . protoVessel . protoPartSnapshots . Exists ( p => p . modules . Exists ( m => m . moduleName == nameof ( ModuleScienceLab ) ) ) )
160
+ {
161
+ //Debug.Log($"[NIMBY] {vessel.GetDisplayName()} doesn't have a science lab.");
162
+ return false ;
163
+ }
164
+ //Check for an antenna on the vessel
165
+ if ( ! vessel . protoVessel . protoPartSnapshots . Exists ( p => p . modules . Exists ( m => m . moduleName == nameof ( ModuleDataTransmitter ) ) ) )
166
+ {
167
+ //Debug.Log($"[NIMBY] {vessel.GetDisplayName()} doesn't have an antenna.");
168
+ return false ;
169
+ }
170
+ //Has an Engineer aboard
171
+ if ( ! vessel . GetVesselCrew ( ) . Exists ( c => c . trait == "Engineer" ) )
172
+ {
173
+ //Debug.Log($"[NIMBY] {vessel.GetDisplayName()} doesn't have an engineer.");
174
+ return false ;
175
+ }
176
+ return true ;
177
+ }
133
178
}
134
179
135
180
//Start in the Flight Scene only, every time it's loaded
0 commit comments