Firstborn/Assets/Scripts/LockpickingManager.cs
Schaken-Mods 5557c03691 Made lockpicking for doors
Finished making lockpicking for doors. Next I will make one for chests with a different type of lock, also increase skill points when successfully picked a lock.
2023-04-29 23:04:18 -05:00

223 lines
5.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RPGCreationKit.Player;
using RPGCreationKit.CellsSystem;
using TMPro;
namespace RPGCreationKit
{
public class LockpickingManager : MonoBehaviour
{
public static LockpickingManager instance;
private void Awake()
{
if (instance == null)
instance = this;
else
Debug.LogError("Anomaly detected with the singleton pattern of 'LockpickingManager', are you using multiple LockpickingManager?");
}
private Door curDoor;
[Space(5)]
[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;
[Space(5)]
[Header("\tAudio")]
[SerializeField] private AudioSource audioSource;
[Space(5)]
[SerializeField] private AudioClip pickAttempt;
[SerializeField] private AudioClip pickBroke;
[SerializeField] private AudioClip pickSuccess;
[SerializeField] private AudioClip LockUnlocking;
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)
{
SV.ResetRotation();
PicksLeft.text = Inventory.PlayerInventory.GetItemCount(LockPick).ToString();
if (_door.lockLevel == DoorLockLevel.Impossible) return;
if (!Inventory.PlayerInventory.HasItem(LockPick.ItemID)) return;
shouldDisableControls = _shouldDisableControls;
curDoor = _door;
angle = 0f;
target = Random.Range(-140, 141);
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;
for (int i = 0; i < ThingsToHide.Count; i++)
ThingsToHide[i].SetActive(false);
if (shouldDisableControls)
RckPlayer.instance.EnableDisableControls(false);
}
void FixedUpdate()
{
if (isShaking)
{
float distance = Mathf.Abs(angle - target);
//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);
shakeTime -= Time.fixedDeltaTime;
if (shakeTime <= 0)
isShaking = false;
}
}
void Update()
{
if (!RckPlayer.instance.isPickingLock)
return;
if (isShaking)
return;
direction = -RckPlayer.instance.input.currentActionMap.FindAction("Move").ReadValue<Vector2>().x;
angle += direction * Time.deltaTime * 16.0f;
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);
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)
{
// Success!
StartCoroutine(UnlockLock());
return;
}
if (durability <= 0) // Breaks Pick. Lets make the pick in 2 pieces and animate a break
{
Inventory.PlayerInventory.RemoveItem(LockPick.ItemID, 1);
PicksLeft.text = Inventory.PlayerInventory.GetItemCount(LockPick).ToString();
if (audioSource != null)
audioSource.PlayOneShot(pickBroke);
if (Inventory.PlayerInventory.GetItemCount(LockPick) < 1)
StopPicking();
}
else
{
isShaking = true;
shakeTime = 1f;
if(audioSource != null)
audioSource.PlayOneShot(pickAttempt);
}
}
public void CheatUnlock() {
StartCoroutine(UnlockLock());
}
IEnumerator UnlockLock() {
curDoor.UnlockDoor();
SV.StartSpinning();
if (audioSource != null)
audioSource.PlayOneShot(LockUnlocking);
yield return new WaitForSecondsRealtime(1.5f);
StopPicking();
}
public void StopPicking()
{
for (int i = 0; i < ThingsToHide.Count; i++)
ThingsToHide[i].SetActive(true);
lockpickingUI.SetActive(false);
isShaking = false;
RckPlayer.instance.isPickingLock = false;
if (shouldDisableControls)
RckPlayer.instance.EnableDisableControls(true);
curDoor = null;
RckPlayer.instance.input.SwitchCurrentActionMap("Player");
}
}
}