/
MechJebModuleDeployableController.cs
152 lines (122 loc) · 4.86 KB
/
MechJebModuleDeployableController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System;
using System.Collections.Generic;
namespace MuMech
{
public abstract class MechJebModuleDeployableController : ComputerModule
{
public MechJebModuleDeployableController(MechJebCore core) : base(core)
{
priority = 200;
enabled = true;
}
protected string buttonText;
protected bool extended;
[Persistent(pass = (int)Pass.Global)]
public bool autoDeploy = false;
[Persistent(pass = (int)Pass.Local)]
protected bool prev_shouldDeploy;
public bool prev_autoDeploy = true;
protected string type = "";
protected List<ModuleDeployablePart> cachedPartModules = new List<ModuleDeployablePart>(16);
protected void DiscoverDeployablePartModules()
{
cachedPartModules.Clear();
foreach (Part p in vessel.Parts)
foreach (PartModule pm in p.Modules)
if (pm != null && pm is ModuleDeployablePart mdp && isModules(mdp))
cachedPartModules.Add(mdp);
}
protected bool isDeployable(ModuleDeployablePart sa)
{
return sa.Events["Extend"].active || sa.Events["Retract"].active;
}
public void ExtendAll()
{
foreach (ModuleDeployablePart mdp in cachedPartModules)
if (mdp != null && isDeployable(mdp) && !mdp.part.ShieldedFromAirstream)
mdp.Extend();
}
public void RetractAll()
{
foreach (ModuleDeployablePart mdp in cachedPartModules)
if (mdp != null && isDeployable(mdp) && !mdp.part.ShieldedFromAirstream)
mdp.Retract();
}
public bool AllRetracted()
{
foreach (ModuleDeployablePart mdp in cachedPartModules)
if (mdp != null && isDeployable(mdp) && mdp.deployState != ModuleDeployablePart.DeployState.RETRACTED)
return false;
return true;
}
public bool ShouldDeploy()
{
if (!mainBody.atmosphere)
return true;
if (!vessel.LiftedOff())
return false;
if (vessel.LandedOrSplashed)
return false; // True adds too many complex case
double dt = 10;
double min_alt; // minimum altitude between now and now+dt seconds
double t = Planetarium.GetUniversalTime();
double PeT = orbit.NextPeriapsisTime(t) - t;
if (PeT > 0 && PeT < dt)
min_alt = orbit.PeA;
else
min_alt = Math.Sqrt(Math.Min(orbit.getRelativePositionAtUT(t).sqrMagnitude, orbit.getRelativePositionAtUT(t + dt).sqrMagnitude)) -
mainBody.Radius;
if (min_alt > mainBody.RealMaxAtmosphereAltitude())
return true;
return false;
}
public override void OnFixedUpdate()
{
// Let the ascent guidance handle the solar panels to retract them before launch
if (autoDeploy && !core.Ascent.enabled)
{
bool tmp = ShouldDeploy();
if (tmp && (!prev_shouldDeploy || autoDeploy != prev_autoDeploy))
ExtendAll();
else if (!tmp && (prev_shouldDeploy || autoDeploy != prev_autoDeploy))
RetractAll();
prev_shouldDeploy = tmp;
prev_autoDeploy = true;
}
else
{
prev_autoDeploy = false;
}
bool extendedThisPass = !AllRetracted();
if (extended != extendedThisPass)
buttonText = getButtonText(extendedThisPass ? DeployablePartState.EXTENDED : DeployablePartState.RETRACTED);
extended = extendedThisPass;
}
protected bool ExtendingOrRetracting()
{
foreach (ModuleDeployablePart mdp in cachedPartModules)
if (mdp != null && isDeployable(mdp)
&& (mdp.deployState == ModuleDeployablePart.DeployState.EXTENDING ||
mdp.deployState == ModuleDeployablePart.DeployState.RETRACTING))
return true;
return false;
}
protected abstract bool isModules(ModuleDeployablePart p);
protected enum DeployablePartState
{
RETRACTED,
EXTENDED
}
protected abstract string getButtonText(DeployablePartState deployablePartState);
public override void OnStart(PartModule.StartState state)
{
base.OnStart(state);
if (HighLogic.LoadedSceneIsFlight)
DiscoverDeployablePartModules();
}
public override void OnVesselWasModified(Vessel v)
{
DiscoverDeployablePartModules();
}
}
}