예제 #1
0
        private static void TestFindNextCrumb()
        {
            // Only run this once.
            if (test)
            {
                test = false;
            }
            else
            {
                return;
            }

            for (int i = 1; i < (int)GameMode.LAST_MODE; i++)
            {
                for (int j = 1; j < (int)GameMode.LAST_MODE; j++)
                {
                    TutorialManager.curGameMode = (GameMode)i;
                    GameMode target = (GameMode)j;
                    Crumb    crumb  = FindNextCrumb(target);

                    if (i == j && crumb == null)
                    {
                        // Not interesting...
                        continue;
                    }

                    /*
                     * if (i == 13 || j == 13 || i == 42 || j == 42 || i == 43 || j == 43 || i == 44 || j == 44)
                     * {
                     *  continue;
                     * }
                     */

#if !NETFX_CORE
                    Debug.Print("cur " + TutorialManager.curGameMode.ToString() + " -> " + target.ToString());
#endif
                    if (crumb == null)
                    {
#if !NETFX_CORE
                        Debug.Print("  null crumb");
#endif
                    }
                    else
                    {
#if !NETFX_CORE
                        Debug.Print("  crumb target " + crumb.targetMode.ToString());
#endif
                    }
                    crumb = null;
                }
            }
        }
예제 #2
0
        public static Crumb[] Init()
        {
            CrumbList    crumbList       = null;
            CrumbList    crumbStrings    = null;
            const string stringsFilename = @"TutorialStrings.Xml";
            const string crumbsFilename  = @"TutorialCrumbs.Xml";

            // Get the actual crumb list.  This contains all the mode links.
            // Note, since this no longer contains strings it is no longer inthe Localizable folder...
            string filename = Path.Combine(@"Content\Xml", crumbsFilename);

            if (Storage4.FileExists(filename, StorageSource.TitleSpace))
            {
                crumbList = Load(filename, StorageSource.TitleSpace);
            }
            else
            {
                Debug.Assert(false, "Missing file!");
            }

            // Now get the strings for each of the crumbs.
            // First we need to get the default, English version.  Look in both user and title space
            // since the shipped version may have been superceeded by a downloaded one.
            if (Storage4.FileExists(Path.Combine(Localizer.DefaultLanguageDir, stringsFilename), StorageSource.All))
            {
                crumbStrings = Load(Path.Combine(Localizer.DefaultLanguageDir, stringsFilename), StorageSource.All);
            }
            else
            {
                Debug.Assert(false, "Missing file!");
            }

            Crumb[] result = null;

            if (crumbStrings != null)
            {
                // Start with list of crumbs.
                result = crumbList.Crumbs;

                // Now match up crumbs with their strings.
                foreach (Crumb crumb in result)
                {
                    // Find matching strings and copy over.
                    for (int i = 0; i < crumbStrings.Crumbs.Length; i++)
                    {
                        Crumb strCrumb = crumbStrings.Crumbs[i];
                        if (crumb.id == strCrumb.id)
                        {
                            crumb.gamepadText = strCrumb.gamepadText;
                            crumb.mouseText   = strCrumb.mouseText;
                            crumb.touchText   = strCrumb.touchText;
                        }
                    }
                }
            }

            // Is our run-time local language different from the default?
            if (!Localizer.IsLocalDefault)
            {
                var localPath = Localizer.LocalLanguageDir;

                // Do we have a directory for the local language?
                if (localPath != null)
                {
                    var localFile = Path.Combine(localPath, stringsFilename);

                    if (Storage4.FileExists(localFile, StorageSource.All))
                    {
                        CrumbList localCrumbs = Load(localFile, StorageSource.All);

                        if (result != null && localCrumbs != null)
                        {
                            // Loop over each of the crumbs we currently have...
                            for (int i = 0; i < result.Length; i++)
                            {
                                var defCrumb        = result[i];
                                var foundLocalCrumb = false;

                                // Loop over each of the localized crumbs searching for a match to existing crumbs.
                                for (int j = 0; j < localCrumbs.Crumbs.Length; j++)
                                {
                                    var localCrumb = localCrumbs.Crumbs[j];

                                    // If the crumbs are the same, override the default with the localized
                                    if (localCrumb.id == defCrumb.id)
                                    {
                                        if (Localizer.ShouldReportMissing &&
                                            localCrumb.GamepadText.Equals(defCrumb.GamepadText, StringComparison.OrdinalIgnoreCase) &&
                                            localCrumb.MouseText.Equals(defCrumb.MouseText, StringComparison.OrdinalIgnoreCase) &&
                                            localCrumb.TouchText.Equals(defCrumb.TouchText, StringComparison.OrdinalIgnoreCase)
                                            )
                                        {
                                            Localizer.ReportIdentical(stringsFilename, "TargetMode: " + defCrumb.TargetMode.ToString());
                                        }

                                        // Copy any localized strings over.
                                        if (!string.IsNullOrEmpty(localCrumb.GamepadText))
                                        {
                                            result[i].gamepadText = localCrumb.GamepadText;
                                        }
                                        if (!string.IsNullOrEmpty(localCrumb.MouseText))
                                        {
                                            result[i].mouseText = localCrumb.MouseText;
                                        }
                                        if (!string.IsNullOrEmpty(localCrumb.TouchText))
                                        {
                                            result[i].touchText = localCrumb.TouchText;
                                        }
                                        foundLocalCrumb = true;
                                        break;
                                    }
                                }

                                if (!foundLocalCrumb)
                                {
                                    Localizer.ReportMissing(stringsFilename, "TargetMode: " + defCrumb.TargetMode.ToString());
                                }
                            }
                        }
                        else
                        {
                            Localizer.ReportMissing(stringsFilename, "CAN'T LOAD CRUMBS!");
                        }
                    }
                    else
                    {
                        Localizer.ReportMissing(stringsFilename, "CAN'T FIND FILE!");
                    }
                }
                else
                {
                    Localizer.ReportMissing(localPath, "CAN'T FIND PATH FOR THIS LANGUAGE!");
                }
            }

            /*
             * // Output crumb data for GraphViz
             * foreach (Crumb crumb in result)
             * {
             *  foreach (TutorialManager.GameMode curmode in crumb.CurModes)
             *  {
             *      Debug.Print(curmode.ToString() + " -> " + crumb.targetMode.ToString() + " [ label = \" \" ];");
             *  }
             * }
             */

            return(result);
        }   // end of Init()
