| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- using UnityEngine;
- using UnityEngine.UI;
- using DamageNumbersPro;
- using System.Collections;
- public class CharacterUIController : MonoBehaviour
- {
- public Slider hpSlider;
- public Slider fatigueSlider;
- public Slider expSlider;
- public GameObject skillPanel;
- public Transform skillListContainer;
- public GameObject skillButtonPrefab;
-
- public GameObject inventoryPanel; // Panel displaying character inventory
- public InventoryUIController inventoryUIController; // Reference to inventory UI controller
- public Image characterIcon;
- public Button attackButton;
- public Button repeatActionButton;
- public Button openSkillsButton;
- public Button openInventoryButton; // Button to open character inventory
- public Image cooldownOverlay;
- public FirstPersonWeapon assignedWeapon;
- public CharacterInGroup character;
- public CharacterInGroup Character => character;
- public DamageNumber damageUIPrefab; // à assigner dans l’inspector (UI)
- public RectTransform damageSpawnPoint;
- public void Setup(CharacterInGroup chara, FirstPersonWeapon weapon)
- {
- character = chara;
- assignedWeapon = weapon;
-
- // Initialisation des sliders
- if (hpSlider != null)
- {
- hpSlider.maxValue = character.maxHP;
- hpSlider.value = character.currentHP;
- }
- if (fatigueSlider != null)
- {
- fatigueSlider.maxValue = character.maxFatigue;
- fatigueSlider.value = character.currentFatigue;
- }
- if (expSlider != null)
- {
- expSlider.maxValue = 100; // ou prochain seuil de level
- expSlider.value = character.experience;
- }
- // Bind des boutons
- if (attackButton != null)
- attackButton.onClick.AddListener(OnAttack);
- if (repeatActionButton != null)
- repeatActionButton.onClick.AddListener(OnRepeat);
- if (openSkillsButton != null)
- openSkillsButton.onClick.AddListener(ToggleSkillPanel);
- if (openInventoryButton != null)
- openInventoryButton.onClick.AddListener(OnOpenInventory);
- // Enregistrement dans l'UIUpdater
- UIUpdater.Instance?.Register(character, this);
- PopulateSkillList();
- if (cooldownOverlay != null)
- {
- cooldownOverlay.gameObject.SetActive(false);
- }
-
- Debug.Log($"[UI Setup] {character.characterName} - HP: {character.currentHP}/{character.maxHP}, Fatigue: {character.currentFatigue}/{character.maxFatigue}");
- }
- public void ShowDamageOnCard(int amount)
- {
-
- if (damageUIPrefab != null && damageSpawnPoint != null)
- {
- Debug.Log($"[Damage UI] {character.characterName} subit {amount} dégâts");
- damageUIPrefab.SpawnGUI(damageSpawnPoint, Vector2.zero, amount);
- }
- else
- {
- Debug.LogWarning("Damage UI prefab ou spawn point manquant pour " + character.characterName);
- }
- }
- void PopulateSkillList()
- {
- foreach (Transform child in skillListContainer)
- Destroy(child.gameObject);
- foreach (var skill in character.learnedSkills)
- {
- SkillData data = skill.GetData();
- if (data == null) continue;
- var btnObj = Instantiate(skillButtonPrefab, skillListContainer);
- btnObj.transform.Find("Image").GetComponent<Image>().sprite = data.icon;
- Button btn = btnObj.GetComponent<Button>();
- if (btn != null)
- {
- // Capture la compétence associée
- SkillData capturedSkill = data;
- btn.onClick.AddListener(() => OnSkillButtonClicked(capturedSkill));
- }
- }
- }
- void OnAttack()
- {
- Debug.Log(character.characterName + " attaque ! - CHARUICONTR");
-
- // Check if character has no stamina - 80% miss chance
- if (character.currentFatigue <= 0)
- {
- if (Random.value < 0.8f) // 80% chance to miss
- {
- Debug.Log($"[Combat] {character.characterName} est trop fatigué et rate son attaque !");
- DisableButtonsTemporarily(5f);
- return;
- }
- }
-
- // 30% chance to consume stamina when attacking
- if (Random.value < 0.3f && character.currentFatigue > 0)
- {
- character.currentFatigue = Mathf.Max(0, character.currentFatigue - 5);
- UIUpdater.Instance?.UpdateCharacterFatigue(character);
- Debug.Log($"[Combat] {character.characterName} consomme 5 stamina en attaquant");
- }
-
- character.lastAction = ActionType.Attack;
- assignedWeapon?.TriggerAttack();
- DisableButtonsTemporarily(5f);
- }
- void OnSkillButtonClicked(SkillData skillData)
- {
- Debug.Log($"Compétence sélectionnée : {skillData.skillName}");
- // Check if character has enough stamina to cast skill
- int staminaCost = 15; // Default stamina cost for skills
- if (character.currentFatigue < staminaCost)
- {
- Debug.Log($"[Combat] {character.characterName} n'a pas assez de stamina pour utiliser {skillData.skillName} !");
- return;
- }
- // Consume stamina
- character.currentFatigue = Mathf.Max(0, character.currentFatigue - staminaCost);
- UIUpdater.Instance?.UpdateCharacterFatigue(character);
- Debug.Log($"[Combat] {character.characterName} consomme {staminaCost} stamina pour {skillData.skillName}");
- if (skillData.skillName == "Boule de Feu")
- {
- FindFirstObjectByType<SpellCastingManager>()?.StartFireballCasting(skillData.icon.texture);
- character.lastAction = ActionType.UseSkill;
- character.lastSkillName = skillData.skillName;
- }
- else
- {
- Debug.Log($"Action pour {skillData.skillName} non encore implémentée.");
- }
-
- DisableButtonsTemporarily(5f);
- }
-
- void OnRepeat()
- {
- switch (character.lastAction)
- {
- case ActionType.Attack:
- Debug.Log($"{character.characterName} répète : Attaque !");
- OnAttack();
- return; // OnAttack already calls DisableButtonsTemporarily
- case ActionType.UseSkill:
- Debug.Log($"{character.characterName} répète : Skill {character.lastSkillName}");
-
- // Find the skill and use it again
- var learnedSkill = character.learnedSkills.Find(s => s.GetData()?.skillName == character.lastSkillName);
- if (learnedSkill != null)
- {
- var skillData = learnedSkill.GetData();
- if (skillData != null)
- {
- OnSkillButtonClicked(skillData);
- return; // OnSkillButtonClicked already calls DisableButtonsTemporarily
- }
- }
- Debug.LogWarning($"Couldn't find previous skill: {character.lastSkillName}");
- break;
- case ActionType.Heal:
- Debug.Log($"{character.characterName} répète : Soin !");
- // Appelle ton système de heal
- break;
- default:
- Debug.Log($"{character.characterName} n'a aucune action précédente.");
- break;
- }
- DisableButtonsTemporarily(5f);
- }
- void ToggleSkillPanel()
- {
- if (skillPanel != null)
- skillPanel.SetActive(!skillPanel.activeSelf);
- }
-
- void OnOpenInventory()
- {
- Debug.Log($"{character.characterName} ouvre son inventaire");
-
- if (inventoryPanel != null)
- {
- inventoryPanel.SetActive(!inventoryPanel.activeSelf);
-
- // Bind the inventory to this character if opening
- if (inventoryPanel.activeSelf && inventoryUIController != null)
- {
- inventoryUIController.Bind(character);
- }
- }
- else
- {
- Debug.LogWarning("Inventory panel is not assigned in the inspector!");
- }
- }
- // Méthode appelée pour mettre à jour dynamiquement les PV
- public void UpdateHPBar()
- {
- if (hpSlider == null)
- {
- Debug.LogWarning($"[UI] HP Slider is null for {character?.characterName}");
- return;
- }
-
- if (character == null)
- {
- Debug.LogWarning("[UI] Character reference is null in UpdateHPBar");
- return;
- }
-
- Debug.Log($"[UI] Mise à jour barre de vie : {character.characterName} ({character.currentHP}/{character.maxHP})");
-
- // Update max first, then value to ensure proper ratio
- hpSlider.maxValue = character.maxHP;
- hpSlider.value = character.currentHP;
-
- // Force layout rebuild to ensure visual update
- UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(hpSlider.GetComponent<RectTransform>());
- }
- public void UpdateFatigueBar()
- {
- if (fatigueSlider == null)
- {
- Debug.LogWarning($"[UI] Fatigue Slider is null for {character?.characterName}");
- return;
- }
-
- if (character == null) return;
-
- fatigueSlider.maxValue = character.maxFatigue; // Update max in case of level up
- fatigueSlider.value = character.currentFatigue;
- UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(fatigueSlider.GetComponent<RectTransform>());
-
- Debug.Log($"[UI] Fatigue bar updated: {character.characterName} ({character.currentFatigue}/{character.maxFatigue})");
- }
- public void UpdateExpBar()
- {
- if (expSlider == null)
- {
- Debug.LogWarning($"[UI] Exp Slider is null for {character?.characterName}");
- return;
- }
-
- if (character == null) return;
-
- expSlider.value = character.experience;
- UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(expSlider.GetComponent<RectTransform>());
-
- Debug.Log($"[UI] Experience bar updated: {character.characterName} ({character.experience}/100)");
- }
- public void DisableButtonsTemporarily(float duration)
- {
- StartCoroutine(CooldownRoutine(duration));
- }
- private IEnumerator CooldownRoutine(float duration)
- {
- cooldownOverlay.gameObject.SetActive(true);
- SetButtonsInteractable(false);
- if (cooldownOverlay) cooldownOverlay.fillAmount = 1f;
- float elapsed = 0f;
- while (elapsed < duration)
- {
- elapsed += Time.deltaTime;
- float fill = Mathf.Clamp01(1f - elapsed / duration);
- if (cooldownOverlay) cooldownOverlay.fillAmount = fill;
- yield return null;
- }
- SetButtonsInteractable(true);
- if (cooldownOverlay) cooldownOverlay.fillAmount = 0f;
- }
- private void SetButtonsInteractable(bool interactable)
- {
- if (attackButton != null)
- attackButton.interactable = interactable;
- if (repeatActionButton != null)
- repeatActionButton.interactable = interactable;
- if (openSkillsButton != null)
- openSkillsButton.interactable = interactable;
- // Note: Inventory button should remain accessible during cooldown
-
- var fadedColor = interactable ? Color.white : new Color(1f, 1f, 1f, 0.5f);
- if (attackButton != null)
- attackButton.image.color = fadedColor;
- if (repeatActionButton != null)
- repeatActionButton.image.color = fadedColor;
- if (openSkillsButton != null)
- openSkillsButton.image.color = fadedColor;
- }
- public void HandleCharacterDeath()
- {
- Debug.Log($"[Death] {character.characterName} est mort, suppression de la carte UI");
-
- string characterName = character.characterName;
-
- // Remove character from the party
- TeamCohesionManager cohesionManager = FindFirstObjectByType<TeamCohesionManager>();
- if (cohesionManager != null)
- {
- cohesionManager.groupMembers.Remove(character);
- }
-
- // Remove from UIUpdater registry
- UIUpdater.Instance?.Unregister(characterName);
-
- // Destroy the card UI
- Destroy(gameObject);
-
- // Check if all characters are dead (party wipe)
- if (cohesionManager != null && cohesionManager.groupMembers.Count == 0)
- {
- Debug.Log("[Game Over] All party members are dead! Triggering respawn system...");
-
- // Notify GameManager of party wipe
- var gameManagerObj = GameObject.Find("GameManager");
- if (gameManagerObj != null)
- {
- gameManagerObj.SendMessage("OnPartyWiped", SendMessageOptions.DontRequireReceiver);
- }
- else
- {
- Debug.LogError("[Death] GameManager not found! Cannot trigger respawn system.");
- }
- }
- }
- }
|