using Mono.Cecil; using MyCollections.Managers; using System; using System.Collections; using System.Collections.Generic; using System.Data.SqlTypes; using System.Reflection; using TMPro; using UnityEngine; using UnityEngine.UI; public class UpgradeManager : MonoBehaviour { public UpgradeData[] upgrades; public GameObject[] upgradesSections; public GameObject[] upgradePanels; public Image[] upgradeButtonsImage; [SerializeField] private GameObject uiMainCharacter; private PlayerController playerController; private GameManager gameManager; private GameStateManager gameStateManager; private GameObject currentUpgradePanelInstance; private Animator animator; [SerializeField] private float timerPressing = 0f; [SerializeField] private float maxTimerPressing = 2f; [SerializeField] private bool isHolding = false; private int currentButtonIndex; [SerializeField] private TextMeshProUGUI playerGoldObj; public event Action<int> OnTakeGold; public event Action OnCancelUpgrade; private void Awake() { animator = uiMainCharacter.GetComponent<Animator>(); } // Start is called before the first frame update void Start() { gameManager = GameManager.Instance; gameStateManager = GameStateManager.Instance; gameStateManager.PauseGame(); OnTakeGold += SetNewAmount; playerGoldObj.text = gameManager.PlayerGold.ToString(); playerController = PlayerController.Instance; for (int i = 0; i < upgradesSections.Length; i++) { upgradesSections[i].SetActive(true); } } // Update is called once per frame void Update() { if (isHolding) { HandleHold(); } } private void ResetFillAmount() { Image img = upgradeButtonsImage[currentButtonIndex]; // Start a coroutine to smoothly reset the fill amount StartCoroutine(SmoothResetFill(img)); } private void FillUpgradeButton(Image image) { float newAmount = Mathf.Clamp(timerPressing, 0f, maxTimerPressing); float result = newAmount / maxTimerPressing; image.fillAmount = result; } public void HoldButton(int index) { Debug.Log("HoldButton Called"); isHolding = true; ResetUpgradeTimer(); currentButtonIndex = index; } public void ReleaseButton() { Debug.Log("ReleaseButton Called"); isHolding = false; if (upgrades[currentButtonIndex].isUnlocked) return; if (timerPressing < maxTimerPressing) { OnCancelUpgrade?.Invoke(); ResetFillAmount(); } } public void ActivatePanel(int index) { upgradePanels[index].SetActive(true); uiMainCharacter.SetActive(false); for (int i = 0; i < upgradesSections.Length; i++) { upgradesSections[i].SetActive(false); } } private UpgradeData GetUpgrade(int index) => upgrades[index]; //Display Upgrade Info public void OnDisplay(int index) { UpgradeData upgrade = GetUpgrade(index); currentUpgradePanelInstance = upgrade.Display(gameObject); } public void OnDisplayExit() { if (currentUpgradePanelInstance != null) { Destroy(currentUpgradePanelInstance); } } public void OnAttackTrigger() => animator.SetTrigger("Attack"); //Goes Back to the previous section public void GoBack() { uiMainCharacter.SetActive(true); for (int i = 0; i < upgradesSections.Length; i++) { upgradesSections[i].SetActive(true); } for (int i = 0; i < upgradePanels.Length; i++) { upgradePanels[i].SetActive(false); } } //Closes the shop public void CloseShop() { gameStateManager.ResumeGame(); Destroy(gameObject); } //Checks if the current Upgrade is upgradable public bool CanUpgrade(int index) { bool c1, c2, c3; if (index == 0) { c1 = gameManager.PlayerLevel >= upgrades[index].requiredLevel; c2 = gameManager.PlayerGold >= upgrades[index].goldAmount; c3 = !upgrades[index].isUnlocked; Debug.Log($"CAN UPGRADE RESULT: {c1}, {c2}, {c3}"); return c1 && c2 && c3; } UpgradeData previousUpgrade = upgrades[index - 1]; c1 = gameManager.PlayerLevel >= upgrades[index].requiredLevel; c2 = gameManager.PlayerGold >= upgrades[index].goldAmount; c3 = !upgrades[index].isUnlocked; Debug.Log($"CAN UPGRADE RESULT: {c1}, {c2}, {c3}"); return previousUpgrade.isUnlocked && c1 && c2 && c3; } //Resets the upgrade button timer public void ResetUpgradeTimer() { Debug.Log("Resetting Timer"); timerPressing = 0f; } public void Upgrade(int index) { if (CanUpgrade(index)) // Only upgrade if conditions are met { // Deduct the required Gold Amount OnTakeGold?.Invoke(upgrades[index].goldAmount); // Unlock the upgrade upgrades[index].isUnlocked = true; // Apply the upgrade effect (attack, defense, etc.) ApplyUpgradeEffect(upgrades[index]); // Optionally, disable the upgrade button once it's unlocked upgradeButtonsImage[index].fillAmount = 1f; // Set the progress bar to full upgradeButtonsImage[index].GetComponent<Button>().interactable = false; // Disable button interaction } else { Debug.Log("Not enough Level or Gold to upgrade."); } } // Handling the button hold private void HandleHold() { if (CanUpgrade(currentButtonIndex)) // Check if the upgrade can be performed { if (timerPressing <= maxTimerPressing) { FillUpgradeButton(upgradeButtonsImage[currentButtonIndex]); timerPressing += Time.unscaledDeltaTime; } else { // If the timer reaches the maximum value, complete the upgrade Upgrade(currentButtonIndex); ResetUpgradeTimer(); // Reset the timer after upgrading isHolding = false; // Stop holding after the upgrade is done } } else { // Stop holding if upgrade cannot be performed isHolding = false; } } // Coroutine to smoothly reset the fill amount private IEnumerator SmoothResetFill(Image image) { float duration = 0.5f; float elapsed = 0f; float initialFill = image.fillAmount; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; image.fillAmount = Mathf.Lerp(initialFill, 0f, elapsed / duration); yield return null; } image.fillAmount = 0f; } //Sets new amount of gold, when the player buys an Updgrade private void SetNewAmount(int amount) { int targetAmount = gameManager.PlayerGold - amount; int currentAmount = gameManager.PlayerGold; gameManager.PlayerGold = currentAmount; StartCoroutine(SmoothGoldTransition(targetAmount, currentAmount)); } //Smoothly interpolates the new amount of gold private IEnumerator SmoothGoldTransition(int targetAmount, int currentAmount) { currentAmount = int.Parse(playerGoldObj.text); // Smooth transition over time float duration = 1f; // Duration for the transition float elapsed = 0f; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; int result = (int)Mathf.Lerp(currentAmount, targetAmount, elapsed / duration); playerGoldObj.text = result.ToString(); yield return null; } // Ensure the final value is set playerGoldObj.text = targetAmount.ToString(); } //Apply the upgrades private void ApplyUpgradeEffect(UpgradeData upgrade) { switch(upgrade.upgradeType) { case UpgradeType.Attack: playerController.CurrentPlayerAttack += upgrade.attackBonus; Debug.Log($"Player Attack was Upgraded to {playerController.CurrentPlayerAttack}"); break; case UpgradeType.Defense: Debug.Log("Player Defense was Upgraded"); break; } } }