예제 #3
0
        public static void LoadContent(bool immediate)
        {
            if (backdrop == null)
            {
                //backdrop = BokuGame.Load<Texture2D>(BokuGame.Settings.MediaPath + @"Textures\GridElements\TutorialTitle");
                backdrop = BokuGame.Load <Texture2D>(BokuGame.Settings.MediaPath + @"Textures\GridElements\CheckboxWhite");
                //backdrop = BokuGame.Load<Texture2D>(BokuGame.Settings.MediaPath + @"Textures\HelpCard\BlackHighlight");
            }

            if (dropShadow == null)
            {
                dropShadow = BokuGame.Load <Texture2D>(BokuGame.Settings.MediaPath + @"Textures\GridElements\DropShadow");
            }

            CreateRenderTarget();

            if (crumbsArray == null)
            {
                crumbsArray = Crumb.Init();

                crumbListMouse   = new List <Crumb>(crumbsArray.Length);
                crumbListTouch   = new List <Crumb>(crumbsArray.Length);
                crumbListGamepad = new List <Crumb>(crumbsArray.Length);

                for (int i = 0; i < crumbsArray.Length; i++)
                {
                    crumbListMouse.Add(crumbsArray[i]);
                    crumbListTouch.Add(crumbsArray[i]);
                    crumbListGamepad.Add(crumbsArray[i]);
                }

                // For each list, pull the input specific crumbs to the top.
                int top = 0;
                for (int i = 0; i < crumbsArray.Length; i++)
                {
                    if (crumbListMouse[i].TargetMode.ToString().Contains("Mouse"))
                    {
                        // Swap with top.
                        Crumb tmp = crumbListMouse[top];
                        crumbListMouse[top] = crumbListMouse[i];
                        crumbListMouse[i]   = tmp;

                        ++top;
                    }
                }
                top = 0;
                for (int i = 0; i < crumbsArray.Length; i++)
                {
                    if (crumbListTouch[i].TargetMode.ToString().Contains("Touch"))
                    {
                        // Swap with top.
                        Crumb tmp = crumbListTouch[top];
                        crumbListTouch[top] = crumbListTouch[i];
                        crumbListTouch[i]   = tmp;

                        ++top;
                    }
                }
                top = 0;
                for (int i = 0; i < crumbsArray.Length; i++)
                {
                    if (crumbListGamepad[i].TargetMode.ToString().Contains("Gamepad"))
                    {
                        // Swap with top.
                        Crumb tmp = crumbListGamepad[top];
                        crumbListGamepad[top] = crumbListGamepad[i];
                        crumbListGamepad[i]   = tmp;

                        ++top;
                    }
                }
            }

            if (modalDisplay != null)
            {
                modalDisplay.LoadContent(immediate);
            }
        }   // end of LoadContent()
