b8ab71969a
Finished lockpicking. tied it to the Attributes system. when you pick a lock you gain dexterity, the higher your dexterity, the easier it is to pick locks.
1458 lines
43 KiB
C#
1458 lines
43 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using RPGCreationKit;
|
|
using RPGCreationKit.CellsSystem;
|
|
using RPGCreationKit.DialogueSystem;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using RPGCreationKit.AI;
|
|
using XNode;
|
|
|
|
namespace RPGCreationKit.Player
|
|
{
|
|
public class PlayerInteractor : PlayerMovements, IDialoguable
|
|
{
|
|
//[SerializeField] private PlayerInteractorUI interactorUI;
|
|
[SerializeField] private LayerMask rayMask;
|
|
[SerializeField] private Transform camT;
|
|
|
|
public bool isInConversation;
|
|
public bool isInteracting;
|
|
public bool isReadingBook;
|
|
public bool isPickingLock;
|
|
public bool isLooting;
|
|
public bool isCrafting;
|
|
|
|
Ray ray;
|
|
RaycastHit rayHit;
|
|
[SerializeField] private Transform rayStartPoint;
|
|
|
|
|
|
// Dialogue
|
|
public IDialoguable speakingTo;
|
|
[SerializeField] private float dialogueDistance = 2.5f; // The distance of which a dialogue is possible
|
|
|
|
// Interact object
|
|
public InteractiveObject_Behaviour interactiveObject;
|
|
[SerializeField] private float interactiveObjectDistance = 2.5f; // The distance of which a dialogue is possible
|
|
|
|
|
|
// Looting
|
|
[HideInInspector] public LootingPoint objLooting; // If so, track the InteractiveObject
|
|
[SerializeField] private float lootingPointDistance = 2.5f; // The distance to interact with an InteractiveObject
|
|
|
|
// Crafting
|
|
[HideInInspector] public CraftingPoint objCrafting; // If so, track the InteractiveObject
|
|
[SerializeField] private float CraftingDistance = 2.5f;
|
|
|
|
// Items
|
|
[SerializeField] private float itemDistance = 2.5f;
|
|
[SerializeField] private float doorDistance = 2.5f;
|
|
private bool cameraLookNPC;
|
|
|
|
|
|
Rigidbody itemRigidbody;
|
|
private ItemInWorld dragItemScript;
|
|
Vector3 dragDirection;
|
|
[SerializeField] private float dragDistance = 2.5f;
|
|
public float dragForce = 50f;
|
|
public bool dragKeyBeingHeld;
|
|
public bool isDragging;
|
|
|
|
string cmdStr;
|
|
|
|
public void INPUT_DragKey(InputAction.CallbackContext value)
|
|
{
|
|
if (value.started)
|
|
dragKeyBeingHeld = true;
|
|
else if (value.canceled)
|
|
dragKeyBeingHeld = false;
|
|
}
|
|
|
|
public override void Start()
|
|
{
|
|
base.Start();
|
|
}
|
|
|
|
public override void Update()
|
|
{
|
|
base.Update();
|
|
|
|
// DialogueFix
|
|
if (isInConversation && !RckInput.isUsingGamepad && uiManager.allPlayerQuestions.Count > 0 && uiManager.playerQuestionsContainer.gameObject.activeInHierarchy)
|
|
Cursor.lockState = CursorLockMode.None;
|
|
|
|
if (isInCutsceneMode || !isLoaded || !IsControlledByPlayer())
|
|
{
|
|
if (uiManager.Interact_text.isActiveAndEnabled)
|
|
uiManager.Interact_text.gameObject.SetActive(false);
|
|
return;
|
|
}
|
|
|
|
if (uiManager.Interact_text.isActiveAndEnabled)
|
|
uiManager.Interact_text.gameObject.SetActive(false);
|
|
|
|
cmdStr = RckInput.isUsingGamepad ? "(A)" : "E)";
|
|
|
|
Raycast();
|
|
}
|
|
|
|
public override void FixedUpdate()
|
|
{
|
|
base.FixedUpdate();
|
|
|
|
ManageDraggable();
|
|
}
|
|
|
|
|
|
public void Raycast()
|
|
{
|
|
ray = new Ray(camT.position, camT.forward);
|
|
|
|
if(Physics.Raycast(ray, out rayHit, RCKSettings.INTERACTOR_RAYCAST_MAXDISTANCE, rayMask))
|
|
{
|
|
if (!RckPlayer.instance.iscrouching) {
|
|
if (rayHit.distance <= dialogueDistance) {
|
|
CheckForIDialoguable();
|
|
}
|
|
} else if (rayHit.distance <= lootingPointDistance) {
|
|
CheckForLootingPoint(true);
|
|
}
|
|
|
|
if (rayHit.distance <= itemDistance)
|
|
CheckForItemsInWorld();
|
|
|
|
if (rayHit.distance <= RCKSettings.PLAYER_DISTANCE_TO_DISPLAY_ENEMY_BAR) {
|
|
CheckForIDamageable();
|
|
} else {
|
|
// UnityEngine.Utility.WaitForSeconds(3.0f); @ Schaken -- Find another way to do this.
|
|
uiManager.enemyHealthContainer.SetActive(false);
|
|
}
|
|
|
|
if (rayHit.distance <= interactiveObjectDistance)
|
|
CheckForInteractiveObjects();
|
|
|
|
if (rayHit.distance <= lootingPointDistance)
|
|
CheckForLootingPoint(false);
|
|
|
|
if (rayHit.distance <= doorDistance)
|
|
CheckForDoors();
|
|
|
|
if (rayHit.distance <= dragDistance)
|
|
CheckForIDraggable();
|
|
|
|
if (rayHit.distance <= CraftingDistance)
|
|
CheckForCrafting();
|
|
}
|
|
}
|
|
|
|
private void CheckForIDialoguable()
|
|
{
|
|
IDialoguable dialoguable = rayHit.transform.gameObject.GetComponent<IDialoguable>();
|
|
|
|
if(dialoguable != null && dialoguable.CanDialogue() && !isInConversation)
|
|
{
|
|
// Set the UI
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
uiManager.Interact_text.text = cmdStr+" Speak: " + dialoguable.GetDialoguableName();
|
|
|
|
|
|
if (input.actions.FindAction("Interact").triggered)
|
|
{
|
|
StartDialogue(dialoguable);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CheckForItemsInWorld()
|
|
{
|
|
if(rayHit.transform.CompareTag("RPG Creation Kit/ItemInWorld"))
|
|
{
|
|
// When we find one, we save this reference
|
|
ItemInWorld obj = rayHit.transform.gameObject.GetComponent<ItemInWorld>();
|
|
|
|
if (obj == null)
|
|
return;
|
|
|
|
if (obj.hasBeenTaken)
|
|
return;
|
|
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
|
|
if (obj.Item is BookItem)
|
|
{
|
|
uiManager.Interact_text.text = cmdStr+" Read: " + obj.Item.ItemName;
|
|
}
|
|
else
|
|
{
|
|
string action = obj.Metadata.IsOwnedByNPC ? " Steal: " : " Take: ";
|
|
if (obj.Amount == 1)
|
|
uiManager.Interact_text.text = cmdStr + action + obj.Item.ItemName;
|
|
else
|
|
// E) Take item.name (Number)
|
|
uiManager.Interact_text.text = cmdStr + action + obj.Item.ItemName + " (" + obj.Amount + ")";
|
|
}
|
|
|
|
if (input.actions.FindAction("Interact").triggered)
|
|
{
|
|
if (obj.Item is BookItem) {
|
|
// ReadBook
|
|
if(!RckPlayer.instance.isReadingBook) {
|
|
BookReaderManager.instance.ReadBook((BookItem)obj.Item, true, obj);
|
|
}
|
|
} else {
|
|
TakeItemInWorld(obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TakeItemInWorld(ItemInWorld _item)
|
|
{
|
|
_item.hasBeenTaken = true;
|
|
|
|
inventory.AddItem(_item.Item, _item.Metadata, _item.Amount);
|
|
|
|
|
|
// We trigger activators
|
|
if (_item.events.EvaluateConditions())
|
|
{
|
|
QuestManager.instance.QuestDealerActivator(_item.events.questDealers);
|
|
QuestManager.instance.QuestUpdaterActivator(_item.events.questUpdaters);
|
|
ConsequenceManager.instance.ConsequencesActivator(gameObject, _item.events.consequences);
|
|
}
|
|
|
|
// Play sound
|
|
if (_item.Item.sOnPickUp)
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.GeneralSounds, _item.Item.sOnPickUp);
|
|
|
|
// If It's NOT created item, save the state
|
|
if(!_item.isCreatedItem)
|
|
_item.SaveOnFile(true);
|
|
else
|
|
{
|
|
// Otherwise, remove it from the dictionary
|
|
_item.DeleteCreatedRecord();
|
|
}
|
|
|
|
// Steal
|
|
if (_item.Metadata.IsOwnedByNPC)
|
|
{
|
|
// Aggro nearby NPC's since you stole something
|
|
// TODO: Optomize this, Just going over everything could become an issue when theres hundreds of NPC's
|
|
// maybe use factions? getowner() - getfaction() - ifisinfaction,then... ?
|
|
foreach (var activeCell in CellInformation.activeCells)
|
|
{
|
|
foreach (var AI in activeCell.Value.aiInWorld)
|
|
{
|
|
// if is in faction...
|
|
AI.Value.TryEngageWithPlayer();
|
|
}
|
|
}
|
|
}
|
|
|
|
Destroy(_item.gameObject);
|
|
}
|
|
|
|
private void CheckForIDamageable()
|
|
{
|
|
IDamageable damageable = rayHit.transform.gameObject.GetComponent<IDamageable>();
|
|
|
|
if (damageable != null && damageable.IsAlive() && !damageable.IsUnconscious())
|
|
{
|
|
if (damageable.ShouldDisplayHealthIfHostile() && (damageable.IsHostile() || damageable.IsHostileAgainstPC()))
|
|
{
|
|
uiManager.enemyHealthSlider.maxValue = damageable.GetMaxHP();
|
|
uiManager.enemyHealthSlider.value = damageable.GetCurrentHP();
|
|
uiManager.enemyName.text = damageable.GetEntityName();
|
|
uiManager.enemyHealthContainer.SetActive(true);
|
|
}
|
|
else
|
|
uiManager.enemyHealthContainer.SetActive(false);
|
|
}
|
|
else
|
|
uiManager.enemyHealthContainer.SetActive(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check with Rays if we're near InteractiveObjects
|
|
/// </summary>
|
|
private void CheckForInteractiveObjects()
|
|
{
|
|
// When we find one, we save this reference
|
|
InteractiveObject_Behaviour obj = rayHit.transform.gameObject.GetComponent<InteractiveObject_Behaviour>();
|
|
|
|
if (obj == null ||obj.interactiveObj == null)
|
|
return;
|
|
|
|
// If the NPC is interactable (not dead and not hostile and we're not yet in a conversation with him)
|
|
if (obj.canInteract && !isInteracting)
|
|
{
|
|
|
|
// Set the UI
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
uiManager.Interact_text.text = cmdStr+" " + obj.interactiveObj.Action + ": " + obj.interactiveObj.Name;
|
|
|
|
// Check for Key to speak with him
|
|
if (input.actions.FindAction("Interact").triggered)
|
|
InteractWithObject(obj);
|
|
}
|
|
else
|
|
uiManager.Interact_text.gameObject.SetActive(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when we select to interact with an Object
|
|
/// </summary>
|
|
private void InteractWithObject(InteractiveObject_Behaviour obj)
|
|
{
|
|
input.SwitchCurrentActionMap("InteractUI");
|
|
// Flag that we're interacting
|
|
isInteracting = true;
|
|
|
|
|
|
// If we can choose between multiple options
|
|
if (obj.interactiveObj.InteractiveOptions.Length > 1)
|
|
{
|
|
// Disable player controls
|
|
RckPlayer.instance.EnableDisableControls(false);
|
|
|
|
// Set UI
|
|
uiManager.interactiveObjectUIContainer.SetActive(true);
|
|
|
|
uiManager.interactiveObjectName.text = obj.interactiveObj.Name;
|
|
uiManager.interactiveObjectDescription.text = obj.interactiveObj.Description;
|
|
|
|
// Instantiate InteractiveOptionsUI
|
|
if (obj.interactiveObj.InteractiveOptions.Length > 0)
|
|
{
|
|
for (int i = 0; i < obj.interactiveObj.InteractiveOptions.Length; i++)
|
|
{
|
|
GameObject newOption = Instantiate(uiManager.interactiveOptionUIPrefab, uiManager.interactiveOptionContent);
|
|
newOption.GetComponent<InteractiveObjectUI>().Init(obj, obj.interactiveObj, obj.interactiveObj.InteractiveOptions[i]);
|
|
|
|
if (i == 0 && RckInput.isUsingGamepad)
|
|
newOption.GetComponent<Selectable>().Select();
|
|
}
|
|
}
|
|
// Otherwise if we have only one option
|
|
}
|
|
else if (obj.interactiveObj.InteractiveOptions.Length == 1)
|
|
{
|
|
// We just trigger the events
|
|
DoInteractiveAction(obj, obj.interactiveObj.InteractiveOptions[0]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by InteractiveObject UI Buttons, perform interactive actions
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
/// <param name="option"></param>
|
|
public void DoInteractiveAction(InteractiveObject_Behaviour obj, InteractiveOptions option)
|
|
{
|
|
// We initialize the array element
|
|
int arrayElement = -1;
|
|
|
|
// We find at what index are the Events of the selected 'option'
|
|
for (int i = 0; i < obj.interactiveObj.InteractiveOptions.Length; i++)
|
|
{
|
|
if (option == obj.interactiveObj.InteractiveOptions[i])
|
|
{
|
|
// We save it
|
|
arrayElement = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// We trigger activators
|
|
if (obj.events[arrayElement].EvaluateConditions())
|
|
{
|
|
QuestManager.instance.QuestDealerActivator(obj.events[arrayElement].questDealers);
|
|
QuestManager.instance.QuestUpdaterActivator(obj.events[arrayElement].questUpdaters);
|
|
ConsequenceManager.instance.ConsequencesActivator(gameObject, obj.events[arrayElement].consequences);
|
|
}
|
|
|
|
// Trigger the Result Script
|
|
if (!string.IsNullOrEmpty(obj.resultScripts[arrayElement]))
|
|
RCKFunctions.ExecuteScript(obj.resultScripts[arrayElement]);
|
|
|
|
// Enable player controls
|
|
EnableDisableControls(true);
|
|
|
|
uiManager.interactiveObjectUIContainer.SetActive(false);
|
|
|
|
// Remove all the previous instantiated options
|
|
foreach (Transform t in uiManager.interactiveOptionContent)
|
|
Destroy(t.gameObject);
|
|
|
|
|
|
StartCoroutine(StopInteractingFixed());
|
|
input.SwitchCurrentActionMap("Player");
|
|
|
|
}
|
|
|
|
IEnumerator StopInteractingFixed() {
|
|
yield return new WaitForEndOfFrame();
|
|
isInteracting = false;
|
|
}
|
|
|
|
private void CheckForLootingPoint(bool isPickPocket) {
|
|
if (isPickPocket == false) {
|
|
if (rayHit.transform.CompareTag("RPG Creation Kit/Looting Point"))
|
|
{
|
|
// When we find one, we save this reference
|
|
LootingPoint obj = rayHit.collider.transform.gameObject.GetComponent<LootingPoint>();
|
|
|
|
// Set the UI
|
|
if (!isLooting) {
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
if (obj.inventory.Items.Count > 0) {
|
|
if (obj.locked) {
|
|
bool HasPick = false;
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(obj.key.ItemID) <= 0) {
|
|
if (Inventory.PlayerInventory.GetItemCount(LockpickingManager.instance.LockPick) > 0) {
|
|
uiManager.Interact_text.text = cmdStr + " Search: " + obj.pointName + " (Use Lockpick)";
|
|
HasPick = true;
|
|
}
|
|
}
|
|
if (HasPick == false) {
|
|
uiManager.Interact_text.text = cmdStr+" Search: " + obj.pointName + " (Locked)"; // orig
|
|
}
|
|
} else {
|
|
uiManager.Interact_text.text = cmdStr+" Search: " + obj.pointName;
|
|
}
|
|
} else {
|
|
if (obj.locked) {
|
|
bool HasPick = false;
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(obj.key.ItemID) <= 0) {
|
|
if (Inventory.PlayerInventory.GetItemCount(LockpickingManager.instance.LockPick) > 0) {
|
|
uiManager.Interact_text.text = cmdStr + " Search: " + obj.pointName + " (Empty) (Use Lockpick)";
|
|
HasPick = true;
|
|
}
|
|
}
|
|
if (HasPick == false) {
|
|
uiManager.Interact_text.text = cmdStr+" Search: " + obj.pointName + " (Empty) (Locked)"; // orig
|
|
}
|
|
} else {
|
|
uiManager.Interact_text.text = cmdStr+" Search: " + obj.pointName + " (Empty)";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for Key to speak with him
|
|
if (input.actions.FindAction("Interact").triggered) {
|
|
if (obj.locked) {
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(obj.key.ItemID) > 0) {
|
|
|
|
if (obj.onLocked != null) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.onLocked);
|
|
} else {
|
|
Debug.Log("SCHAKEN - You need a UNLOCKING sound!!!");
|
|
}
|
|
StartCoroutine(UnlockThenOpen(obj)); // Added a delay for locking sound and realism
|
|
} else {
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(LockpickingManager.instance.LockPick) > 0) {
|
|
if (!RckPlayer.instance.isPickingLock) {
|
|
LockpickingManager.instance.StartPicking(obj);
|
|
}
|
|
} else {
|
|
// We don't have the key, alert message the player
|
|
AlertMessage.instance.InitAlertMessage("You don't have the key", 3f);
|
|
}
|
|
if (obj.onUnlocked != null) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.onUnlocked);
|
|
}
|
|
}
|
|
} else {
|
|
OpenLootPoint(obj);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// When we find one, we save this reference
|
|
RckAI obj = rayHit.transform.gameObject.GetComponent<RckAI>();
|
|
|
|
if (obj != null) {
|
|
|
|
// Set the UI
|
|
if (!isLooting) {
|
|
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
uiManager.Interact_text.text = cmdStr + " Pickpocket: " + obj.GetEntityName();
|
|
}
|
|
|
|
// Check for Key to speak with him
|
|
if (input.actions.FindAction("Interact").triggered) {
|
|
OpenLootPoint(obj);
|
|
}
|
|
}
|
|
// Check for Key to speak with him
|
|
}
|
|
}
|
|
|
|
IEnumerator UnlockThenOpen(LootingPoint obj) {
|
|
yield return new WaitForSeconds(0.7f);
|
|
obj.UnlockContainer();
|
|
OpenLootPoint(obj);
|
|
}
|
|
|
|
private void OpenLootPoint(RckAI _AI) {
|
|
isLooting = true;
|
|
LootingInventoryUI.instance.OpenLootingPanel(_AI.gameObject.GetComponentInChildren<LootingPoint>(), true, true, _AI);
|
|
}
|
|
|
|
private void OpenLootPoint(LootingPoint _point) {
|
|
isLooting = true;
|
|
objLooting = _point;
|
|
|
|
if (_point.openSound)
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.GeneralSounds, _point.openSound);
|
|
|
|
if (_point.anim != null) {
|
|
_point.OpenCloseContainer();
|
|
StartCoroutine(DelayOpenLootingPoint(_point));
|
|
} else {
|
|
LootingInventoryUI.instance.OpenLootingPanel(_point);
|
|
}
|
|
}
|
|
|
|
IEnumerator DelayOpenLootingPoint(LootingPoint _point) {
|
|
yield return new WaitForSeconds(0.7f);
|
|
LootingInventoryUI.instance.OpenLootingPanel(_point);
|
|
}
|
|
|
|
private void CheckForDoors()
|
|
{
|
|
if(rayHit.transform.CompareTag("RPG Creation Kit/Door") || (rayHit.transform.CompareTag("RPG Creation Kit/Cave")))
|
|
{
|
|
// When we find one, we save this reference
|
|
Door obj = rayHit.transform.gameObject.GetComponent<Door>();
|
|
|
|
// Set the UI
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
|
|
if (obj.teleports && rayHit.transform.CompareTag("RPG Creation Kit/Door")) {
|
|
uiManager.Interact_text.text = cmdStr+" Door to: " + obj.toCell.cellName;
|
|
} else if (obj.teleports && rayHit.transform.CompareTag("RPG Creation Kit/Cave")) {
|
|
uiManager.Interact_text.text = cmdStr+" Enter: " + obj.toCell.cellName;
|
|
} else {
|
|
if (obj.isOpened) {
|
|
uiManager.Interact_text.text = cmdStr+" Close: Door";
|
|
} else {
|
|
if (obj.locked) {
|
|
bool HasPick = false;
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(obj.key.ItemID) <= 0) {
|
|
if (Inventory.PlayerInventory.GetItemCount(LockpickingManager.instance.LockPick) > 0) { //HERE we arent seeing it..
|
|
uiManager.Interact_text.text = cmdStr + " Open: Door (Use Lockpick)";
|
|
HasPick = true;
|
|
}
|
|
}
|
|
if (HasPick == false) {
|
|
uiManager.Interact_text.text = cmdStr+" Open: Door (Locked)";
|
|
}
|
|
} else {
|
|
uiManager.Interact_text.text = cmdStr+" Open: Door";
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for opening door
|
|
if (input.actions.FindAction("Interact").triggered && !WorldManager.instance.isLoading) {
|
|
if (!obj.isOpened) {
|
|
if (obj.locked) {
|
|
// We have the key
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(obj.key.ItemID) > 0) {
|
|
if (obj.onDoorOpenLocked != null) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.onDoorOpenUnlocked);
|
|
}
|
|
|
|
StartCoroutine(UnlockDoorThenOpen(obj));// Just delaying for realism and sounds
|
|
//obj.UnlockDoor();
|
|
//OpenDoor(obj);
|
|
} else {
|
|
if (obj.key != null && Inventory.PlayerInventory.GetItemCount(LockpickingManager.instance.LockPick) > 0) {
|
|
if (!RckPlayer.instance.isPickingLock) {
|
|
LockpickingManager.instance.StartPicking(obj);
|
|
}
|
|
} else {
|
|
// We don't have the key, alert message the player
|
|
AlertMessage.instance.InitAlertMessage("You don't have the key to open this door", 3f);
|
|
if (obj.onDoorOpenLocked != null) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.onDoorOpenLocked);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (obj.onDoorOpen != null) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.onDoorOpen);
|
|
}
|
|
|
|
OpenDoor(obj);
|
|
}
|
|
} else {
|
|
if (obj.onDoorOpen != null) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.onDoorOpen);
|
|
}
|
|
|
|
OpenDoor(obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IEnumerator UnlockDoorThenOpen(Door obj) {
|
|
yield return new WaitForSeconds(0.7f);
|
|
obj.UnlockDoor();
|
|
OpenDoor(obj);
|
|
}
|
|
|
|
private void OpenDoor(Door obj) {
|
|
if (obj.onDoorOpen) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.GeneralSounds, obj.onDoorOpen);
|
|
} else {
|
|
Debug.Log("SCHAKEN - Add sounds here!");
|
|
}
|
|
|
|
if (obj.teleports) {
|
|
FreezeAndDisableControl();
|
|
WorldManager.instance.LoadCell(obj.toCell, UnityEngine.Random.Range(int.MinValue, int.MaxValue), false, obj, null, true);
|
|
} else {
|
|
// Open door by rotating pivot/playing animation
|
|
obj.OpenCloseDoor();
|
|
}
|
|
}
|
|
|
|
private void CheckForCrafting() {
|
|
if (rayHit.transform.CompareTag("RPG Creation Kit/Crafting")) {
|
|
// When we find one, we save this reference
|
|
CraftingPoint obj = rayHit.collider.transform.gameObject.GetComponent<CraftingPoint>();
|
|
|
|
// Set the UI
|
|
if (!isCrafting) {
|
|
uiManager.Interact_text.gameObject.SetActive(true);
|
|
uiManager.Interact_text.text = cmdStr+" Use: " + obj.pointName;
|
|
}
|
|
|
|
// Check for Key to speak with him
|
|
if (input.actions.FindAction("Interact").triggered) {
|
|
GameAudioManager.instance.PlayOneShot(AudioSources.PlayerFPS, obj.Using);
|
|
AlchemyManager.instance.OpenAlchemyPanel();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void StartDialogue(IDialoguable dialoguable) {
|
|
speakingTo = dialoguable;
|
|
dialoguable.SetSpeakerIndex(0); // Always 0 here because the player is talking to someone
|
|
dialoguable.OnDialogueStarts(this.gameObject);
|
|
DialogueLogic(dialoguable.GetCurrentDialogueGraph());
|
|
}
|
|
|
|
void DialogueLogic(DialogueGraph dialogue) {
|
|
if (dialogue != null) {
|
|
StartCoroutine(ExecuteNode(dialogue.GetEntryNode()));
|
|
}
|
|
}
|
|
|
|
public bool isPlainLineDialogue = false;
|
|
IEnumerator ExecuteNode(XNode.Node _node)
|
|
{
|
|
// Trigger Events and Script
|
|
DialogueNode globalNode = (DialogueNode)_node;
|
|
|
|
RCKFunctions.ExecuteEvents(globalNode.events);
|
|
|
|
if (!string.IsNullOrEmpty(globalNode.resultScript))
|
|
RCKFunctions.ExecuteScript(globalNode.resultScript);
|
|
|
|
if (_node is EntryNode)
|
|
{
|
|
EntryNode thisNode = (EntryNode)_node;
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("firstNode").Connection.node));
|
|
}
|
|
else if (_node is ConditionsNode)
|
|
{
|
|
ConditionsNode thisNode = (ConditionsNode)_node;
|
|
|
|
bool conditionsResult = RCKFunctions.VerifyConditions(thisNode.conditions);
|
|
|
|
if (conditionsResult)
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("resultTrue").Connection.node));
|
|
else
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("resultFalse").Connection.node));
|
|
|
|
}
|
|
else if (_node is NPCDialogueLineNode)
|
|
{
|
|
NPCDialogueLineNode thisNode = (NPCDialogueLineNode)_node;
|
|
|
|
// Set the Dialoguable state
|
|
speakingTo.OnSpeakALine(thisNode);
|
|
|
|
if (!thisNode.plainLine)
|
|
{
|
|
input.SwitchCurrentActionMap("DialogueUI");
|
|
|
|
// Flag that we're in conversation
|
|
isInConversation = true;
|
|
|
|
// Disable player controls
|
|
mouseLook.SetLookAtTarget(speakingTo.GetEntityLookAtPos());
|
|
EnableDisableControls(false);
|
|
|
|
// Set the UI properly
|
|
uiManager.heardDialogues.gameObject.SetActive(false);
|
|
|
|
uiManager.playerQuestionsContainer.SetActive(false);
|
|
uiManager.compassGameObject.SetActive(false);
|
|
uiManager.StatsUIGameObject.SetActive(false);
|
|
uiManager.crosshairGameObject.SetActive(false);
|
|
|
|
|
|
// Npc Name
|
|
uiManager.npc_Name.text = speakingTo.GetDialoguableName();
|
|
uiManager.npc_Name.gameObject.SetActive(true);
|
|
|
|
// Npc Line
|
|
uiManager.npc_Line.text = thisNode.line;
|
|
uiManager.npc_Line.gameObject.SetActive(true);
|
|
|
|
// Whole Dialogue UI
|
|
uiManager.dialogueContainer.SetActive(true);
|
|
|
|
cameraLookNPC = true;
|
|
}
|
|
else
|
|
{
|
|
// Flag that we're in conversation
|
|
isInConversation = true;
|
|
isPlainLineDialogue = true;
|
|
|
|
uiManager.heardDialogues.text = thisNode.line;
|
|
uiManager.heardDialogues.gameObject.SetActive(true);
|
|
}
|
|
|
|
// - End UI
|
|
|
|
// - End Updaters
|
|
// Play the audio if exists
|
|
if (thisNode.audioClip != null)
|
|
{
|
|
speakingTo.PlayAudioClip(thisNode.audioClip);
|
|
speakingTo.GetEntityGameObject().GetComponent<Equipment>().characterModel.Voice.Talk(thisNode.audioClip);
|
|
}
|
|
|
|
// Play talking animation if choosen
|
|
if(!string.IsNullOrEmpty(thisNode.dialogueAnimationStr))
|
|
{
|
|
speakingTo.GetAnimator().CrossFade(thisNode.dialogueAnimationStr, .1f);
|
|
}
|
|
|
|
// Check for the timing of the line
|
|
bool outOfTime = false;
|
|
float startTime = Time.time;
|
|
|
|
// To wait until the line ends
|
|
while (!outOfTime)
|
|
{
|
|
// If we press X button
|
|
if (input.actions.FindAction("SkipDialogue").triggered && Time.time - startTime >= 0.5f && !thisNode.plainLine ||
|
|
WorldManager.instance.isLoading)
|
|
outOfTime = true;
|
|
|
|
// If the time expires
|
|
if (!thisNode.useLenghtOfClip)
|
|
{
|
|
if (Time.time - startTime >= thisNode.lineTime)
|
|
outOfTime = true;
|
|
}
|
|
else
|
|
{
|
|
if (Time.time - startTime >= thisNode.audioClip.length)
|
|
outOfTime = true;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
// Line has finished and player was teleported
|
|
if (WorldManager.instance.isLoading)
|
|
{
|
|
// Reset the player status
|
|
isInConversation = false;
|
|
isPlainLineDialogue = false;
|
|
|
|
// Disable the UI
|
|
if (!thisNode.plainLine)
|
|
{
|
|
uiManager.dialogueContainer.SetActive(false);
|
|
|
|
|
|
uiManager.compassGameObject.SetActive(true);
|
|
uiManager.StatsUIGameObject.SetActive(true);
|
|
uiManager.crosshairGameObject.SetActive(true);
|
|
EnableDisableControls(false);
|
|
|
|
cameraLookNPC = false;
|
|
}
|
|
else
|
|
{
|
|
uiManager.heardDialogues.gameObject.SetActive(false);
|
|
}
|
|
|
|
// Destroy every previous question
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
Destroy(t.gameObject);
|
|
|
|
speakingTo = null;
|
|
|
|
yield break;
|
|
}
|
|
|
|
// Stop the audio source
|
|
if(speakingTo != null)
|
|
speakingTo.StopAudio();
|
|
|
|
|
|
// Check what we have to do next
|
|
switch (thisNode.afterLine)
|
|
{
|
|
case AfterLine.NPC_DialogueLine:
|
|
// If we have to trigger another dialogue line, we just re-start this courutine with the new line
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("nextLine").Connection.node));
|
|
yield break;
|
|
|
|
case AfterLine.PlayerQuestions:
|
|
|
|
// Play listening animation if choosen
|
|
if (!string.IsNullOrEmpty(thisNode.dialogueAnimationListeningStr))
|
|
{
|
|
speakingTo.GetAnimator().CrossFade(thisNode.dialogueAnimationListeningStr, .1f);
|
|
}
|
|
|
|
if (thisNode.removePreviousQuestions)
|
|
{
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
Destroy(t.gameObject);
|
|
}
|
|
else if (thisNode.questionsToRemove.Length > 0)
|
|
{
|
|
List<GameObject> toDelete = new List<GameObject>();
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
{
|
|
for (int i = 0; i < thisNode.questionsToRemove.Length; i++)
|
|
{
|
|
if (t.GetComponent<PlayerQuestionUI>().question.qID == thisNode.questionsToRemove[i])
|
|
toDelete.Add(t.gameObject);
|
|
}
|
|
}
|
|
|
|
foreach (GameObject go in toDelete)
|
|
{
|
|
Destroy(go);
|
|
}
|
|
}
|
|
|
|
List<PlayerQuestionUI> questions = new List<PlayerQuestionUI>();
|
|
// Check if we have to add some new question
|
|
for (int i = 0; i < thisNode.playerQuestions.Count; i++)
|
|
{
|
|
int tempPosition = thisNode.playerQuestions[i].Position;
|
|
// In case, add them
|
|
GameObject newQuestion = Instantiate(uiManager.playerQuestionPrefab, uiManager.playerQuestionsContent);
|
|
|
|
if (tempPosition == 0)
|
|
tempPosition = i;
|
|
|
|
questions.Add(newQuestion.GetComponent<PlayerQuestionUI>());
|
|
|
|
newQuestion.GetComponent<PlayerQuestionUI>()
|
|
.Init(thisNode.playerQuestions[i], speakingTo,
|
|
(DialogueNode)thisNode.GetOutputPort("playerQuestions " + i).Connection.node,
|
|
thisNode.playerQuestions[i].Question, thisNode.playerQuestions[i].DeleteAfterAnswer,
|
|
tempPosition);
|
|
|
|
newQuestion.GetComponent<RectTransform>().SetSiblingIndex(tempPosition);
|
|
}
|
|
|
|
|
|
// Set the UI to allow the player to ask questions
|
|
uiManager.npc_Line.gameObject.SetActive(false);
|
|
uiManager.playerQuestionsContainer.SetActive(true);
|
|
|
|
// Reset the scroll bar of the PlayerQuestionScrollView
|
|
if (uiManager.playerQuestionsContainer.GetComponentInChildren<Scrollbar>() != null)
|
|
uiManager.playerQuestionsContainer.GetComponentInChildren<Scrollbar>().value = 1f;
|
|
|
|
speakingTo.OnFinishedSpeakingALine();
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
uiManager.ReorderQuestions();
|
|
uiManager.PreventUnselectedQuestionWithGamepad();
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
uiManager.PreventUnselectedQuestionWithGamepad();
|
|
|
|
yield break;
|
|
|
|
case AfterLine.EndDialogue:
|
|
|
|
speakingTo.OnDialogueEnds(this.gameObject);
|
|
|
|
// Reset the player status
|
|
isInConversation = false;
|
|
|
|
// Disable the UI
|
|
if (!thisNode.plainLine)
|
|
{
|
|
uiManager.dialogueContainer.SetActive(false);
|
|
|
|
|
|
uiManager.compassGameObject.SetActive(true);
|
|
uiManager.StatsUIGameObject.SetActive(true);
|
|
uiManager.crosshairGameObject.SetActive(true);
|
|
EnableDisableControls(true);
|
|
|
|
cameraLookNPC = false;
|
|
EndDialogue();
|
|
}
|
|
else
|
|
{
|
|
isPlainLineDialogue = false;
|
|
uiManager.heardDialogues.gameObject.SetActive(false);
|
|
}
|
|
|
|
// Destroy every previous question
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
Destroy(t.gameObject);
|
|
|
|
// Reset speaking to animator
|
|
if(speakingTo != null && speakingTo.GetAnimator() != null)
|
|
speakingTo.GetAnimator().SetTrigger("CancelDialogueAnimation");
|
|
|
|
speakingTo = null;
|
|
|
|
yield break;
|
|
|
|
case AfterLine.Continue:
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("output").Connection.node));
|
|
break;
|
|
}
|
|
}
|
|
else if (_node is PlayerQuestionsNode)
|
|
{
|
|
PlayerQuestionsNode thisNode = (PlayerQuestionsNode)_node;
|
|
|
|
// Play listening animation if choosen
|
|
if (!string.IsNullOrEmpty(thisNode.dialogueAnimationListeningStr))
|
|
{
|
|
speakingTo.GetAnimator().CrossFade(thisNode.dialogueAnimationListeningStr, .1f);
|
|
}
|
|
else
|
|
{
|
|
// Reset speaking to animator
|
|
speakingTo.GetAnimator().SetTrigger("CancelDialogueAnimation");
|
|
}
|
|
|
|
// Flag that we're in conversation
|
|
isInConversation = true;
|
|
|
|
input.SwitchCurrentActionMap("DialogueUI");
|
|
|
|
mouseLook.SetLookAtTarget(speakingTo.GetEntityLookAtPos());
|
|
// Disable player controls
|
|
EnableDisableControls(false);
|
|
|
|
// Set the UI properly
|
|
uiManager.heardDialogues.gameObject.SetActive(false);
|
|
|
|
uiManager.playerQuestionsContainer.SetActive(false);
|
|
uiManager.compassGameObject.SetActive(false);
|
|
uiManager.StatsUIGameObject.SetActive(false);
|
|
uiManager.crosshairGameObject.SetActive(false);
|
|
|
|
|
|
// Npc Name
|
|
uiManager.npc_Name.text = speakingTo.GetDialoguableName();
|
|
uiManager.npc_Name.gameObject.SetActive(true);
|
|
|
|
// Whole Dialogue UI
|
|
uiManager.dialogueContainer.SetActive(true);
|
|
|
|
cameraLookNPC = true;
|
|
|
|
if (thisNode.removePreviousQuestions)
|
|
{
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
Destroy(t.gameObject);
|
|
}
|
|
else if (thisNode.questionsToRemove.Length > 0)
|
|
{
|
|
List<GameObject> toDelete = new List<GameObject>();
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
{
|
|
for (int i = 0; i < thisNode.questionsToRemove.Length; i++)
|
|
{
|
|
if (t.GetComponent<PlayerQuestionUI>().question.qID == thisNode.questionsToRemove[i])
|
|
toDelete.Add(t.gameObject);
|
|
}
|
|
}
|
|
|
|
foreach (GameObject go in toDelete)
|
|
{
|
|
Destroy(go);
|
|
}
|
|
}
|
|
|
|
List<PlayerQuestionUI> questions = new List<PlayerQuestionUI>();
|
|
// Check if we have to add some new question
|
|
for (int i = 0; i < thisNode.playerQuestions.Count; i++)
|
|
{
|
|
int tempPosition = thisNode.playerQuestions[i].Position;
|
|
// In case, add them
|
|
GameObject newQuestion = Instantiate(uiManager.playerQuestionPrefab, uiManager.playerQuestionsContent);
|
|
|
|
if (tempPosition == 0)
|
|
tempPosition = i;
|
|
|
|
questions.Add(newQuestion.GetComponent<PlayerQuestionUI>());
|
|
|
|
newQuestion.GetComponent<PlayerQuestionUI>()
|
|
.Init(thisNode.playerQuestions[i], speakingTo,
|
|
(DialogueNode)thisNode.GetOutputPort("playerQuestions " + i).Connection.node,
|
|
thisNode.playerQuestions[i].Question, thisNode.playerQuestions[i].DeleteAfterAnswer,
|
|
tempPosition);
|
|
|
|
newQuestion.GetComponent<RectTransform>().SetSiblingIndex(tempPosition);
|
|
}
|
|
|
|
// Set the UI to allow the player to ask questions
|
|
uiManager.npc_Line.gameObject.SetActive(false);
|
|
uiManager.playerQuestionsContainer.SetActive(true);
|
|
|
|
// Reset the scroll bar of the PlayerQuestionScrollView
|
|
if (uiManager.playerQuestionsContainer.GetComponentInChildren<Scrollbar>() != null)
|
|
uiManager.playerQuestionsContainer.GetComponentInChildren<Scrollbar>().value = 1f;
|
|
|
|
speakingTo.OnFinishedSpeakingALine();
|
|
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
uiManager.ReorderQuestions();
|
|
|
|
uiManager.PreventUnselectedQuestionWithGamepad();
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
uiManager.PreventUnselectedQuestionWithGamepad();
|
|
}
|
|
else if (_node is ChangeDialogueNode)
|
|
{
|
|
ChangeDialogueNode thisNode = (ChangeDialogueNode)_node;
|
|
|
|
if (thisNode.onNPCWhosSpeaking)
|
|
{
|
|
speakingTo.ChangeDialogueGraph(thisNode.newDialogue);
|
|
|
|
if (thisNode.startDialogueImmediatly)
|
|
{
|
|
var npcSpeakingSaved = speakingTo;
|
|
EndDialogue();
|
|
|
|
StartDialogue(npcSpeakingSaved);
|
|
}
|
|
else
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("output").Connection.node));
|
|
|
|
}
|
|
else
|
|
{
|
|
RCKFunctions.ChangeDialogueToRckAI(thisNode.npcRef, thisNode.newDialogue.ID);
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("output").Connection.node));
|
|
}
|
|
|
|
yield break;
|
|
}
|
|
else if (_node is ChangeStateNode)
|
|
{
|
|
ChangeStateNode thisNode = (ChangeStateNode)_node;
|
|
|
|
switch (thisNode.stateChange)
|
|
{
|
|
case ChangeStateNode.DialogueStateChange.Trade:
|
|
|
|
if (thisNode.toCurrentNPC)
|
|
RCKFunctions.StartTrading(speakingTo.GetEntityGameObject().GetComponent<Merchant>());
|
|
|
|
// TODO find npc and do stuff
|
|
break;
|
|
|
|
case ChangeStateNode.DialogueStateChange.Loot:
|
|
|
|
// TODO find looting point and do stuff
|
|
|
|
break;
|
|
|
|
case ChangeStateNode.DialogueStateChange.Teleport:
|
|
|
|
//WorldStreaming.manager.Teleport(thisNode.coordinates);
|
|
|
|
break;
|
|
|
|
case ChangeStateNode.DialogueStateChange.ChangeCell:
|
|
|
|
//WorldStreaming.manager.StartLoadingInterior(thisNode.cell.worldspace, thisNode.cell, null, thisNode.coordinates);
|
|
|
|
break;
|
|
|
|
case ChangeStateNode.DialogueStateChange.SpeakToNPC:
|
|
|
|
// TODO Find the NPC and do stuff
|
|
|
|
break;
|
|
}
|
|
|
|
if (thisNode.interruptsDialogue)
|
|
EndDialogue();
|
|
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("output").Connection.node));
|
|
}
|
|
else if (_node is RandomNode)
|
|
{
|
|
RandomNode thisNode = (RandomNode)_node;
|
|
StartCoroutine(ExecuteNode(thisNode.PickRandomExit()));
|
|
}
|
|
else if(_node is Dialogue_AISetFieldNode)
|
|
{
|
|
Dialogue_AISetFieldNode thisNode = (Dialogue_AISetFieldNode)_node;
|
|
thisNode.OnStart();
|
|
|
|
if(thisNode.speakerID == 0) // Its to the NPC we're talking to
|
|
{
|
|
var component = speakingTo.GetEntityGameObject().GetComponent<RckAI>(); // it's always the speaker with id 0 because it's player to ai dialogue
|
|
|
|
if (component == null)
|
|
{
|
|
Debug.Log("Dialogue Node : Tried to SetField but the given Component: \"RckAI\" was not found on Speaker Index 0. Node fails.");
|
|
yield break;
|
|
}
|
|
|
|
var field = component.GetType().GetField(thisNode.FieldToSet);
|
|
|
|
field.SetValue(component, thisNode.storedValue.GetValue());
|
|
}
|
|
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("output").Connection.node));
|
|
}
|
|
else if(_node is Dialogue_AIInvokeNode)
|
|
{
|
|
Dialogue_AIInvokeNode thisNode = (Dialogue_AIInvokeNode)_node;
|
|
|
|
NodesHelper.AIInvokeCall(thisNode.MethodToCall, speakingTo.GetEntityGameObject().GetComponent<RckAI>(), thisNode.parameters);
|
|
|
|
StartCoroutine(ExecuteNode(thisNode.GetOutputPort("output").Connection.node));
|
|
}
|
|
else if (_node is EndNode)
|
|
{
|
|
EndNode thisNode = (EndNode)_node;
|
|
|
|
// Reset speaking to animator
|
|
speakingTo.GetAnimator().SetTrigger("CancelDialogueAnimation");
|
|
speakingTo.OnDialogueEnds(this.gameObject);
|
|
|
|
EndDialogue();
|
|
yield break;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
void EndDialogue()
|
|
{
|
|
//speakingTo.OnDialogueEnds(this.gameObject);
|
|
mouseLook.ApplyCurrentRotation();
|
|
mouseLook.ClearLookAt();
|
|
|
|
// Reset the player status
|
|
isInConversation = false;
|
|
isPlainLineDialogue = false;
|
|
|
|
// Disable the UI
|
|
uiManager.dialogueContainer.SetActive(false);
|
|
|
|
|
|
uiManager.compassGameObject.SetActive(true);
|
|
uiManager.StatsUIGameObject.SetActive(true);
|
|
uiManager.crosshairGameObject.SetActive(true);
|
|
EnableDisableControls(true);
|
|
|
|
cameraLookNPC = false;
|
|
uiManager.heardDialogues.gameObject.SetActive(false);
|
|
|
|
// Destroy every previous question
|
|
foreach (Transform t in uiManager.playerQuestionsContent)
|
|
Destroy(t.gameObject);
|
|
|
|
speakingTo = null;
|
|
|
|
// Input scheme
|
|
input.SwitchCurrentActionMap("Player");
|
|
|
|
}
|
|
public static int SortByPosition(PlayerQuestionUI p1, PlayerQuestionUI p2)
|
|
{
|
|
return p1.position.CompareTo(p2.position);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method called from PlayerQuestionUI to ask a question
|
|
/// </summary>
|
|
/// <param name="npc">The NPC with we are speaking with</param>
|
|
/// <param name="response">His response to our question</param>
|
|
/// <param name="DestroyQuestion">Destroy the question after answer?</param>
|
|
/// <param name="theQuestion">The question to destroy</param>
|
|
public void AskQuestion(IDialoguable _dialoguable, XNode.Node response, bool DestroyQuestion, GameObject theQuestion = null, bool isNpcToNpcDialogue = false, IDialoguable[] _dialoguables = null)
|
|
{
|
|
if (!isNpcToNpcDialogue)
|
|
StartCoroutine(ExecuteNode(response));
|
|
else
|
|
{
|
|
isInConversation = false;
|
|
speakingTo = null;
|
|
_dialoguable.ExecuteDialogueNode(response, _dialoguables);
|
|
}
|
|
|
|
// DestroyQuestion = What we said in the ScriptableObject
|
|
// Destroy after .05f seconds to not have bad effects in the PlayerQuestionUI (Question disappear before the panel's fadeout)
|
|
if (DestroyQuestion)
|
|
Destroy(theQuestion, .05f);
|
|
}
|
|
|
|
private void CheckForIDraggable()
|
|
{
|
|
IDraggable draggable = rayHit.transform.gameObject.GetComponent<IDraggable>();
|
|
|
|
if (draggable != null && !isDragging)
|
|
{
|
|
if(!isDragging && dragKeyBeingHeld)
|
|
{
|
|
itemRigidbody = draggable.GetGameObject().GetComponent<Rigidbody>();
|
|
dragItemScript = draggable.GetGameObject().GetComponent<ItemInWorld>();
|
|
|
|
if (itemRigidbody != null)
|
|
{
|
|
draggable.OnBeingDragged();
|
|
|
|
BeginDragItem();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void BeginDragItem()
|
|
{
|
|
//if (ItemUnderFeet())
|
|
// return;
|
|
itemRigidbody.angularVelocity = Vector3.zero;
|
|
itemRigidbody.velocity = Vector3.zero;
|
|
|
|
itemRigidbody.useGravity = false;
|
|
|
|
isDragging = true;
|
|
}
|
|
|
|
public float powerVector = 5f;
|
|
|
|
public float droppingDistance = 3f;
|
|
public float moveThresold = .1f;
|
|
public float stopThresold = .1f;
|
|
|
|
private void ManageDraggable()
|
|
{
|
|
if (isDragging && itemRigidbody != null)
|
|
{
|
|
if (!dragKeyBeingHeld)
|
|
StopDragging();
|
|
else if(itemRigidbody != null && dragKeyBeingHeld && dragItemScript.canBeDragged)
|
|
{
|
|
//if (ItemUnderFeet())
|
|
//{
|
|
// StopDragging();
|
|
// return;
|
|
//}
|
|
|
|
//itemRigidbody.position = Vector3.Lerp(itemRigidbody.position, mainCamera.transform.position + mainCamera.transform.forward * 1f, (dragForce * Time.deltaTime));
|
|
//itemRigidbody.MovePosition(Vector3.Lerp(itemRigidbody.transform.position, mainCamera.transform.position + mainCamera.transform.forward, Time.fixedDeltaTime * dragForce));
|
|
|
|
//Vector3 toCameraCenterVector = (mainCamera.transform.position + mainCamera.transform.forward) - itemRigidbody.transform.position;
|
|
//toCameraCenterVector = toCameraCenterVector.normalized;
|
|
|
|
//itemRigidbody.AddForce(Vector3.MoveTowards(itemRigidbody.transform.position, toCameraCenterVector, dragForce * Time.deltaTime) * powerVector, ForceMode.VelocityChange);
|
|
//itemRigidbody.velocity = Vector3.zero;
|
|
|
|
Vector3 toCameraCenterVector = (mainCamera.transform.position + mainCamera.transform.forward) - itemRigidbody.transform.position;
|
|
toCameraCenterVector = toCameraCenterVector.normalized * .25f;
|
|
|
|
var dst = Vector3.Distance(itemRigidbody.transform.position, mainCamera.transform.position + mainCamera.transform.forward);
|
|
if (dst > moveThresold)
|
|
dragForce = 1000f;
|
|
else
|
|
dragForce = 150f;
|
|
|
|
if(dst > stopThresold)
|
|
itemRigidbody.AddForce(toCameraCenterVector * (dragForce * Time.fixedDeltaTime), ForceMode.VelocityChange);
|
|
|
|
itemRigidbody.velocity = Vector3.zero;
|
|
|
|
|
|
Debug.DrawRay(itemRigidbody.transform.position, toCameraCenterVector, Color.red);
|
|
|
|
if (Mathf.Abs(mouseLook.x) > 2f || Mathf.Abs(mouseLook.y) > 2f)
|
|
{
|
|
dragDirection = new Vector3(mouseLook.x, mouseLook.y, 0);
|
|
dragDirection = transform.TransformDirection(dragDirection.normalized * (dragForce * Time.fixedDeltaTime));
|
|
}
|
|
else
|
|
dragDirection = Vector3.zero;
|
|
|
|
if (Vector3.Distance(mainCamera.transform.position + mainCamera.transform.forward, itemRigidbody.transform.position) > droppingDistance)
|
|
StopDragging();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isDragging = false;
|
|
}
|
|
}
|
|
|
|
|
|
public void DisplayHeardLine(string _line, float _time)
|
|
{
|
|
uiManager.heardDialogues.text = _line;
|
|
uiManager.heardDialogues.gameObject.SetActive(true);
|
|
|
|
Invoke("HideHeardLine", _time);
|
|
}
|
|
|
|
public void HideHeardLine()
|
|
{
|
|
uiManager.heardDialogues.gameObject.SetActive(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when we stop to drag the item, reset its state to default world item
|
|
/// </summary>
|
|
public void StopDragging()
|
|
{
|
|
itemRigidbody.useGravity = true;
|
|
itemRigidbody.velocity = Vector3.zero;
|
|
|
|
itemRigidbody = null;
|
|
isDragging = false;
|
|
}
|
|
|
|
public void SetSpeakerIndex(int index)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void DialogueLogic(IDialoguable[] entities, DialogueGraph dialogue)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public IEnumerator ExecuteDialogueNode(Node _node, IDialoguable[] _entities)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void SpeakToEntity(IDialoguable target)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void ChangeDialogueGraph(DialogueGraph _newDialogueGraph)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public bool CanDialogue()
|
|
{
|
|
return (isAlive && !isInConversation && !isInteracting && !isLooting && isLoaded);
|
|
}
|
|
|
|
public string GetDialoguableName()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void OnDialogueStarts(GameObject target)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void OnDialogueEnds(GameObject target)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public DialogueGraph GetCurrentDialogueGraph()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void OnSpeakALine(NPCDialogueLineNode currentNode)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void OnFinishedSpeakingALine()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public Transform GetEntityLookAtPos()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public GameObject GetEntityGameObject()
|
|
{
|
|
return gameObject;
|
|
}
|
|
|
|
public void PlayAudioClip(AudioClip clip)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void StopAudio()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public bool IsTalking()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
Animator IDialoguable.GetAnimator()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
int IDialoguable.GetSpeakerIndex()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
|
|
void IDialoguable.ForceToStopDialogue()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
}
|
|
} |