Jump to content

TutorialOrbit101 source code


blizzy78

Recommended Posts

HarvesteR has been posting this on the blog when they implemented in-game tutorials. The code must have gone lost with all the forum updates and whatnot, so here's a copy:


using System.Collections;
using UnityEngine;

public class TutorialOrbit101 : TutorialScenario
{

Texture2D navBallVectors;

protected override void OnAssetSetup()
{
instructorPrefabName = "Instructor_Gene";

navBallVectors = AssetBase.GetTexture("navBall_vectors");
}


TutorialPage welcome, whatsAnOrbit, mapView, attitude1, attitude2, attitude3, navball,
waitForMap1, raiseAp1, waitForPeriapsis1, raiseAp2, raiseAp3a, raiseAp3b, raiseAp4, raiseAp5, raiseAp6,
waitForApoapsis1, raisePe1, raisePe2, raisePe3,
incChange1, incChange2, incChange3,
lowerPe1, lowerPe2, lowerPe3,
conclusion;



protected override void OnTutorialSetup()
{
#region welcome

welcome = new TutorialPage("welcome");
welcome.windowTitle = "Orbiting 101";
welcome.OnEnter = (KFSMState st) =>
{
instructor.StopRepeatingEmote();
InputLockManager.SetControlLock((ControlTypes.STAGING | ControlTypes.THROTTLE), "Orbit101TutorialLock");
};
welcome.OnDrawContent = () =>
{
GUILayout.Label("Welcome to the Orbiting 101 training program! I'm Wernher von Kerman, and I'm going to teach you the basics of orbiting.\n\nI assume you've already done the basic flight tutorials, and are now ready to learn how to get around in space. If you haven't done them, well, I hope you know what you're doing.\n\nLet's get started.");

if (GUILayout.Button("Next")) Tutorial.GoToNextPage();
};
Tutorial.AddPage(welcome);

#endregion
#region whatsAnOrbit

whatsAnOrbit = new TutorialPage("whatsAnOrbit");
whatsAnOrbit.windowTitle = "Orbiting 101 - Basics";
whatsAnOrbit.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_smileA, 5f);
};
whatsAnOrbit.OnDrawContent = () =>
{
GUILayout.Label("Orbiting is really nothing more than free-falling. The only thing is that as you fall, you're moving so fast forward, you actually miss the ground. Because up here there is no atmosphere to slow you down, you will continue to free-fall endlessly around the planet, without having to use your engines.\n\nWe are currently on a low, almost circular orbit around Kerbin. To get a better view of your situation, press the " + GameSettings.MAP_VIEW_TOGGLE.name + " key to go into the Map View.");

};
whatsAnOrbit.SetAdvanceCondition((KFSMState st) => { return MapView.MapIsEnabled; });
Tutorial.AddPage(whatsAnOrbit);

#endregion
#region MapView

mapView = new TutorialPage("mapView");
mapView.windowTitle = "Orbiting 101 - The Map View";
mapView.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_idle_lookAround, 5f);
};
mapView.OnDrawContent = () =>
{
GUILayout.Label("This is the Map View. Here, you can see your ship's position and its current trajectory around the planet.\n\nUse the mouse to look around, to see your orbit from various angles. Also, hovering over the icons on the map will display more information about them.\n\nClose the map when you're ready (press the " + GameSettings.MAP_VIEW_TOGGLE.name + " key again), so we can proceed.");

};
mapView.SetAdvanceCondition((KFSMState st) => { return !MapView.MapIsEnabled; });
Tutorial.AddPage(mapView);

#endregion
#region attitude1

attitude1 = new TutorialPage("attitude1");
attitude1.windowTitle = "Orbiting 101 - Attitude and SAS";
attitude1.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_nodB, 0f);
};
attitude1.OnDrawContent = () =>
{
GUILayout.Label("Good, let's get practical now. I trust you already know your basic spacecraft controls... Up here, they're very much the same, only that the lack of an atmosphere makes the ship behave quite a bit differently. Because there is no drag slowing you down, for every input you apply, you'll have to apply an opposite one to come to a stop again.\n\nI'm going to remotely nudge your attitude controls a little. Try to get the ship back under control afterwards.\n\nIf you find yourself totally out of control, hit " + GameSettings.SAS_TOGGLE.name + " to toggle the SAS on.\n\nAre you ready?");

if (GUILayout.Button("Ready")) Tutorial.GoToNextPage();

GUI.enabled = true;
};
Tutorial.AddPage(attitude1);