예제 #4
0
        }   // end of Print()

        #endregion

        #region Internal

        /// <summary>
        /// Given the targetMode, find the next crumb that will lead us from
        /// our current mode to the target.
        /// Returns null if no valid Crumb.
        /// </summary>
        /// <param name="targetMode"></param>
        /// <returns></returns>
        private static Crumb FindNextCrumb(GameMode targetMode)
        {
            crumbList.Clear();

            // Pick which list to use basedon current input mode.
            List <Crumb> crumbs = crumbListMouse;

            if (GamePadInput.ActiveMode == GamePadInput.InputMode.Touch)
            {
                crumbs = crumbListTouch;
            }
            else if (GamePadInput.ActiveMode == GamePadInput.InputMode.GamePad)
            {
                crumbs = crumbListGamepad;
            }

            // Start with the current mode.
            crumbList.Add(new CrumbNode(null, curGameMode, 0));

            int cur = 0;

            do
            {
                // For each crumb.
                for (int i = 0; i < crumbs.Count; i++)
                {
                    Crumb crumb = crumbs[i];
                    for (int j = 0; j < crumb.CurModes.Length; j++)
                    {
                        // Is this crumb a match?
                        if (crumbList[cur].mode == crumb.CurModes[j])
                        {
                            // See if this crumb's target is already in the list, if not, don't add it.
                            bool needToAdd = true;
                            for (int k = 0; k < crumbList.Count; k++)
                            {
                                if (crumbList[k].mode == crumb.targetMode)
                                {
                                    needToAdd = false;
                                    break;
                                }
                            }

                            if (needToAdd)
                            {
                                crumbList.Add(new CrumbNode(crumb, crumb.targetMode, cur));

                                // Are we done?
                                if (crumb.targetMode == targetMode)
                                {
                                    // Work backwards from what we just added and find the mode
                                    // along the path that has the current mode as its parent.
                                    cur = crumbList.Count - 1;
                                    while (crumbList[cur].parentIndex != 0)
                                    {
                                        cur = crumbList[cur].parentIndex;
                                    }

                                    // Found it!
                                    return(crumbList[cur].crumb);
                                }
                            }

                            break;
                        }
                    }
                }

                ++cur;
            } while (cur < crumbList.Count);

            // No solution found, return null.
            return(null);
        }   // end of FindNextCrumb()
예제 #5
0
 public CrumbNode(Crumb crumb, GameMode mode, int parent)
 {
     this.crumb       = crumb;
     this.mode        = mode;
     this.parentIndex = parent;
 }
