Example #1
0
    protected override void OnTutorialSetup()
    {
        instructor.name = "Togfox";

        #region opening

        opening             = new TutorialPage("opening");
        opening.windowTitle = "[KGSS] Mission";
        opening.OnEnter     = (KFSMState st) =>
        {
            instructor.StopRepeatingEmote();
            InputLockManager.SetControlLock((ControlTypes.STAGING | ControlTypes.THROTTLE), "UnamedLock");
        };
        opening.OnDrawContent = () =>
        {
            instructor.PlayEmote(instructor.anim_idle_sigh);
            GUILayout.Label("This is mission control to ...");

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

        #endregion

        Tutorial.StartTutorial(opening);
    }
    protected override void OnTutorialSetup()
    {
        readParameters();

        #region Failure

        failure             = new TutorialPage("failure");
        failure.windowTitle = "[KGSS] Mission Debrief";
        failure.OnEnter     = (KFSMState st) =>
        {
            instructor.name = "Rich";
            instructor.StopRepeatingEmote();
        };
        failure.OnDrawContent = () =>
        {
            instructor.PlayEmote(instructor.anim_false_disappointed);

            foreach (string s in resultText)
            {
                GUILayout.Label(s);
            }

            if (GUILayout.Button("Exit"))
            {
                Destroy(this);
            }
        };
        Tutorial.AddPage(failure);

        #endregion

        #region Success

        success             = new TutorialPage("success");
        success.windowTitle = "[KGSS] Mission Debrief";
        success.OnEnter     = (KFSMState st) =>
        {
            instructor.name = "Rich";
            instructor.StopRepeatingEmote();
        };
        success.OnDrawContent = () =>
        {
            instructor.PlayEmote(instructor.anim_true_thumbsUp);

            foreach (string s in resultText)
            {
                GUILayout.Label(s);
            }


            if (GUILayout.Button("Exit"))
            {
                Destroy(this);
            }
        };
        Tutorial.AddPage(success);

        #endregion
    }
Example #3
0
        protected override void OnTutorialSetup()
        {
            TutorialPage page1 = new TutorialPage("Page1");

            Tutorial.AddPage(page1);
            page1.windowTitle   = "Mission Control";
            page1.OnDrawContent = () =>
            {
                GUILayout.Label("What the---?\nDid that lightning just score a direct hit on the " + FlightGlobals.ActiveVessel.vesselName + "?\nOh no...");
            };

            if (FlightGlobals.ActiveVessel.GetCrewCount() == 0)
            {
                page1.SetAdvanceCondition((KFSMState s) => FlightGlobals.ActiveVessel.missionTime > 18);

                TutorialPage page2 = new TutorialPage("Page2");
                Tutorial.AddPage(page2);
                page2.windowTitle   = "Mission Control";
                page2.OnDrawContent = () =>
                {
                    GUILayout.Label("The controls are all locked up!\nThat lightning took them out!");
                };
                page2.SetAdvanceCondition((KFSMState s) => FlightGlobals.ActiveVessel.missionTime > 22);
            }
            else
            {
                page1.SetAdvanceCondition((KFSMState s) => FlightGlobals.ActiveVessel.missionTime > 22);
            }

            TutorialPage page3 = new TutorialPage("Page3");

            Tutorial.AddPage(page3);
            page3.windowTitle   = "Mission Control";
            page3.OnDrawContent = () =>
            {
                GUILayout.Label("...Hold on, " + FlightGlobals.ActiveVessel.vesselName + ", someone here thinks they have a solution.\n" +
                                "Try \"SCE to AUX\". Supposedly it's on the Obscure Control Panel. Funny, I've never heard of it.");
            };

            TutorialPage page4 = new TutorialPage("Page4");

            Tutorial.AddPage(page4);
            page4.windowTitle   = "Mission Control";
            page4.OnDrawContent = () =>
            {
                GUILayout.BeginVertical();
                GUILayout.Label("That did it!\nThe controls are back!");
                if (GUILayout.Button("Close"))
                {
                    SetDialogRect(new Rect(Screen.width + 100, 0, 0, 0));
                }
                GUILayout.EndVertical();
            };
        }
Example #4
0
        /// <summary>
        /// Generates a full tutorial with the least amount of tutorial pages possible, and adds it to the list of existing tutorials
        /// </summary>
        /// <param name="windowLayout">The layout the tutorial will use</param>
        /// <param name="container">The container to which this tutorial will be added</param>
        /// <returns>The created Tutorial</returns>
        static Tutorial CreateTutorialFlow(UnityEngine.Object windowLayout, TutorialContainer container)
        {
            var          path               = GetActiveFolderPath();
            TutorialPage startPage          = CreateTutorialPageWithNarrative($"{path}/5-StartPage");
            TutorialPage instructivePage    = CreateTutorialPageWithInstructions($"{path}/10-TutorialPage");
            TutorialPage tutorialSwitchPage = CreateTutorialPageWithSwitch($"{path}/15-LastPage", null);

            Tutorial tutorial = CreateEmptyTutorial($"{path}/New Tutorial.asset");

            // TODO: this would be the ideal solution to provide a more complete setup experience,
            // but a bug with Scriptable object prevents Scriptable Objects created "after" to
            // be referenced from Scriptable Objects created before them...

            //TutorialPage tutorialSwitchPage = CreateTutorialPageWithSwitch("15-LastPage", tutorial);
            Debug.LogWarning(
                Tr($"The created tutorial switch page doesn't have a Tutorial assiged. Please assign the '{tutorial.name}' object to the field 'Next Tutorial', in the Inspector of the object '{tutorialSwitchPage.name}'."),
                tutorialSwitchPage
                );

            tutorial.AddPage(startPage);
            tutorial.AddPage(instructivePage);
            tutorial.AddPage(tutorialSwitchPage);

            tutorial.TutorialTitle           = "New Tutorial";
            tutorial.ProgressTrackingEnabled = true;
            tutorial.LessonId = Guid.NewGuid().ToString();

            if (container)
            {
                TutorialContainer.Section lastTutorial = null;
                if (container.Sections.Length > 0)
                {
                    lastTutorial = container.Sections.Where(s => !string.IsNullOrEmpty(s.TutorialId)).Last();
                }

                TutorialContainer.Section section = new TutorialContainer.Section();
                section.OrderInView = 0;
                section.Heading     = "Tutorial title";
                section.Text        = "Tutorial description";
                section.Tutorial    = tutorial;

                TutorialContainer.Section[] updatedTutorials = new TutorialContainer.Section[container.Sections.Length + 1];
                Array.Copy(container.Sections, updatedTutorials, container.Sections.Length);
                updatedTutorials[updatedTutorials.Length - 1] = section;
                container.Sections = updatedTutorials;
            }

            if (windowLayout)
            {
                tutorial.WindowLayout = windowLayout;
            }
            else
            {
                Debug.LogWarning(Tr($"The tutorial '{tutorial.name}' does not have a Window Layout assigned. Please assign one to its 'Window Layout' field in the Inspector if you want to load a new Window Layout when this tutorial starts."), tutorial);
            }
            tutorial.Version = "1";

            EnsureAssetChangesAreSaved(tutorial);
            Debug.LogWarning(
                Tr($"The tutorial '{tutorial.name}' does not have a Scene assigned. Please assign one to its 'Scene' field in the Inspector if you want to load a specific Scene when this tutorial starts"),
                tutorial
                );
            return(tutorial);
        }
        protected override void OnTutorialSetup()
        {
            TutorialPage introduction, grid, detector, sounds, colors, timewarp, conclusion;

            instructor.CharacterName = "Majiir";

            #region Introduction

            introduction             = new TutorialPage("introduction");
            introduction.windowTitle = "Kethane Scanning Tutorial";

            introduction.OnEnter = s =>
            {
                instructor.StopRepeatingEmote();
            };

            introduction.OnDrawContent = () =>
            {
                GUILayout.Label("Hi there! Today we're going to use satellites to scan for Kethane, a valuable resource found all around the Kerbal system. Kethane can be processed into rocket fuel or burned in special engines, but we'll have to find it first.\n\nWe'll be controlling a Mun satellite together from here at KSC. It's been equipped with a Kethane survey unit and solar panels for power. Let's get started!");

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

            Tutorial.AddPage(introduction);

            #endregion

            #region Grid

            grid             = new TutorialPage("grid");
            grid.windowTitle = "Kethane Scanning Tutorial";

            grid.OnEnter = s =>
            {
                MapView.EnterMapView();
                MapOverlay.ShowOverlay      = true;
                MapOverlay.SelectedResource = "Kethane";
                instructor.PlayEmote(instructor.anim_idle_lookAround);
            };

            grid.OnDrawContent = () =>
            {
                GUILayout.Label("Here we are in the map view. The cellular grid around the Mun will display resource scan data once we've collected it.\n\nYou can hide the grid or switch to other resources (if you have other resource mods installed) using the green window. (It might be hidden under this one.) The grid will appear around whatever planet or moon you're focused on, so you can view scan data from anywhere in the system.\n\nTake a moment to get comfortable with the grid controls and we'll continue when you're ready.");

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

            grid.OnLeave = s =>
            {
                MapView.ExitMapView();
            };

            Tutorial.AddPage(grid);

            #endregion

            #region Detector

            detector             = new TutorialPage("detector");
            detector.windowTitle = "Kethane Scanning Tutorial";

            detector.OnEnter = s =>
            {
                instructor.PlayEmote(instructor.anim_idle_wonder);
                InputLockManager.RemoveControlLock(lockName + "_actions");
            };

            detector.OnDrawContent = () =>
            {
                GUILayout.Label("Now, let's get scanning! There's a Kethane detector mounted on the front of the satellite. Right-click it and click \"Activate Detector\" to begin scanning.");
            };

            detector.OnFixedUpdate = () =>
            {
                if (FlightGlobals.ActiveVessel.Parts.SelectMany(p => p.Modules.OfType <KethaneDetector>()).Any(d => d.IsDetecting))
                {
                    Tutorial.GoToNextPage();
                }
            };

            detector.OnLeave = s =>
            {
                InputLockManager.SetControlLock(ControlTypes.ACTIONS_SHIP, lockName + "_actions");
                MapView.ExitMapView();
            };

            Tutorial.AddPage(detector);

            #endregion

            #region Sounds

            sounds             = new TutorialPage("sounds");
            sounds.windowTitle = "Kethane Scanning Tutorial";

            sounds.OnEnter = s =>
            {
                instructor.PlayEmote(instructor.anim_true_thumbsUp);
                InputLockManager.RemoveControlLock(lockName + "_map");
            };

            sounds.OnDrawContent = () =>
            {
                GUILayout.Label("Excellent! The detector has turned toward the surface of the Mun, scanning for underground Kethane deposits. You'll occasionally hear beeping or blipping noises as the detector passes over cells on the grid. A louder tone indicates the presence of Kethane directly underneath the satellite.\n\nWhen you're ready, open the map view and we'll take a look at the results.");
            };

            sounds.OnFixedUpdate = () =>
            {
                if (MapView.MapIsEnabled)
                {
                    Tutorial.GoToNextPage();
                }
            };

            sounds.OnLeave = s =>
            {
                InputLockManager.SetControlLock(ControlTypes.MAP, lockName + "_map");
            };

            Tutorial.AddPage(sounds);

            #endregion

            #region Colors

            colors             = new TutorialPage("colors");
            colors.windowTitle = "Kethane Scanning Tutorial";

            colors.OnEnter = s =>
            {
                instructor.PlayEmote(instructor.anim_idle_lookAround);
            };

            colors.OnDrawContent = () =>
            {
                GUILayout.Label("Now that we're scanning, you can see that some cells on the grid have changed color. Green cells indicate the presence of Kethane, and light gray cells have been scanned but nothing was found underneath.\n\nFor detailed information, you can hover your mouse over a cell on the grid. When you hover over a resource deposit, the quantity available for mining will also be displayed.");

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

            Tutorial.AddPage(colors);

            #endregion

            #region Timewarp

            timewarp             = new TutorialPage("timewarp");
            timewarp.windowTitle = "Kethane Scanning Tutorial";

            timewarp.OnEnter = s =>
            {
                instructor.PlayEmote(instructor.anim_idle_sigh);
                InputLockManager.RemoveControlLock(lockName + "_timewarp");
            };

            timewarp.OnDrawContent = () =>
            {
                if (boldStyle == null)
                {
                    boldStyle           = new GUIStyle(GUI.skin.label);
                    boldStyle.fontStyle = FontStyle.Bold;
                }

                GUILayout.Label("Scanning the Mun is going to take a while at this rate. Luckily, we can send our satellite into time warp to finish the job faster. Note that while warping, the detector will lose some data, but overall it will still work faster.\n\nUse time warp to get 2% of the Mun scanned. Watch your battery levels as you approach the dark side. Detectors use a lot of power!");
                GUILayout.Label(String.Format("Surface Coverage: {0:P2}", surfaceCoverage), boldStyle);
            };

            timewarp.OnUpdate = () =>
            {
                surfaceCoverage = (float)Cell.AtLevel(KethaneData.GridLevel).Count(c => KethaneData.Current["Kethane"][FlightGlobals.currentMainBody].IsCellScanned(c)) / Cell.CountAtLevel(KethaneData.GridLevel);
                if (surfaceCoverage >= 0.02f)
                {
                    Tutorial.GoToNextPage();
                }
            };

            Tutorial.AddPage(timewarp);

            #endregion

            #region Conclusion

            conclusion             = new TutorialPage("conclusion");
            conclusion.windowTitle = "Kethane Scanning Tutorial";

            conclusion.OnEnter = s =>
            {
                instructor.PlayEmoteRepeating(instructor.anim_true_smileB, 2);
                InputLockManager.RemoveControlLock(lockName + "_map");
            };

            conclusion.OnDrawContent = () =>
            {
                GUILayout.Label("Nice work! That wraps up our scanning session. Now try building a satellite of your own, or we can move onto using drills to extract Kethane from the ground. Thanks for stopping by!");

                if (GUILayout.Button("Finish"))
                {
                    GameObject.Destroy(this);
                }
            };

            Tutorial.AddPage(conclusion);

            #endregion

            InputLockManager.SetControlLock(ControlTypes.ACTIONS_SHIP, lockName + "_actions");
            InputLockManager.SetControlLock(ControlTypes.ALL_SHIP_CONTROLS & ~ControlTypes.ACTIONS_SHIP, lockName + "_controls");
            InputLockManager.SetControlLock(ControlTypes.MAP, lockName + "_map");
            InputLockManager.SetControlLock(ControlTypes.TIMEWARP, lockName + "_timewarp");

            Tutorial.StartTutorial(introduction);
        }
Example #6
0
        protected override void OnTutorialSetup()
        {
            #region welcome

            welcome             = new TutorialPage("welcome");
            welcome.windowTitle = "FAR Editor Tutorial";
            welcome.OnEnter     = (KFSMState st) =>
            {
                instructor.StopRepeatingEmote();
            };
            welcome.OnDrawContent = () =>
            {
                GUILayout.Label("Welcome to the lecture on the use of the new Ferram Aerospace Research Control and Analysis Systems Tools (FAR-CAST).  I am famous rocket scientist Werhner von Kerman, and I will be instructing you in the use of these tools to perfect your airplane and spaceplane design.");

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

            #region selectship

            selectship             = new TutorialPage("selectship");
            selectship.windowTitle = "FAR Editor Tutorial";
            selectship.OnEnter     = (KFSMState st) =>
            {
                instructor.PlayEmote(instructor.anim_idle_lookAround);
            };
            selectship.OnDrawContent = () =>
            {
                GUILayout.Label("You should begin by selecting a plane to load; I assume that you have some experience in plane design, even if you are not as skilled as famous airplane designers Wilbur and Orville Kerman were.\n\r\n\rIf you have difficulty deciding on a plane to select, I would suggest loading the FAR Velocitas.");

                if (EditorLogic.SortedShipList.Count > 0)
                {
                    Tutorial.GoToNextPage();
                }
            };
            Tutorial.AddPage(selectship);
            #endregion

            #region selectship

            ctrlsurfGUI1             = new TutorialPage("ctrlsurfGUI1");
            ctrlsurfGUI1.windowTitle = "FAR Control Systems";
            ctrlsurfGUI1.OnEnter     = (KFSMState st) =>
            {
                instructor.PlayEmote(instructor.anim_idle_lookAround);
            };
            ctrlsurfGUI1.OnDrawContent = () =>
            {
                GUILayout.Label("This should do.  On the right of your screen should should see the FAR-CAST interface.  There are currently two modes: control and analysis.  It is currently in control mode, which is sued to specify the behavior of any aerodynamic control surfaces attached to the vehicle.");

                if (EditorLogic.SortedShipList.Count > 0)
                {
                    Tutorial.GoToNextPage();
                }
            };
            Tutorial.AddPage(ctrlsurfGUI1);
            #endregion
        }