Scriptum/Assets/Scripts/REFACTORING/Application/Mission/Mission.cs
2023-01-07 17:50:25 +01:00

377 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
[Serializable]
[CreateAssetMenu(fileName = "New Mission", menuName = "Mission/New Mission")]
public class Mission : ScriptableObject
{
[SerializeField]
public string MissionName;
[SerializeField]
public Task PlayerTask;
[SerializeField]
public string SpeakerName;
/* [SerializeField]
public MissionTypeEnum Type;*/
[SerializeField]
public MissionStatusEnum Status = MissionStatusEnum.None;
[SerializeField]
public int CurrentStep = 0;
[SerializeField]
public List<MissionStepModel> MissionStepsList;
/*
[SerializeField]
public MissionProcess missionProcess = null;*/
[SerializeField]
public MissionReward Reward;
//ConditionController . check condition
//private ConditionFactory factory = new ConditionFactory();
/*
public void AssignMissionProcessToStep(int stepNumber)
{
MissionStepsList[stepNumber].SetStepProcess(missionProcess);
}
*/
/* public void SetMissionCondition(string name)
{
//factory.CreateCondition(Type); //, name)
}*/
// Set by hand as mission condition as final astion specyfic step
public void CheckMissionRequirements()
{
}
public void SetSpeakerName(string speakerName) { SpeakerName = speakerName; }
public void Accept()
{
Debug.Log("Accepting mission");
Status = MissionStatusEnum.Accepted;
// ADD CONDITION LISTENING TO SPECIFY MISSION MANAGER missions list
CreateQuestOnList();
//// TODO ! ! !
///saveController.SaveMissions();
///
}
public void Reject()
{
Status = MissionStatusEnum.Rejected;
ConditionManager.Instance.RemoveCondition(MissionName);
// 3. Save Mission status in game
//// TODO ! ! !
}
// Assign geting reward as Model End Action
// Bind by hand to specyfic mission step action
public void GiveReward()
{
// TODO status is overwritten during building
//if (Status != MissionStatusEnum.Accepted)
// return;
var Player = GameObject.FindGameObjectWithTag("Player");
if (!Player)
Debug.LogError("MissionStepModel::GetReward - There is no player on scene!!!");
Player.GetComponent<PlayerActions>().GetReward(Reward);
}
public void FinishMission()
{
Debug.Log("FinishMission");
Status = MissionStatusEnum.Finished;
// 3. remove quest from player list
RemoveQuestFromList();
}
/// <summary>
/// czy ta akcja ma by wywolywana w buttonie i ma wywoływac inn eakcje z 'end of step actions lsit'
/// czy ma byc jedna z nich i byc wywoływana przez 'go to next sentence' ....
/// </summary>
public void FinishMissionStep()
{
MissionStepsList[CurrentStep].Status = MissionStepStatusEnum.Finished;
CurrentStep++;
// build without starting
BuildMission(MissionStepsList);
}
/// <summary>
/// Alias dla tego co powinna robić logika 'GoToNextStep' w Missjach
/// </summary>
public void FinishMissionStepAndGoToNext()
{
MissionStepsList[CurrentStep].Status = MissionStepStatusEnum.Finished;
CurrentStep++;
// build & start
StartDialogue();
}
public bool CheckStepFinalCondition()
{
if (MissionStepsList[CurrentStep].CheckCondition())
{
//MissionStepsList[CurrentStep].GiveReward();
MissionStepsList[CurrentStep].Status = MissionStepStatusEnum.Finished;
}
else
{
// Show dialoge with sentence like "you dont compleeted requirements"
Debug.Log("Soprry you dont meet the criteria yet...");
return false;
}
return true;
}
// dialogue components
public void StartDialogue()
{
// 1. Build
BuildMission(MissionStepsList);
// 2. Show first step
ShowStep();
}
public void BreakDialogueStep()
{
foreach (var MissionStep in MissionStepsList)
{
// NIKE TYLKO ACTIVE !!
if ((MissionStep.Status == MissionStepStatusEnum.Active || MissionStep.Status == MissionStepStatusEnum.AfterCondition) && MissionStep.DialogueStep.GetCurrentStep().DialogueController.CurrentPanel != null)
{
MissionStep.DialogueStep.GetCurrentStep().DialogueController.CloseCurrentPanel(); // close panel
break;
}
}
}
public void ShowStep()
{
foreach (var MissionStep in MissionStepsList)
{
// jesli krok jest aktywny & ma niewypowiedziane zdania
if ((MissionStep.Status == MissionStepStatusEnum.Active || MissionStep.Status == MissionStepStatusEnum.AfterCondition) && MissionStep.DialogueStep.GetCurrentStep()?.DialogueController.listOfDialogue.Count != 0)
{
MissionStep.DialogueStep.StartDialogue();
break;
}
/*
// jesli stan jest oczekujacy && dialog nie został w całości przegadany
// jesli warnek jest zpeniony - idz dalej - nie, czeksaj
if (MissionStep.Status == MissionStepStatusEnum.Pending && MissionStep.DialogueStep.GetCurrentStep().DialogueController.listOfDialogue.Count != 0)
{
// Check or register condition.....
// 1. Register condition
//ConditionManager.Instance.RegisterCondition(MissionName, MissionStep.MissionConditions);
// 2. register next step action
// TODO
// 3. Open panel (dialogue) ???
MissionStep.DialogueStep.StartDialogue(); // create panel
break;
}*/
}
}
public void GoToNextStep()
{
foreach (var MissionStep in MissionStepsList)
{
// Case I: Do nothing sepciaj just get first Step which wasn't invoked yet
if (MissionStep.Status == MissionStepStatusEnum.Pending)
{
/// var nextSentence = MissionStep.DialogueStep.DialogueController.ShowNextPanel(
// MissionStep.DialogueStep.DialogueController
//);
//If there is no sentence in Step - go to next one
/* if (!nextSentence)
{
MissionStep.Status = MissionStepStatusEnum.Finished;
ShowStep();
}
*/
break;
}
// Case II: Before go foward we must check final condition
if (MissionStep.Status == MissionStepStatusEnum.Active)
{
// po co to ? ? ? - obecnie warunek misji jest sprawdazany nankoncu podanego stepu dialogu
// po spełnieniu step misji oznaczany jest jako ukończony
var conditionResult = CheckStepFinalCondition();
if (conditionResult)
ShowStep();
break;
}
}
}
public void BuildMission()
{
BuildMission(MissionStepsList);
}
private void BuildMission(List<MissionStepModel> Mission)
{
// Obligatory
if (Status == MissionStatusEnum.None)
Status = MissionStatusEnum.Available;
foreach (var missionStep in Mission)
{
missionStep.SetSpeakerName(SpeakerName);
missionStep.Build(this);
}
// Additionaly set first step as active
//Debug.Log("BuildMission - Activate step");
if (MissionStepsList.Count() > CurrentStep)
MissionStepsList[CurrentStep].ActivateStep();
else
Debug.Log($"Mission [{MissionName}] step {CurrentStep} out of steps list containing {MissionStepsList.Count()}");
}
#region Dialogue Status API
/// <summary>
/// Function to reset rememebered dialogue status
///
/// (Scriptable objects clones are overwritten during clone modification)
/// </summary>
public void ResetMission()
{
Status = MissionStatusEnum.None;
CurrentStep = 0;
MissionStepsList.ForEach(step => step.ResetMissionStep());
}
public void UpdateMissionState(MissionData missionData)
{
// 1 Rule - speaker name shouldnt change !!! its our 'key'
Status = missionData.Status;
CurrentStep = missionData.CurrentStep;
for (int i = 0; i < missionData.MissionStepsDataList.Count; i++)
{
MissionStepsList[i].UpdateMissionStepState(missionData.MissionStepsDataList[i]);
}
}
#endregion
public MissionStepModel GetCurrentStep()
{
return MissionStepsList[CurrentStep];
}
#region Quest managment
public void CreateQuestOnList()
{
// WHERE IS CONDITION TO CHECK IF MISSION ALREADY EXISTS ??? ??? ???
// 2. Add mission to Player Panel :D
TaskUIManager.Instance.Add(PlayerTask);
// 3. Save Player Quest Panel status & (somehow) mission status in game
// Don't save quest in this moement on list because mission proggrss isnt saved before using
// teleport or saving proggress by player - data consistency
/*
var saveController = GameObject.FindObjectOfType<SaveController>();
if (saveController == null)
throw new Exception($"There is no SaveController component on scene!!!");
saveController.GetComponent<SaveController>().SavePlayerQuests();
*/
}
public void RemoveQuestFromList()
{
var task = TaskUIManager.Instance.FindTaskByName(PlayerTask.Title);
if (task.Count == 0)
Debug.LogError($"Task '{PlayerTask.Title}' not found");
else
TaskUIManager.Instance.RemoveByName(PlayerTask.Title);
}
/// <summary>
/// Po co misja idwoluje sie do dziecka zamiast ustawic to samemu?
///
/// Wprzyszlosci ustawic nowy content w stepei!
///
/// IMPORANT:
/// nadpisanie w jednym kroku nadpisuje żródłowy Description w Taku obiektu Mission!!!
/// </summary>
/// <param name="newMissionissue"></param>
public void PlayerQuestContentManage(string newMissionissue)
{
var task = TaskUIManager.Instance.FindTaskByName(PlayerTask.Title);
if (task.Count() == 0)
CreateQuestOnList();
// manually setupped new contrent for wqizard first mission script
((TaskUIManager)TaskUIManager.Instance).ChangeTaskIssue(PlayerTask.Title, newMissionissue);
}
#endregion
}