Skip to content
This repository was archived by the owner on Oct 26, 2020. It is now read-only.

Commit 18c6451

Browse files
committed
Don't require mobile beacons to be loaded to work.
1 parent 2e23d00 commit 18c6451

File tree

4 files changed

+135
-39
lines changed

4 files changed

+135
-39
lines changed

NotInMyBackYard/ModuleMobileBeacon.cs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,7 @@ public bool StrictRequirementsMet
2525
return false;
2626
}
2727

28-
return SoftRequirementsMet;
29-
}
30-
}
31-
32-
/// <summary>
33-
/// Checks that there is a Science Lab and an Antenna on the ship
34-
/// </summary>
35-
//[KSPField(guiActive = true, guiName = "Mobile Beacon Ready")]
36-
public bool SoftRequirementsMet
37-
{
38-
get
39-
{
40-
//check for a lab on the vessel
41-
if (!vessel.Parts.Exists(p => p.Modules.Contains(nameof(ModuleScienceLab))))
42-
{
43-
return false;
44-
}
45-
//Check for an antenna on the vessel
46-
if (!vessel.Parts.Exists(p => p.Modules.Contains(nameof(ModuleDataTransmitter))))
47-
{
48-
return false;
49-
}
50-
//Has an Engineer aboard
51-
if (!vessel.GetVesselCrew().Exists(c => c.trait == "Engineer"))
52-
{
53-
return false;
54-
}
55-
return true;
28+
return Active;
5629
}
5730
}
5831

@@ -87,7 +60,7 @@ public double Range
8760
{
8861
get
8962
{
90-
return 2000;
63+
return NotInMyBackYard.MobileBeaconRange;
9164
}
9265
set { }
9366
}
@@ -96,9 +69,8 @@ public bool Active
9669
{
9770
get
9871
{
99-
return SoftRequirementsMet;
72+
return NotInMyBackYard.MobileBeaconRequirementsMet(vessel);
10073
}
101-
10274
set { }
10375
}
10476

NotInMyBackYard/NotInMyBackYard.cs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class NotInMyBackYard : MonoBehaviour
1212
protected Button.ButtonClickedEvent originalCallback;
1313

1414
public List<IBeacon> StaticBeacons { get; set; } = new List<IBeacon>();
15+
public static double MobileBeaconRange { get; set; } = 2000;
1516

1617
public void Start()
1718
{
@@ -53,25 +54,27 @@ protected void NewRecoveryFunction(Vessel vessel)
5354
IBeacon closestBeacon = null; //Used for if we're not in range of any beacons
5455
double shortestDistance = double.PositiveInfinity;
5556

56-
57-
5857
foreach (IBeacon beacon in GetAllBeacons())
5958
{
60-
if (!beacon.Active)
59+
if (!beacon.Active || beacon.Range <= 0)
6160
{
6261
continue;
6362
}
6463
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+
6568
if (beacon.CanRecoverVessel(vessel))
6669
{
6770
originalCallback.Invoke();
6871
return;
6972
}
7073
else
7174
{
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
7376
{
74-
shortestDistance = distance;
77+
shortestDistance = adjustedDistance;
7578
closestBeacon = beacon;
7679
}
7780
}
@@ -84,7 +87,8 @@ protected void NewRecoveryFunction(Vessel vessel)
8487
string closestMessage = "There are no Recovery Beacons nearby.";
8588
if (closestBeacon != null)
8689
{
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).";
8892
}
8993

9094
PopupDialog.SpawnPopupDialog(new Vector2(), new Vector2(), "tooFarPopup",
@@ -99,18 +103,25 @@ public IList<IBeacon> GetAllBeacons()
99103

100104

101105
//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)
103107
{
104108
//make sure it's active
105109
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)
107111
{
112+
Debug.Log($"[NIMBY] {vessel.GetDisplayName()} has module");
108113
IBeacon active = modules.FirstOrDefault(m => m.Active);
109114
if (active != null)
110115
{
116+
Debug.Log($"[NIMBY] Module is Active.");
111117
beacons.Add(active);
112118
}
113119
}
120+
else if (MobileBeaconRequirementsMet(vessel))
121+
{
122+
Debug.Log($"[NIMBY] Adding unloaded Beacon for {vessel.GetDisplayName()}.");
123+
beacons.Add(new UnloadedMobileBeacon(vessel));
124+
}
114125
}
115126
Debug.Log($"[NIMBY] Counting {staticBeacons} static beacons and {beacons.Count - staticBeacons} mobile beacons.");
116127
return beacons;
@@ -130,6 +141,40 @@ public static double DefaultGreatCircleDistance(double radius, double latitude1,
130141

131142
return Math.Sqrt(d * d);
132143
}
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+
}
133178
}
134179

135180
//Start in the Flight Scene only, every time it's loaded

NotInMyBackYard/NotInMyBackYard.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<Compile Include="ModuleMobileBeacon.cs" />
5454
<Compile Include="NotInMyBackYard.cs" />
5555
<Compile Include="Properties\AssemblyInfo.cs" />
56+
<Compile Include="UnloadedMobileBeacon.cs" />
5657
</ItemGroup>
5758
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
5859
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace NotInMyBackYard
7+
{
8+
public class UnloadedMobileBeacon : IBeacon
9+
{
10+
private Vessel _vessel = null;
11+
public string Name
12+
{
13+
get
14+
{
15+
return _vessel.GetDisplayName();
16+
}
17+
set { }
18+
}
19+
20+
public double Latitude
21+
{
22+
get
23+
{
24+
return _vessel.latitude;
25+
}
26+
set { }
27+
}
28+
29+
public double Longitude
30+
{
31+
get
32+
{
33+
return _vessel.longitude;
34+
}
35+
set { }
36+
}
37+
38+
public double Range
39+
{
40+
get
41+
{
42+
return NotInMyBackYard.MobileBeaconRange;
43+
}
44+
set { }
45+
}
46+
47+
public bool Active
48+
{
49+
get
50+
{
51+
return NotInMyBackYard.MobileBeaconRequirementsMet(_vessel);
52+
}
53+
54+
set { }
55+
}
56+
57+
public UnloadedMobileBeacon(Vessel vessel)
58+
{
59+
_vessel = vessel;
60+
}
61+
62+
63+
public bool CanRecoverVessel(Vessel vessel)
64+
{
65+
return vessel.id != _vessel.id && GreatCircleDistance(vessel.mainBody.Radius, vessel.latitude, vessel.longitude) < Range;
66+
}
67+
68+
public double GreatCircleDistance(double radius, double latitude, double longitude)
69+
{
70+
return NotInMyBackYard.DefaultGreatCircleDistance(radius, Latitude, Longitude, latitude, longitude);
71+
}
72+
73+
public double GreatCircleDistance(Vessel vessel)
74+
{
75+
return GreatCircleDistance(vessel.mainBody.Radius, vessel.latitude, vessel.longitude);
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)