Scriptum/Assets/Scripts/REFACTORING/Application/Dialogue/MultiDialogue.cs
2022-12-28 16:16:08 +01:00

191 lines
6.1 KiB
C#

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<IndexValuePair<int, Dialogue>> 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<Tuple<string, Action>> {
new Tuple<string, Action>("AcceptButton", CustomPanel),
new Tuple<string, Action>("RejectButton", QuestionPanel)
}));*//*
DialogueStep.SetActionAfterDialogueEnds(() => { });
DialogueStepModel dialogueStepModel = new DialogueStepModel(DialogueStep);
DialogueStepsList = new List<DialogueStepModel> { 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();
}
/// <summary>
/// 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) :)
/// </summary>
public void ShowDialogueStepPanel()
{
Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.ShowDialogueStepPanel();
}
/// <summary>
/// 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
/// </summary>
public void GoToNextSentence()
{
Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.GoToNextSentence();
}
/// <summary>
/// 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
///
/// </summary>
/// <param name="dialogueNumber"></param>
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();
}
/// <summary>
/// Dialogue API
///
/// Function to finish current dialog and immediately start next one
///
/// </summary>
/// <param name="dialogueNumber"></param>
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<DialogueStepModel> Dialogue)
{
foreach (var dialogueStep in Dialogue)
{
dialogueStep.Header = SpeakerName;
dialogueStep.Build();
}
}
/// <summary>
/// Build each step of dialogue
/// </summary>
public void BuildDialogue(Dialogue Dialogue)
{
Dialogue.SetSpeakerName(SpeakerName);
Dialogue.BuildDialogue();
}
public void BuildCurrentDialogue()
{
BuildDialogue(Dialogues.Where(dial => dial.Key == CurrentDialogue).ToArray().First().Value);
}
/// <summary>
/// Function to reset rememebered dialogue status
///
/// (Scriptable objects clones are overwritten during clone modification)
/// </summary>
public void ResetDialogue()
{
Dialogues.ForEach(dial => dial.Value.DialogueSteps.ForEach(step => step.WasDisplayed = false));
}
public (int, int) DialogueStepStatus()
{
var currentDialogueStepIndex = Dialogues
.Where(el => el.Key == CurrentDialogue)
.Select(el => el.Value)
.First()
.DialogueSteps
.Where(step => step.WasDisplayed == true)
.ToArray()
.Count()
;
return(CurrentDialogue, currentDialogueStepIndex);
}
}