using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; public class Tutorial : MonoBehaviour { TMPro.TMP_Text tutorialText; public UnityEngine.UI.Button escapeButton; void SetText(string label, string fallbackText = "") { var localized = Localization.GetString(label); if (localized == "E-R-R-O-R") localized = fallbackText; Debug.LogFormat("Setting tutorial text to {0}", localized); tutorialText.text = localized; } public GameBoard board; void Drop() => board.board = board.DropNow(board.board); WaitUntil UntilDrop() => new WaitUntil(() => board.delayState.Equals(GameBoard.DelayState.None)); // Start is called before the first frame update void Start() { board.Setup(); board.StartGame(); board.AIEnabled = true; // Disable player input on the board tutorialText = GetComponent(); escapeButton.onClick.AddListener(() => Application.LoadLevel(0)); StartCoroutine(TutorialRoutine()); } IEnumerator TutorialRoutine() { board.board = BoardStateExtension.Initialize(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); board.currentPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); SetText("TUTORIAL_INTRO", "Welcome to Touhou: Luminous Strike!"); yield return new WaitForSeconds(2.5f); activePatchyNumber = 2; SetText("TUTORIAL_INTRO1", "The goal of the game is to place and light lanterns on your board."); var bs = board.board; // Fill the bottom three rows with blue lanterns for (int i = 0; i < 3; i++) { yield return PlayerMove((0, 0)); Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); yield return PlayerMove((2, 0)); yield return UntilDrop(); Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); yield return PlayerMove((4, 0)); yield return UntilDrop(); Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); } board.currentPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Activator, TileColor.Yellow)); SetText("TUTORIAL_INTRO2", "Attack by igniting your lanterns with a flame, the more you ignite, the bigger the attack"); yield return PlayerMove((3, 0)); yield return new WaitForSeconds(2f); board.nextPair = (new TileInfo(TileKind.Activator, TileColor.Yellow), new TileInfo(TileKind.Activator, TileColor.Blue)); Drop(); activePatchyNumber = 3; board.nextPair = (new TileInfo(TileKind.Activator, TileColor.Red), new TileInfo(TileKind.Activator, TileColor.Green)); yield return UntilDrop(); SetText("TUTORIAL_COLORS", "But of course, lanterns come in a variety of colors"); activePatchyNumber = 1; for (int i = 0; i < GameBoard.COLUMN; ++i) { bs[i].AddRange(new[] { new TileInfo(TileKind.Block, TileColor.Red), new TileInfo(TileKind.Block, TileColor.Blue), new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Green) }); yield return new WaitForSeconds(0.5f); } yield return new WaitForSeconds(1.5f); SetText("TUTORIAL_COLORS2", "Only flames of same color can ignite lanterns. If you use this carefully you can create combos!"); yield return PlayerMove((2, 0)); yield return new WaitForSeconds(1f); activePatchyNumber = 1; Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); yield return PlayerMove((4, 0)); yield return new WaitForSeconds(1f); activePatchyNumber = 2; Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Activator, TileColor.Yellow)); yield return UntilDrop(); //board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); SetText("TUTORIAL_COLORS3", "As you can see, combos can be quite big!"); for (int i = 0; i < GameBoard.COLUMN; ++i) { bs[i].AddRange(new[] { new TileInfo(TileKind.Block, TileColor.Yellow,0), new TileInfo(TileKind.Block, TileColor.Yellow,0), new TileInfo(TileKind.Trash,TileColor.Yellow,5) }); yield return new WaitForSeconds(0.5f); } activePatchyNumber = 3; SetText("TUTORIAL_TRASH", "When the other player ingites lanterns, you will be bombarded with sealed lanterns"); yield return new WaitForSeconds(2f); Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); yield return PlayerMove((4, 0)); yield return UntilDrop(); yield return new WaitForSeconds(2f); activePatchyNumber = 1; SetText("TUTORIAL_TRASH2", "Sealed lanterns can't be ignited, but after enough moves, the seal breaks."); for (int i = 0; i < 4; ++i) { Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Activator, TileColor.Yellow)); yield return PlayerMove((i, 0)); yield return UntilDrop(); } board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); board.currentPair = (new TileInfo(TileKind.Activator, TileColor.Red), new TileInfo(TileKind.Special, TileColor.Yellow)); yield return new WaitForSeconds(3f); activePatchyNumber = 2; SetText("TUTORIAL_TRASH3", "The rare rainbow-flame however ignites all laterns of the provided color, even if they are sealed"); for (int i = 0; i < GameBoard.COLUMN; ++i) { bs[i].AddRange(new[] { new TileInfo(TileKind.Block, TileColor.Yellow,0), new TileInfo(TileKind.Block, TileColor.Red,0), new TileInfo(TileKind.Trash,TileColor.Yellow,5) }); yield return new WaitForSeconds(0.5f); } yield return PlayerMove((0, 0)); Drop(); board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Yellow)); board.currentPair = (new TileInfo(TileKind.Block, TileColor.Red), new TileInfo(TileKind.Block, TileColor.Red)); yield return UntilDrop(); yield return new WaitForSeconds(2f); SetText("TUTORIAL_EXTRA", "Lanterns always come in pairs, but you can swap with the next pair by pressing [Z]"); activePatchyNumber = 3; for (int i = 0; i < 5; ++i) { board.SwapTiles(); yield return new WaitForSeconds(1f); } board.nextPair = (new TileInfo(TileKind.Block, TileColor.Yellow), new TileInfo(TileKind.Block, TileColor.Red)); board.currentPair = (new TileInfo(TileKind.Block, TileColor.Red), new TileInfo(TileKind.Block, TileColor.Yellow)); activePatchyNumber = 1; SetText("TUTORIAL_EXTRA2", "Even more useful, you can rotate your lanterns with UP/DOWN"); yield return PlayerMove((3, 0)); for (int i = 0; i < 12; ++i) { board.playerRotation = i % 4; yield return new WaitForSeconds(0.5f); } activePatchyNumber = 3; SetText("TUTORIAL_EXTRA3", "Finally, be cautious, as if your board fills up, it will collapse and you will lose."); for (int i = 0; i < 12; ++i) { yield return new WaitForSeconds(0.15f); for (int j = 0; j < GameBoard.COLUMN; ++j) { yield return new WaitForSeconds(0.05f); bs[j].Add(TileInfo.CreateRandomTrashTile()); } } board.Clear(); yield return new WaitForSeconds(5f); activePatchyNumber = 1; SetText("TUTORIAL_EXTRA4", "That's all I have to share with you, please enjoy playing Luminous Strike"); yield return new WaitForSeconds(5f); Application.LoadLevel(0); } IEnumerator PlayerMove((int c, int r) goal, float actionTime = 0.2f) { board.playerRotation = goal.r; // instantly rotate we're lazy here while (goal.c < board.dropColumn) { board.dropColumn -= 1; yield return new WaitForSeconds(actionTime); } while (goal.c > board.dropColumn) { board.dropColumn += 1; yield return new WaitForSeconds(actionTime); } } public int activePatchyNumber = 1; public GameObject Patchy1, Patchy2, Pacthy3; // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Escape)) { Application.LoadLevel(0); } Patchy1.SetActive(activePatchyNumber == 1); Patchy2.SetActive(activePatchyNumber == 2); Pacthy3.SetActive(activePatchyNumber == 3); } }