Skip to content

Commit 698b1c6

Browse files
authored
Allow selecting patches (#165)
1 parent 63288dd commit 698b1c6

File tree

6 files changed

+429
-168
lines changed

6 files changed

+429
-168
lines changed

RasterPropMonitor/Core/MonitorPage.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class MonitorPage
3333
public readonly int pageNumber;
3434
public readonly string name = string.Empty;
3535
public readonly bool unlocker;
36+
private const int INVALID_BUTTON = -1;
3637
private string text;
3738
private StringProcessorFormatter[] spf;
3839
private string[] outputLines;
@@ -80,7 +81,8 @@ public enum BackgroundType
8081
private readonly MonoBehaviour backgroundHandlerModule, pageHandlerModule;
8182
private readonly List<string> techsRequired = new List<string>();
8283
private readonly string fallbackPageName = string.Empty;
83-
84+
private readonly int buttonNextPatch = INVALID_BUTTON;
85+
private readonly int buttonPrevPatch = INVALID_BUTTON;
8486

8587
private struct HandlerSupportMethods
8688
{
@@ -433,6 +435,16 @@ public MonitorPage(int idNum, ConfigNode node, RasterPropMonitor thatMonitor)
433435
}
434436
}
435437

438+
int intValue = INVALID_BUTTON;
439+
if (node.TryGetValue("buttonNextPatch", ref intValue))
440+
{
441+
buttonNextPatch = intValue;
442+
}
443+
444+
if (node.TryGetValue("buttonPrevPatch", ref intValue))
445+
{
446+
buttonPrevPatch = intValue;
447+
}
436448
}
437449

438450
private static MethodInfo InstantiateHandler(ConfigNode node, RasterPropMonitor ourMonitor, out MonoBehaviour moduleInstance, out HandlerSupportMethods support)
@@ -622,7 +634,7 @@ public void Active(bool state)
622634
public bool GlobalButtonClick(int buttonID)
623635
{
624636
buttonID = redirectGlobals[buttonID] ?? buttonID;
625-
if (buttonID == -1)
637+
if (buttonID == INVALID_BUTTON)
626638
{
627639
return false;
628640
}
@@ -637,6 +649,16 @@ public bool GlobalButtonClick(int buttonID)
637649
backgroundHandlerS.buttonClick(buttonID);
638650
actionTaken = true;
639651
}
652+
if (buttonID == buttonNextPatch)
653+
{
654+
ourMonitor.SelectNextPatch();
655+
actionTaken = true;
656+
}
657+
if (buttonID == buttonPrevPatch)
658+
{
659+
ourMonitor.SelectPreviousPatch();
660+
actionTaken = true;
661+
}
640662
return actionTaken;
641663
}
642664

RasterPropMonitor/Core/OrbitExtensions.cs

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,7 @@ public static Vector3d SwappedOrbitNormal(this Orbit o)
4545
//occurs at a true anomaly that a does not actually ever attain
4646
public static double TimeOfAscendingNode(this Orbit a, Orbit b, double UT)
4747
{
48-
if (a.eccentricity >= 1.0)
49-
{
50-
return UT;
51-
}
52-
else
53-
{
54-
return a.TimeOfTrueAnomaly(Orbit.AscendingNodeTrueAnomaly(a, b), UT);
55-
}
48+
return a.TimeOfTrueAnomaly(Orbit.AscendingNodeTrueAnomaly(a, b), UT);
5649
}
5750
//Returns the next time at which a will cross its descending node with b.
5851
//For elliptical orbits this is a time between UT and UT + a.period.
@@ -62,14 +55,7 @@ public static double TimeOfAscendingNode(this Orbit a, Orbit b, double UT)
6255
//occurs at a true anomaly that a does not actually ever attain
6356
public static double TimeOfDescendingNode(this Orbit a, Orbit b, double UT)
6457
{
65-
if (a.eccentricity >= 1.0)
66-
{
67-
return UT;
68-
}
69-
else
70-
{
71-
return a.TimeOfTrueAnomaly(Orbit.DescendingNodeTrueAnomaly(a, b), UT);
72-
}
58+
return a.TimeOfTrueAnomaly(Orbit.DescendingNodeTrueAnomaly(a, b), UT);
7359
}
7460
//Returns the next time at which the orbiting object will cross the equator
7561
//moving northward, if o is east-moving, or southward, if o is west-moving.
@@ -80,14 +66,7 @@ public static double TimeOfDescendingNode(this Orbit a, Orbit b, double UT)
8066
//"ascending node" occurs at a true anomaly that o does not actually ever attain.
8167
public static double TimeOfAscendingNodeEquatorial(this Orbit o, double UT)
8268
{
83-
if (o.eccentricity >= 1.0)
84-
{
85-
return UT;
86-
}
87-
else
88-
{
89-
return o.TimeOfTrueAnomaly(o.AscendingNodeEquatorialTrueAnomaly(), UT);
90-
}
69+
return o.TimeOfTrueAnomaly(o.AscendingNodeEquatorialTrueAnomaly(), UT);
9170
}
9271
//Returns the next time at which the orbiting object will cross the equator
9372
//moving southward, if o is east-moving, or northward, if o is west-moving.

