229 lines
7.3 KiB
C#
229 lines
7.3 KiB
C#
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
using Northbound.Data;
|
|
|
|
namespace Northbound
|
|
{
|
|
/// <summary>
|
|
/// 업그레이드 리스트 아이템 UI
|
|
/// </summary>
|
|
public class UpgradeListItem : MonoBehaviour, IPointerClickHandler
|
|
{
|
|
[Header("UI References")]
|
|
[SerializeField] private TextMeshProUGUI _nameText;
|
|
[SerializeField] private TextMeshProUGUI _costText;
|
|
[SerializeField] private Transform _effectRowsParent;
|
|
[SerializeField] private Transform _reqChipsParent;
|
|
[SerializeField] private Button _purchaseButton;
|
|
[SerializeField] private GameObject _purchasedOverlay;
|
|
[SerializeField] private Image _backgroundImage;
|
|
|
|
private UpgradeData _upgradeData;
|
|
private bool _isOwned;
|
|
private bool _canPurchase;
|
|
private UpgradeListPopup _parentPopup;
|
|
|
|
private Color _normalColor = new Color(1f, 1f, 1f, 0.44f); // 기본 배경색
|
|
private Color _disabledColor = new Color(0.5f, 0.5f, 0.5f, 0.6f); // 회색
|
|
|
|
private void Awake()
|
|
{
|
|
if (_purchaseButton == null)
|
|
{
|
|
_purchaseButton = GetComponent<Button>();
|
|
}
|
|
|
|
if (_purchaseButton != null)
|
|
{
|
|
_purchaseButton.onClick.AddListener(OnPurchaseClicked);
|
|
}
|
|
|
|
if (_backgroundImage == null)
|
|
{
|
|
_backgroundImage = GetComponent<Image>();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 아이템 설정
|
|
/// </summary>
|
|
public void Setup(UpgradeData upgrade, bool isOwned, bool canPurchase, UpgradeListPopup parentPopup)
|
|
{
|
|
_upgradeData = upgrade;
|
|
_isOwned = isOwned;
|
|
_canPurchase = canPurchase;
|
|
_parentPopup = parentPopup;
|
|
|
|
UpdateUI();
|
|
}
|
|
|
|
private void UpdateUI()
|
|
{
|
|
if (_upgradeData == null) return;
|
|
|
|
// 이름
|
|
if (_nameText != null)
|
|
{
|
|
_nameText.text = _upgradeData.memo;
|
|
}
|
|
|
|
// 비용
|
|
if (_costText != null)
|
|
{
|
|
_costText.text = $"{_upgradeData.mana}";
|
|
}
|
|
|
|
// 구매 가능 여부 확인 (비용 체크 포함)
|
|
bool hasEnoughResources = CheckHasEnoughResources();
|
|
bool isAvailable = _canPurchase && !_isOwned && hasEnoughResources;
|
|
|
|
// 구매 불가능한 경우 회색 처리
|
|
if (_backgroundImage != null)
|
|
{
|
|
_backgroundImage.color = isAvailable ? _normalColor : _disabledColor;
|
|
}
|
|
|
|
// 이름 텍스트 색상도 변경
|
|
if (_nameText != null)
|
|
{
|
|
_nameText.color = isAvailable ? Color.white : Color.gray;
|
|
}
|
|
|
|
// 비용 텍스트 색상 (자원 부족 시 빨간색)
|
|
if (_costText != null)
|
|
{
|
|
_costText.color = hasEnoughResources ? Color.white : Color.red;
|
|
}
|
|
|
|
// 구매 버튼 - 항상 클릭 가능하게 설정
|
|
if (_purchaseButton != null)
|
|
{
|
|
_purchaseButton.interactable = true;
|
|
}
|
|
|
|
// 구매 완료 오버레이
|
|
if (_purchasedOverlay != null)
|
|
{
|
|
_purchasedOverlay.SetActive(_isOwned);
|
|
}
|
|
|
|
// 효과 표시
|
|
UpdateEffectRows();
|
|
|
|
// 선행조건 표시
|
|
UpdateReqChips();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 자원이 충분한지 확인
|
|
/// </summary>
|
|
private bool CheckHasEnoughResources()
|
|
{
|
|
var core = CoreResourceManager.Instance?.mainCore;
|
|
if (core == null) return false;
|
|
return core.TotalResources >= _upgradeData.mana;
|
|
}
|
|
|
|
private void UpdateEffectRows()
|
|
{
|
|
if (_effectRowsParent == null || _upgradeData == null) return;
|
|
|
|
// 기존 자식 제거
|
|
foreach (Transform child in _effectRowsParent)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
|
|
// 효과 목록 생성
|
|
for (int i = 0; i < _upgradeData.effectStatList.Count; i++)
|
|
{
|
|
if (i >= _upgradeData.effectOpList.Count || i >= _upgradeData.effectValueList.Count)
|
|
break;
|
|
|
|
string statName = FormatStatName(_upgradeData.effectStatList[i]);
|
|
string op = _upgradeData.effectOpList[i];
|
|
float value = _upgradeData.effectValueList[i];
|
|
|
|
// 간단한 텍스트로 표시 (EffectRow 프리팹이 없는 경우)
|
|
var textObj = new GameObject($"Effect_{i}");
|
|
textObj.transform.SetParent(_effectRowsParent);
|
|
var text = textObj.AddComponent<TextMeshProUGUI>();
|
|
text.text = $"{statName}: {FormatValue(op, value)}";
|
|
text.fontSize = 24;
|
|
}
|
|
}
|
|
|
|
private void UpdateReqChips()
|
|
{
|
|
if (_reqChipsParent == null || _upgradeData == null) return;
|
|
|
|
// 기존 자식 제거
|
|
foreach (Transform child in _reqChipsParent)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
|
|
// 선행조건이 없으면 표시하지 않음
|
|
if (_upgradeData.requireUpgradeId.Count == 0) return;
|
|
|
|
foreach (int reqId in _upgradeData.requireUpgradeId)
|
|
{
|
|
var database = UpgradeDatabase.Instance;
|
|
var reqUpgrade = database?.GetUpgradeById(reqId);
|
|
if (reqUpgrade == null) continue;
|
|
|
|
// 간단한 텍스트로 표시 (ReqChip 프리팹이 없는 경우)
|
|
var textObj = new GameObject($"Req_{reqId}");
|
|
textObj.transform.SetParent(_reqChipsParent);
|
|
var text = textObj.AddComponent<TextMeshProUGUI>();
|
|
text.text = $"Requires: {reqUpgrade.memo}";
|
|
text.fontSize = 20;
|
|
text.color = Color.yellow;
|
|
}
|
|
}
|
|
|
|
private string FormatStatName(string stat)
|
|
{
|
|
return stat switch
|
|
{
|
|
"player_max_hp" => "Max HP",
|
|
"player_atk_damage" => "ATK Damage",
|
|
"player_capacity" => "Capacity",
|
|
"player_manpower" => "Manpower",
|
|
"player_move_speed" => "Move Speed",
|
|
"player_sight" => "Sight",
|
|
"player_atk_range" => "ATK Range",
|
|
_ => stat
|
|
};
|
|
}
|
|
|
|
private string FormatValue(string op, float value)
|
|
{
|
|
return op switch
|
|
{
|
|
"add" => $"+{value}",
|
|
"mul" => $"x{value}",
|
|
"set" => $"{value}",
|
|
_ => $"{value}"
|
|
};
|
|
}
|
|
|
|
private void OnPurchaseClicked()
|
|
{
|
|
if (_upgradeData == null || _parentPopup == null) return;
|
|
if (_isOwned || !_canPurchase) return;
|
|
|
|
_parentPopup.RequestPurchase(_upgradeData.id);
|
|
}
|
|
|
|
// IPointerClickHandler 구현 - 직접 클릭 감지
|
|
public void OnPointerClick(PointerEventData eventData)
|
|
{
|
|
OnPurchaseClicked();
|
|
}
|
|
}
|
|
}
|