#endregion
#region attitude2

attitude2 = new TutorialPage("attitude2");
attitude2.windowTitle = "Orbiting 101 - Attitude and SAS";
attitude2.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_idle_wonder, 3f);

nudge = Random.onUnitSphere;

FlightInputHandler.OnFlyByWire += remoteNudge;
};
attitude2.OnDrawContent = () =>
{
if (Tutorial.TimeAtCurrentState < 3f)
{
GUILayout.Label("Ok, here we go...");
}
else
{
GUILayout.Label("There! You're in control now. Stop rotation using the Pitch, Yaw and Roll controls.\n\nI suggest you use the NavBall to orient yourself, instead of looking at the ship. The NavBall isn't affected by the camera rotation, so it should be easier to get your bearings through it than by looking at the outside.");
GUILayout.Label("Still Rotating (" +
(FlightGlobals.ActiveVessel.angularVelocity.magnitude * Mathf.Rad2Deg).ToString("0.0") + "°/s)...",
GUI.skin.FindStyle("Bold Label"));
}
};
attitude2.OnLeave = (KFSMState st) =>
{
FlightInputHandler.OnFlyByWire -= remoteNudge;
};
attitude2.SetAdvanceCondition((KFSMState st) =>
{
return Tutorial.TimeAtCurrentState > 4f &&
FlightGlobals.ActiveVessel.angularVelocity.magnitude < 0.05;
});
Tutorial.AddPage(attitude2);

#endregion
#region attitude3

attitude3 = new TutorialPage("attitude3");
attitude3.windowTitle = "Orbiting 101 - Attitude and SAS";
attitude3.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_thumbsUp, 0f);
};
attitude3.OnDrawContent = () =>
{
GUILayout.Label("Nicely Done!\n\nAttitude control is an essential skill for a spacecraft pilot. Master it, and you'll be well on your way to becoming an expert commander.\n\nYou can try this again if you want, or press Next if you're ready to move on.");

if (GUILayout.Button("Try that again!")) Tutorial.GoToLastPage();
if (GUILayout.Button("Ready")) Tutorial.GoToNextPage();

GUI.enabled = true;
};
Tutorial.AddPage(attitude3);

#endregion
#region navBall

navball = new TutorialPage("navball");
navball.windowTitle = "Orbiting 101 - The NavBall";
navball.OnEnter = (KFSMState st) =>
{
instructor.StopRepeatingEmote();
};
navball.OnDrawContent = () =>
{
GUILayout.Label("Ok, now let's have a look at the NavBall. You've probably seen the symbols on it when you were spinning around.\n\n Here's what they mean:");

GUILayout.BeginHorizontal();
GUI.color = XKCDColors.ElectricLime;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r1 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r1, navBallVectors, new Rect(0f, 0.5f, 0.5f, 0.5f));
GUI.color = Color.white;
GUILayout.Label("Prograde Vector: It points towards your velocity vector. That is, it points to where you're going.");
GUILayout.EndHorizontal();

GUILayout.BeginHorizontal();
GUI.color = XKCDColors.ElectricLime;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r2 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r2, navBallVectors, new Rect(0.5f, 0.5f, 0.5f, 0.5f));
GUI.color = Color.white;
GUILayout.Label("Retrograde Vector: It points directly away from your velocity.");
GUILayout.EndHorizontal();


GUILayout.BeginHorizontal();
GUI.color = Color.magenta;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r3 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r3, navBallVectors, new Rect(0f, 0f, 0.5f, 0.5f));
GUI.color = Color.white;
GUILayout.Label("Prograde Waypoint Vector: It points towards your current Waypoint.");
GUILayout.EndHorizontal();


