using System; using System.Collections.Generic; using Unity.Netcode; using UnityEngine; using Northbound.Data; namespace Northbound { /// /// 플레이어별 업그레이드 보유 상태를 관리하는 컴포넌트 /// public class PlayerUpgradeManager : NetworkBehaviour { // 보유한 업그레이드 ID 목록 (네트워크 동기화) private NetworkList _ownedUpgradeIds; // 이벤트 public event Action OnUpgradePurchased; // upgradeId private NetworkPlayerController _networkPlayerController; public new bool IsLocalPlayer => _networkPlayerController != null && _networkPlayerController.IsLocalPlayer; public ulong OwnerPlayerId => _networkPlayerController != null ? _networkPlayerController.OwnerPlayerId : OwnerClientId; private void Awake() { _ownedUpgradeIds = new NetworkList(); _networkPlayerController = GetComponent(); } public override void OnNetworkSpawn() { base.OnNetworkSpawn(); if (_networkPlayerController != null) { _networkPlayerController.OnOwnerChanged += OnOwnerChanged; } } public override void OnNetworkDespawn() { base.OnNetworkDespawn(); if (_networkPlayerController != null) { _networkPlayerController.OnOwnerChanged -= OnOwnerChanged; } _ownedUpgradeIds.Dispose(); } private void OnOwnerChanged(ulong newOwnerId) { // 소유자 변경 시 필요한 처리 } /// /// 보유한 업그레이드 ID 목록 (복사본 반환) /// public List GetOwnedUpgradeIdList() { var list = new List(); foreach (int id in _ownedUpgradeIds) { list.Add(id); } return list; } /// /// 특정 업그레이드를 보유하고 있는지 확인 /// public bool HasUpgrade(int upgradeId) { foreach (int id in _ownedUpgradeIds) { if (id == upgradeId) return true; } return false; } /// /// 보유한 업그레이드 ID를 HashSet으로 반환 /// public HashSet GetOwnedUpgradeIdSet() { var set = new HashSet(); foreach (int id in _ownedUpgradeIds) { set.Add(id); } return set; } /// /// 업그레이드 구매 요청 (클라이언트에서 호출) /// public void RequestPurchaseUpgrade(int upgradeId) { PurchaseUpgradeServerRpc(upgradeId); } [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] private void PurchaseUpgradeServerRpc(int upgradeId) { if (!CanPurchaseUpgrade(upgradeId, out string failReason)) { Debug.LogWarning($"[PlayerUpgradeManager] 업그레이드 구매 실패: {failReason}"); return; } // 업그레이드 데이터 가져오기 var upgrade = UpgradeDatabase.Instance?.GetUpgradeById(upgradeId); if (upgrade == null) { Debug.LogError($"[PlayerUpgradeManager] 업그레이드 ID {upgradeId}를 찾을 수 없습니다."); return; } // 비용 차감 var core = CoreResourceManager.Instance?.mainCore; if (core == null) { Debug.LogError("[PlayerUpgradeManager] 코어를 찾을 수 없습니다."); return; } if (!core.CanConsumeResource(upgrade.mana)) { Debug.LogWarning($"[PlayerUpgradeManager] 자원이 부족합니다. 필요: {upgrade.mana}"); return; } core.ConsumeResourceServerRpc(upgrade.mana); // 업그레이드 추가 _ownedUpgradeIds.Add(upgradeId); Debug.Log($"[PlayerUpgradeManager] 업그레이드 '{upgrade.memo}' 구매 완료! (ID: {upgradeId})"); // 스탯 변경 확인 var playerStats = GetComponent(); playerStats?.PrintCurrentStats(); // 이벤트 발생 OnUpgradePurchased?.Invoke(upgradeId); } /// /// 업그레이드 구매 가능 여부 확인 /// private bool CanPurchaseUpgrade(int upgradeId, out string failReason) { failReason = string.Empty; var upgradeDatabase = UpgradeDatabase.Instance; if (upgradeDatabase == null) { failReason = "UpgradeDatabase가 초기화되지 않았습니다."; return false; } var upgrade = upgradeDatabase.GetUpgradeById(upgradeId); if (upgrade == null) { failReason = $"업그레이드 ID {upgradeId}를 찾을 수 없습니다."; return false; } // 이미 보유 중인지 확인 if (HasUpgrade(upgradeId)) { failReason = "이미 보유한 업그레이드입니다."; return false; } // 선행 조건 확인 if (!upgradeDatabase.ArePrerequisitesMet(upgradeId, GetOwnedUpgradeIdSet())) { failReason = "선행 업그레이드 조건을 충족하지 않았습니다."; return false; } // 비용 확인 var core = CoreResourceManager.Instance?.mainCore; if (core == null) { failReason = "코어를 찾을 수 없습니다."; return false; } if (!core.CanConsumeResource(upgrade.mana)) { failReason = $"자원이 부족합니다. 필요: {upgrade.mana}, 보유: {core.TotalResources}"; return false; } // 개인 업그레이드인지 확인 if (upgrade.upgradeTarget != "person") { failReason = "팀 업그레이드는 개인이 구매할 수 없습니다."; return false; } return true; } /// /// 업그레이드 구매 가능 여부 (외부용) /// public bool CanPurchase(int upgradeId) { return CanPurchaseUpgrade(upgradeId, out _); } /// /// 구매 가능한 업그레이드 목록 반환 /// public List GetPurchasableUpgrades() { var result = new List(); var upgradeDatabase = UpgradeDatabase.Instance; if (upgradeDatabase == null) return result; var personalUpgrades = upgradeDatabase.GetPersonalUpgrades(); var ownedIds = GetOwnedUpgradeIdSet(); foreach (var upgrade in personalUpgrades) { if (upgrade == null) continue; // 이미 보유하면 제외 if (ownedIds.Contains(upgrade.id)) continue; // 선행 조건 충족 시 구매 가능 if (upgradeDatabase.ArePrerequisitesMet(upgrade.id, ownedIds)) { result.Add(upgrade); } } return result; } /// /// 보유한 업그레이드 데이터 목록 반환 /// public List GetOwnedUpgradeData() { var result = new List(); var upgradeDatabase = UpgradeDatabase.Instance; if (upgradeDatabase == null) return result; foreach (int id in _ownedUpgradeIds) { var upgrade = upgradeDatabase.GetUpgradeById(id); if (upgrade != null) { result.Add(upgrade); } } return result; } } }