예제 #6
0
        public static void Update()
        {
            // Lazy creation since we don't have a c'tor.
            if (modalDisplay == null)
            {
                modalDisplay = new ModalDisplay(OnContinue, OnBack, OnExitTutorial);
            }

            if (emptyCrumb == null)
            {
                emptyCrumb = new Crumb();
            }

            if (Active)
            {
                modalDisplay.Update();

                InGame.RestoreViewportToFull();

                // Adjust BokuGame screen size and position depending on whether or not the modal dialog is active.
                // When the dislog is active, we don't have the bar across the top so we should return to full size.
                // Note, when display is changing active/inactive we want to twitch.  When the screen size changes
                // because the window got resized we don't want to twitch.
                // TODO (****) Twitching taken out since it was getting mixed up.
                if (modalDisplay.Active)
                {
                    // Calc new screen size and position for full viewport.
                    BokuGame.ScreenSize     = new Vector2(BokuGame.bokuGame.GraphicsDevice.Viewport.Width, BokuGame.bokuGame.GraphicsDevice.Viewport.Height);
                    BokuGame.ScreenPosition = Vector2.Zero;
                }
                else
                {
                    // Yes, this looks clumsy.  The issue here is that the modalDisplay Update call may have
                    // deactivated tutorial mode.  If so, Active is no longer true and we don't want to mess
                    // with the screen position and size.
                    if (Active)
                    {
                        // Set the screen size to leave some room for the tutorial stuff.
                        float rtHeight = rt != null ? rt.Height : 0;
                        BokuGame.ScreenSize     = new Vector2(BokuGame.bokuGame.GraphicsDevice.Viewport.Width, BokuGame.bokuGame.GraphicsDevice.Viewport.Height - rtHeight);
                        targetPositionY         = BokuGame.bokuGame.GraphicsDevice.Viewport.Height - BokuGame.ScreenSize.Y;
                        BokuGame.ScreenPosition = new Vector2(0, targetPositionY);
                    }
                }
            }
            else
            {
                // Tutorial mode is not active.
            }
#if DEBUG
            // For testing purposes...
            if (KeyboardInput.WasPressed(Keys.F12))
            {
                if (Active)
                {
                    Deactivate();
                }
                else
                {
                    Activate();
                }
            }
#endif

            // Always keep this up to date in case someone else wants to use it.
            SetGameMode();

            if (curGameMode != lastGameMode)
            {
                lastGameMode = curGameMode;
            }

            // Test for null shouldn't be needed in normal operation but allows
            // for debugging of screen position and scaling without having to
            // run a full tutorial level.
            if (Active && InGame.XmlWorldData != null)
            {
                curStep = null;
                if (InGame.XmlWorldData.tutorialSteps.Count > 0)
                {
                    // Is the current step modal?  If so, activate the modal display if needed.
                    curStep = InGame.XmlWorldData.tutorialSteps[curStepIndex];
                    if (modalDisplay.Active == false && curStep.DisplayMode == Step.Display.Modal)
                    {
                        modalDisplay.Activate(curStep.GamepadText, curStep.MouseText, curStep.TouchText, true, true);
                    }
                }
                else
                {
                    // This only happens when the tutorial system is activated in debug mode
                    // and there's no actual tutorial.  So, create a fake, nonmodal step.
                    curStep                   = new Step();
                    curStep.DisplayMode       = Step.Display.NonModal;
                    curStep.GamepadText       = "Test";
                    curStep.MouseText         = "Test";
                    curStep.TargetModeGamepad = GameMode.MainMenu;
                    curStep.TargetModeMouse   = GameMode.MainMenu;
                }

                // NonModal?
                if (curStep.DisplayMode == Step.Display.NonModal)
                {
                    curCrumb = null;

                    targetModeReached |= CurGameMode == curStep.TargetMode;

                    // HACK When the target mode is GamepadEditObject and the curretn mode is
                    // GamepadEditObjectFocus we give the user the instruction to move the cursor
                    // to a blank spot int he world.  This kind of sucks.  So detect that case
                    // and set reached to true for either.
                    if (curStep.TargetMode == GameMode.GamepadEditObject && CurGameMode == GameMode.GamepadEditObjectFocus)
                    {
                        targetModeReached = true;
                    }

                    // Check for completion.  If we have a completion test then use that
                    // as the criteria.  If not, we consider the step complete when the
                    // target mode is reached.

                    if (curStep.CompletionTest == null)
                    {
                        if (targetModeReached)
                        {
                            OnContinue();
                        }
                    }
                    else
                    {
                        if (targetModeReached && curStep.CompletionTest.Evaluate())
                        {
                            OnContinue();
                        }
                    }

                    // Hack.  Right now the code is set up to latch targetModeReached until that step is
                    // completed.  This behavior is required for some things to work correctly but this
                    // also causes a problem; when the user moves away from the target mode they no
                    // longer get instructions on how to get to the target mode.  So hack in special
                    // case code for times where this a problem.
                    if ((targetModeReached && CurGameMode != curStep.TargetMode) &&
                        (
                            curStep.TargetMode == GameMode.Programming ||
                            curStep.TargetMode == GameMode.AddItem
                        ))
                    {
                        targetModeReached = false;
                    }

                    // Note yet at the target mode?  Get next crumb.
                    if (!targetModeReached)
                    {
                        curCrumb = FindNextCrumb(curStep.TargetMode);
                        //Debug.Assert(curCrumb != null, "Don't know how to get there from here...");
                    }

                    // Swallow any mouse clicks just in case user thinks to click on display.
                    // TODO (****) With changes, mouse hits will never be outside of active screen
                    // so this should never happen...

                    /*
                     * if (GamePadInput.ActiveMode == GamePadInput.InputMode.KeyboardMouse)
                     * {
                     *  Vector2 mouseHit = new Vector2(MouseInput.Position.X, MouseInput.Position.Y);
                     *  if (MouseInput.Left.WasPressedOrRepeat)
                     *  {
                     *      if (backdropBox.Contains(mouseHit))
                     *      {
                     *          MouseInput.Left.ClearAllWasPressedState();
                     *          Foley.PlayNoBudget();
                     *      }
                     *  }
                     *  if (MouseInput.Right.WasPressedOrRepeat)
                     *  {
                     *      if (backdropBox.Contains(mouseHit))
                     *      {
                     *          MouseInput.Right.ClearAllWasPressedState();
                     *          Foley.PlayNoBudget();
                     *      }
                     *  }
                     *  if (MouseInput.Middle.WasPressedOrRepeat)
                     *  {
                     *      if (backdropBox.Contains(mouseHit))
                     *      {
                     *          MouseInput.Middle.ClearAllWasPressedState();
                     *          Foley.PlayNoBudget();
                     *      }
                     *  }
                     * }
                     */
                }   // end if non-Modal

                // Find focus actor if needed.
                string focusActorName = curStep.TargetCharacter;
                if (string.IsNullOrEmpty(focusActorName))
                {
                    focusActor = null;
                }
                else
                {
                    // ALWAYS set the character to null since it may be destroyed any frame
                    // and we don't want to reference a missing character.
                    focusActor = null;
                    if (focusActor == null || focusActor.DisplayNameNumber != focusActorName)
                    {
                        for (int i = 0; i < InGame.inGame.gameThingList.Count; i++)
                        {
                            GameActor actor = InGame.inGame.gameThingList[i] as GameActor;
                            if (actor != null && actor.DisplayNameNumber == focusActorName)
                            {
                                // Found it!
                                focusActor = actor;
                                break;
                            }
                        }
                    }
                }
            } // end if active.
        }     // end of Update()