GUILayout.BeginHorizontal();
GUI.color = Color.magenta;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r4 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r4, navBallVectors, new Rect(0.5f, 0f, 0.5f, 0.5f));
GUI.color = Color.white;
GUILayout.Label("Retrograde Waypoint Vector: It points directly away from your current Waypoint.");
GUILayout.EndHorizontal();


if (GUILayout.Button("Next")) Tutorial.GoToNextPage();
};
Tutorial.AddPage(navball);

#endregion
#region waitForMap1

waitForMap1 = new TutorialPage("waitForMap1");
waitForMap1.windowTitle = "Orbiting 101";
waitForMap1.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_idle_sigh, 0f);
};
waitForMap1.OnDrawContent = () =>
{
GUILayout.Label("Ok!\n\nNow, let's try something a little more involved. Open your map again.");

};
waitForMap1.SetAdvanceCondition((KFSMState st) => { return MapView.MapIsEnabled; });
Tutorial.AddPage(waitForMap1);

#endregion
#region raiseAp1


raiseAp1 = new TutorialPage("raiseAp");
raiseAp1.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp1.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_nodA, 0f);
};
raiseAp1.OnDrawContent = () =>
{
GUILayout.Label("What we want to do now is go through some of the basic maneuvers you'll need to know. Let's try raising your Apoapsis first.\n\nThe Apoapsis is the highest point in an orbit, and it's indicated by the node marked [Ap].\n\nThe best place to raise your apoapsis is at the Periapsis [Pe] node, which is the lowest point of your orbit. If you hover the mouse over Periapsis node, you'll see that we'll reach it node in a few minutes. Once there, we will face prograde and burn.\n\nPress " + GameSettings.TIME_WARP_INCREASE.name + " to speed up time a little, so we can get there faster.");

};
raiseAp1.SetAdvanceCondition((KFSMState st) => { return TimeWarp.CurrentRate > 1f; });
Tutorial.AddPage(raiseAp1);

#endregion
#region waitForPeriapsis1

waitForPeriapsis1 = new TutorialPage("waitForPeriapsis");
waitForPeriapsis1.windowTitle = "Orbiting 101 - Time Warp";
waitForPeriapsis1.OnEnter = (KFSMState st) =>
{
TimeWarp.SetRate(1, false);
};
waitForPeriapsis1.OnDrawContent = () =>
{
GUILayout.Label("Ok, time is now passing " + TimeWarp.CurrentRate.ToString("0") + " times faster than normal, we should be there in a few moments.\n\nYou can control time warp with the " + GameSettings.TIME_WARP_INCREASE.name + " and " + GameSettings.TIME_WARP_DECREASE.name + " keys, or click the arrows on the panel on the top left of the screen.\n\nThis time, I'll put us back to normal time just before we reach periapsis.\n\nOut of training though, you'll have to warp time down to 1x yourself, so don't go too fast or you might miss your mark.");

};
waitForPeriapsis1.SetAdvanceCondition((KFSMState st) => { return FlightGlobals.ActiveVessel.orbit.timeToPe < 60.0; });
waitForPeriapsis1.onAdvanceConditionMet.OnEvent = () =>
{
TimeWarp.SetRate(0, true);
};
Tutorial.AddPage(waitForPeriapsis1);

#endregion
#region raiseAP2

raiseAp2 = new TutorialPage("raiseAp3");
raiseAp2.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp2.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_idle_sigh, 0f);
};
raiseAp2.OnDrawContent = () =>
{
GUILayout.Label("Ok, we are a few seconds away from Periapsis now. Time to turn prograde and do our burn.\n\nHowever, instead of closing the map, let's just bring up the NavBall here, so we can see what's happening to our orbit as we accelerate.\n\nTo bring up the NavBall on the Map, click the little tab on the bottom-center of the screen, or press the Numpad Period key.");

};
raiseAp2.SetAdvanceCondition((KFSMState st) => { return MapView.ManeuverModeActive; });
Tutorial.AddPage(raiseAp2);

#endregion
#region raiseAp3

