2021-11-27 00:53:57 +01:00
|
|
|
#include <Common.h>
|
|
|
|
#include <Exd/ExdData.h>
|
|
|
|
#include <Service.h>
|
|
|
|
|
|
|
|
#include <Network/PacketDef/Zone/ServerZoneDef.h>
|
|
|
|
#include <Network/PacketContainer.h>
|
|
|
|
|
|
|
|
#include "Network/GameConnection.h"
|
|
|
|
|
|
|
|
#include "PartyMgr.h"
|
|
|
|
#include "WorldServer.h"
|
|
|
|
#include "ChatChannelMgr.h"
|
|
|
|
|
|
|
|
#include "Session.h"
|
|
|
|
|
|
|
|
#include "Actor/Player.h"
|
|
|
|
|
|
|
|
#include "Network/PacketWrappers/PcPartyUpdatePacket.h"
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
using namespace Sapphire;
|
|
|
|
using namespace Sapphire::World::Manager;
|
2021-11-27 00:53:57 +01:00
|
|
|
using namespace Sapphire::Network::Packets;
|
|
|
|
using namespace Sapphire::Network::Packets::WorldPackets::Server;
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onJoin( uint32_t joinerId, uint32_t inviterId )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto& ccMgr = Common::Service< World::Manager::ChatChannelMgr >::ref();
|
|
|
|
|
|
|
|
auto pInvitee = server.getSession( joinerId );
|
|
|
|
auto pInviter = server.getSession( inviterId );
|
|
|
|
|
|
|
|
if( !pInvitee || !pInviter )
|
|
|
|
{
|
|
|
|
Logger::error( "Joining player or inviter is null!!" );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& inviteePlayer = *pInvitee->getPlayer();
|
|
|
|
auto& invitingPlayer = *pInviter->getPlayer();
|
|
|
|
|
|
|
|
if( inviteePlayer.getPartyId() != 0 )
|
|
|
|
{
|
|
|
|
Logger::error( "Player#{} already in a party, cannot be invited!!", inviteePlayer.getId() );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t partyId;
|
|
|
|
// if there is no party yet, one has to be created
|
|
|
|
PartyPtr party;
|
|
|
|
if( inviteePlayer.getPartyId() == 0 && invitingPlayer.getPartyId() == 0 )
|
|
|
|
{
|
|
|
|
partyId = createParty();
|
|
|
|
party = getParty( partyId );
|
|
|
|
assert( party );
|
|
|
|
|
|
|
|
inviteePlayer.setPartyId( partyId );
|
|
|
|
inviteePlayer.addOnlineStatus( Common::OnlineStatus::PartyMember );
|
|
|
|
invitingPlayer.setPartyId( partyId );
|
|
|
|
invitingPlayer.addOnlineStatus( Common::OnlineStatus::PartyLeader );
|
|
|
|
|
2022-01-18 00:21:38 +01:00
|
|
|
ccMgr.addToChannel( party->ChatChannel, invitingPlayer );
|
|
|
|
ccMgr.addToChannel( party->ChatChannel, inviteePlayer );
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
party->MemberId.push_back( invitingPlayer.getId() );
|
|
|
|
party->MemberId.push_back( inviteePlayer.getId() );
|
|
|
|
party->PartyCount = 2;
|
|
|
|
party->LeaderId = invitingPlayer.getId();
|
|
|
|
}
|
|
|
|
else if( inviteePlayer.getPartyId() == 0 )
|
|
|
|
{
|
|
|
|
partyId = invitingPlayer.getPartyId();
|
|
|
|
party = getParty( partyId );
|
|
|
|
|
|
|
|
inviteePlayer.setPartyId( partyId );
|
|
|
|
inviteePlayer.addOnlineStatus( Common::OnlineStatus::PartyMember );
|
|
|
|
|
2022-01-18 00:21:38 +01:00
|
|
|
ccMgr.addToChannel( party->ChatChannel, inviteePlayer );
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
party->MemberId.push_back( inviteePlayer.getId() );
|
|
|
|
party->PartyCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto pcUpdateParty = makePcPartyUpdate( invitingPlayer, inviteePlayer, UpdateStatus::JOINED, party->PartyCount );
|
|
|
|
auto members = getPartyMembers( *party );
|
|
|
|
sendPartyUpdate( *party );
|
|
|
|
for( const auto& member : members )
|
|
|
|
{
|
|
|
|
server.queueForPlayer( member->getCharacterId(), pcUpdateParty );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onLeave( Sapphire::Entity::Player &leavingPlayer )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
|
|
|
|
auto party = getParty( leavingPlayer.getPartyId() );
|
|
|
|
assert( party );
|
|
|
|
|
|
|
|
auto leadingPlayer = getPartyLeader( *party );
|
|
|
|
assert( leadingPlayer );
|
|
|
|
|
|
|
|
if( !leadingPlayer )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if( party->PartyCount == 2 )
|
|
|
|
{
|
|
|
|
onDisband( *leadingPlayer );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto members = getPartyMembers( *party );
|
|
|
|
removeMember( *party, leavingPlayer.getAsPlayer() );
|
|
|
|
|
|
|
|
uint32_t newLeaderId = 0;
|
|
|
|
for( const auto& member : members )
|
|
|
|
{
|
|
|
|
if( member->getId() == leavingPlayer.getId() )
|
|
|
|
{
|
2022-01-27 21:08:43 +01:00
|
|
|
member->removeOnlineStatus( { Common::OnlineStatus::PartyMember,
|
|
|
|
Common::OnlineStatus::PartyLeader } );
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
server.queueForPlayer( leavingPlayer.getCharacterId() , makeZonePacket< FFXIVIpcUpdateParty >( leavingPlayer.getId() ) );
|
|
|
|
server.queueForPlayer( member->getCharacterId(), makePcPartyUpdate( leadingPlayer, nullptr,
|
|
|
|
UpdateStatus::KICK_SELF, party->PartyCount ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( leavingPlayer.getId() == party->LeaderId )
|
|
|
|
{
|
|
|
|
newLeaderId = party->MemberId[ 0 ];
|
|
|
|
auto pSession = server.getSession( newLeaderId );
|
|
|
|
if( !pSession )
|
|
|
|
continue;
|
2022-01-27 21:08:43 +01:00
|
|
|
pSession->getPlayer()->addOnlineStatus( Common::OnlineStatus::PartyLeader );
|
2021-11-27 00:53:57 +01:00
|
|
|
server.queueForPlayer( member->getCharacterId(), makePcPartyUpdate( leavingPlayer.getAsPlayer(), pSession->getPlayer(),
|
|
|
|
UpdateStatus::LEAVELEADER_LEAVED_MEMBER, party->PartyCount ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
server.queueForPlayer( member->getCharacterId(), makePcPartyUpdate( leavingPlayer.getAsPlayer(), nullptr,
|
|
|
|
UpdateStatus::LEAVE_MEMBER, party->PartyCount ) );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( newLeaderId != 0 )
|
|
|
|
party->LeaderId = newLeaderId;
|
|
|
|
party->PartyCount--;
|
|
|
|
sendPartyUpdate( *party );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onDisband( Entity::Player& disbandingPlayer )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto party = getParty( disbandingPlayer.getPartyId() );
|
|
|
|
assert( party );
|
|
|
|
|
|
|
|
auto members = getPartyMembers( *party );
|
|
|
|
for( const auto& member : members )
|
|
|
|
{
|
|
|
|
removeMember( *party, member );
|
2022-01-27 21:08:43 +01:00
|
|
|
member->removeOnlineStatus( { Common::OnlineStatus::PartyMember, Common::OnlineStatus::PartyLeader } );
|
2021-11-27 00:53:57 +01:00
|
|
|
server.queueForPlayer( member->getCharacterId(), { makePcPartyUpdate( disbandingPlayer, disbandingPlayer, UpdateStatus::DISBAND, party->PartyCount ),
|
|
|
|
makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } );
|
|
|
|
}
|
|
|
|
|
|
|
|
removeParty( party->PartyID );
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onMoveZone( Sapphire::Entity::Player &movingPlayer )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
2023-02-22 14:55:59 +01:00
|
|
|
if( movingPlayer.getPartyId() == 0 )
|
|
|
|
return;
|
2021-11-27 00:53:57 +01:00
|
|
|
auto party = getParty( movingPlayer.getPartyId() );
|
|
|
|
assert( party );
|
|
|
|
sendPartyUpdate( *party );
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onMemberDisconnect( Entity::Player& disconnectingPlayer )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
2023-02-22 14:55:59 +01:00
|
|
|
if( disconnectingPlayer.getPartyId() == 0 )
|
|
|
|
return;
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto party = getParty( disconnectingPlayer.getPartyId() );
|
|
|
|
assert( party );
|
|
|
|
auto members = getPartyMembers( *party );
|
|
|
|
auto pLeader = getPartyLeader( *party );
|
|
|
|
|
|
|
|
bool anyMembersOnline = false;
|
|
|
|
|
|
|
|
for( const auto& member : members )
|
|
|
|
{
|
|
|
|
bool isConnected = server.getSession( member->getCharacterId() ) != nullptr;
|
|
|
|
if( isConnected )
|
|
|
|
{
|
|
|
|
anyMembersOnline = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if there are no party members online, destroy the party
|
|
|
|
if( !anyMembersOnline )
|
|
|
|
return onDisband( *pLeader );
|
|
|
|
|
|
|
|
for( const auto& member : members )
|
|
|
|
{
|
|
|
|
// TODO: 2nd argument here makes it automatically send passing leadership message
|
|
|
|
server.queueForPlayer( member->getCharacterId(), { makePcPartyUpdate( disconnectingPlayer, UpdateStatus::OFFLINE_MEMBER, party->PartyCount ),
|
|
|
|
makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } );
|
|
|
|
}
|
|
|
|
|
|
|
|
sendPartyUpdate( *party );
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onMemberRejoin( Entity::Player& joiningPlayer )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto party = getParty( joiningPlayer.getPartyId() );
|
|
|
|
assert( party );
|
|
|
|
|
|
|
|
// TODO: do we need a party update here? move zone handler already handles it
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onKick( const std::string& kickPlayerName, Entity::Player& leader )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto party = getParty( leader.getPartyId() );
|
|
|
|
assert( party );
|
|
|
|
auto pLeader = getPartyLeader( *party );
|
|
|
|
auto members = getPartyMembers( *party );
|
|
|
|
auto pKickedSession = server.getSession( kickPlayerName );
|
|
|
|
if( !pKickedSession )
|
|
|
|
{
|
|
|
|
Logger::error( "Target player for kicking not found (\"{t}\")", kickPlayerName );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( party->PartyCount == 2 )
|
|
|
|
{
|
|
|
|
onDisband( *pLeader );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for( const auto &member: members )
|
|
|
|
{
|
|
|
|
if( kickPlayerName == member->getName() )
|
|
|
|
{
|
|
|
|
removeMember( *party, member );
|
2022-01-27 21:08:43 +01:00
|
|
|
member->removeOnlineStatus( Common::OnlineStatus::PartyMember );
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
server.queueForPlayer( member->getCharacterId(), { makePcPartyUpdate( *pLeader, *member, UpdateStatus::KICK_SELF, party->PartyCount ),
|
|
|
|
makeZonePacket< FFXIVIpcUpdateParty >( member->getId() ) } );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
server.queueForPlayer( member->getCharacterId(), makePcPartyUpdate( *pKickedSession->getPlayer(), UpdateStatus::KICK_MEMBER, party->PartyCount ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
party->PartyCount--;
|
|
|
|
sendPartyUpdate( *party );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::onChangeLeader( const std::string& newLeaderName, Entity::Player& oldLeader )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
auto party = getParty( oldLeader.getPartyId() );
|
|
|
|
|
|
|
|
auto pNewLeader = server.getPlayer( newLeaderName );
|
|
|
|
|
|
|
|
if( !pNewLeader )
|
|
|
|
{
|
|
|
|
Logger::error( "Target player for new leader not found (\"{t}\")", newLeaderName );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( auto memberId : party->MemberId )
|
|
|
|
{
|
|
|
|
if( memberId == pNewLeader->getId() )
|
|
|
|
{
|
2022-01-27 21:08:43 +01:00
|
|
|
pNewLeader->addOnlineStatus( Common::OnlineStatus::PartyLeader );
|
2021-11-27 00:53:57 +01:00
|
|
|
// this is not ideal, probably better to have a function which can add
|
|
|
|
// and remove at the same time so packets are only triggered once
|
2022-01-27 21:08:43 +01:00
|
|
|
oldLeader.addOnlineStatus( Common::OnlineStatus::PartyMember );
|
|
|
|
oldLeader.removeOnlineStatus( Common::OnlineStatus::PartyLeader );
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
party->LeaderId = pNewLeader->getId();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto members = getPartyMembers( *party );
|
|
|
|
for( auto& member : members )
|
|
|
|
{
|
|
|
|
auto pcUpdateParty = makePcPartyUpdate( oldLeader.getAsPlayer(), pNewLeader, UpdateStatus::CHANGELEADER, party->PartyCount );
|
|
|
|
server.queueForPlayer( member->getCharacterId(), pcUpdateParty );
|
|
|
|
}
|
|
|
|
|
|
|
|
sendPartyUpdate( *party );
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
uint64_t PartyMgr::createParty()
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& chatChannelMgr = Common::Service< ChatChannelMgr >::ref();
|
|
|
|
auto party = std::make_shared< Party >();
|
|
|
|
party->PartyID = getNextPartyId();
|
|
|
|
party->ChatChannel = chatChannelMgr.createChatChannel( Common::ChatChannelType::PartyChat );
|
|
|
|
m_partyIdMap[ party->PartyID ] = party;
|
|
|
|
return party->PartyID;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
uint64_t PartyMgr::getNextPartyId()
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
return ++m_maxPartyId;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
PartyPtr PartyMgr::getParty( uint64_t partyId )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto it = m_partyIdMap.find( partyId );
|
|
|
|
if( it != m_partyIdMap.end() )
|
|
|
|
return it->second;
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
std::vector< Entity::PlayerPtr > PartyMgr::getPartyMembers( Party& party )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
2022-01-27 21:08:43 +01:00
|
|
|
std::vector< Entity::PlayerPtr > members;
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
for( auto& memberId : party.MemberId )
|
|
|
|
{
|
|
|
|
if( memberId == 0 )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto pPlayer = server.getPlayer( memberId );
|
|
|
|
|
|
|
|
members.push_back( pPlayer );
|
|
|
|
}
|
|
|
|
return members;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
Entity::PlayerPtr PartyMgr::getPartyLeader( Party& party )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
|
|
|
|
if( party.LeaderId == 0 )
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
auto pLeader = server.getPlayer( party.LeaderId );
|
|
|
|
|
|
|
|
return pLeader;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::sendPartyUpdate( Party& party )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
|
|
|
auto partyMembers = getPartyMembers( party );
|
|
|
|
std::vector< ZoneProtoDownPartyMember > entries;
|
|
|
|
auto& server = Common::Service< World::WorldServer >::ref();
|
|
|
|
|
|
|
|
for( const auto& member : partyMembers )
|
|
|
|
{
|
2022-01-27 21:24:54 +01:00
|
|
|
auto classJob = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( member->getClass() ) );
|
2021-11-27 00:53:57 +01:00
|
|
|
if( !classJob )
|
|
|
|
continue;
|
|
|
|
|
2023-01-17 11:27:25 +01:00
|
|
|
ZoneProtoDownPartyMember memberEntry{};
|
2021-11-27 00:53:57 +01:00
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
memberEntry.ParentEntityId = Common::INVALID_GAME_OBJECT_ID;
|
|
|
|
memberEntry.PetEntityId = Common::INVALID_GAME_OBJECT_ID;
|
2021-11-27 00:53:57 +01:00
|
|
|
memberEntry.Hp = member->getHp();
|
|
|
|
memberEntry.HpMax = member->getMaxHp();
|
|
|
|
memberEntry.Mp = member->getMp();
|
|
|
|
memberEntry.MpMax = member->getMaxMp();
|
|
|
|
memberEntry.ClassJob = static_cast< uint8_t >( member->getClass() );
|
|
|
|
memberEntry.Lv = member->getLevel();
|
|
|
|
memberEntry.ObjType = 4; // 1 PC, 2 Buddy ??
|
|
|
|
memberEntry.TerritoryType = member->getTerritoryTypeId();
|
|
|
|
memberEntry.Valid = 1;
|
|
|
|
memberEntry.Tp = member->getTp();
|
|
|
|
memberEntry.Role = classJob->data().Role;
|
|
|
|
/*
|
|
|
|
memberEntry.CharaId = member->getContentId();
|
|
|
|
memberEntry.EntityId = member->getId();
|
|
|
|
strcpy( memberEntry.Name, member->getName().c_str() );*/
|
|
|
|
|
|
|
|
entries.push_back( memberEntry );
|
|
|
|
}
|
|
|
|
|
|
|
|
for( const auto& pMember : partyMembers )
|
|
|
|
{
|
|
|
|
size_t idx = 0;
|
|
|
|
|
|
|
|
auto updatePartyPacket = makeZonePacket< FFXIVIpcUpdateParty >( partyMembers[ 0 ]->getId() );
|
|
|
|
auto& data = updatePartyPacket->data();
|
|
|
|
data.PartyID = party.PartyID;
|
|
|
|
data.LeaderIndex = getPartyLeaderIndex( party );
|
|
|
|
data.ChatChannel = party.ChatChannel;
|
|
|
|
data.PartyCount = party.PartyCount;
|
|
|
|
|
|
|
|
for( const auto& member : partyMembers )
|
|
|
|
{
|
|
|
|
bool isConnected = server.getSession( member->getCharacterId() ) != nullptr;
|
|
|
|
// if player is online and in the same zone as current member in party, display more data in partylist
|
2022-01-11 00:18:00 +01:00
|
|
|
bool hasInfo = isConnected && member->getTerritoryTypeId() == pMember->getTerritoryTypeId();
|
2021-11-27 00:53:57 +01:00
|
|
|
|
|
|
|
if( hasInfo )
|
|
|
|
{
|
|
|
|
data.Member[ idx ] = entries[ idx ];
|
|
|
|
}
|
|
|
|
|
|
|
|
data.Member[ idx ].CharaId = member->getCharacterId();
|
|
|
|
data.Member[ idx ].EntityId = member->getId();
|
|
|
|
strcpy( data.Member[ idx ].Name, member->getName().c_str() );
|
|
|
|
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
|
|
|
|
server.queueForPlayer( pMember->getCharacterId(), updatePartyPacket );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::removeParty( uint64_t partyId )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
m_partyIdMap.erase( partyId );
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
int8_t PartyMgr::getPartyLeaderIndex( const Party &party )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
size_t idx = 0;
|
|
|
|
for( const auto& memberId : party.MemberId )
|
|
|
|
{
|
|
|
|
if( memberId == party.LeaderId )
|
|
|
|
return static_cast< int8_t >( idx );
|
|
|
|
idx++;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-01-27 21:08:43 +01:00
|
|
|
void PartyMgr::removeMember( Party &party, const Entity::PlayerPtr& pMember )
|
2021-11-27 00:53:57 +01:00
|
|
|
{
|
|
|
|
auto& ccMgr = Common::Service< World::Manager::ChatChannelMgr >::ref();
|
|
|
|
pMember->setPartyId( 0 );
|
2022-01-18 00:21:38 +01:00
|
|
|
ccMgr.removeFromChannel( party.ChatChannel, *pMember );
|
2021-11-27 00:53:57 +01:00
|
|
|
party.MemberId.erase( std::remove( party.MemberId.begin(), party.MemberId.end(), pMember->getId() ), party.MemberId.end() );
|
|
|
|
}
|