Scriptum/Assets/Scripts/REFACTORING/Application/Dialogue/Dialogue.cs
2022-12-04 20:48:40 +01:00

203 lines
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[Serializable]
[CreateAssetMenu(fileName = "New Dialogue", menuName = "Dialogue/New Dialogue")]
public class Dialogue : ScriptableObject
{
[SerializeField]
int CurrentDialogue = 0;
[SerializeField]
public List<IndexValuePair<int, List<DialogueStepModel>>> MultiWayDialogue;
/*
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 StartDialogue()
{
// 1. Build
BuildDialogue(MultiWayDialogue.Where(el => el.Key == CurrentDialogue).First().Value);
// 2. Show first step
ShowStep();
}
public void BreakDialogue()
{
// 1. Find first yet undisplayed for player anbd show
var dialogueStepsList = MultiWayDialogue.Where(el => el.Key == CurrentDialogue).ToArray().First().Value;
foreach (var DialogueStep in dialogueStepsList)
{
Debug.Log($"List of dialogue count: {DialogueStep.DialogueController.listOfDialogue.Count}");
if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0)
{
Debug.Log("Break Dialogue - close panel");
DialogueStep.DialogueController.CloseCurrentPanel(); // close panel
break;
}
Debug.Log("a");
}
}
/// <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 ShowStep()
{
// 1. Find first yet undisplayed for player anbd show
var dialogueStepsList = MultiWayDialogue.Where(el => el.Key == CurrentDialogue).ToArray().First().Value;
foreach (var DialogueStep in dialogueStepsList)
{
if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0)
{
DialogueStep.DialogueController.Show(DialogueStep.DialogueController.listOfDialogue.Dequeue()); // create panel
break;
}
}
}
/// <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()
{
// 1. Find first yet undisplayed for player anbd show
var dialogueStepsList = MultiWayDialogue.Where(el => el.Key == CurrentDialogue).ToArray().First().Value;
foreach (var DialogueStep in dialogueStepsList)
{
if (!DialogueStep.WasDisplayed)
{
var nextSentence = DialogueStep.DialogueController.ShowNextPanel(DialogueStep.DialogueController);
if (!nextSentence)
{
DialogueStep.WasDisplayed = true;
ShowStep();
}
break;
}
}
}
/// <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)
{
if (MultiWayDialogue.Where(el => el.Key == dialogueNumber).ToArray().Count() == 0)
return;
// 1. Make sure to close current panel after finishing current dialogue and 'finish action' will invoked if setuped
GoToNextSentence();
// 2. Chane index
CurrentDialogue = dialogueNumber;
}
/// <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);
// 3. Build new dialogue
BuildDialogue(MultiWayDialogue.Where(el => el.Key == CurrentDialogue).First().Value);
// 4. Start new dialogue bucket
ShowStep();
}
/// <summary>
/// Build each step of dialogue
/// </summary>
private void BuildDialogue(List<DialogueStepModel> Dialogue)
{
foreach (var dialogueStep in Dialogue)
{
dialogueStep.Build();
}
}
public (int, int) DialogueStepStatus()
{
var currentDialogueStepIndex = MultiWayDialogue
.Where(el => el.Key == CurrentDialogue)
.Select(el => el.Value)
.First()
.Where(step => step.WasDisplayed == true)
.ToArray()
.Count()
;
return(CurrentDialogue, currentDialogueStepIndex);
}
}