raiseAp3a = new TutorialPage("raiseAp3");
raiseAp3a.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp3a.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_nodA, 0f);
};
raiseAp3a.OnDrawContent = () =>
{
GUILayout.Label("Good. Time to do our burn. Turn the ship to face the Prograde Vector now.\n\nTurn SAS on if you need help maintaining stability.");

GUILayout.Label("Remember, the prograde vector looks like this:");
GUI.color = XKCDColors.ElectricLime;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r2 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r2, navBallVectors, new Rect(0.0f, 0.5f, 0.5f, 0.5f));
GUI.color = Color.white;
GUILayout.Label("Make sure the ship is pointing towards it before accelerating.");
};
raiseAp3a.SetAdvanceCondition((KFSMState st) => { return Mathf.Acos(Vector3.Dot(FlightGlobals.ActiveVessel.transform.up, FlightGlobals.ActiveVessel.obt_velocity.normalized)) * Mathf.Rad2Deg < 5f; });
Tutorial.AddPage(raiseAp3a);

#endregion
#region raiseAp3b

raiseAp3b = new TutorialPage("raiseAp3b");
raiseAp3b.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp3b.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_nodA, 0f);

FlightInputHandler.state.killRot = true;
InputLockManager.SetControlLock(ControlTypes.STAGING, "Orbit101TutorialLock");
};
raiseAp3b.OnDrawContent = () =>
{
GUILayout.Label("Ok, we are now turned prograde. I've engaged SAS for you to keep her steady. Go ahead and throttle up now.");
};
raiseAp3b.SetAdvanceCondition((KFSMState st) => { return FlightInputHandler.state.mainThrottle > 0.0f; });
Tutorial.AddPage(raiseAp3b);

#endregion
#region raiseAp4

raiseAp4 = new TutorialPage("raiseAp4");
raiseAp4.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp4.OnEnter = (KFSMState st) =>
{

};
raiseAp4.OnDrawContent = () =>
{
GUILayout.Label("Notice how the opposite side of your orbit starts to rise as you accelerate.\n\nKeep thrusting prograde until your apoapsis altitude reaches about 800,000m.");

GUILayout.Label("Apoapsis Altitude: " + FlightGlobals.ActiveVessel.orbit.ApA.ToString("N0") + "m", GUI.skin.FindStyle("Bold Label"));

};
raiseAp4.SetAdvanceCondition((KFSMState st) => { return FlightGlobals.ActiveVessel.orbit.ApA >= 800000.0; });
Tutorial.AddPage(raiseAp4);

#endregion
#region raiseAp5

raiseAp5 = new TutorialPage("raiseAp5");
raiseAp5.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp5.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_thumbUp, 0f);
};
raiseAp5.OnUpdate = () =>
{
if (Tutorial.TimeAtCurrentState > 6f && FlightInputHandler.state.mainThrottle != 0f)
{
FlightInputHandler.SetNeutralControls();
}
};
raiseAp5.OnDrawContent = () =>
{
GUILayout.Label("Ok, cut the throttle now!\n\nHold " + GameSettings.THROTTLE_DOWN.name + " or hit " + GameSettings.THROTTLE_CUTOFF.name + " to cut throttle immediately.");

};
raiseAp5.SetAdvanceCondition((KFSMState st) => { return FlightInputHandler.state.mainThrottle == 0.0f; });
Tutorial.AddPage(raiseAp5);

#endregion
#region raiseAp6

raiseAp6 = new TutorialPage("raiseAp6");
raiseAp6.windowTitle = "Orbiting 101 - Essential Maneuvers";
raiseAp6.OnEnter = (KFSMState st) =>
{
instructor.PlayEmoteRepeating(instructor.anim_true_thumbsUp, 0f);
};
raiseAp6.OnDrawContent = () =>
{
GUILayout.Label("Well Done!\n\nThis is how you raise your Apoapsis node.\n\nWith orbital maneuvers, pretty much everything you do will affect the opposite side of your orbit. So to raise the highest point (Apoapsis), you thrust forward (or prograde) at the lowest point (Periapsis). Similarly, to raise your Periapsis, you thrust prograde at Apoapsis. We're on our way to the Apoapsis now, so let's do just that.\n\nPress Next when ready, and I'll warp time to get us there quickly.");

if (GUILayout.Button("Next")) Tutorial.GoToNextPage();
};
raiseAp6.SetAdvanceCondition((KFSMState st) => { return TimeWarp.CurrentRate > 1f; });
Tutorial.AddPage(raiseAp6);

