Firstborn/Assets/Scripts/LockpickingManager.cs

183 lines
4.2 KiB
C#
Raw Normal View History

using UnityEngine;
using RPGCreationKit.Player;
using RPGCreationKit.CellsSystem;
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;
public string LockpickItemID;
[Space(5)]
[Header("Book References")]
public GameObject backgroundUI;
public GameObject lockpickingUI;
public RectTransform PickSprite;
[Space(5)]
[Header("Audio")]
public AudioSource audioSource;
[Space(5)]
public AudioClip pickAttempt;
public AudioClip pickBroke;
public AudioClip pickSuccess;
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)
{
if (_door.lockLevel == DoorLockLevel.Impossible) return;
if (!Inventory.PlayerInventory.HasItem(LockpickItemID)) return;
shouldDisableControls = _shouldDisableControls;
curDoor = _door;
angle = 0f;
target = UnityEngine.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;
}
backgroundUI.SetActive(true);
RckPlayer.instance.input.SwitchCurrentActionMap("LockpickingUI");
lockpickingUI.SetActive(true);
RckPlayer.instance.isPickingLock = true;
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((UnityEngine.Random.Range(-distance, distance) / 90f) * 10f, -10, 10));
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, -90, 90);
PickSprite.rotation = Quaternion.Euler(0, 0, angle);
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!
curDoor.UnlockDoor();
if (audioSource != null)
audioSource.PlayOneShot(pickBroke);
StopPicking();
return;
}
if (durability <= 0)
{
Inventory.PlayerInventory.RemoveItem(LockpickItemID, 1);
if (audioSource != null)
audioSource.PlayOneShot(pickBroke);
StopPicking();
}
else
{
isShaking = true;
shakeTime = 1f;
if(audioSource != null)
audioSource.PlayOneShot(pickAttempt);
}
}
public void StopPicking()
{
backgroundUI.SetActive(false);
lockpickingUI.SetActive(false);
isShaking = false;
RckPlayer.instance.isPickingLock = false;
if (shouldDisableControls)
RckPlayer.instance.EnableDisableControls(true);
curDoor = null;
RckPlayer.instance.input.SwitchCurrentActionMap("Player");
}
}
}