RasterPropMonitor/Core/RPMCEvaluators.cs

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,22 @@ internal VariableEvaluator GetEvaluator(string input, out VariableUpdateType upd
319319
{
320320
return ScienceUtil.GetExperimentBiome(vessel.mainBody, vessel.latitude, vessel.longitude);
321321
};
322-
322+
case "PATCHENCOUNTERBODY":
323+
return (RPMVesselComputer comp) =>
324+
{
325+
if (!JUtil.OrbitMakesSense(vessel)) return string.Empty;
326+
Orbit patch = GetSelectedPatchOrbit();
327+
switch (patch.patchEndTransition)
328+
{
329+
case Orbit.PatchTransitionType.ENCOUNTER:
330+
return patch.nextPatch.referenceBody.bodyName;
331+
case Orbit.PatchTransitionType.ESCAPE:
332+
return patch.referenceBody.bodyName;
333+
}
334+
return string.Empty;
335+
};
336+
case "PATCHORBITBODY":
337+
return (RPMVesselComputer comp) => GetSelectedPatchOrbit().referenceBody.name;
323338
}
324339

325340
return null;
@@ -1600,6 +1615,8 @@ internal NumericVariableEvaluator GetNumericEvaluator(string input, out Variable
16001615
}
16011616
return double.NaN;
16021617
};
1618+
case "ANYTARGETEXISTS":
1619+
return (RPMVesselComputer comp) => comp.target == null ? -1d : 1d;
16031620
case "TARGETEXISTS":
16041621
return (RPMVesselComputer comp) =>
16051622
{
@@ -2626,6 +2643,138 @@ internal NumericVariableEvaluator GetNumericEvaluator(string input, out Variable
26262643
}
26272644
return -1d;
26282645
};
2646+
case "PATCHINDEX":
2647+
return (RPMVesselComputer comp) =>
2648+
{
2649+
(int index, Orbit _) = GetSelectedPatch();
2650+
return index + 1;
2651+
};
2652+
case "PATCHCOUNT":
2653+
return (RPMVesselComputer comp) =>
2654+
{
2655+
(int index, Orbit _) = GetLastPatch();
2656+
return index + 1;
2657+
};
2658+
case "PATCHALTITUDE":
2659+
return (RPMVesselComputer comp) => GetSelectedPatchOrbit().referenceBody.GetAltitude(vessel.CoM);
2660+
case "PATCHORBTSPEED":
2661+
return (RPMVesselComputer comp) => GetSelectedPatchOrbit().GetVel().magnitude;
2662+
case "PATCHAPOAPSIS":
2663+
return (RPMVesselComputer comp) => JUtil.OrbitMakesSense(vessel) ? GetSelectedPatchOrbit().ApA : double.NaN;
2664+
case "PATCHPERIAPSIS":
2665+
return (RPMVesselComputer comp) => JUtil.OrbitMakesSense(vessel) ? GetSelectedPatchOrbit().PeA : double.NaN;
2666+
case "PATCHINCLINATION":
2667+
return (RPMVesselComputer comp) => JUtil.OrbitMakesSense(vessel) ? GetSelectedPatchOrbit().inclination : double.NaN;
2668+
case "PATCHECCENTRICITY":
2669+
return (RPMVesselComputer comp) => JUtil.OrbitMakesSense(vessel) ? GetSelectedPatchOrbit().eccentricity : double.NaN;
2670+
case "PATCHTIMETOAPSECS":
2671+
return (RPMVesselComputer comp) =>
2672+
{
2673+
if (!JUtil.OrbitMakesSense(vessel)) return double.NaN;
2674+
Orbit patch = GetSelectedPatchOrbit();
2675+
// When the tracking station is not upgraded, StartUT will not be updated to the current time.
2676+
if (patch.StartUT == 0.0) return patch.timeToAp;
2677+
return patch.timeToAp + patch.StartUT - Planetarium.GetUniversalTime();
2678+
};
2679+
case "PATCHTIMETOPESECS":
2680+
return (RPMVesselComputer comp) =>
2681+
{
2682+
if (!JUtil.OrbitMakesSense(vessel)) return double.NaN;
2683+
Orbit patch = GetSelectedPatchOrbit();
2684+
// When the tracking station is not upgraded, StartUT will not be updated to the current time.
2685+
if (patch.StartUT == 0.0) return patch.timeToPe;
2686+
return patch.timeToPe + patch.StartUT - Planetarium.GetUniversalTime();
2687+
};
2688+
case "PATCHORBPERIODSECS":
2689+
return (RPMVesselComputer comp) => JUtil.OrbitMakesSense(vessel) ? GetSelectedPatchOrbit().period : double.NaN;
2690+
case "PATCHTIMETOANEQUATORIAL":
2691+
return (RPMVesselComputer comp) =>
2692+
{
2693+
Orbit patch = GetSelectedPatchOrbit();
2694+
if (!JUtil.OrbitMakesSense(vessel) || !patch.AscendingNodeEquatorialExists())
2695+
{
2696+
return double.NaN;
2697+
}
2698+
return patch.TimeOfAscendingNodeEquatorial(Planetarium.GetUniversalTime()) - Planetarium.GetUniversalTime();
2699+
};
2700+
case "PATCHTIMETODNEQUATORIAL":
2701+
return (RPMVesselComputer comp) =>
2702+
{
2703+
Orbit patch = GetSelectedPatchOrbit();
2704+
if (!JUtil.OrbitMakesSense(vessel) || !patch.DescendingNodeEquatorialExists())
2705+
{
2706+
return double.NaN;
2707+
}
2708+
return patch.TimeOfDescendingNodeEquatorial(Planetarium.GetUniversalTime()) - Planetarium.GetUniversalTime();
2709+
};
2710+
case "PATCHFIRST":
2711+
return (RPMVesselComputer comp) =>
2712+
{
2713+
(int index, Orbit _) = GetSelectedPatch();
2714+
return index == 0 ? 1.0d : 0.0d;
2715+
};
2716+
case "PATCHLAST":
2717+
return (RPMVesselComputer comp) =>
2718+
{
2719+
(int selected, Orbit _) = GetSelectedPatch();
2720+
(int last, Orbit _) = GetLastPatch();
2721+
return selected == last ? 1.0d : 0.0d;
2722+
};
2723+
case "PATCHNEXTAPSISTYPE":
2724+
return (RPMVesselComputer comp) =>
2725+
{
2726+
Orbit patch = GetSelectedPatchOrbit();
2727+
if (patch.eccentricity < 1.0)
2728+
{
2729+
// Which one will we reach first?
2730+
return (patch.timeToPe < patch.timeToAp) ? -1.0 : 1.0;
2731+
}
2732+
2733+
// Ship is hyperbolic. There is no Ap. Have we already
2734+
// passed Pe?
2735+
return (patch.timeToPe > 0.0) ? -1.0 : 0.0;
2736+
};
2737+
case "PATCHNEXT_ANDN_EQUATORIAL":
2738+
return (RPMVesselComputer comp) =>
2739+
{
2740+
Orbit patch = GetSelectedPatchOrbit();
2741+
double universalTime = Planetarium.GetUniversalTime();
2742+
if (!JUtil.OrbitMakesSense(vessel)) return 0.0;
2743+
2744+
double dnTime = patch.DescendingNodeEquatorialExists() ? patch.TimeOfDescendingNodeEquatorial(universalTime) : double.NaN;
2745+
double anTime = patch.AscendingNodeEquatorialExists() ? patch.TimeOfAscendingNodeEquatorial(universalTime) : double.NaN;
2746+
2747+
if (double.IsNaN(anTime)) return -1.0;
2748+
if (double.IsNaN(dnTime)) return 1.0;
2749+
return Math.Max(0.0, anTime) < Math.Max(dnTime, 0.0) ? 1.0 : -1.0;
2750+
};
2751+
case "PATCHENCOUNTEREXISTS":
2752+
return (RPMVesselComputer comp) =>
2753+
{
2754+
if (!JUtil.OrbitMakesSense(vessel)) return 0.0;
2755+
Orbit patch = GetSelectedPatchOrbit();
2756+
switch (patch.patchEndTransition)
2757+
{
2758+
case Orbit.PatchTransitionType.ESCAPE:
2759+
return -1d;
2760+
case Orbit.PatchTransitionType.ENCOUNTER:
2761+
return 1d;
2762+
default:
2763+
return 0.0d;
2764+
}
2765+
};
2766+
case "PATCHENCOUNTERTIME":
2767+
return (RPMVesselComputer comp) =>
2768+
{
2769+
if (!JUtil.OrbitMakesSense(vessel)) return 0.0;
2770+
Orbit patch = GetSelectedPatchOrbit();
2771+
if (patch.patchEndTransition == Orbit.PatchTransitionType.ENCOUNTER ||
2772+
patch.patchEndTransition == Orbit.PatchTransitionType.ESCAPE)
2773+
{
2774+
return patch.UTsoi - Planetarium.GetUniversalTime();
2775+
}
2776+
return 0.0;
2777+
};
26292778
}
26302779