#endregion
#region waitForApoapsis1

waitForApoapsis1 = new TutorialPage("waitForApoapsis1");
waitForApoapsis1.windowTitle = "Orbiting 101 - Essential Maneuvers";
waitForApoapsis1.OnEnter = (KFSMState st) =>
{
TimeWarp.SetRate(3, false);
instructor.PlayEmoteRepeating(instructor.anim_true_nodB, 0f);
};
waitForApoapsis1.OnDrawContent = () =>
{
GUILayout.Label("Ok, we're on our way to the Apoapsis node now. Notice how your ship loses speed as we rise. That's because we're climbing away from the planet, so we lose speed as we go higher, just as you would if you were climbing a hill back here on Kerbin.\n\nThe higher you are, the slower your orbit will be. Notice how the Mun's orbital speed is around 540m/s, while yours is far higher.\n\nWhen we reach Apoapsis, we will burn prograde again, to raise the Periapsis node and circularize our orbit.");

};
waitForPeriapsis1.OnFixedUpdate = () =>
{
if (FlightGlobals.ActiveVessel.orbit.timeToAp < 180f && TimeWarp.CurrentRateIndex >= 3)
{
TimeWarp.SetRate(2, false);
}
};
waitForApoapsis1.SetAdvanceCondition((KFSMState st) => { return FlightGlobals.ActiveVessel.orbit.timeToAp < 60f; });
waitForApoapsis1.onAdvanceConditionMet.OnEvent = () =>
{
TimeWarp.SetRate(0, true);
};
Tutorial.AddPage(waitForApoapsis1);

#endregion
#region raisePe1

raisePe1 = new TutorialPage("raisePe1");
raisePe1.windowTitle = "Orbiting 101 - Raise Periapsis";
raisePe1.OnEnter = (KFSMState st) =>
{

};
raisePe1.OnDrawContent = () =>
{
GUILayout.Label("Ok, Here we are... Same as before, turn prograde and fire up those engines, and watch the Periapsis rise.\n\nMind that we are probably turned the other way right now, so the Prograde Vector might not be visible.");


GUILayout.Label("Prograde Vector:");
GUI.color = XKCDColors.ElectricLime;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r2 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r2, navBallVectors, new Rect(0.0f, 0.5f, 0.5f, 0.5f));
GUI.color = Color.white;

GUI.enabled = true;
};
raisePe1.SetAdvanceCondition((KFSMState st) => { return FlightInputHandler.state.mainThrottle > 0.0f; });
Tutorial.AddPage(raisePe1);

#endregion
#region raisePe2

raisePe2 = new TutorialPage("raisePe2");
raisePe2.windowTitle = "Orbiting 101 - Raise Periapsis";
raisePe2.OnEnter = (KFSMState st) =>
{

};
raisePe2.OnDrawContent = () =>
{
GUILayout.Label("Keep burning prograde until the orbit is nearly circular...");

GUILayout.Label("Periapsis Altitude: " + FlightGlobals.ActiveVessel.orbit.PeA.ToString("N0") + "m\n\nEccentricity: " + FlightGlobals.ActiveVessel.orbit.eccentricity.ToString("0.000"), GUI.skin.FindStyle("Bold Label"));

};
raisePe2.SetAdvanceCondition((KFSMState st) => { return FlightGlobals.ActiveVessel.orbit.PeA >= 750000.0; });
Tutorial.AddPage(raisePe2);

#endregion
#region raisePe3

