Mission - add module template

This commit is contained in:
kabix09 2022-12-27 15:16:59 +01:00
parent 886eec8984
commit 4373cdc48d
50 changed files with 1363 additions and 74 deletions

View File

@ -17,44 +17,78 @@ MonoBehaviour:
title: title:
description: description:
difficulty: 0 difficulty: 0
Type: 0
Status: 0 Status: 0
CurrentStep: 0 CurrentStep: 0
MissionStepsList: MissionStepsList:
- Status: 0 - SpeakerName:
DialogueStep: Status: 0
WasDisplayed: 0 DialogueStep: {fileID: 0}
ListOfSentences: [] missionProcess:
EndOfDialogueStepAction: Amount: 0
m_PersistentCalls: PrefabAsset: {fileID: 0}
m_Calls: _currentAmount: 0
- m_Target: {fileID: 0} NextStepCondition:
m_TargetAssemblyTypeName:
m_MethodName:
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName:
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
Reward:
Items:
- {fileID: 11400000, guid: 5935777f7ac390a4187e03f34e7cafdd, type: 2}
Cash: 0
FinalCondidtion:
m_PersistentCalls: m_PersistentCalls:
m_Calls: m_Calls:
- m_Target: {fileID: 11400000} - m_Target: {fileID: 11400000}
m_TargetAssemblyTypeName: m_TargetAssemblyTypeName: Mission, Assembly-CSharp
m_MethodName: m_MethodName: AssignMissionProcessToStep
m_Mode: 1 m_Mode: 3
m_Arguments: m_Arguments:
m_ObjectArgument: {fileID: 0} m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0 m_IntArgument: 0
m_FloatArgument: 0 m_FloatArgument: 0
m_StringArgument: m_StringArgument:
m_BoolArgument: 0 m_BoolArgument: 0
m_CallState: 2 m_CallState: 2
- SpeakerName:
Status: 0
DialogueStep: {fileID: 0}
missionProcess:
Amount: 0
PrefabAsset: {fileID: 0}
_currentAmount: 0
NextStepCondition:
m_PersistentCalls:
m_Calls: []
- SpeakerName:
Status: 0
DialogueStep: {fileID: 0}
missionProcess:
Amount: 0
PrefabAsset: {fileID: 0}
_currentAmount: 0
NextStepCondition:
m_PersistentCalls:
m_Calls: []
- SpeakerName:
Status: 0
DialogueStep: {fileID: 0}
missionProcess:
Amount: 0
PrefabAsset: {fileID: 0}
_currentAmount: 0
NextStepCondition:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 11400000}
m_TargetAssemblyTypeName: Mission, Assembly-CSharp
m_MethodName: GiveReward
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
missionProcess:
Amount: 0
PrefabAsset: {fileID: 0}
_currentAmount: 0
Reward:
Items: []
Cash: 0

View File

@ -110,7 +110,6 @@ public class BossThug : MonoBehaviour
{ {
if (other.tag == "Player" && state == BossThugEnum.Talking && !isAfterConversation && !isDuringConversation) if (other.tag == "Player" && state == BossThugEnum.Talking && !isAfterConversation && !isDuringConversation)
{ {
Debug.Log("OnTriggerEnter2D");
//gameObject.GetComponent<CircleCollider2D>().enabled = false; //gameObject.GetComponent<CircleCollider2D>().enabled = false;
//gameObject.GetComponent<CircleCollider2D>().radius = 2f; //gameObject.GetComponent<CircleCollider2D>().radius = 2f;

View File

@ -220,6 +220,9 @@ public class FollowingEnemy : Enemy
gameObject.SetActive(false); gameObject.SetActive(false);
isKilled = 1; isKilled = 1;
other.GetComponent<Player>().GetExp(expValue); other.GetComponent<Player>().GetExp(expValue);
// pass info about killing assigned enemy to mission manager listener
ConditionManager.Instance.UpdateKillCondition(gameObject.name);
} }
} }

View File

@ -192,6 +192,9 @@ public class FollowingPatrollingEnemy : Enemy
gameObject.SetActive(false); gameObject.SetActive(false);
isKilled = 1; isKilled = 1;
other.GetComponent<Player>().GetExp(expValue); other.GetComponent<Player>().GetExp(expValue);
// pass info about killing assigned enemy to mission manager listener
ConditionManager.Instance.UpdateKillCondition(gameObject.name);
} }
} }

View File

