2023-04-30 00:04:18 -04:00
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
2023-04-22 18:44:01 -04:00
|
|
|
using UnityEngine;
|
|
|
|
using RPGCreationKit.Player;
|
|
|
|
using RPGCreationKit.CellsSystem;
|
2023-04-30 00:04:18 -04:00
|
|
|
using TMPro;
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
namespace RPGCreationKit
|
|
|
|
{
|
|
|
|
public class LockpickingManager : MonoBehaviour
|
|
|
|
{
|
|
|
|
public static LockpickingManager instance;
|
|
|
|
private void Awake()
|
|
|
|
{
|
2023-04-30 00:04:18 -04:00
|
|
|
if (instance == null)
|
2023-04-22 18:44:01 -04:00
|
|
|
instance = this;
|
|
|
|
else
|
|
|
|
Debug.LogError("Anomaly detected with the singleton pattern of 'LockpickingManager', are you using multiple LockpickingManager?");
|
|
|
|
}
|
|
|
|
|
|
|
|
private Door curDoor;
|
2023-04-30 00:04:18 -04:00
|
|
|
|
2023-04-22 18:44:01 -04:00
|
|
|
[Space(5)]
|
|
|
|
|
2023-04-30 00:04:18 -04:00
|
|
|
[Header("\tLockpicking References")]
|
|
|
|
[SerializeField] private GameObject lockpickingUI;
|
|
|
|
[SerializeField] private RectTransform PickSprite;
|
|
|
|
[SerializeField] private Transform LockPickUI;
|
|
|
|
[SerializeField] public Item LockPick;
|
|
|
|
[SerializeField] private Animator PadLock;
|
|
|
|
[SerializeField] private TextMeshProUGUI PicksLeft;
|
|
|
|
[SerializeField] private SpinVert SV;
|
|
|
|
[SerializeField] private List<GameObject> ThingsToHide;
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
[Space(5)]
|
|
|
|
|
2023-04-30 00:04:18 -04:00
|
|
|
[Header("\tAudio")]
|
|
|
|
[SerializeField] private AudioSource audioSource;
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
[Space(5)]
|
|
|
|
|
2023-04-30 00:04:18 -04:00
|
|
|
[SerializeField] private AudioClip pickAttempt;
|
|
|
|
[SerializeField] private AudioClip pickBroke;
|
|
|
|
[SerializeField] private AudioClip pickSuccess;
|
|
|
|
[SerializeField] private AudioClip LockUnlocking;
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
|
|
|
|
private bool isShaking = false;
|
|
|
|
private float shakeTime = 0f;
|
|
|
|
private bool shouldDisableControls = false;
|
|
|
|
private float angle = 0f;
|
|
|
|
private float target = 0f;
|
|
|
|
private float acceptableRange = 0f;
|
|
|
|
private float direction = 0f;
|
|
|
|
|
|
|
|
|
|
|
|
// Durability is Static, and Held between lockpicking sessions, so that they cant exit then return to lockpicking to reset durability
|
|
|
|
private static int durability = 0;
|
|
|
|
|
|
|
|
public void StartPicking(Door _door, bool _shouldDisableControls)
|
|
|
|
{
|
2023-04-30 00:04:18 -04:00
|
|
|
SV.ResetRotation();
|
|
|
|
PicksLeft.text = Inventory.PlayerInventory.GetItemCount(LockPick).ToString();
|
2023-04-22 18:44:01 -04:00
|
|
|
if (_door.lockLevel == DoorLockLevel.Impossible) return;
|
2023-04-30 00:04:18 -04:00
|
|
|
if (!Inventory.PlayerInventory.HasItem(LockPick.ItemID)) return;
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
shouldDisableControls = _shouldDisableControls;
|
|
|
|
curDoor = _door;
|
|
|
|
angle = 0f;
|
2023-04-30 00:04:18 -04:00
|
|
|
target = Random.Range(-140, 141);
|
2023-04-22 18:44:01 -04:00
|
|
|
if (durability <= 0)
|
|
|
|
durability = 5; // 5 attempts per Lockpick
|
|
|
|
|
|
|
|
switch (_door.lockLevel)
|
|
|
|
{
|
|
|
|
case DoorLockLevel.VeryEasy:
|
|
|
|
acceptableRange = 25f;
|
|
|
|
break;
|
|
|
|
case DoorLockLevel.Easy:
|
|
|
|
acceptableRange = 20f;
|
|
|
|
break;
|
|
|
|
case DoorLockLevel.Medium:
|
|
|
|
acceptableRange = 13f;
|
|
|
|
break;
|
|
|
|
case DoorLockLevel.Hard:
|
|
|
|
acceptableRange = 8f;
|
|
|
|
break;
|
|
|
|
case DoorLockLevel.VeryHard:
|
|
|
|
acceptableRange = 3f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
RckPlayer.instance.input.SwitchCurrentActionMap("LockpickingUI");
|
|
|
|
lockpickingUI.SetActive(true);
|
|
|
|
|
|
|
|
RckPlayer.instance.isPickingLock = true;
|
2023-04-30 00:04:18 -04:00
|
|
|
for (int i = 0; i < ThingsToHide.Count; i++)
|
|
|
|
ThingsToHide[i].SetActive(false);
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
if (shouldDisableControls)
|
|
|
|
RckPlayer.instance.EnableDisableControls(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FixedUpdate()
|
|
|
|
{
|
|
|
|
if (isShaking)
|
|
|
|
{
|
|
|
|
float distance = Mathf.Abs(angle - target);
|
2023-04-30 00:04:18 -04:00
|
|
|
//PickSprite.rotation = Quaternion.Euler(0, 0, angle + Mathf.Clamp((Random.Range(-distance, distance) / 90f) * 10f, -10, 10));
|
|
|
|
|
|
|
|
Vector3 temp = LockPickUI.transform.rotation.eulerAngles;
|
|
|
|
temp.x = 170 + Mathf.Clamp((Random.Range(-distance, distance) / 90f) * 10f, -10, 10);
|
|
|
|
temp.y = angle;
|
|
|
|
temp.z = 270f;
|
|
|
|
LockPickUI.rotation = Quaternion.Euler(temp);
|
|
|
|
|
|
|
|
//LockPickUI.rotation = Quaternion.Euler(angle, 90 + , 180);
|
2023-04-22 18:44:01 -04:00
|
|
|
shakeTime -= Time.fixedDeltaTime;
|
|
|
|
if (shakeTime <= 0)
|
|
|
|
isShaking = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Update()
|
|
|
|
{
|
2023-04-30 00:04:18 -04:00
|
|
|
if (!RckPlayer.instance.isPickingLock)
|
|
|
|
return;
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
if (isShaking)
|
|
|
|
return;
|
|
|
|
|
|
|
|
direction = -RckPlayer.instance.input.currentActionMap.FindAction("Move").ReadValue<Vector2>().x;
|
|
|
|
|
|
|
|
angle += direction * Time.deltaTime * 16.0f;
|
2023-04-30 00:04:18 -04:00
|
|
|
angle = Mathf.Clamp(angle, 10, 170);
|
|
|
|
//PickSprite.rotation = Quaternion.Euler(0, 0, angle);
|
|
|
|
//LockPickUI.rotation = Quaternion.Euler(angle, 90, 180);
|
|
|
|
|
|
|
|
|
|
|
|
Vector3 temp = LockPickUI.transform.rotation.eulerAngles;
|
|
|
|
temp.x = 170f;
|
|
|
|
temp.y = angle;
|
|
|
|
temp.z = 270f;
|
|
|
|
LockPickUI.rotation = Quaternion.Euler(temp);
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
if (RckPlayer.instance.input.currentActionMap.FindAction("Attempt").triggered)
|
|
|
|
{
|
|
|
|
Attempt();
|
|
|
|
}
|
|
|
|
else if (RckPlayer.instance.input.currentActionMap.FindAction("Close").triggered)
|
|
|
|
{
|
|
|
|
StopPicking();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Attempt()
|
|
|
|
{
|
|
|
|
if (!RckPlayer.instance.isPickingLock) return;
|
|
|
|
if (durability <= 0) return;
|
|
|
|
|
|
|
|
durability--;
|
|
|
|
|
|
|
|
// Check if successfull attempt
|
|
|
|
if(angle > target - acceptableRange && angle < target + acceptableRange)
|
|
|
|
{
|
2023-04-30 00:04:18 -04:00
|
|
|
// Success!
|
|
|
|
StartCoroutine(UnlockLock());
|
2023-04-22 18:44:01 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-04-30 00:04:18 -04:00
|
|
|
if (durability <= 0) // Breaks Pick. Lets make the pick in 2 pieces and animate a break
|
2023-04-22 18:44:01 -04:00
|
|
|
{
|
2023-04-30 00:04:18 -04:00
|
|
|
Inventory.PlayerInventory.RemoveItem(LockPick.ItemID, 1);
|
|
|
|
PicksLeft.text = Inventory.PlayerInventory.GetItemCount(LockPick).ToString();
|
2023-04-22 18:44:01 -04:00
|
|
|
if (audioSource != null)
|
|
|
|
audioSource.PlayOneShot(pickBroke);
|
2023-04-30 00:04:18 -04:00
|
|
|
if (Inventory.PlayerInventory.GetItemCount(LockPick) < 1)
|
|
|
|
StopPicking();
|
2023-04-22 18:44:01 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
isShaking = true;
|
|
|
|
shakeTime = 1f;
|
|
|
|
if(audioSource != null)
|
|
|
|
audioSource.PlayOneShot(pickAttempt);
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 00:04:18 -04:00
|
|
|
|
|
|
|
public void CheatUnlock() {
|
|
|
|
StartCoroutine(UnlockLock());
|
|
|
|
}
|
|
|
|
|
|
|
|
IEnumerator UnlockLock() {
|
|
|
|
curDoor.UnlockDoor();
|
|
|
|
SV.StartSpinning();
|
|
|
|
if (audioSource != null)
|
|
|
|
audioSource.PlayOneShot(LockUnlocking);
|
|
|
|
yield return new WaitForSecondsRealtime(1.5f);
|
|
|
|
StopPicking();
|
|
|
|
}
|
2023-04-22 18:44:01 -04:00
|
|
|
|
|
|
|
public void StopPicking()
|
|
|
|
{
|
2023-04-30 00:04:18 -04:00
|
|
|
|
|
|
|
for (int i = 0; i < ThingsToHide.Count; i++)
|
|
|
|
ThingsToHide[i].SetActive(true);
|
2023-04-22 18:44:01 -04:00
|
|
|
lockpickingUI.SetActive(false);
|
|
|
|
isShaking = false;
|
|
|
|
|
|
|
|
RckPlayer.instance.isPickingLock = false;
|
|
|
|
|
|
|
|
if (shouldDisableControls)
|
|
|
|
RckPlayer.instance.EnableDisableControls(true);
|
|
|
|
|
|
|
|
curDoor = null;
|
|
|
|
|
|
|
|
RckPlayer.instance.input.SwitchCurrentActionMap("Player");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|