using System; using System.Collections.Generic; using System.Linq; using System.Text; using VBXSE; using Microsoft.Xna.Framework; namespace DIGIEVO { public static class Menu { public enum NotificationReason { None, ConfirmLearnMove, ConfirmForget, FatalError, ConfirmLearnTrait, ConfirmLearnMoveFinal, ConfirmLearnTraitFinal, ConfirmErase } public static List menuElements; public static List buttons; public static List buttonTexts; public static int selectedButton = 0; public const string SPRITE_BUTTON_PASSIVE = "AttackButtonPassive"; public const string SPRITE_BUTTON_ACTIVE = "AttackButtonActive"; public static Sprite background1; public static Sprite background2; public const float BACKGROUND_MOVE_SPEED = 30; public static Creature presentedCreature = null; public static List creaturePresentationObjects = null; public static GText spriteText = null; public static bool mayEvolve = false; public static int creatureRequestStatus = -1; public static GText moveName = null; public static GText moveExpl = null; public static Input.InputMode previousInput = Input.InputMode.VerticalMenu; public static void OpenMenu(Main.Menus menu) { Main.currentMenu = menu; OpenMenu(); } public static void OpenMenu() { Combat.auto = false; selectedButton = 0; Input.inputMode = Input.InputMode.VerticalMenu; menuElements = new List(); buttons = new List(); buttonTexts = new List(); bool printCreature = true; bool printStats = true; SpriteEngine.EraseGObject(background1); SpriteEngine.EraseGObject(background2); bool evo = false; switch(Main.currentMenu) { case Main.Menus.Profile: evo = true; break; case Main.Menus.Traits: case Main.Menus.Moves: evo = false; if (presentedCreature != null) if (presentedCreature.pass != Main.creature.pass) evo = true; break; } if (evo) { background1 = SpriteEngine.CreateSprite("backgroundEvo", 0, 0, 1f); background2 = SpriteEngine.CreateSprite("backgroundEvo", 800, 0, 1f); } else { background1 = SpriteEngine.CreateSprite("background", 0, 0, 1f); background2 = SpriteEngine.CreateSprite("background", 800, 0, 1f); } background1.depth = 500; background2.depth = 501; switch (Main.currentMenu) { case Main.Menus.Main: Main.creature.FullHeal(); presentedCreature = Main.creature; CreateSideMenu(new string[] { "LOCAL BATTLE", "RANDOM BATTLE", "CUSTOM BATTLE", "AUTO BATTLE", "EVOLVE", "LIST MOVES", "LIST TRAITS", "EXIT" }); break; case Main.Menus.ListOfEnemies: CreateSideMenu(new string[] { "DUMMY", "DISABLER", "FIGHTER", "ELEMENTAL", "DUMMY EX", "DISABLER EX", "FIGHTER EX", "ELEMENTAL EX", "(BACK)" }); break; case Main.Menus.Profile: if (mayEvolve) { CreateSideMenu(new string[] { "EVOLVE MOVES", "EVOLVE TRAITS", "(BACK)" }); } else { CreateSideMenu(new string[] { "VIEW MOVES", "VIEW TRAITS", "(BACK)" }); } break; case Main.Menus.EvolveKey: printCreature = false; PrintExplanation(new string[] { "To EVOLVE your CREATURE, you will need to obtain the CODE", "of another player's CREATURE. You will then be able to spend", "EXP to evolve one of that CREATURE's MOVEs or TRAITs." }); menuElements.Add(SpriteEngine.CreateGText("Please enter the CODE to EVOLVE with:", 400 - "Please enter they CODE to EVOLVE with:".Length * 8, 280)); spriteText = SpriteEngine.CreateGText("_", 392, 320); menuElements.Add(spriteText); Input.StartTextEntry(); break; case Main.Menus.CustomBattle: printCreature = false; PrintExplanation(new string[] { "Enter a CREATURE's CODE here to have a friendly battle with", "that CREATURE. Friendly battles do not earn you any EXP." }); menuElements.Add(SpriteEngine.CreateGText("Please enter the CODE to battle with:", 400 - "Please enter they CODE to battle with:".Length * 8, 280)); spriteText = SpriteEngine.CreateGText("_", 392, 320); menuElements.Add(spriteText); Input.StartTextEntry(); break; case Main.Menus.AutoBattle: printCreature = false; PrintExplanation(new string[] { "AUTO BATTLES let you have a battle where both sides", "pick their moves randomly.", "Enter a CREATURE's CODE here to have a friendly battle with", "that CREATURE. Friendly battles do not earn you any EXP." }); menuElements.Add(SpriteEngine.CreateGText("Please enter the CODE to battle with:", 400 - "Please enter they CODE to battle with:".Length * 8, 280)); spriteText = SpriteEngine.CreateGText("_", 392, 320); menuElements.Add(spriteText); Input.StartTextEntry(); break; case Main.Menus.NameCreature: printCreature = false; PrintExplanation(new string[] { "Welcome to the DIGIEVO system. In the DIGIEVO system you", "will control a CREATURE in battle and help it EVOLVE", "using CODEs gained from other players. Before you start,", "please give your CREATURE a NAME." }); menuElements.Add(SpriteEngine.CreateGText("Please enter the NAME of your CREATURE:", 400 - "Please enter the NAME of your CREATURE:".Length * 8, 280)); spriteText = SpriteEngine.CreateGText("_", 392, 320); menuElements.Add(spriteText); Input.StartTextEntry(); break; case Main.Menus.Moves: printStats = false; List theMoves = new List(); for (int i = 0; i < presentedCreature.moves.Count; i++) { theMoves.Add(presentedCreature.moves[i].name + " (" + presentedCreature.moves[i].maxPP + ")"); } theMoves.Add("(BACK)"); CreateSideMenu(theMoves.ToArray()); Sprite explainSprite = SpriteEngine.CreateSprite("explanation", 0, 0, 1f); explainSprite.depth = -200; menuElements.Add(explainSprite); menuElements.Add(moveName = SpriteEngine.CreateGText("", 20, 340)); moveName.depth = -250; menuElements.Add(moveExpl = SpriteEngine.CreateGText("", 20, 400)); moveExpl.depth = -250; UpdateSelected(); break; case Main.Menus.Traits: printStats = false; List theTraits = new List(); for (int i = 0; i < presentedCreature.traits.Count; i++) { theTraits.Add(presentedCreature.traits[i].name); } theTraits.Add("(BACK)"); CreateSideMenu(theTraits.ToArray()); Sprite explainSprite2 = SpriteEngine.CreateSprite("explanation", 0, 0, 1f); explainSprite2.depth = -200; menuElements.Add(explainSprite2); menuElements.Add(moveName = SpriteEngine.CreateGText("", 20, 340)); moveName.depth = -250; menuElements.Add(moveExpl = SpriteEngine.CreateGText("", 20, 400)); moveExpl.depth = -250; UpdateSelected(); break; } if(printCreature) PresentCreature(printStats); } public static void PrintExplanation(string[] lines, int verticalStart = 100) { for (int i = 0; i < lines.Length; i++) { menuElements.Add(SpriteEngine.CreateGText(lines[i], 400 - (int)Math.Floor(lines[i].Length * 6.5f), 100 + 40 * i)); } } public static void PresentCreature(bool stats = true) { EraseCreature(); creaturePresentationObjects = new List(); int startX = 150; if (presentedCreature != null) { creaturePresentationObjects.Add(presentedCreature.CreateSprite(startX, 120)); creaturePresentationObjects.Add(SpriteEngine.CreateGText(presentedCreature.name, startX + 64 - presentedCreature.name.Length * 8, 90)); creaturePresentationObjects.Add(SpriteEngine.CreateGText("CODE:", startX + 64 - 5 * 8, 250)); creaturePresentationObjects.Add(SpriteEngine.CreateGText(presentedCreature.code, startX + 64 - presentedCreature.code.Length * 8, 280)); int basef = 340; int gap = 30; if (stats) { AddCreatureLine("Element: " + Convert.ToString(presentedCreature.element), startX, basef + gap * 0); AddCreatureLine("HP: " + presentedCreature.GetMaxHP(), startX, basef + gap * 1); AddCreatureLine("ATK: " + presentedCreature.GetATK(), startX, basef + gap * 2); AddCreatureLine("DEF: " + presentedCreature.GetDEF(), startX, basef + gap * 3); AddCreatureLine("SPC: " + presentedCreature.GetSPC(), startX, basef + gap * 4); AddCreatureLine("AGI: " + presentedCreature.GetAGI(), startX, basef + gap * 5); AddCreatureLine("EXP: " + presentedCreature.EXP, startX, basef + gap * 6); AddCreatureLine("POWER RATING: " + presentedCreature.totalEXP, startX, basef + gap * 7); } } } public static void AddCreatureLine(string message, int startX, int y) { creaturePresentationObjects.Add(SpriteEngine.CreateGText(message, startX + 64 - message.Length * 8, y)); } public static void EraseCreature() { if (creaturePresentationObjects != null) { for (int i = 0; i < creaturePresentationObjects.Count; i++) { SpriteEngine.EraseGObject(creaturePresentationObjects[i]); } } } public static void CreateSideMenu(string[] contents) { for (int i = 0; i < contents.Length; i++) { Sprite button = SpriteEngine.CreateMultiSprite(new string[] { SPRITE_BUTTON_PASSIVE, SPRITE_BUTTON_ACTIVE }, 450, 100 + 45 * i, 1f); buttons.Add(button); menuElements.Add(button); GText buttonText = SpriteEngine.CreateGText(contents[i], 460, 100 + 45 * i + 5); buttonTexts.Add(buttonText); menuElements.Add(buttonText); if (Main.currentMenu == Main.Menus.Moves) { if (i < presentedCreature.moves.Count) { if (Main.creature.pass != presentedCreature.pass) { if (!mayEvolve) button.color = Microsoft.Xna.Framework.Color.DarkGray; if (presentedCreature.moves[i].expcost > Main.creature.EXP) button.color = Microsoft.Xna.Framework.Color.DarkGray; for (int ii = 0; ii < Main.creature.moves.Count; ii++) { if (presentedCreature.moves[i].type == Main.creature.moves[ii].type) button.color = Microsoft.Xna.Framework.Color.DarkGray; } } } } if (Main.currentMenu == Main.Menus.Traits) { if (i < presentedCreature.traits.Count) { if (Main.creature.pass != presentedCreature.pass) { if (!mayEvolve) button.color = Microsoft.Xna.Framework.Color.DarkGray; if (presentedCreature.traits[i].expCost > Main.creature.EXP) button.color = Microsoft.Xna.Framework.Color.DarkGray; for (int ii = 0; ii < Main.creature.traits.Count; ii++) { if (presentedCreature.traits[i].type == Main.creature.traits[ii].type) button.color = Microsoft.Xna.Framework.Color.DarkGray; } } } } } UpdateSelected(); } public static void CloseMenu() { EraseCreature(); for (int i = 0; i < menuElements.Count; i++) SpriteEngine.EraseGObject(menuElements[i]); } public static void UpdateSelected() { for (int i = 0; i < buttons.Count; i++) { if (i == selectedButton) buttons[i].currentImage = 1; else buttons[i].currentImage = 0; } if (Main.currentMenu == Main.Menus.Moves) { if (selectedButton < buttons.Count - 1) { if (moveName != null) { moveName.text = presentedCreature.moves[selectedButton].name; } if (moveExpl != null) { moveExpl.text = "Element: " + Convert.ToString(presentedCreature.moves[selectedButton].element) + "\n" + presentedCreature.moves[selectedButton].description; if (presentedCreature.pass != Main.creature.pass) moveExpl.text += "\n\nEvolve cost: " + presentedCreature.moves[selectedButton].expcost; } } else { if (moveName != null) { moveName.text = "(BACK)"; } if (moveExpl != null) { moveExpl.text = "Returns to the previous menu."; } } } if (Main.currentMenu == Main.Menus.Traits) { if (selectedButton < buttons.Count - 1) { if (moveName != null) { moveName.text = presentedCreature.traits[selectedButton].name; } if (moveExpl != null) { moveExpl.text = presentedCreature.traits[selectedButton].description; if (presentedCreature.pass != Main.creature.pass) moveExpl.text += "\n\nEvolve cost: " + presentedCreature.traits[selectedButton].expCost; } } else { if (moveName != null) { moveName.text = "(BACK)"; } if (moveExpl != null) { moveExpl.text = "Returns to the previous menu."; } } } if (Main.currentMenu == Main.Menus.Traits || Main.currentMenu == Main.Menus.Moves) { //Center on selected choice (located at normal #2) for (int i = 0; i < buttons.Count; i++) { //145 +- 45 int ypos = 145; if (i < selectedButton) ypos = 145 - 45 * (selectedButton - i); else if (i > selectedButton) ypos = 145 + 45 * (i - selectedButton); buttons[i].SetY(ypos); buttonTexts[i].SetY(ypos); } } } public static void MoveSelection(int direction) { Audio.PlaySound("cursor"); selectedButton += direction; if (selectedButton < 0) selectedButton = buttons.Count - 1; if (selectedButton >= buttons.Count) selectedButton = 0; UpdateSelected(); } public static void Confirm() { Audio.PlaySound("confirm"); switch (Main.currentMenu) { case Main.Menus.Main: switch (selectedButton) { case 0: //Local battle Combat.friendly = false; CloseMenu(); OpenMenu(Main.Menus.ListOfEnemies); break; case 1: //Random battle Combat.friendly = false; CloseMenu(); Main.RequestRandomBattle(Main.creature.totalEXP); break; case 2: //Custom battle CloseMenu(); OpenMenu(Main.Menus.CustomBattle); break; case 3: //Auto battle CloseMenu(); OpenMenu(Main.Menus.AutoBattle); break; case 4: //Evolution CloseMenu(); OpenMenu(Main.Menus.EvolveKey); break; case 5: //List Moves CloseMenu(); OpenMenu(Main.Menus.Moves); break; case 6: //List Traits CloseMenu(); OpenMenu(Main.Menus.Traits); break; case 7: //Exit Main.QuitGame(); break; } break; case Main.Menus.ListOfEnemies: if (selectedButton == buttons.Count - 1) { CloseMenu(); OpenMenu(Main.Menus.Main); } else { Creature.EnemyType enemy = Creature.EnemyType.TrainingDummy; switch (buttonTexts[selectedButton].text) { case "DUMMY": enemy = Creature.EnemyType.TrainingDummy; break; case "DISABLER": enemy = Creature.EnemyType.Disabler; break; case "FIGHTER": enemy = Creature.EnemyType.Fighter; break; case "ELEMENTAL": enemy = Creature.EnemyType.Elemental; break; case "DUMMY EX": enemy = Creature.EnemyType.DummyEx; break; case "DISABLER EX": enemy = Creature.EnemyType.DisablerEx; break; case "FIGHTER EX": enemy = Creature.EnemyType.FighterEx; break; case "ELEMENTAL EX": enemy = Creature.EnemyType.ElementalEx; break; } SpriteEngine.Nuke(); Combat.StartCombat(new Creature(enemy)); } break; case Main.Menus.Profile: switch (selectedButton) { case 0: CloseMenu(); OpenMenu(Main.Menus.Moves); break; case 1: CloseMenu(); OpenMenu(Main.Menus.Traits); break; case 2: Cancel(); break; } break; case Main.Menus.Moves: if (selectedButton == buttons.Count - 1) Cancel(); else { if (presentedCreature.pass != Main.creature.pass) { if (mayEvolve) { bool ownsAttack = false; for (int i = 0; i < Main.creature.moves.Count; i++) { if (Main.creature.moves[i].type == presentedCreature.moves[selectedButton].type) ownsAttack = true; } if (!ownsAttack) { if (presentedCreature.moves[selectedButton].expcost <= Main.creature.EXP) { ShowNotification("It will cost " + presentedCreature.moves[selectedButton].expcost + " EXP to learn this move.\n\nPress Y or Z to learn this move.\nPress N or X to cancel.", NotificationReason.ConfirmLearnMove, true); } } } } else { ShowNotification("Do you wish to forget the move " + presentedCreature.moves[selectedButton].name + "?\n\nPress Y or Z to forget this move.\nPress N or X to cancel.", NotificationReason.ConfirmForget, true); } } break; case Main.Menus.Traits: if (selectedButton == buttons.Count - 1) Cancel(); else { if (presentedCreature.pass != Main.creature.pass) { if (mayEvolve) { bool ownsTrait = false; for (int i = 0; i < Main.creature.traits.Count; i++) { if (Main.creature.traits[i].type == presentedCreature.traits[selectedButton].type) ownsTrait = true; } if (!ownsTrait) { if (presentedCreature.traits[selectedButton].expCost <= Main.creature.EXP) { ShowNotification("It will cost " + presentedCreature.moves[selectedButton].expcost + " EXP to gain this trait.\n\nPress Y or Z to gain this trait.\nPress N or X to cancel.", NotificationReason.ConfirmLearnTrait, true); } } } } else { ShowNotification("Do you wish to erase the trait " + presentedCreature.traits[selectedButton].name + "?\n\nPress Y or Z to erase this trait.\nPress N or X to cancel.", NotificationReason.ConfirmErase, true); } } break; case Main.Menus.NameCreature: if (Input.enteredText != "") { Main.creature.name = Input.enteredText; Main.SendCreature(); Menu.CloseMenu(); Menu.OpenMenu(Main.Menus.Main); } break; case Main.Menus.EvolveKey: creatureRequestStatus = -1; Main.AskCreature(Input.enteredText); Menu.CloseMenu(); while (creatureRequestStatus == -1) { System.Threading.Thread.Sleep(50); } if (creatureRequestStatus == 1) Menu.OpenMenu(Main.Menus.Profile); else { Menu.OpenMenu(Main.Menus.Main); Menu.ShowNotification("No creature with that code exists within the\nDIGIEVO system."); } break; case Main.Menus.CustomBattle: creatureRequestStatus = -1; Main.AskCreature(Input.enteredText); Menu.CloseMenu(); while (creatureRequestStatus == -1) { System.Threading.Thread.Sleep(50); } if (creatureRequestStatus == 1) { Combat.friendly = true; Combat.StartCombat(Menu.presentedCreature); } else { Menu.OpenMenu(Main.Menus.Main); Menu.ShowNotification("No creature with that code exists within the\nDIGIEVO system."); } break; case Main.Menus.AutoBattle: creatureRequestStatus = -1; Main.AskCreature(Input.enteredText); Menu.CloseMenu(); while (creatureRequestStatus == -1) { System.Threading.Thread.Sleep(50); } if (creatureRequestStatus == 1) { Combat.friendly = true; Combat.auto = true; Combat.StartCombat(Menu.presentedCreature); } else { Menu.OpenMenu(Main.Menus.Main); Menu.ShowNotification("No creature with that code exists within the\nDIGIEVO system."); } break; } } public static void Cancel() { Audio.PlaySound("confirm"); //TODO: Cancel sound switch (Main.currentMenu) { case Main.Menus.Main: if (selectedButton == 5) Main.QuitGame(); else { selectedButton = 5; UpdateSelected(); } break; case Main.Menus.EvolveKey: CloseMenu(); OpenMenu(Main.Menus.Main); break; case Main.Menus.NameCreature: Main.QuitGame(); break; case Main.Menus.Moves: case Main.Menus.Traits: CloseMenu(); if (presentedCreature.pass == Main.creature.pass) { OpenMenu(Main.Menus.Main); } else { OpenMenu(Main.Menus.Profile); } break; case Main.Menus.Profile: CloseMenu(); OpenMenu(Main.Menus.Main); break; } } public static NotificationReason notificationReason = NotificationReason.None; public static Sprite notificationSprite = null; public static GText notificationGText = null; public static void ShowNotification(string message, NotificationReason reason = NotificationReason.None, bool yesno = false) { previousInput = Input.inputMode; notificationReason = reason; Input.inputMode = Input.InputMode.Notification; if (yesno) Input.inputMode = Input.InputMode.YesNo; notificationSprite = SpriteEngine.CreateSprite("notification", 0, 0, 1f); notificationSprite.depth = -500; notificationGText = SpriteEngine.CreateGText(message, 100, 215); notificationGText.depth = -550; } public static void ConfirmNotification() { SpriteEngine.EraseGObject(notificationSprite); SpriteEngine.EraseGObject(notificationGText); Input.inputMode = previousInput; switch (notificationReason) { case NotificationReason.ConfirmForget: Main.creature.moves.RemoveAt(selectedButton); Main.SendCreature(); Menu.CloseMenu(); Menu.OpenMenu(); break; case NotificationReason.ConfirmErase: Main.creature.traits.RemoveAt(selectedButton); Main.creature.ApplyTraits(); Main.SendCreature(); Menu.CloseMenu(); Menu.OpenMenu(); break; case NotificationReason.ConfirmLearnMove: if (Main.creature.LearnMove(presentedCreature.moves[selectedButton])) { Main.creature.EXP -= presentedCreature.moves[selectedButton].expcost; Main.EvolutionNotice(presentedCreature.code); //Menu.mayEvolve = false; Main.SendCreature(); Menu.ShowNotification(Main.creature.name + " has learned " + presentedCreature.moves[selectedButton].name + "!", NotificationReason.ConfirmLearnMoveFinal); //CloseMenu(); //OpenMenu(); } break; case NotificationReason.ConfirmLearnTrait: Main.creature.LearnTrait(presentedCreature.traits[selectedButton]); Main.creature.EXP -= presentedCreature.traits[selectedButton].expCost; Main.EvolutionNotice(presentedCreature.code); //Menu.mayEvolve = false; Main.SendCreature(); Menu.ShowNotification(Main.creature.name + " has gained " + presentedCreature.traits[selectedButton].name + "!", NotificationReason.ConfirmLearnTraitFinal); //CloseMenu(); //OpenMenu(); break; case NotificationReason.FatalError: Main.QuitGame(); break; case NotificationReason.ConfirmLearnMoveFinal: case NotificationReason.ConfirmLearnTraitFinal: CloseMenu(); OpenMenu(); break; } } public static void CancelNotification() { switch(notificationReason) { case NotificationReason.ConfirmLearnMove: case NotificationReason.ConfirmLearnTrait: CloseMenu(); OpenMenu(); break; } SpriteEngine.EraseGObject(notificationSprite); SpriteEngine.EraseGObject(notificationGText); Input.inputMode = previousInput; } private static float remainder1 = 0; private static float remainder2 = 0; public static void Update(GameTime gameTime) { if (background1 != null && background2 != null) { float tempChange1 = (float)gameTime.ElapsedGameTime.TotalSeconds * (float)BACKGROUND_MOVE_SPEED + remainder1; float realChange1 = (float)Math.Floor(tempChange1); remainder1 = tempChange1 - realChange1; float tempChange2 = (float)gameTime.ElapsedGameTime.TotalSeconds * (float)BACKGROUND_MOVE_SPEED + remainder2; float realChange2 = (float)Math.Floor(tempChange2); remainder2 = tempChange2 - realChange2; background1.SetX((float)background1.position.X - realChange1); background2.SetX((float)background2.position.X - realChange2); if (background1.position.X <= -800) background1.SetX(background1.position.X + 1600); if (background2.position.X <= -800) background2.SetX(background2.position.X + 1600); } switch (Main.currentMenu) { case Main.Menus.EvolveKey: case Main.Menus.NameCreature: case Main.Menus.CustomBattle: case Main.Menus.AutoBattle: if (spriteText != null) { spriteText.text = Input.enteredText + "_"; spriteText.SetX(400 - (Input.enteredText.Length + 1) * 8); } break; } } } }