Jump to content

Rich

Members
  • Posts

    1,056
  • Joined

  • Last visited

Everything posted by Rich

  1. Telemachus 1.4.12.0 has been released; here is the change log: Implemented potential fix for the OSX path issue. While I do have an OSX machine to test on, I am not at liberty to run games on it. So if it still doesn't work on OSX please let me know as soon as possible. Fixed Kerbal Maps integration. Installation Files (version 1.4.12.0) - SpacePort
  2. You can use Telemachus to adjust the throttle, toggle SAS, fire action groups and control some of Smart ASS.
  3. IP_ADDRESS:PORT/[B]datalink[/B]?pe=o.timeToPe On the information page there is an API tab; on this page there is a list of all the actions you can perform (changing the throttle etc.) and the information you can request (velocity, periapsis etc.)
  4. Couple of troubleshooting questions off the top of my head: Are you specifying the port on the iPad? Try turning your computer firewall off. Does the iPad have an internet connection? I am not aware of any method of accessing the JSON directly. Also your polling strategy sounds great . Figure 1: Navball in the web browser powered by Telemachus
  5. The Telemachus part is instantiated but power consumption is static, it all stems from the fact that there is only one web server running at anyone time. It is not advised that you use more than one Telemachus antenna on a ship because I haven't bothered fixing all the bugs relating to this (I just fixed it enough such that it doesn't explode the game). global::Telemachus.TelemachusPowerDrain.powerConsumption is the correct variable to be reading as the powerConsumptionIncrease variable is added to it. Admittedly it might fluctuate depending on when you read it but more often than not the value will be correct.
  6. I will try to whip up an example today, as it is the only way to prove if I am talking rubbish or not I plan to release a fix for this when KSP 0.23 debuts as this allows me to kill two Kerbals with one rocket.
  7. Have you tried using this method for accessing fields, properties and methods of class?
  8. How are you accessing the values? Via reflection? Are you using OSX? As there is currently an issue with KSP 0.23 and Telemachus on OSX. Some OSX users have created a fix, so maybe you can contact them for their fixed version of Telemachus.
  9. Figure 1: Extra monitors using Telemachus Figure 2: One of several KSP hardware projects in progress
  10. I was away on work so it was a mixture of stressful and enjoyable, but now I have returned to my desk. Those are some comprehensive instructions, but I need to ask about step 4 - do you really need all 4 of those .dll files? I would have guessed you would only need the following two: ~/Library/Application\ Support/Steam/SteamApps/common/Kerbal\ Space\ Program/KSP.app/Contents/Data/Managed/UnityEngine.dll ~/Library/Application\ Support/Steam/SteamApps/common/Kerbal\ Space\ Program/KSP.app/Contents/Data/Managed/Assembly-CSharp.dll I'm not sure when I will put a fix for this into the main Telemachus download, but hopefully I will have some time over Christmas. This is a limitation (as far as I can see) of Google graphs, in that when the graph is updated any pop ups are hidden. This has motivated the need to find a new graphing API, but I have not got round to it.
  11. You can access individual data values from Telemachus using the appropriate URL; an example is given below. http://[B]127.0.0.1:8085[/B]/telemachus/datalink?alt=[B]v.altitude[/B]&pd=[B]v.dynamicPressure[/B] This will return a JSON formatted string with the requested values.
  12. It is possible, but you must: 1) Be using the correct form of IP address (192.168.xxx.xxx); and 2) Make sure your mobile device has Internet connectivity.
  13. There are plans, but it is not a priority feature so I suggest using one of the other logging mods.
  14. Thanks for your investigative work alains; this is helpful in 2 ways: 1) It will make it easier for me to create a hotfix when I return to base; and 2) while I do have an OSX machine, it is strictly a work only device so it is useful to have some OSX testing once in a while. Rich
  15. Unfortunately a recompilation is required to turn debug mode on, and even then it isn't complete enough to help in this case. If you want to compile Telemachus from the source you only need to have a copy of KSP, so that you can reference its API. This is the file you will need to instrument - https://github.com/richardbunt/Telemachus/blob/master/Telemachus/src/IOPageResponsibility.cs I am away from my development box for 2 weeks otherwise I would take a look myself.
  16. Sounds like this could be a Telemachus issues localised to OSX. I will look into it.
  17. There are plans for this, but I currently lack time. Pretty much what xZise says is true, so you can simply use Java's support for HTTP requests to access the JSON data. The only real gotcha is to make sure you use a polling strategy which doesn't request more information until the previous request has completed, otherwise you end up DDoS'ing the Telemachus server. It is possible if you have a little bit of HTML/CSS knowledge, but it is not something I plan to add inbuilt support for.
  18. Just KSP. Not sure why it is hanging - was OS are you using? Could you show me a screen shot of the 404 please?
  19. Please check your firewall is open for Telemachus as this is usually the cause of a loading hang.
  20. Possible, but that functionality has been disabled and would require a recompile to turn it back on. However, you can work around this issue by adding the Telemachus config definitions to your command pod.
  21. The tools you require will depend on whether you are planning to make a 3D model, a plugin or both. So I recommend alluding to what you plan to create for KSP to better aid the community's suggestions to you.
  22. Couple of comments: 1. Thanks for putting the time into building this. 2. Can we have a crash landing achievement series for each planet? 3. Here's some interesting code: 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); } } } It's some demo source for the KSP tutorial system. If you could leverage this, then the achievements could be arbitrarily complex (and deliciously obscure) without you needing to build your own KSP event system from scratch.
  23. Things to check: 1. Phone has internet connection. 2. You are using an address of the form 192.168.xxx.xxx
×
×
  • Create New...