using System.Collections; using UnityEngine; using Game; using Music; using Player; namespace Player { /// /// This class allows a player to pick up, hold, and drop items during the game. /// It is primarily used for managing interactions with the "hat" in "keep-away" mode. /// public class UseItem : MonoBehaviour { /// /// The tag used to identify items that can be picked up. /// [SerializeField] private string itemTag; /// /// The item currently being held by the player. /// private GameObject heldItem; /// /// Whether the player is currently holding an item. /// private bool isHoldingItem = false; /// /// The time when the player started holding the item. /// private float holdStartTime; /// /// The total time the player has held the item. /// public float holdTime; /// /// Reference to the player's component. /// private Damageable damageable; /// /// The position where the item will be held (e.g., above the player's head). /// [SerializeField] public Transform head; /// /// Initializes the player's component. /// private void Start() { damageable = GetComponent(); } /// /// Updates the player's state every frame. /// If the player is holding an item, it keeps the item positioned on their head /// and updates the hold time in "keep-away" mode. /// private void Update() { if (isHoldingItem) { // Keeps the item positioned on the player's head heldItem.transform.localPosition = Vector3.zero; if (GameManager.gameMode == GameManager.GameMode.keepAway) { // Adds time to the player's leaderboard standing holdTime += Time.deltaTime; GameManager.Instance.UpdatePlayerHoldTime(gameObject, holdTime); } } } /// /// Automatically picks up an item when the player collides with it. /// /// The collision data from the item. private void OnCollisionEnter2D(Collision2D collision) { // Check if the collided object is a "hat" and the player is not already holding an item if (collision.gameObject.CompareTag("Hat") && !isHoldingItem && !damageable.dying) { PickUpItem(collision.gameObject); } } /// /// Allows the player to pick up an item and start the hold timer. /// /// The item to pick up. public void PickUpItem(GameObject item) { // Prevent picking up items if the player is dying or the item is not interactable if (damageable.dying) return; if (HatRespawn.canBePickedUp == false) return; // Set the item as the held item and update its state heldItem = item; isHoldingItem = true; holdStartTime = Time.time; item.GetComponent().enabled = false; item.GetComponent().bodyType = RigidbodyType2D.Static; item.GetComponent().Interact(); item.transform.parent = head; item.transform.localRotation = Quaternion.identity; item.transform.localPosition = Vector3.zero; // Initialize the player's hold time in the GameManager if not already set if (!GameManager.playerHoldTimes.ContainsKey(gameObject)) { GameManager.playerHoldTimes[gameObject] = 0f; } // Play the pickup sound and stop any ongoing hat movement AudioManager.Instance.PlaySound("Pickup Hat"); GameManager.Instance.StopCoroutine("MoveHatToWinner"); } /// /// Allows the player to drop the item they are holding. /// public void DropItem() { // Prevent dropping items if the game is over if (GameManager.Instance.gameOver) return; if (isHoldingItem) { // Enable the item's collider and make it interactable after a short delay heldItem.GetComponent().enabled = true; HatRespawn.canBePickedUp = false; StartCoroutine(WaitForInteractability()); // Make the item dynamic and apply random force and torque to it heldItem.GetComponent().bodyType = RigidbodyType2D.Dynamic; heldItem.GetComponent().AddForce(Vector2.up * Random.Range(10f, 30f) + Vector2.right * Random.Range(-10, 10), ForceMode2D.Impulse); heldItem.GetComponent().AddTorque(Random.Range(-1, 1), ForceMode2D.Impulse); // Notify the item that it has been dropped heldItem.GetComponent().OnHatDropped(); // Detach the item from the player heldItem.transform.parent = GameManager.Instance.transform; heldItem = null; isHoldingItem = false; // Remove the player's hold time from the GameManager if (GameManager.playerHoldTimes.ContainsKey(gameObject)) { GameManager.playerHoldTimes.Remove(gameObject); } } } /// /// Waits for a short delay before making the item interactable again. /// /// An IEnumerator for coroutine execution. private IEnumerator WaitForInteractability() { yield return new WaitForSeconds(0.1f); HatRespawn.canBePickedUp = true; } /// /// Checks if the player is currently holding an item. /// /// True if the player is holding an item, false otherwise. public bool IsHoldingItem() { return isHoldingItem; } } }