업그레이드 데이터 입력 로직 및 기능 추가
캐릭터 스탯을 PlayerStats 컴포넌트에서 모아서 관리하도록 변경 코드에서도 마찬가지
This commit is contained in:
269
Assets/Scripts/PlayerUpgradeManager.cs
Normal file
269
Assets/Scripts/PlayerUpgradeManager.cs
Normal file
@@ -0,0 +1,269 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using Northbound.Data;
|
||||
|
||||
namespace Northbound
|
||||
{
|
||||
/// <summary>
|
||||
/// 플레이어별 업그레이드 보유 상태를 관리하는 컴포넌트
|
||||
/// </summary>
|
||||
public class PlayerUpgradeManager : NetworkBehaviour
|
||||
{
|
||||
// 보유한 업그레이드 ID 목록 (네트워크 동기화)
|
||||
private NetworkList<int> _ownedUpgradeIds;
|
||||
|
||||
// 이벤트
|
||||
public event Action<int> 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<int>();
|
||||
_networkPlayerController = GetComponent<NetworkPlayerController>();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// 소유자 변경 시 필요한 처리
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 보유한 업그레이드 ID 목록 (복사본 반환)
|
||||
/// </summary>
|
||||
public List<int> GetOwnedUpgradeIdList()
|
||||
{
|
||||
var list = new List<int>();
|
||||
foreach (int id in _ownedUpgradeIds)
|
||||
{
|
||||
list.Add(id);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 특정 업그레이드를 보유하고 있는지 확인
|
||||
/// </summary>
|
||||
public bool HasUpgrade(int upgradeId)
|
||||
{
|
||||
foreach (int id in _ownedUpgradeIds)
|
||||
{
|
||||
if (id == upgradeId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 보유한 업그레이드 ID를 HashSet으로 반환
|
||||
/// </summary>
|
||||
public HashSet<int> GetOwnedUpgradeIdSet()
|
||||
{
|
||||
var set = new HashSet<int>();
|
||||
foreach (int id in _ownedUpgradeIds)
|
||||
{
|
||||
set.Add(id);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업그레이드 구매 요청 (클라이언트에서 호출)
|
||||
/// </summary>
|
||||
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($"<color=green>[PlayerUpgradeManager] 업그레이드 '{upgrade.memo}' 구매 완료! (ID: {upgradeId})</color>");
|
||||
|
||||
// 이벤트 발생
|
||||
OnUpgradePurchased?.Invoke(upgradeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업그레이드 구매 가능 여부 확인
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업그레이드 구매 가능 여부 (외부용)
|
||||
/// </summary>
|
||||
public bool CanPurchase(int upgradeId)
|
||||
{
|
||||
return CanPurchaseUpgrade(upgradeId, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 구매 가능한 업그레이드 목록 반환
|
||||
/// </summary>
|
||||
public List<UpgradeData> GetPurchasableUpgrades()
|
||||
{
|
||||
var result = new List<UpgradeData>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 보유한 업그레이드 데이터 목록 반환
|
||||
/// </summary>
|
||||
public List<UpgradeData> GetOwnedUpgradeData()
|
||||
{
|
||||
var result = new List<UpgradeData>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user