raisePe3 = new TutorialPage("raisePe3");
raisePe3.windowTitle = "Orbiting 101 - Raise Periapsis";
raisePe3.OnEnter = (KFSMState st) =>
{
instructor.PlayEmote(instructor.anim_true_thumbUp);
};
raisePe3.OnUpdate = () =>
{
if (Tutorial.TimeAtCurrentState > 5f && FlightInputHandler.state.mainThrottle != 0f)
{
FlightInputHandler.SetNeutralControls();
}
};
raisePe3.OnDrawContent = () =>
{
GUILayout.Label("Nicely done!\n\nThis is how you change the size of your orbit. This maneuver should come in handy on many situations.\n\nNext, we'll look into changing your orbital inclination.\n\nPress Next when ready to proceed.");


if (GUILayout.Button("Next")) Tutorial.GoToNextPage();
};
Tutorial.AddPage(raisePe3);

#endregion
#region incChange1

incChange1 = new TutorialPage("incChange1");
incChange1.windowTitle = "Orbiting 101 - Inclination";
incChange1.OnEnter = (KFSMState st) =>
{
instructor.PlayEmote(instructor.anim_idle_sigh);
};
incChange1.OnDrawContent = () =>
{
GUILayout.Label("Your orbital inclination is the angle your orbit makes to Kerbin's Equator. If you've managed to maintain a reasonable amount of control this far, we should still be in a nearly 0° inclination orbit. That is, even though we've changed the altitude of our orbit, it still has the same inclination as before.\n\nChanging inclination is done by thrusting in 90° angles to your prograde vector, but without changing your pitch relative to the surface.\n\nOn our present, nearly equatorial orbit, prograde is due east. That means to increase our inclination, so that our orbit takes us into higher latitudes, we have to burn towards the North.\n\nLet's try that now: Turn the ship to heading 360° and open the throttle.");

};
incChange1.SetAdvanceCondition((KFSMState st) => { return FlightInputHandler.state.mainThrottle > 0f; });
Tutorial.AddPage(incChange1);

#endregion
#region incChange2

incChange2 = new TutorialPage("incChange2");
incChange2.windowTitle = "Orbiting 101 - Inclination";
incChange2.OnEnter = (KFSMState st) =>
{
instructor.PlayEmote(instructor.anim_idle_sigh);
};
incChange2.OnDrawContent = () =>
{
GUILayout.Label("Notice how as you burn North, your orbit starts to tilt up, but the Periapsis and Apoapsis nodes remain mostly the same.\n\nThat is because we are accelerating on a completely new direction, so this maneuver doesn't add or take away any energy from the orbit.\n\nKeep accelerating North until your inclination is about 10°.");

GUILayout.Label("Orbit Inclination: " + FlightGlobals.ActiveVessel.orbit.inclination.ToString("0.0") + "°", GUI.skin.FindStyle("Bold Label"));
};
incChange2.SetAdvanceCondition((KFSMState st) => { return FlightGlobals.ActiveVessel.orbit.inclination >= 10.0; });
Tutorial.AddPage(incChange2);

#endregion
#region incChange3

incChange3 = new TutorialPage("incChange3");
incChange3.windowTitle = "Orbiting 101 - Inclination";
incChange3.OnEnter = (KFSMState st) =>
{
instructor.PlayEmote(instructor.anim_idle_sigh);
};
incChange3.OnUpdate = () =>
{
if (Tutorial.TimeAtCurrentState > 5f && FlightInputHandler.state.mainThrottle != 0f)
{
FlightInputHandler.SetNeutralControls();
}
};
incChange3.OnDrawContent = () =>
{
GUILayout.Label("Good! This is how you change your orbital inclination.\n\nFor these maneuvers, it's always better to do it in the slowest parts of the orbit, so you don't have to spend as much delta-V to turn your orbit around. That also means inclination changes on larger orbits, such as we are on now, take less fuel than the same inclination change on a lower one.\n\nAlso, keep in mind that changing inclination doesn't necessarily mean accelerating to the north or south. It means accelerating on 90° headings to your prograde vector, which on our nearly equatorial orbit, also happened to be towards the north.\n\nNext, let's look into the last essential maneuver you'll need to learn: Lowering our orbit.");

if (GUILayout.Button("Proceed")) Tutorial.GoToNextPage();

};
Tutorial.AddPage(incChange3);

#endregion
#region lowerPe1

