Firstborn/Assets/RPG Creation Kit/Scripts/Quest System/Consequences System/ConsequenceManager.cs

379 lines
15 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using RPGCreationKit;
using RPGCreationKit.CellsSystem;
using RPGCreationKit.SaveSystem;
using RPGCreationKit.AI;
namespace RPGCreationKit
{
/// <summary>
/// Class that execute the consequences. All the consequences logic is written here
/// </summary>
public class ConsequenceManager : MonoBehaviour
{
#region Singleton
public static ConsequenceManager instance;
private void Awake()
{
if (instance == null)
instance = this;
else
{
Debug.LogError("Anomaly detected with the Singleton Pattern of 'ConsequenceManager', are you using multple ConsequenceManager?");
Destroy(this);
}
}
#endregion
[Header("References")]
// Used in DeleteQuestionFromCurrentDialogue
public Transform PlayerQuestionContent;
/// <summary>
/// Activate a List of consequences
/// </summary>
/// <param name="gObjectCaller">The gameObject that calls this function</param>
/// <param name="consequences">The list of consequences to execute</param>
public void ConsequencesActivator(GameObject gObjectCaller, List<Consequence> consequences)
{
for (int i = 0; i < consequences.Count; i++)
{
ApplyConsequence(gObjectCaller, consequences[i]);
}
}
/// <summary>
/// Execute a consequence
/// </summary>
/// <param name="gObjectCaller">The gameObject that calls this function</param>
/// <param name="consec">The consequence to execute</param>
private void ApplyConsequence(GameObject gObjectCaller, Consequence consec)
{
switch (consec.type)
{
case ConsequencesTypes.ChangeScene:
SceneManager.LoadScene(consec.sceneIndex);
break;
case ConsequencesTypes.Teleport:
#region code
for (int i = 0; i < consec.toTeleport.Length; i++)
{
if (consec.toTeleport[i].gameObject != null)
{
// If we have to teleport a NPC we have firstly to disable him (NavMesh problem)
if (consec.toTeleport[i].gameObject.CompareTag("NPC"))
{
consec.toTeleport[i].gameObject.SetActive(false);
if (consec.toTeleport[i].localPosition)
consec.toTeleport[i].gameObject.transform.localPosition = consec.toTeleport[i].coordinates;
else
consec.toTeleport[i].gameObject.transform.position = consec.toTeleport[i].coordinates;
consec.toTeleport[i].gameObject.SetActive(true);
}
else if (consec.toTeleport[i].gameObject.CompareTag("Player"))
{
// If the is in conversation
if (Player.RckPlayer.instance.isInConversation)
{
// Start the coroutine that will wait until the dialogue ended and repeat this consequence
StartCoroutine(DelayConsequence(consec));
}
else
{
consec.toTeleport[i].gameObject.SetActive(false);
if(consec.toTeleport[i].localPosition)
consec.toTeleport[i].gameObject.transform.localPosition = consec.toTeleport[i].coordinates;
else
consec.toTeleport[i].gameObject.transform.position = consec.toTeleport[i].coordinates;
consec.toTeleport[i].gameObject.SetActive(true);
}
}
else
{
// For every other type of gameObject
if (consec.toTeleport[i].localPosition)
consec.toTeleport[i].gameObject.transform.localPosition = consec.toTeleport[i].coordinates;
else
consec.toTeleport[i].gameObject.transform.position = consec.toTeleport[i].coordinates;
}
}
else
{
Debug.LogError("Tried to teleport an unassigned GameObject in the consequences of the GameObject: " + gObjectCaller.name);
}
}
#endregion
break;
case ConsequencesTypes.AlertMessage:
AlertMessage.instance.InitAlertMessage(consec.AlertMessage, consec.duration);
break;
case ConsequencesTypes.AddInInventory:
#region code
if (consec.itemToModifyInInventory.item != null)
{
if (consec.itemToModifyInInventory.isPlayerInventory)
Inventory.PlayerInventory.AddItem(consec.itemToModifyInInventory.item, consec.itemToModifyInInventory.metadata, consec.itemToModifyInInventory.amount);
}
#endregion
break;
case ConsequencesTypes.RemoveFromInventory:
#region code
/*
if (consec.inventory != null && !consec.isPlayerInventory || consec.itemInInventory != null)
{
if (consec.isPlayerInventory)
for (int i = 0; i < consec.itemAmount; i++)
Inventory.PlayerInventory.ConsequenceRemoveItem(consec.itemInInventory);
else
for (int i = 0; i < consec.itemAmount; i++)
consec.inventory.ConsequenceRemoveItem(consec.itemInInventory);
}
else
Debug.LogError("Tried to remove from Inventory an unassigned Inventory or ItemInInventory in the consequences of the GameObject: " + gObjectCaller.name);
*/
if(consec.itemToModifyInInventory.item != null)
{
if (consec.itemToModifyInInventory.isPlayerInventory)
Inventory.PlayerInventory.RemoveItem(consec.itemToModifyInInventory.item, consec.itemToModifyInInventory.amount);
}
#endregion
break;
case ConsequencesTypes.RemoveAllFromInventory:
#region code
if (consec.inventory != null || consec.isPlayerInventory)
{
if (consec.isPlayerInventory)
{
Inventory.PlayerInventory.ClearInventory();
PlayerCombat.instance.RemoveCurrentWeapon();
PlayerInInventory.instance.OnEquipmentChangesHands();
}
else
consec.inventory.ClearInventory();
}
else
Debug.LogError("Tried to remove from Inventory an unassigned Inventory or ItemInInventory in the consequences of the GameObject: " + gObjectCaller.name);
#endregion
break;
case ConsequencesTypes.MutateMutable:
#region code
if (!string.IsNullOrEmpty(consec.mutableID))
RCKFunctions.MutateMutable(consec.mutableID, consec.restoreMutable);
else
Debug.Log("Tried to mutate in Consequences, but no ID was provided.");
#endregion
break;
case ConsequencesTypes.ChangeRckAIDialogue:
#region code
var allAI = SaveSystemManager.instance.saveFile.AIData.aiDictionary;
RckAI ai = null;
CellInformation.TryToGetAI(consec.rckAID, out ai); // Tries to grab the NPC if he's loaded - null if he's not
if (ai != null)
{
ai.currentDialogueGraph = consec.dialogueGraph;
}
else if (allAI.ContainsKey(consec.rckAID))
{
AISaveData data = allAI[consec.rckAID];
allAI[consec.rckAID].currentDialogueID = consec.dialogueGraph.ID;
}
else
{
Debug.LogWarning("Tried to change dialogue to an NPC that isn't loaded and wasn't met before, this is not supported.");
}
#endregion
break;
case ConsequencesTypes.ChangeRckBTree:
#region code
allAI = SaveSystemManager.instance.saveFile.AIData.aiDictionary;
ai = null;
CellInformation.TryToGetAI(consec.rckAID, out ai); // Tries to grab the NPC if he's loaded - null if he's not
if (ai != null)
{
ai.SetNewBehaviourTree(consec.behaviourTree.IsCombatBehaviour, consec.behaviourTree.ID);
if (consec.immediatlySwitchToBehaviour)
ai.SwitchBehaviourTree(consec.behaviourTree.IsCombatBehaviour);
}
else if (allAI.ContainsKey(consec.rckAID))
{
AISaveData data = allAI[consec.rckAID];
if (consec.behaviourTree.IsCombatBehaviour)
data.combatBehaviourTreeID = consec.behaviourTree.ID;
else
data.purposeBehaviourTreeID = consec.behaviourTree.ID;
if (consec.immediatlySwitchToBehaviour)
data.curBehaviourTreeID = consec.behaviourTree.ID;
allAI[consec.rckAID].currentDialogueID = consec.dialogueGraph.ID;
}
else
{
Debug.LogWarning("Tried to change dialogue to an NPC that isn't loaded and wasn't met before, this is not supported.");
}
#endregion
break;
case ConsequencesTypes.RckAI_AddInFaction:
#region code
allAI = SaveSystemManager.instance.saveFile.AIData.aiDictionary;
ai = null;
CellInformation.TryToGetAI(consec.rckAID, out ai); // Tries to grab the NPC if he's loaded - null if he's not
if (ai != null)
{
ai.AddToFaction(consec.factionID);
}
else if (allAI.ContainsKey(consec.rckAID))
{
AISaveData data = allAI[consec.rckAID];
data.allFactions.Add(consec.factionID);
}
else
{
Debug.LogWarning("Tried to Add In Faction an NPC that isn't loaded and wasn't met before, this is not supported.");
}
#endregion
break;
case ConsequencesTypes.RckAI_RemoveFromFaction:
#region code
allAI = SaveSystemManager.instance.saveFile.AIData.aiDictionary;
ai = null;
CellInformation.TryToGetAI(consec.rckAID, out ai); // Tries to grab the NPC if he's loaded - null if he's not
if (ai != null)
{
ai.RemoveFromFaction(consec.factionID);
}
else if (allAI.ContainsKey(consec.rckAID))
{
AISaveData data = allAI[consec.rckAID];
data.allFactions.Remove(consec.factionID);
}
else
{
Debug.LogWarning("Tried to Remove From Faction an NPC that isn't loaded and wasn't met before, this is not supported.");
}
#endregion
break;
case ConsequencesTypes.LockDoor:
RCKFunctions.LockDoor(consec.doorID, consec.lockLevel);
break;
case ConsequencesTypes.UnlockDoor:
RCKFunctions.UnlockDoor(consec.doorID);
break;
case ConsequencesTypes.ClearPurpose:
#region code
allAI = SaveSystemManager.instance.saveFile.AIData.aiDictionary;
ai = null;
CellInformation.TryToGetAI(consec.rckAID, out ai); // Tries to grab the NPC if he's loaded - null if he's not
if (ai != null)
{
ai.purposeState.ClearPurpose();
}
else if (allAI.ContainsKey(consec.rckAID))
{
AISaveData data = allAI[consec.rckAID];
data.purposeState = null;
}
else
{
Debug.LogWarning("Tried to Add Clear Purpose an NPC that isn't loaded and wasn't met before, this is not supported.");
}
#endregion
break;
case ConsequencesTypes.PlayerLearnSpell:
#region
if(consec.spellToLearn != null)
SpellsKnowledge.Player.LearnSpell(consec.spellToLearn);
#endregion
break;
}
}
/// <summary>
/// Delay a consequence, only called from Consequences activated from NPCDialogueLines
/// </summary>
/// <param name="consec">The consequence to delay</param>
/// <returns></returns>
private IEnumerator DelayConsequence(Consequence consec)
{
// Delay for conversation
while (Player.RckPlayer.instance.isInConversation)
{
yield return null;
}
// You can add other delays here
// Redo the consequence
ApplyConsequence(gameObject, consec);
}
private IEnumerator DelayConsequence2(Consequence consec)
{
// Delay for conversation
while (Player.RckPlayer.instance.isInConversation)
{
yield return null;
}
// You can add other delays here
// Redo the consequence
ApplyConsequence(gameObject, consec);
}
}
}