@ -12,7 +12,7 @@ public class Dialogue : ScriptableObject, IDialogue
public string SpeakerName; public string SpeakerName;
[SerializeField] [SerializeField]
int CurrentStep = 0; public int CurrentStep = 0;
[SerializeField] [SerializeField]
public List<DialogueStepModel> DialogueSteps; public List<DialogueStepModel> DialogueSteps;
@ -81,6 +81,34 @@ public class Dialogue : ScriptableObject, IDialogue
} }
} }
/// <summary>
/// Show next sentence ONLY in the same step
///
/// Return next panel status ponly for first faounded not displayed dialogue step
///
/// TODO change name this function and one below - but this break buttons with this action assigned
///
/// It would be much safer if function were return int not void bu unity event dont allow to bind methods in that scenario
/// </summary>
/// <returns></returns>
public void ShowNextPanel()
{
// we dont use foreach and "was displayed" condition because ther is DATA LEAK
// MISLEADING - last sentence mark step ad "wasDisplayed" but not increase "CurrentPanel" index
var currentStep = GetCurrentStep();
var nextSentenceIndex = currentStep.DialogueController.ShowNextPanel(currentStep.DialogueController);
if (!nextSentenceIndex)
{
CurrentStep++;
Debug.Log($"Increase - {CurrentStep}");
}
//return nextSentenceIndex;
}
/// <summary> /// <summary>
/// Dialogue API /// Dialogue API
/// ///
@ -98,16 +126,23 @@ public class Dialogue : ScriptableObject, IDialogue
/// </summary> /// </summary>
public void GoToNextSentence() public void GoToNextSentence()
{ {
// wskazujemy na inny krok kolejno niz nieoznaczony
Debug.Log($"Step befor next: {CurrentStep}");
// MISLEADING - last sentence mark step ad "wasDisplayed" but not increase "CurrentPanel" index
foreach (var DialogueStep in DialogueSteps) foreach (var DialogueStep in DialogueSteps)
{ {
if (!DialogueStep.WasDisplayed) if (!DialogueStep.WasDisplayed)
{ {
var nextSentence = DialogueStep.DialogueController.ShowNextPanel(DialogueStep.DialogueController); var nextSentence = DialogueStep.DialogueController.ShowNextPanel(DialogueStep.DialogueController);
Debug.Log($"GoToNextSentence - {nextSentence}");
if (!nextSentence) if (!nextSentence)
{ {
DialogueStep.WasDisplayed = true; DialogueStep.WasDisplayed = true;
CurrentStep++;
Debug.Log($"Step after: {CurrentStep}");
ShowDialogueStepPanel(); ShowDialogueStepPanel();
} }
@ -117,16 +152,28 @@ public class Dialogue : ScriptableObject, IDialogue
} }
#endregion #endregion
public void BuildDialogue()
{
BuildDialogue(DialogueSteps);
}
/// <summary> /// <summary>
/// Function to build each step of dialogue /// Function to build each step of dialogue
/// </summary> /// </summary>
public void BuildDialogue(List<DialogueStepModel> Dialogue) public void BuildDialogue(List<DialogueStepModel> Dialogue)
{ {
Debug.Log("BuildDialogue");
foreach (var dialogueStep in Dialogue) foreach (var dialogueStep in Dialogue)
{ {
dialogueStep.Header = SpeakerName; dialogueStep.Header = SpeakerName;
dialogueStep.Build(); dialogueStep.Build();
// synchronize current step counter
// cause ERROR - multi counting ....
/* if (dialogueStep.WasDisplayed)
CurrentStep++;*/
} }
} }
@ -139,4 +186,25 @@ public class Dialogue : ScriptableObject, IDialogue
{ {
DialogueSteps.ForEach(step => step.WasDisplayed = false); DialogueSteps.ForEach(step => step.WasDisplayed = false);
} }
public DialogueStepModel GetCurrentStep()
{// TODO - argument out of colection :/
return DialogueSteps[CurrentStep];
}
/* public DialogueStepModel GetCurrentStep()
{
foreach (var DialogueStep in DialogueSteps)
{
Debug.Log("-" + DialogueStep.DialogueController.listOfDialogue.Count);
if (!DialogueStep.WasDisplayed && DialogueStep.DialogueController.listOfDialogue.Count != 0)
{
return DialogueStep;
}
}
return null;
}*/
} }

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
[RequireComponent(typeof(NPC))]
public class DialogueManager : MonoBehaviour public class DialogueManager : MonoBehaviour
{ {
[SerializeField] [SerializeField]
@ -116,7 +117,7 @@ public class DialogueManager : MonoBehaviour
/// Closed = 0 /// Closed = 0
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool GetCurrentDialoguePanelStatus() public virtual bool GetCurrentDialoguePanelStatus()
{ {
var multiDialStatius = Dialogue.DialogueStepStatus(); var multiDialStatius = Dialogue.DialogueStepStatus();
@ -127,7 +128,7 @@ public class DialogueManager : MonoBehaviour
.Value .Value
.DialogueSteps .DialogueSteps
.ElementAtOrDefault(multiDialStatius.Item2) .ElementAtOrDefault(multiDialStatius.Item2)
?.DialogueController.CurrentPanel != null; .DialogueController.CurrentPanel != null;
} }
} }

View File

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
[Serializable]
[CreateAssetMenu(fileName = "New Mission Dialogue", menuName = "Dialogue/New Mission Dialogue")]
public class MissionDialogue : Dialogue
{
[NonSerialized]
private MissionStepModel Parent;
public void BindParent(MissionStepModel parent)
{
Parent = parent;
}
#region Mission API for button actions
/// <summary>
/// Api for mission allowing to bind action to button
/// </summary>
public void AcceptMission()
{
Parent.GetOriginMission().Accept();
// show next panel if exists
ShowNextPanel();
}
/// <summary>
/// Api for mission allowing to bind action to button
/// </summary>
public void RejectMission()
{
Parent.GetOriginMission().Reject();
Parent.Status = MissionStepStatusEnum.Finished;
GetCurrentStep().DialogueController.CloseCurrentPanel();
}
/// <summary>
/// Function to bind checking condition method from associated Mission (parent)
/// to specifi button in dialogue step structure
/// </summary>
public void HandleCondition()
{
Debug.Log("Handle Conditoion");
var result = Parent.HanldeMissionStepCondition();
Debug.Log(CurrentStep);
if (result) GoToNextSentence();
else BreakDialogueStep();
}
public void GiveReward()
{
Debug.Log("Give reward");
Parent.GetOriginMission().GiveReward();
}
public void FinishMission()
{
Parent.GetOriginMission().FinishMission();
}
#endregion
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67587597537a4344cad65ddbcebee119
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -54,7 +54,7 @@ public class DialogueStepModel
{ {
// Pass data to builded panel (name, sentence, buttons) // Pass data to builded panel (name, sentence, buttons)
DialogueModel.Header = Header; // set header DialogueModel.Header = Header; // set header
//Debug.Log($"Add sentence - {DialogueModel.Sentence}");
DialogueController.AddSentence(DialogueModel); DialogueController.AddSentence(DialogueModel);
} }

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 239d9cc21abf7664191a9c9151dbe59e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class CollectMissionCondition : MissionCondition
{
public CollectMissionCondition()
{
Type = MissionTypeEnum.Collect;
}
public CollectMissionCondition(MissionCondition missionCondition)
{
Type = MissionTypeEnum.Collect;
// Convert base type Subject on specified sub-class (with own functions)
RequiredElements.Clear();
foreach (RequiredSubject requiredSubject in missionCondition.RequiredElements)
{
RequiredElements.Add(new CollectRequiredSubject(requiredSubject));
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 684c5eae357a2414190a61953b22ac39
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
class KillMissionCondion : MissionCondition
{
public KillMissionCondion()
{
Type = MissionTypeEnum.Kill;
}
public KillMissionCondion(MissionCondition missionCondition)
{
Type = MissionTypeEnum.Kill;
// Convert base type Subject on specified sub-class (with own functions)
RequiredElements.Clear();
foreach(RequiredSubject requiredSubject in missionCondition.RequiredElements)
{
RequiredElements.Add(new KillRequiredSubject(requiredSubject));
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 439e1e19b22afd4478b4c1151588c35b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
[Serializable]
public class MissionCondition
{
[SerializeField]
public MissionTypeEnum Type;
[SerializeField]
public List<RequiredSubject> RequiredElements = new List<RequiredSubject>();
public MissionCondition() { }
public bool IsConditionMeeted()
{
return RequiredElements.Where(element => element.CheckCondition()).Count() == RequiredElements.Count();
}
public MissionCondition Build()
{
switch(Type)
{
case MissionTypeEnum.Kill:
{
return new KillMissionCondion(this);
}
case MissionTypeEnum.Collect:
{
return new CollectMissionCondition(this);
}
default:
{
throw new Exception($"MissionCondition - Build - unrecognized type: {Type}");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41d6d4ac56f2a8c4683c3d12d35a4632
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d40eae03936af1a488b16f147cf79a41
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
/// <summary>
/// Note: we dont add here local counter like in (Kill condition) because amount of items may be decreasing after np selling not only increased
/// </summary>
[Serializable]
public class CollectRequiredSubject : RequiredSubject
{
protected override string MODEL_LOCALIZATION => "Items/";
public CollectRequiredSubject(RequiredSubject requiredSubject) : base(requiredSubject.RequiredAmount, requiredSubject.RequiredObject) { }
public CollectRequiredSubject(int requiredAmount, GameObject enemy) : base(requiredAmount, enemy) { }
public CollectRequiredSubject(int requiredAmount, string enemyName) : base(requiredAmount, enemyName) { }
public override bool CheckCondition()
{
var isConditionMet =
InventoryUIManager.Instance.FindItemInWarehouseByName(RequiredObject.gameObject.name).Count >= RequiredAmount;
if (isConditionMet)
for(int i = 0; i < RequiredAmount; i++)
InventoryUIManager.Instance.RemoveOneByItemName(RequiredObject.gameObject.name);
return isConditionMet;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5d455cc0e62cd9a4c9ac0f4671a6ab82
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
[Serializable]
class KillRequiredSubject : RequiredSubject // Enemy - WTF is this class...
{
protected override string MODEL_LOCALIZATION => "Enemies/";
[SerializeField]
public int CurrentAmount;
public KillRequiredSubject(RequiredSubject requiredSubject) : base(requiredSubject.RequiredAmount, requiredSubject.RequiredObject) { }
public KillRequiredSubject(int requiredAmount, GameObject enemy) : base(requiredAmount, enemy) { }
public KillRequiredSubject(int requiredAmount, string enemyName) : base(requiredAmount, enemyName) { }
public void IncreaseAmount()
{
Debug.Log("IncreaseAmount");
CurrentAmount += 1;
}
public void IncreaseAmount(int amount)
{
CurrentAmount += amount;
}
public override bool CheckCondition()
{
return CurrentAmount >= RequiredAmount;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f63fea44d9f66fe48b6a0b2f000f5f8b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
[Serializable]
public class RequiredSubject
{
protected virtual string MODEL_LOCALIZATION => "";
[SerializeField]
public int RequiredAmount;
[SerializeField]
public GameObject RequiredObject;
public RequiredSubject(int requiredAmount, GameObject _object)
{
RequiredAmount = requiredAmount;
RequiredObject = _object;
}
public RequiredSubject(int requiredAmount, string objectName)
{
RequiredAmount = requiredAmount;
RequiredObject = MonoBehaviour.Instantiate(FindObjectInResource(objectName));
}
public GameObject FindObjectInResource(string modelName)
{
var resource = Resources.Load<GameObject>(MODEL_LOCALIZATION + modelName);
if (!resource)
throw new System.Exception($"Resource {modelName} not found!!");
return resource;
}
public virtual bool CheckCondition() { return false; }
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d654b2d74c95bc24ea5bf5aa139b6c30
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 62a32c24c34e2574abf1aad2a990580a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
using UnityEditor;
using UnityEngine;
[System.Serializable]
public enum MissionTypeEnum
{
Collect,
Kill
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9201cf781094374695560616e933d19
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;
[Serializable]
class ConditionManager : MonoBehaviour
{
public static ConditionManager Instance { get; protected set; }
[SerializeField]
public string CurrentScene;
/// <summary>
/// Key: missionUniqueName || old -> map name && npc name
/// </summary>
[SerializeField]
public List<IndexValuePair<string, List<MissionCondition>>> Conditions;
public void Awake()
{
if (Instance == null)
{
CurrentScene = SceneManager.GetActiveScene().name;
Instance = this;
}
else
{
Destroy(gameObject);
}
}
public void RegisterCondition(string missionName, List<MissionCondition> conditionsToContinue)
{
if(HasMissionActiveCondition(missionName))
{
Debug.LogError($"Mission '{missionName}' has currently active Condition");
return;
}
Conditions.Add(
new IndexValuePair<string, List<MissionCondition>>(
missionName,
conditionsToContinue
)
);
Debug.Log("Condition registered :D");
}
/// <summary>
/// Update all regfistered conditions (for all missions) which refer to passed object (item, enemy) name
/// </summary>
public void UpdateKillCondition(string objectName)
{
Debug.Log($"UpdateKillCondition - {objectName}");
Conditions
.SelectMany(conditions => conditions.Value)
.Where(missionCondition => missionCondition.Type == MissionTypeEnum.Kill)
.ToList()
.ForEach(killCondition => killCondition.RequiredElements
.Where(element => element.RequiredObject.name == objectName)
.ToList()
.ForEach(element => ((KillRequiredSubject)element).IncreaseAmount())
);
// SaveChanges
// SaveConditions();
}
/// <summary>
/// If mission step has no condition (nothing registered) return TRUE defaultly
/// </summary>
/// <param name="missionName"></param>
/// <returns></returns>
public bool CheckCondition(string missionName)
{
if(!HasMissionActiveCondition(missionName))
{
Debug.LogError($"Data inconsistency!!! Mission dont have any registered condition to check");
return true;
}
int unmeetedConditions = Conditions
.Where(condition => condition.Key == missionName)
.FirstOrDefault()
.Value
.ToList()
.SelectMany(missionCondition => missionCondition.RequiredElements)
.ToList()
.Where(el => !el.CheckCondition())
.Count()
;
return !(unmeetedConditions > 0);
}
public void RemoveCondition(string missionName)
{
Conditions.RemoveAll(condition => condition.Key == missionName);
}
/// <summary>
/// Function to check if lists contain any condition for selected mission
/// If contain - reject - prev condition must be removed after his fulified! ! !
/// If dont contain - add
///
/// </summary>
/// <param name="npc"></param>
/// <returns></returns>
public bool HasMissionActiveCondition(string missionName)
{
return Conditions.Where(conditon => conditon.Key == missionName).Any();
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d851232db77451e44b9841aa53bfd56d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
@ -9,6 +10,19 @@ using UnityEngine;
public class Mission : ScriptableObject public class Mission : ScriptableObject
{ {
[SerializeField]
public string MissionName;
[SerializeField]
public Task PlayerTask;
[SerializeField]
public string SpeakerName;
/* [SerializeField]
public MissionTypeEnum Type;*/
[SerializeField] [SerializeField]
public MissionStatusEnum Status = MissionStatusEnum.None; public MissionStatusEnum Status = MissionStatusEnum.None;
@ -17,19 +31,245 @@ public class Mission : ScriptableObject
[SerializeField] [SerializeField]
public List<MissionStepModel> MissionStepsList; public List<MissionStepModel> MissionStepsList;
/*
[SerializeField]
public MissionProcess missionProcess = null;*/
public void CheckIfComplete() [SerializeField]
public MissionReward Reward;
//ConditionController . check condition
//private ConditionFactory factory = new ConditionFactory();
/*
public void AssignMissionProcessToStep(int stepNumber)
{ {
Debug.Log("Checkl if complete"); 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() public void Accept()
{ {
Debug.Log("Accepting mission");
Status = MissionStatusEnum.Accepted; Status = MissionStatusEnum.Accepted;
// ADD CONDITION LISTENING TO SPECIFY MISSION MANAGER missions list
// 2. Add mission to Player Panel :D
TaskUIManager.Instance.Add(PlayerTask);
// 3. Save Player Quest Panel status & (somehow) mission status in game
var saveController = GameObject.FindObjectOfType<SaveController>();
if (saveController == null)
throw new Exception($"There is no SaveController component on scene!!!");
saveController.GetComponent<SaveController>().SavePlayerQuests();
//// TODO ! ! !
///saveController.SaveMissions();
///
} }
public void Reject() public void Reject()
{ {
Status = MissionStatusEnum.Rejected; 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
var task = TaskUIManager.Instance.FindTaskByName(PlayerTask.Title);
if (task.Count == 0)
Debug.LogError($"Task '{PlayerTask.Title}' not found");
else
TaskUIManager.Instance.RemoveByName(PlayerTask.Title);
}
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
MissionStepsList[CurrentStep].ActivateStep();
}
public MissionStepModel GetCurrentStep()
{
return MissionStepsList[CurrentStep];
} }
} }

View File

@ -3,43 +3,143 @@ using System.Collections;
using UnityEngine; using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using UnityEngine.Events;
/*
* In basic want to have 3 steps
* - first to say hello and accept/reject mission
* - secont - to check condition with plain dialogue
* - third - to get reward
*/
[Serializable] [Serializable]
public class MissionStepModel public class MissionStepModel
{ {
protected Mission MissionOrigin { get; private set; }
// Must be filled manually ! ! !
[SerializeField]
public string SpeakerName;
[SerializeField] // this flag tell whatewer dialoge ware already display to user [SerializeField] // this flag tell whatewer dialoge ware already display to user
public MissionStepStatusEnum Status = MissionStepStatusEnum.None; public MissionStepStatusEnum Status = MissionStepStatusEnum.None;
/*
[SerializeField]
public MissionDialogue DialogueStepTemplate;*/
[SerializeField] [SerializeField]
public DialogueStepModel DialogueStep; public MissionDialogue DialogueStep;
// Conditions must be assigned to specify dialogue step
[SerializeField] [SerializeField]
public MissionReward Reward; public IndexValuePair<int, List<MissionCondition>> MissionConditions;
public MissionStepModel() { } public MissionStepModel() { }
public void SetSpeakerName(string speakerName) { SpeakerName = speakerName; }
// Copied from DialogueStepModel public Mission GetOriginMission()
public virtual void Build()
{ {
DialogueStep.EndOfDialogueStepAction.AddListener(GiveReward); return MissionOrigin;
DialogueStep.Build();
} }
// Assign geting reward as Model End Action public virtual void Build(Mission parent)
public void GiveReward()
{ {
var Player = GameObject.FindGameObjectWithTag("Player"); if(Status == MissionStepStatusEnum.None)
Status = MissionStepStatusEnum.Pending;
if (!Player) MissionOrigin = parent;
Debug.LogError("MissionStepModel::GetReward - There is no player on scene!!!");
Player.GetComponent<PlayerActions>().GetReward(Reward); //DialogueStep = MonoBehaviour.Instantiate(DialogueStepTemplate); // create copy to prevent overwritting oryginal object! !
DialogueStep.BindParent(this);
DialogueStep.SetSpeakerName(SpeakerName);
DialogueStep.BuildDialogue();
//DialogueStep.SetActionAfterDialogueStep(MissionConditions.Key, HanldeMissionStepCondition);
} }
/// <summary>
/// Important: Mission Step must be previously builded by Build function!!!
/// </summary>
public void ActivateStep()
{
// Dialogue MUST be builded ALWAYS - Build dialogue without displayed panel
//DialogueStep.BuildDialogue(DialogueStep.DialogueSteps);
if (Status != MissionStepStatusEnum.Pending)
return;
Status = MissionStepStatusEnum.Active;
RegisterCondition();
}
#region Condition Mangment section
public void RegisterCondition()
{
Debug.Log(MissionConditions);
Debug.Log(MissionConditions.Value[0].Type);
ConditionManager.Instance.RegisterCondition(MissionOrigin.MissionName, BuildConditionsList());
Debug.Log("Condition registered");
}
/// <summary>
/// Function to change Base Conditions objects put in list defaultly to specific
///
/// Note: This allow to cover base methods by this overwrittens in specific sub-class (like: CheckCondition method)
/// </summary>
/// <returns></returns>
public List<MissionCondition> BuildConditionsList()
{
var buildedList = new List<MissionCondition>();
foreach (var baseCondition in MissionConditions.Value)
{
buildedList.Add(baseCondition.Build());
}
return buildedList;
}
// If mission's stem condition is fulified then mrak mission step as finished
// else do nothing - player MUST this loop step
// Its not required to condition be in last dialogue step
// Checking condition and handling after action is assigned by button in dialogue step
// If no then there is no possibility to go foward in proggress
public bool HanldeMissionStepCondition()
{
if(CheckCondition())
{
Status = MissionStepStatusEnum.AfterCondition;
// 2. Remove Misison Steps Conditon from global list
ConditionManager.Instance.RemoveCondition(MissionOrigin.MissionName);
// 3. Remove founded elements
return true;
}
else
{
Debug.Log("Dialogue - FinalAction - CheckCondition - HanldeMissionStepCondition - Condition not meeted");
}
return false;
}
public bool CheckCondition()
{
return ConditionManager.Instance.CheckCondition(MissionOrigin.MissionName);
}
#endregion
} }
// TODO // TODO
// zapobieganie zniuknieciu itemow po otrzymaniu nagrody z poanelu gracza - WYKONANIE SAVE PO ZAKOŃCZENIU STEPU: // zapobieganie zniuknieciu itemow po otrzymaniu nagrody z poanelu gracza - WYKONANIE SAVE PO ZAKOŃCZENIU STEPU:
// -- zapisanie postępu misji w pliku z misjami // -- zapisanie postępu misji w pliku z misjami

View File

@ -1,33 +1,114 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using UnityEngine; using UnityEngine;
//[Serializable] //[Serializable]
//[CreateAssetMenu(fileName = "New Mission", menuName = "Mission/New Mission")] //[CreateAssetMenu(fileName = "New Mission", menuName = "Mission/New Mission")]
public class NpcMissionManager : ScriptableObject public class NpcMissionManager : DialogueManager // ScriptableObject
{ {
public Mission mission = null; [SerializeField]
public Mission MissionTemplate;
private void BuildMission() /* We user object CLONED TO PREVENT overwritting changes in main object inassets */
[SerializeField]
public Mission Mission;
[SerializeField]
public DialogueStepModel FreeDialogue;
// List<Key<mission No, mission step No>, Value : UnityEvent>
public List<IndexValuePair<IndexValuePair<int, int>, MissionProcess>> EndactionEventList;
public void Start()
{ {
//mission.Status = MissionStatusEnum.Available; Mission = Instantiate(MissionTemplate);
foreach(var missionStep in mission.MissionStepsList) Mission.SetSpeakerName(gameObject.GetComponent<NPC>().Name);
//Mission.BuildMission();
if (FreeDialogue != null)
FreeDialogue.Build();
}
public void Update() { }
public override void OnTriggerEnter2D(Collider2D collision)
{ {
missionStep.Build(); // don't listen when component is disabled
if (ComponentEnabledCondition())
return;
if (collision.gameObject.tag == "Player" && !GetCurrentDialoguePanelStatus())
{
CanBeOpened = true;
SpeakerName = collision.gameObject.name;
Mission.StartDialogue();
} }
} }
public void ShowStep() public override void OnTriggerExit2D(Collider2D collision)
{ {
foreach (var MissionStep in mission.MissionStepsList) // don't listen when component is disabled
{ if (ComponentEnabledCondition())
if (MissionStep.Status != MissionStepStatusEnum.Finished && MissionStep.DialogueStep.ListOfSentences.Count != 0) return;
{
MissionStep.DialogueStep.DialogueController.Show(MissionStep.DialogueStep.DialogueController.listOfDialogue.Dequeue()); // create panel
break; if (collision.gameObject.tag == "Player")
{
CanBeOpened = false;
if (GetCurrentDialoguePanelStatus())
{
Debug.Log("BreakDialogueStep");
Mission.BreakDialogueStep();
} }
} }
} }
/* public void Talk()
{
if (Mission == null || Mission.Status == MissionStatusEnum.Finished)
{
// show free dialogue
//if(FreeDialogue != null)
//FreeDialogue.DialogueController.
} else
{
// continue mission
Mission.StartDialogue();
}
}
*/
protected override bool ComponentEnabledCondition()
{
return !gameObject.GetComponent<NpcMissionManager>().enabled;
}
public override bool GetCurrentDialoguePanelStatus()
{
Debug.Log(Mission
.GetCurrentStep()
.DialogueStep.CurrentStep
);
Debug.Log(Mission
.GetCurrentStep()
.DialogueStep
.GetCurrentStep()
.DialogueController
.CurrentPanel
);
return Mission
.GetCurrentStep()
.DialogueStep
.GetCurrentStep() // ?
.DialogueController
.CurrentPanel != null;
}
} }

View File

@ -24,11 +24,15 @@ public class PlayerActions : MonoBehaviour
{ {
InventoryUIManager.Instance.Add(item); InventoryUIManager.Instance.Add(item);
} }
// 2. Add cash
AccountBalanceManager.Instance.IncreaseAccountBalanceValue(reward.Cash);
Debug.Log($"Give reward - {reward.Cash}");
// 3. Save changes
GameObject.FindObjectOfType<SaveController>().SavePlayerEquipmentItems(); GameObject.FindObjectOfType<SaveController>().SavePlayerEquipmentItems();
GameObject.FindObjectOfType<SaveController>().SavePlayerInventory(); GameObject.FindObjectOfType<SaveController>().SavePlayerInventory();
GameObject.FindObjectOfType<SaveController>().SaveAccountBalance();
// 2. Add cach
//cash += reward.Cash;
//GameObject.FindObjectOfType<SaveController>().SavePlayerBankAccount();
} }
} }

View File

@ -0,0 +1,9 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class CollectItemEvent : UnityEvent<Item>
{
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e7df0e18b0f89f6498f54c1b9cf01203
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class KillEnemyEvent : UnityEvent<int> // Npc
{
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72f38346275815f4894b23741c71612d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 25bc0c2571fa5314aae5fa90952181b2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,84 @@
using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using System.Collections.Generic;
/* https://learn.unity.com/tutorial/create-a-simple-messaging-system-with-events */
public class EventManager<T, V> : MonoBehaviour
where V : UnityEvent //where V : UnityEvent<int>
{
private Dictionary<T, V> eventDictionary;
private static EventManager<T, V> eventManager;
public static EventManager<T, V> instance
{
get
{
if (!eventManager)
{
eventManager = FindObjectOfType(typeof(EventManager<T, V>)) as EventManager<T, V>;
if (!eventManager)
{
Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene.");
}
else
{
eventManager.Init();
}
}
return eventManager;
}
}
void Init()
{
if (eventDictionary == null)
{
eventDictionary = new Dictionary<T, V>();
}
}
public static void StartListening(T eventName, UnityAction listener)
{
V thisEvent = null;
if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.AddListener(listener);
}
else
{
thisEvent = (V)(new UnityEvent());
thisEvent.AddListener(listener);
instance.eventDictionary.Add(eventName, thisEvent);
}
}
public static void StopListening(T eventName, UnityAction listener)
{
if (eventManager == null) return;
V thisEvent = null;
if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.RemoveListener(listener);
}
}
public static void TriggerEvent(T eventName)
{
V thisEvent = null;
if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
{
thisEvent.Invoke();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 222869e41c01eeb439d624c38890b2d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -26,6 +26,7 @@ public abstract class UISlotPanelManager<T> : UIBaseManager<T>
public abstract int RemoveByItemId(int itemId); public abstract int RemoveByItemId(int itemId);
public abstract int RemoveOneByItemName(string itemName);
public abstract int RemoveByItemName(string itemName); public abstract int RemoveByItemName(string itemName);
public virtual void RemoveAll() public virtual void RemoveAll()

View File

@ -94,6 +94,18 @@ public abstract class UIWarehouseManager : UISlotPanelManager<IndexValuePair<int
return Elements.RemoveAll(itemSlot => itemSlot.Value.Id == itemId); return Elements.RemoveAll(itemSlot => itemSlot.Value.Id == itemId);
} }
public override int RemoveOneByItemName(string itemName)
{
var items = FindItemInWarehouseByName(itemName);
if (items.Count == 0)
return -1;
Elements.RemoveAll(el => el.Key == items.First().Key);
return items.First().Key;
}
public override int RemoveByItemName(string itemName) public override int RemoveByItemName(string itemName)
{ {
return Elements.RemoveAll(itemSlot => itemSlot.Value.Name == itemName); return Elements.RemoveAll(itemSlot => itemSlot.Value.Name == itemName);

View File

@ -54,4 +54,47 @@ public class InventoryUIManager : UIWarehouseManager
// Resources = default path - Asset/Resources ... .obj // Resources = default path - Asset/Resources ... .obj
return Resources.Load(ITEM_LOCALIZATION + PANEL_NAME) as GameObject; return Resources.Load(ITEM_LOCALIZATION + PANEL_NAME) as GameObject;
} }
#region List API
public override void RemoveByPosition(int keyPosition)
{
base.RemoveByPosition(keyPosition);
UpdateList();
}
public override int RemoveByItemId(int itemId)
{
var result = base.RemoveByItemId(itemId);
UpdateList();
return result;
}
public override int RemoveOneByItemName(string itemName)
{
var result = base.RemoveOneByItemName(itemName);
UpdateList();
return result;
}
public override int RemoveByItemName(string itemName)
{
var result = base.RemoveByItemName(itemName);
UpdateList();
return result;
}
public override void RemoveAll()
{
Elements.Clear();
UpdateList();
}
#endregion
} }

View File

@ -46,7 +46,7 @@ public class SkillsPanelController : MonoBehaviour
int inteligencePoints int inteligencePoints
) { ) {
FreePointsLabel.transform.FindChild("Layer").transform.FindChild("Value").GetComponent<TextMeshProUGUI>().text = $"{freePoints}"; FreePointsLabel.transform.Find("Layer").transform.Find("Value").GetComponent<TextMeshProUGUI>().text = $"{freePoints}";
FreePoints = freePoints; FreePoints = freePoints;
@ -58,7 +58,7 @@ public class SkillsPanelController : MonoBehaviour
public void BildSkillLabelContent(GameObject skillPanelLabel, int value) public void BildSkillLabelContent(GameObject skillPanelLabel, int value)
{ {
skillPanelLabel.transform.FindChild("Layer").transform.FindChild("Value").GetComponent<TextMeshProUGUI>().text = $"{value}"; skillPanelLabel.transform.Find("Layer").transform.Find("Value").GetComponent<TextMeshProUGUI>().text = $"{value}";
if (FreePoints > 0) if (FreePoints > 0)
skillPanelLabel.transform.Find("Button").gameObject.active = true; skillPanelLabel.transform.Find("Button").gameObject.active = true;

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3a3ead5abcec4e84dbc4496bfdc5612b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 8d1920d282403b24487be27311492292 guid: 6bd7d61ed7cdaa94a9752415e5c8f1a6
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -4,6 +4,7 @@ public enum MissionStepStatusEnum
None, None,
Pending, Pending,
Active, Active,
AfterCondition,
Finished Finished
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 61ca24d1b5f7786479bf70a674872f4e guid: 288b6921257406d439fb365b29109b6e
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 34139aaa0c762de4ba558264b192a6b9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +1,6 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2010 # Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{F58AF4E0-3E6D-54B1-523D-8F755DC8E665}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assembly-CSharp", "Assembly-CSharp.csproj", "{F58AF4E0-3E6D-54B1-523D-8F755DC8E665}"
EndProject EndProject
Global Global