using System; using System.Collections.Generic; using System.Linq; using UnityEngine; [Serializable] [CreateAssetMenu(fileName = "New Dialogue", menuName = "Dialogue/New Multi Dialogue")] public class MultiDialogue : ScriptableObject, IDialogue { [SerializeField] public string SpeakerName; [SerializeField] public int CurrentDialogue = 0; [SerializeField] public List> Dialogues; /* Dialogues - list of dialoges Steps bucket (one dialogue unit) - list of liner 'steps', finished special action, whole can be stopped special requirements (like go and do something - to declared in 'finish action') Steps - its a cell package contains 'sentences' (one per panel) Sentence - its a opanel with phrase and buttons */ /* * WAZNE: * Jesli przechodzimy odpowiedzia do nastepnego dialogu musi to byc osttani panel w obecnym!!! */ public void Start() { /* CODE DIALOGUE DECLARATION EXAMPLE DialogueController DialogueStep = new DialogueController(); DialogueStep.AddSentence(new DialogueModel("lorem ipsum")); *//* di.AddSentence(new QuestionDialogueModel("tolore dolore?", new List> { new Tuple("AcceptButton", CustomPanel), new Tuple("RejectButton", QuestionPanel) }));*//* DialogueStep.SetActionAfterDialogueEnds(() => { }); DialogueStepModel dialogueStepModel = new DialogueStepModel(DialogueStep); DialogueStepsList = new List { dialogueStepModel }; */ /*if (MultiWayDialogue.Count > 0) BuildDialogue(MultiWayDialogue.Where(el => el.Key == CurrentDialogue).First().Value);*/ } public void SetSpeakerName(string speakerName) { SpeakerName = speakerName; Dialogues.ForEach(dialogue => dialogue.Value.SetSpeakerName(speakerName)); } public void StartDialogue() { // 1. Start Dialogue (build + show panel) Dialogues.Where(el => el.Key == CurrentDialogue).First().Value.StartDialogue(); } public void BreakDialogueStep() { // 1. Break Dialogue (close panel without marking as displayed) Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.BreakDialogueStep(); } /// /// Dialogue API /// /// MAIN bunction to begin dialogue /// Create new panel instance on scene by force with sentence from queue /// /// The best way is to invoked its after player reaction from other script (by event - collision) :) /// public void ShowDialogueStepPanel() { Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.ShowDialogueStepPanel(); } /// /// Dialogue API /// /// Default function to get next sentence if dialogue is currently started /// It is responsible for detecting /// 1) if there is any dialogue panel already created before displaying next sentence /// 2) if its last panel sentence and invoiking 'end dialogue' action /// /// Whats more, if there was no more sentences in 'step', althroughr closing panel go to next step automatiiccally /// public void GoToNextSentence() { Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.GoToNextSentence(); } /// /// Dialogue API /// /// Function to prepare next dialogue to start after one more palyer interaction with actor /// - ends current dialogue (destroy panel & invoke finish action - if setupped) /// - set new dialogue pointer /// /// /// public void SetNextDialogue(int dialogueNumber) { Debug.Log("----------------- SetNextDialogue"); Debug.Log(dialogueNumber); if (Dialogues.Where(el => el.Key == dialogueNumber).ToArray().Count() == 0) return; // 2. Chane index CurrentDialogue = dialogueNumber; // 1. Make sure to close current panel after finishing current dialogue and 'finish action' will invoked if setuped GoToNextSentence(); } /// /// Dialogue API /// /// Function to finish current dialog and immediately start next one /// /// /// public void GoToNextDialogue(int dialogueNumber) { // 1. Prepare necessary environoment parts SetNextDialogue(dialogueNumber); // 2. Build new (next) dialogue & show panel StartDialogue(); } // MUST BE IMPLEMENTED - INTERFACE RULES // USELESS IN THIS FILE public void BuildDialogue(List Dialogue) { foreach (var dialogueStep in Dialogue) { dialogueStep.Header = SpeakerName; dialogueStep.Build(); } } /// /// Build each step of dialogue /// public void BuildDialogue(Dialogue Dialogue) { Dialogue.SetSpeakerName(SpeakerName); Dialogue.BuildDialogue(); } public void BuildCurrentDialogue() { BuildDialogue(Dialogues.Where(dial => dial.Key == CurrentDialogue).ToArray().First().Value); } /// /// Function to reset rememebered dialogue status /// /// (Scriptable objects clones are overwritten during clone modification) /// public void ResetDialogue() { Dialogues.ForEach(dial => dial.Value.DialogueSteps.ForEach(step => step.WasDisplayed = false)); } public (int, int) DialogueStepStatus() { Debug.Log(CurrentDialogue); var currentDialogueStepIndex = Dialogues .Where(el => el.Key == CurrentDialogue) .Select(el => el.Value) .First() .DialogueSteps .Where(step => step.WasDisplayed == true) .ToArray() .Count() ; return(CurrentDialogue, currentDialogueStepIndex); } }