26312780
return null;

RasterPropMonitor/Core/RasterPropMonitor.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,16 @@ public void PageButtonClick(MonitorPage triggeredPage)
379379
}
380380
}
381381

382+
internal void SelectNextPatch()
383+
{
384+
rpmComp.SelectNextPatch();
385+
}
386+
387+
internal void SelectPreviousPatch()
388+
{
389+
rpmComp.SelectPreviousPatch();
390+
}
391+
382392
// Update according to the given refresh rate.
383393
private bool UpdateCheck()
384394
{
@@ -508,8 +518,8 @@ public void LateUpdate()
508518
firstRenderComplete = false;
509519
textRefreshRequired = true;
510520
}
511-
else if (!activePage.isMutable)
512-
{
521+
else if (!activePage.isMutable)
522+
{
513523
// In case the page is empty and has no camera, the screen is treated as turned off and blanked once.
514524
if (!firstRenderComplete)
515525
{

RasterPropMonitor/Core/RasterPropMonitorComputer.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ internal PeriodicRandomValue(int period_)
111111

112112
private ExternalVariableHandlers plugins = null;
113113
internal Dictionary<string, Color32> overrideColors = new Dictionary<string, Color32>();
114+
private int selectedPatchIndex;
114115

115116
static readonly Regex x_agmemoRegex = new Regex("^AG([0-9])\\s*=\\s*(.*)\\s*");
116117

@@ -332,6 +333,69 @@ public void RestoreInternalModule(InternalModule module)
332333
modulesToRestore.Add(module);
333334
}
334335

336+
/// <summary>
337+
/// Find the selected orbital patch. A patch is selected if we are
338+
/// looking at it.
339+
/// </summary>
340+
/// <returns>
341+
/// 1. The count of the patch. 0 for current orbit, 1 for next SOI, and
342+
/// so on
343+
/// 2. The orbit object that represents the patch.
344+
/// </returns>
345+
internal (int, Orbit) GetSelectedPatch()
346+
{
347+
return EffectivePatch(selectedPatchIndex);
348+
}
349+
350+
private Orbit GetSelectedPatchOrbit()
351+
{
352+
(int _, Orbit patch) = GetSelectedPatch();
353+
return patch;
354+
}
355+
356+
internal (int, Orbit) GetLastPatch()
357+
{
358+
return EffectivePatch(1000);
359+
}
360+
361+
internal void SelectNextPatch()
362+
{
363+
(int effectivePatchIndex, _) = GetSelectedPatch();
364+
SelectPatch(effectivePatchIndex + 1);
365+
}
366+
367+
internal void SelectPreviousPatch()
368+
{
369+
(int effectivePatchIndex, _) = GetSelectedPatch();
370+
SelectPatch(effectivePatchIndex - 1);
371+
}
372+
373+
private void SelectPatch(int patchIndex)
374+
{
375+
(int effectivePatchIndex, _) = EffectivePatch(patchIndex);
376+
selectedPatchIndex = effectivePatchIndex;
377+
}
378+
379+
/// <summary>
380+
/// Returns the orbit (patch) and orbit index given a selection.
381+
/// </summary>
382+
/// <returns>true if it's time to update things</returns>
383+
private (int, Orbit) EffectivePatch(int patchIndex)
384+
{
385+
Orbit patch = vessel.orbit;
386+
int effectivePatchIndex = 0;
387+
while (effectivePatchIndex < patchIndex
388+
&& patch.nextPatch != null
389+
&& patch.nextPatch.activePatch
390+
&& (patch.patchEndTransition == Orbit.PatchTransitionType.ENCOUNTER || patch.patchEndTransition == Orbit.PatchTransitionType.ESCAPE))
391+
{
392+
patch = patch.nextPatch;
393+
effectivePatchIndex++;
394+
}
395+
396+
return (effectivePatchIndex, patch);
397+
}
398+
335399
#region Monobehaviour
336400
/// <summary>
337401
/// Configure this computer for operation.

0 commit comments

Comments
 (0)