183 lines
4.2 KiB
C#
183 lines
4.2 KiB
C#
|
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");
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|