153 lines
3.7 KiB
C#
153 lines
3.7 KiB
C#
using MMOserver.Utils;
|
|
|
|
namespace MMOserver.Game.Party;
|
|
|
|
public class PartyManager : Singleton<PartyManager>
|
|
{
|
|
private readonly UuidGenerator partyUuidGenerator = new UuidGenerator();
|
|
|
|
// partyId → PartyInfo
|
|
private readonly Dictionary<int, PartyInfo> parties = new();
|
|
|
|
// playerId → partyId (한 플레이어는 하나의 파티만)
|
|
private readonly Dictionary<int, int> playerPartyMap = new();
|
|
|
|
// 파티 생성
|
|
public bool CreateParty(int leaderId, string partyName, out PartyInfo? party)
|
|
{
|
|
party = null;
|
|
|
|
if (playerPartyMap.ContainsKey(leaderId))
|
|
{
|
|
return false; // 이미 파티에 속해있음
|
|
}
|
|
|
|
int partyId = partyUuidGenerator.Create();
|
|
party = new PartyInfo
|
|
{
|
|
PartyId = partyId,
|
|
LeaderId = leaderId,
|
|
PartyName = partyName,
|
|
};
|
|
party.PartyMemberIds.Add(leaderId);
|
|
|
|
parties[partyId] = party;
|
|
playerPartyMap[leaderId] = partyId;
|
|
|
|
return true;
|
|
}
|
|
|
|
// 파티 참가
|
|
public bool JoinParty(int playerId, int partyId, out PartyInfo? party)
|
|
{
|
|
party = null;
|
|
|
|
if (playerPartyMap.ContainsKey(playerId))
|
|
{
|
|
return false; // 이미 파티에 속해있음
|
|
}
|
|
|
|
if (!parties.TryGetValue(partyId, out party))
|
|
{
|
|
return false; // 파티 없음
|
|
}
|
|
|
|
if (party.GetPartyMemberCount() >= PartyInfo.partyMemberMax)
|
|
{
|
|
party = null;
|
|
return false; // 파티 인원 초과
|
|
}
|
|
|
|
party.PartyMemberIds.Add(playerId);
|
|
playerPartyMap[playerId] = partyId;
|
|
|
|
return true;
|
|
}
|
|
|
|
// 파티 탈퇴
|
|
public bool LeaveParty(int playerId, out PartyInfo? party)
|
|
{
|
|
party = null;
|
|
|
|
if (!playerPartyMap.TryGetValue(playerId, out int partyId))
|
|
{
|
|
return false; // 파티에 속해있지 않음
|
|
}
|
|
|
|
if (!parties.TryGetValue(partyId, out party))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
party.PartyMemberIds.Remove(playerId);
|
|
playerPartyMap.Remove(playerId);
|
|
|
|
// 마지막 멤버가 나가면 파티 해산
|
|
if (party.PartyMemberIds.Count == 0)
|
|
{
|
|
DeletePartyInternal(partyId, party);
|
|
party = null;
|
|
return true;
|
|
}
|
|
|
|
// 리더가 나갔으면 남은 멤버 중 첫 번째를 리더로 승계
|
|
if (party.LeaderId == playerId)
|
|
{
|
|
party.LeaderId = party.PartyMemberIds[0];
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 파티 해산 (리더만)
|
|
public bool DeleteParty(int leaderId, int partyId, out PartyInfo? party)
|
|
{
|
|
party = null;
|
|
|
|
if (!parties.TryGetValue(partyId, out party))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (party.LeaderId != leaderId)
|
|
{
|
|
party = null;
|
|
return false; // 리더만 해산 가능
|
|
}
|
|
|
|
DeletePartyInternal(partyId, party);
|
|
return true;
|
|
}
|
|
|
|
// 조회
|
|
public PartyInfo? GetParty(int partyId)
|
|
{
|
|
parties.TryGetValue(partyId, out PartyInfo? party);
|
|
return party;
|
|
}
|
|
|
|
public PartyInfo? GetPartyByPlayer(int playerId)
|
|
{
|
|
if (!playerPartyMap.TryGetValue(playerId, out int partyId))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
parties.TryGetValue(partyId, out PartyInfo? party);
|
|
return party;
|
|
}
|
|
|
|
// 삭제
|
|
private void DeletePartyInternal(int partyId, PartyInfo party)
|
|
{
|
|
// 남아 있는인원도 제거
|
|
foreach (int memberId in party.PartyMemberIds)
|
|
{
|
|
playerPartyMap.Remove(memberId);
|
|
}
|
|
|
|
parties.Remove(partyId);
|
|
partyUuidGenerator.Release(partyId);
|
|
}
|
|
}
|