Scriptum/Assets/Scripts/REFACTORING/Application/Dialogue/MultiDialogue.cs
2023-01-02 00:22:39 +01:00

217 lines
7.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 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)
{
if (Dialogues.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
Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.FinishDialogue();
// 2. Chane index
CurrentDialogue = dialogueNumber;
}
public void SetNextDialogueWithoutFinalAction(int dialogueNumber)
{
if (Dialogues.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
Dialogues.Where(el => el.Key == CurrentDialogue).ToArray().First().Value.CloseDialogue();
// 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);
// 2. Update proggress
// Savintg one more time because saving in final action invoking by line above
// dont contain increased 'CurrentDialogue' index pointer !!!
//((MultiDialogueDataManager)MultiDialogueDataManager.Instance).RegisterDialogue(this);
// 3. Build new (next) dialogue & show panel
StartDialogue();
}
/// <summary>
/// Function like one above but
/// PREFPARED AS FINAL ACTION IN DIALOGUE WHICH IS INVOKED VIA 'Dialogue.FinishDialoge'
/// to prevent looping Final aCTION INVOKING
/// once from 'Dialogue.FinishDialoge' in button next time from 'MultiDialogue.SetNextDialogue -> FinishDialogue' ....
/// </summary>
/// <param name="dialogueNumber"></param>
public void GoToNextDialogueWithoutFinalAction(int dialogueNumber)
{
// 1. Prepare necessary environoment parts
SetNextDialogueWithoutFinalAction(dialogueNumber);
// 2. Update proggress
//((MultiDialogueDataManager)MultiDialogueDataManager.Instance).RegisterDialogue(this);
// 3. 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()
{
SpeakerName = "";
CurrentDialogue = 0;
Dialogues.ForEach(dial => dial.Value.SetSpeakerName(""));
Dialogues.ForEach(dial => dial.Value.CurrentStep = 0);
Dialogues.ForEach(dial => dial.Value.DialogueSteps.ForEach(step => step.WasDisplayed = false));
}
public (int, int) DialogueStepStatus()
{
/* var currentStep = Dialogues
.Where(el => el.Key == CurrentDialogue)
.Select(el => el.Value)
.First()
.CurrentStep
;*/
var currentDialogueStepIndex = Dialogues
.Where(el => el.Key == CurrentDialogue)
.Select(el => el.Value)
.First()
.DialogueSteps
.Where(step => step.WasDisplayed == true)
.ToArray()
.Count()
;
return(CurrentDialogue, currentDialogueStepIndex);
}
}