lowerPe1 = new TutorialPage("lowerPe1");
lowerPe1.windowTitle = "Orbiting 101 - Lower Periapsis";
lowerPe1.OnEnter = (KFSMState st) =>
{

};
lowerPe1.OnDrawContent = () =>
{
GUILayout.Label("As you can imagine, lowering your orbit's altitude is very much like raising it, only in reverse.\n\nBecause there's no air up here, we can use our main engines to decelerate as well as accelerate, because nothing says we have to be facing some direction or another.\n\nAlso, since our orbit is nearly circular, we can just turn retrograde and do our burn at any time now, so let's get to it.\n\nTurn towards the Retrograde Vector and start those engines up again.");


GUILayout.Label("Retrograde Vector:");
GUI.color = XKCDColors.ElectricLime;
GUILayout.Label("", GUILayout.Width(32f), GUILayout.Height(32f));
Rect r2 = GUILayoutUtility.GetLastRect();
GUI.DrawTextureWithTexCoords(r2, navBallVectors, new Rect(0.5f, 0.5f, 0.5f, 0.5f));
GUI.color = Color.white;

};
lowerPe1.SetAdvanceCondition((KFSMState st) => { return FlightInputHandler.state.mainThrottle > 0.0f; });
Tutorial.AddPage(lowerPe1);

#endregion
#region lowerPe2

lowerPe2 = new TutorialPage("lowerPe2");
lowerPe2.windowTitle = "Orbiting 101 - Lower Periapsis";
lowerPe2.OnEnter = (KFSMState st) =>
{

};
lowerPe2.OnDrawContent = () =>
{
GUILayout.Label("Keep burning retrograde until the Periapsis altitude is around 30,000m.\n\nTry getting it as close as possible this time. If you overshoot and get it too low, turn prograde and accelerate again.");

GUILayout.Label("Periapsis Altitude: " + FlightGlobals.ActiveVessel.orbit.PeA.ToString("N0") + "m", GUI.skin.FindStyle("Bold Label"));

};
lowerPe2.SetAdvanceCondition((KFSMState st) => { return FlightGlobals.ActiveVessel.orbit.PeA <= 30000.0; });
Tutorial.AddPage(lowerPe2);

#endregion
#region lowerPe3

lowerPe3 = new TutorialPage("lowerPe3");
lowerPe3.windowTitle = "Orbiting 101 - Lower Periapsis";
lowerPe3.OnEnter = (KFSMState st) =>
{
instructor.PlayEmote(instructor.anim_true_thumbUp);
};
lowerPe3.OnDrawContent = () =>
{
GUILayout.Label("That's it! You're now on your way back.\n\n30,000m is low enough to be in the atmosphere, so you are now on a re-entry course to Kerbin. Once we're below 60,000m, the atmosphere will start slowing the ship down, so that it won't have enough velocity to rise back up again. ");


if (GUILayout.Button("Next")) Tutorial.GoToNextPage();
};
Tutorial.AddPage(lowerPe3);

#endregion
#region conclusion

conclusion = new TutorialPage("conclusion");
conclusion.windowTitle = "Orbiting 101 - Complete!";
conclusion.OnEnter = (KFSMState st) =>
{
instructor.PlayEmote(instructor.anim_true_smileB);

};
conclusion.OnDrawContent = () =>
{
GUILayout.Label("This is the end of our lesson now. You can continue doing maneuvers on your own, or wait for periapsis and do a reentry and land. Don't forget to decouple the capsule and deploy the parachutes.\n\nSee you on the ground!");


if (GUILayout.Button("Finish"))
{
Destroy(this);
}
};
Tutorial.AddPage(conclusion);

#endregion


Tutorial.StartTutorial(welcome);
}

void OnDestroy()
{
InputLockManager.RemoveControlLock("Orbit101TutorialLock");
}

Vector3 nudge = Vector3.zero;
void remoteNudge(FlightCtrlState fcst)
{
if (Tutorial.TimeAtCurrentState < 3f)
{
FlightInputHandler.state.pitch = nudge.x;
FlightInputHandler.state.yaw = nudge.y;
FlightInputHandler.state.roll = nudge.z;
FlightGlobals.ActiveVessel.FeedInputFeed(FlightInputHandler.state);
}
}
}


Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...