using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Sirenix.OdinInspector; using UnityEngine; using UnityEngine.Serialization; namespace Ichni.Story.UI { public partial class Storyline : MonoBehaviour { [Header("UI References")] public RectTransform content; // Content of ScrollRect [FormerlySerializedAs("textBlockPrefab")] public GameObject dialogBlockPrefab; // Prefab of UI Node public GameObject musicBlockPrefab; public GameObject tutorialBlockPrefab; public GameObject connectionCurvePrefab; // Prefab of connection curve [Header("Layout Settings")] public float marginLeft = 50f; // additive space on the left public float marginRight = 50f; // Extra space on the right public float marginTop = 50f; // Extra space on the top public float marginBottom = 50f; // Extra space on the bottom public RectTransform connectionContainer; public StoryBlockUIBase currentBlock; public List storyBlocks; public List dialogBlocks; public List songBlocks; public List tutorialBlocks; public List connectors; private void Start() { storyBlocks = new List(); dialogBlocks = new List(); songBlocks = new List(); tutorialBlocks = new List(); connectors = new List(); //TutorialBlockUI t0 = GenerateTutorialBlock(new Vector2(200, -400), "ZakoCurse 0"); //TextBlockUI b1 = GenerateTextBlock("Departure_P1_A", new Vector2(1000, -400), StoryBlockState.Current); SetUpStoryline(ChapterSelectionManager.instance.currentChapter); /*GenerateTextBlock("Departure_P1_A", new Vector2(1000, -400), StoryBlockState.Current); GenerateTextBlock("Departure_P2_A", new Vector2(1500, -400), StoryBlockState.Current); GenerateConnector("Departure_P1_A", "Departure_P2_A");*/ SetUpBackground(); connectionContainer.SetParent(content); connectionContainer.SetAsFirstSibling(); } } public partial class Storyline { public TutorialBlockUI GenerateTutorialBlock(string blockName, Vector2 position, StoryBlockState state) { TutorialBlockUI block = Instantiate(tutorialBlockPrefab, content).GetComponent(); StoryData storyData = StoryManager.instance.storyDatas[ChapterSelectionManager.instance.currentChapter]; TutorialBlockData blockData = storyData.tutorialBlockDatas.FirstOrDefault(data => data.blockName == blockName); if (blockData == null) throw new KeyNotFoundException("There is no block with name " + blockName); block.Initialize(blockData.blockName, position, new Vector2(marginLeft, 0), blockData.blockSize, state, blockData.tutorialName); storyBlocks.Add(block); tutorialBlocks.Add(block); return block; } public DialogBlockUI GenerateDialogBlock(string blockName, Vector2 position, StoryBlockState state) { DialogBlockUI block = Instantiate(dialogBlockPrefab, content).GetComponent(); StoryData storyData = StoryManager.instance.storyDatas[ChapterSelectionManager.instance.currentChapter]; DialogBlockData blockData = storyData.dialogBlockDatas.FirstOrDefault(data => data.blockName == blockName); if (blockData == null) throw new KeyNotFoundException("There is no block with name " + blockName); block.Initialize(blockData.blockName, position, new Vector2(marginLeft, 0), blockData.blockSize, state, blockData.dialogTitle); storyBlocks.Add(block); dialogBlocks.Add(block); return block; } public SongBlockUI GenerateSongBlock(string blockName, Vector2 position, StoryBlockState state) { SongBlockUI block = Instantiate(musicBlockPrefab, content).GetComponent(); StoryData storyData = StoryManager.instance.storyDatas[ChapterSelectionManager.instance.currentChapter]; SongBlockData blockData = storyData.songBlockDatas.FirstOrDefault(data => data.blockName == blockName); if (blockData == null) throw new KeyNotFoundException("There is no block with name " + blockName); block.Initialize(blockName,position,new Vector2(marginLeft, 0), blockData.blockSize, state, blockData.songName); storyBlocks.Add(block); songBlocks.Add(block); return block; } public void GenerateConnector(StoryBlockUIBase startBlock, StoryBlockUIBase endBlock) { BlockConnectorUI connector = Instantiate(connectionCurvePrefab, connectionContainer).GetComponent(); Vector2 startPosition = SpaceConverter.GetLocalUIPosition(startBlock.outPort, GetComponent()); Vector2 endPosition = SpaceConverter.GetLocalUIPosition(endBlock.inPort, GetComponent()); connector.startBlock = startBlock; connector.endBlock = endBlock; connector.SetCurve(startPosition, endPosition); connectors.Add(connector); } public void GenerateConnector(string startBlockName, string endBlockName) { StoryBlockUIBase startBlock = storyBlocks.FirstOrDefault(block => block.blockName == startBlockName); StoryBlockUIBase endBlock = storyBlocks.FirstOrDefault(block => block.blockName == endBlockName); GenerateConnector(startBlock, endBlock); } } public partial class Storyline { private void ClearStoryline() { foreach (var block in storyBlocks) { Destroy(block.gameObject); } storyBlocks.Clear(); dialogBlocks.Clear(); songBlocks.Clear(); tutorialBlocks.Clear(); foreach (var connector in connectors) { Destroy(connector.gameObject); } connectors.Clear(); content.sizeDelta = Vector2.zero; } private void SetUpBackground() { float maxRight = float.MinValue; foreach (var block in storyBlocks) { float rightEdge = block.blockRect.anchoredPosition.x + block.blockRect.sizeDelta.x * 0.5f; if (rightEdge > maxRight) { maxRight = rightEdge; } } maxRight += marginRight; if (maxRight < 2560f) { maxRight = 2560f; } float lowY = float.MaxValue; foreach (var block in storyBlocks) { float bottomEdge = block.blockRect.anchoredPosition.y - block.blockRect.sizeDelta.y * 0.5f; if (bottomEdge < lowY) { lowY = bottomEdge; } } float maxHeight = Mathf.Abs(lowY) + marginTop + marginBottom; if (maxHeight < 1440f) { maxHeight = 1440f; } content.sizeDelta = new Vector2(maxRight, maxHeight); } } public partial class Storyline { public void SetUpStoryline(string chapterName) { GameSaveManager.instance.StorySaveModule.LoadStoryline(chapterName); foreach (var blockSave in GameSaveManager.instance.StorySaveModule.tutorialBlockSaves[chapterName]) { GenerateTutorialBlock(blockSave.blockName, blockSave.position, blockSave.state); } foreach (var blockSave in GameSaveManager.instance.StorySaveModule.songBlockSaves[chapterName]) { GenerateSongBlock(blockSave.blockName, blockSave.position, blockSave.state); } foreach (var blockSave in GameSaveManager.instance.StorySaveModule.dialogBlockSaves[chapterName]) { GenerateDialogBlock(blockSave.blockName, blockSave.position, blockSave.state); } foreach (var connectorSave in GameSaveManager.instance.StorySaveModule.connectorSaves[chapterName]) { GenerateConnector(connectorSave.startBlockName, connectorSave.endBlockName); } } [Button] public void SaveStoryline(string chapterName) { List tutorialBlockSaves = tutorialBlocks.Select(block => block.GetBlockSave() as TutorialBlockSave).ToList(); List songBlockSaves = songBlocks.Select(block => block.GetBlockSave() as SongBlockSave).ToList(); List dialogBlockSaves = dialogBlocks.Select(block => block.GetBlockSave() as DialogBlockSave).ToList(); List connectorSaves = connectors.Select(connector => new BlockConnectorSave(connector.startBlock.blockName, connector.endBlock.blockName)).ToList(); GameSaveManager.instance.StorySaveModule.SaveStoryline( chapterName, tutorialBlockSaves, songBlockSaves, dialogBlockSaves, connectorSaves); } [Button] public void ResetStory() { ClearStoryline(); StoryData storyData = StoryManager.instance.storyDatas[ChapterSelectionManager.instance.currentChapter]; List initialBlocks = storyData.initialBlocks; foreach (InitialBlockData blockData in initialBlocks) { storyData.GetDataByName(blockData.blockName, out Type dataType); if (dataType == typeof(TutorialBlockData)) { GenerateTutorialBlock(blockData.blockName, blockData.blockPosition, blockData.initialState); } else if (dataType == typeof(DialogBlockData)) { GenerateDialogBlock(blockData.blockName, blockData.blockPosition, blockData.initialState); } else if (dataType == typeof(SongBlockData)) { GenerateSongBlock(blockData.blockName, blockData.blockPosition, blockData.initialState); } } foreach (InitialBlockData blockData in initialBlocks) { foreach (string nextBlockName in blockData.nextBlocks) { GenerateConnector(blockData.blockName, nextBlockName); } } SetUpBackground(); SaveStoryline(ChapterSelectionManager.instance.currentChapter); } } }