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 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().GetReward(Reward); } public void FinishMission() { Debug.Log("FinishMission"); Status = MissionStatusEnum.Finished; // 3. remove quest from player list RemoveQuestFromList(); } /// /// 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' .... /// public void FinishMissionStep() { MissionStepsList[CurrentStep].Status = MissionStepStatusEnum.Finished; CurrentStep++; // build without starting BuildMission(MissionStepsList); } /// /// Alias dla tego co powinna robić logika 'GoToNextStep' w Missjach /// 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 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 /// /// Function to reset rememebered dialogue status /// /// (Scriptable objects clones are overwritten during clone modification) /// 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(); if (saveController == null) throw new Exception($"There is no SaveController component on scene!!!"); saveController.GetComponent().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); } /// /// 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!!! /// /// 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 }