201 lines
7.3 KiB
C#

using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Kryz.CharacterStats.Examples
{
public class StatPanel : MonoBehaviour
{
[SerializeField] private Transform statDisplaysParent;
[SerializeField] StatDisplay[] statDisplays;
[SerializeField] private StatDisplay[] secondaryStatDisplays;
[SerializeField] string[] statNames;
[SerializeField] Button[] addStatButtons;
[SerializeField] private string[] secondaryStatNames;
[SerializeField] private TMP_Text characterName;
[SerializeField] private TMP_Text characterLevel;
[SerializeField] private TMP_Text characterRepLevel;
[SerializeField] private StatDisplay unallocated;
[SerializeField] private Button resetAllocated;
[SerializeField] private TMP_Text rankText;
[SerializeField] private TMP_Text powerLevelText;
private CharacterStat[] stats;
private CharacterStat[] secondaryStats;
private PlayerCharacterStats playerStats;
private bool InitializedListeners = false;
const string almost = "≈";
/* private void OnValidate()
{
if (statDisplaysParent != null)
{
statDisplays = statDisplaysParent.GetComponentsInChildren<StatDisplay>();
UpdateStatNames();
UpdateSecondaryStatNames();
}
}*/
[ContextMenu("UpdateNames")]
private void UpdateNames()
{
UpdateStatNames();
UpdateSecondaryStatNames();
}
public void SetPlayerStats(PlayerCharacterStats playerStats)
{
this.playerStats = playerStats;
}
public void SetStats(Dictionary<string, CharacterStat> primaryStats)
{
// Store both dictionary values as array (for compatibility with existing methods)
stats = primaryStats.Values.ToArray();
for (int i = 0; i < statDisplays.Length && i < primaryStats.Count; i++)
{
var stat = primaryStats.Values.ElementAt(i);
statDisplays[i].Stat = stat;
statDisplays[i].NameText.text = stat.statDefinition.DisplayName; // This requires updating CharacterStat first
statDisplays[i].gameObject.SetActive(true);
}
// Hide unused displays
for (int i = primaryStats.Count; i < statDisplays.Length; i++)
{
statDisplays[i].gameObject.SetActive(false);
}
unallocated.ValueText.text = playerStats.AvailablePointsToAllocate.ToString();
unallocated.gameObject.SetActive(playerStats.AvailablePointsToAllocate > 0);
if (InitializedListeners) return;
InitializedListeners = true;
addStatButtons[0].onClick.AddListener(() => AllocateStat(0));
addStatButtons[1].onClick.AddListener(() => AllocateStat(1));
addStatButtons[2].onClick.AddListener(() => AllocateStat(2));
resetAllocated.onClick.AddListener(ResetAllocatedStats);
}
public void SetSecondaryStats(Dictionary<string, CharacterStat> secondaryStats)
{
// Store as array for compatibility
this.secondaryStats = secondaryStats.Values.ToArray();
int index = 0;
foreach (var kvp in secondaryStats)
{
if (index >= secondaryStatDisplays.Length) break;
secondaryStatDisplays[index].Stat = kvp.Value;
secondaryStatDisplays[index].NameText.text = kvp.Value.statDefinition.DisplayName;
index++;
}
// Hide unused displays
for (int i = index; i < secondaryStatDisplays.Length; i++)
{
secondaryStatDisplays[i].gameObject.SetActive(false);
}
}
int pointsToAllocate;
public void AllocateStat(int index)
{
if (playerStats.AvailablePointsToAllocate <= 0) return;
// Determine points to allocate based on shift key
pointsToAllocate = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) ? 10 : 1;
pointsToAllocate = Mathf.Min(pointsToAllocate, playerStats.AvailablePointsToAllocate);
playerStats.AllocatedStatPoints[index] += pointsToAllocate;
playerStats.AvailablePointsToAllocate -= pointsToAllocate;
playerStats.UpdateAllocatedStats();
ToggleAllocateButtonsInteractable(playerStats.AvailablePointsToAllocate > 0);
}
public void ResetAllocatedStats()
{
for (int i = 0; i < playerStats.AllocatedStatPoints.Count; i++)
{
playerStats.AvailablePointsToAllocate += playerStats.AllocatedStatPoints[i];
playerStats.AllocatedStatPoints[i] = 0;
}
playerStats.UpdateAllocatedStats();
ToggleAllocateButtonsInteractable(playerStats.AvailablePointsToAllocate > 0);
}
public void SetCharacterInfo(string name, string level, string repLevel)
{
characterName.text = name;
characterLevel.text = level;
characterRepLevel.text = repLevel;
}
public void UpdateLevelInfo(string level, string repLevel)
{
characterLevel.text = level;
characterRepLevel.text = repLevel;
}
public void UpdateStatValues()
{
for (int i = 0; i < stats.Length; i++)
{
statDisplays[i].ValueText.text = stats[i].Value.ToString();
}
UpdateSecondaryStatValues();
}
public void UpdateStatNames()
{
for (int i = 0; i < statNames.Length; i++)
{
statDisplays[i].NameText.text = statNames[i];
}
}
public void UpdateSecondaryStatNames()
{
for (int i = 0; i < secondaryStatNames.Length; i++)
{
secondaryStatDisplays[i].NameText.text = secondaryStatNames[i];
}
}
int relativePowerLevel;
public void UpdateSecondaryStatValues()
{
for (int i = 0; i < secondaryStats.Length; i++)
{
secondaryStatDisplays[i].ValueText.text = secondaryStatDisplays[i].NameText.text.Contains("crit") ? secondaryStats[i].Value.ToString() + " %" : secondaryStats[i].Value.ToString();
}
relativePowerLevel = Mathf.RoundToInt(playerStats.GetRelativePowerLevel());
if (rankText != null)
rankText.text = GameConstants.CharacterBalancing.GetRankBasedOnRelativeTotalPowerLevel(relativePowerLevel) + " Rank";
if (powerLevelText != null)
powerLevelText.text = almost + relativePowerLevel.ToString();
}
public void ToggleAllocateButtonsInteractable(bool interactable)
{
unallocated.ValueText.text = playerStats.AvailablePointsToAllocate.ToString();
unallocated.gameObject.SetActive(playerStats.AvailablePointsToAllocate > 0);
for (int i = 0; i < addStatButtons.Length; i++)
{
addStatButtons[i].gameObject.SetActive(interactable);
}
}
}
}