bool Battlefield::AddOrSetPlayerToCorrectBfGroup(Player *player) { if (!player->IsInWorld()) return false; if (Group* group = player->GetGroup()) group->RemoveMember(player->GetGUID()); Group* group = GetFreeBfRaid(player->GetTeamId()); if (!group) { group = new Group; group->SetBattlefieldGroup(this); group->Create(player); sGroupMgr->AddGroup(group); m_Groups[player->GetTeamId()].insert(group->GetGUID()); } else if (group->IsMember(player->GetGUID())) { uint8 subgroup = group->GetMemberGroup(player->GetGUID()); player->SetBattlegroundOrBattlefieldRaid(group, subgroup); } else group->AddMember(player); return true; }
bool Battlefield::AddOrSetPlayerToCorrectBfGroup(Player* player) { if (!player->IsInWorld()) return false; if (player->GetGroup() && (player->GetGroup()->isBGGroup() || player->GetGroup()->isBFGroup())) { sLog->outMisc("Battlefield::AddOrSetPlayerToCorrectBfGroup - player is already in %s group!", (player->GetGroup()->isBGGroup() ? "BG" : "BF")); return false; } Group* group = GetFreeBfRaid(player->GetTeamId()); if (!group) { group = new Group; group->SetBattlefieldGroup(this); group->Create(player); sGroupMgr->AddGroup(group); m_Groups[player->GetTeamId()].insert(group->GetGUID()); } else if (group->IsMember(player->GetGUID())) { uint8 subgroup = group->GetMemberGroup(player->GetGUID()); player->SetBattlegroundOrBattlefieldRaid(group, subgroup); } else group->AddMember(player); return true; }
void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData) { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_ACCEPT"); #endif recvData.read_skip<uint32>(); Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); if (GetPlayer()->IsSpectator()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_INVITE_RESTRICTED); return; } if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { sLog->outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); return; } // Group is full if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = ObjectAccessor::FindPlayerInOrOutOfWorld(group->GetLeaderGUID()); // Forming a new group, create it if (!group->IsCreated()) { // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented if (!leader || leader->IsSpectator()) { group->RemoveAllInvites(); return; } // If we're about to create a group there really should be a leader present ASSERT(leader); group->RemoveInvite(leader); group->Create(leader); sGroupMgr->AddGroup(group); } // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer())) return; group->BroadcastGroupUpdate(); }
/** Function that checks if the player can be added to a raid group @param player to be added to raid */ bool Battlefield::CanAddPlayerToRaid(Player* player) { if (!player->IsInWorld()) return false; DEBUG_LOG("Battlefield: Adding player %s to raid", player->GetGuidStr().c_str()); if (Group* group = player->GetGroup()) { DEBUG_LOG("Battlefield: Player %s already has group %s, uninviting", player->GetGuidStr().c_str(), group->GetGuidStr().c_str()); group->RemoveMember(player->GetObjectGuid(), 0); } PvpTeamIndex teamIdx = GetTeamIndexByTeamId(player->GetTeam()); Group* group = GetFreeRaid(teamIdx); if (!group) { DEBUG_LOG("Battlefield: No free raid for %s!", player->GetGuidStr().c_str()); if (IsTeamFull(teamIdx)) { DEBUG_LOG("Battlefield: Battlefield is full! Can't add player %s!", player->GetGuidStr().c_str()); return false; } DEBUG_LOG("Battlefield: Trying to create new group for %s!", player->GetGuidStr().c_str()); group = new Group; group->SetBattlefieldGroup(this); if (group->Create(player->GetObjectGuid(), player->GetName())) DEBUG_LOG("Battlefield: Successfully created new group %s", group->GetGuidStr().c_str()); else sLog.outError("Battlefield: Failed to create group for player %s.", player->GetGuidStr().c_str()); m_battlefieldRaids[teamIdx].insert(group); } else if (group->IsMember(player->GetObjectGuid())) { DEBUG_LOG("Battlefield: Raid already has players %s, making some shit", player->GetGuidStr().c_str()); uint8 subgroup = group->GetMemberGroup(player->GetObjectGuid()); player->SetBattleRaid(group, subgroup); } else { if (IsTeamFull(teamIdx)) { DEBUG_LOG("Battlefield: Group %s found, but battlefield is full! Can't add player %s!", group->GetGuidStr().c_str(), player->GetGuidStr().c_str()); return false; } return group->AddMember(player->GetObjectGuid(), player->GetName()); } return true; }
void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_ACCEPT"); recvData.read_skip<uint32>(); Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } // Group is full if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); // Forming a new group, create it if (!group->IsCreated()) { // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented if (!leader) { group->RemoveAllInvites(); return; } // If we're about to create a group there really should be a leader present ASSERT(leader); group->RemoveInvite(leader); group->Create(leader); sGroupMgr->AddGroup(group); } // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer())) return; group->BroadcastGroupUpdate(); }
void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data ) { if (!GetPlayer()->GetPlayerbotAI()) recv_data.read_skip<uint32>(); // roles mask? Group *group = GetPlayer()->GetGroupInvite(); if (!group) return; if (group->GetLeaderGuid() == GetPlayer()->GetObjectGuid()) { sLog.outError("HandleGroupAcceptOpcode: %s tried to accept an invite to his own group", GetPlayer()->GetGuidStr().c_str()); return; } // remove in from invites in any case group->RemoveInvite(GetPlayer()); /** error handling **/ /********************/ // not have place if(group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid()); // forming a new group, create it if (!group->IsCreated()) { if (leader) group->RemoveInvite(leader); if (group->Create(group->GetLeaderGuid(), group->GetLeaderName())) sObjectMgr.AddGroup(group); else return; } // everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if(!group->AddMember(GetPlayer()->GetObjectGuid(), GetPlayer()->GetName())) return; // Frozen Mod group->BroadcastGroupUpdate(); // Frozen Mod }
void WorldSession::HandleGroupAcceptOpcode(WorldPacket & /*recv_data*/) { Group *group = GetPlayer()->GetGroupInvite(); if (!group) return; if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } // remove in from ivites in any case group->RemoveInvite(GetPlayer()); /** error handling **/ /********************/ // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = objmgr.GetPlayer(group->GetLeaderGUID()); // forming a new group, create it if (!group->IsCreated()) { if (leader) group->RemoveInvite(leader); group->Create(group->GetLeaderGUID(), group->GetLeaderName()); objmgr.AddGroup(group); } // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName())) return; SendLfgUpdatePlayer(LFG_UPDATETYPE_REMOVED_FROM_QUEUE); for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player *plrg = itr->getSource()) { plrg->GetSession()->SendLfgUpdatePlayer(LFG_UPDATETYPE_CLEAR_LOCK_LIST); plrg->GetSession()->SendLfgUpdateParty(LFG_UPDATETYPE_CLEAR_LOCK_LIST); } group->BroadcastGroupUpdate(); }
void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ ) { Group *group = GetPlayer()->GetGroupInvite(); if (!group) return; if(group->GetLeaderGUID() == GetPlayer()->GetGUID()) { sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } // remove in from ivites in any case group->RemoveInvite(GetPlayer()); /** error handling **/ /********************/ // not have place if(group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); return; } Player* leader = objmgr.GetPlayer(group->GetLeaderGUID()); if(leader && leader->InBattleGround()) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_INVITE_RESTRICTED); return; } // forming a new group, create it if(!group->IsCreated()) { if(leader) group->RemoveInvite(leader); group->Create(group->GetLeaderGUID(), group->GetLeaderName()); objmgr.AddGroup(group); } // everything's fine, do it if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName())) return; uint8 subgroup = group->GetMemberGroup(GetPlayer()->GetGUID()); GetPlayer()->SetGroup(group, subgroup); }
void WorldSession::HandleGroupAcceptOpcode( WorldPacket & /*recv_data*/ ) { Group *group = GetPlayer()->GetGroupInvite(); if (!group) return; if(group->GetLeaderGUID() == GetPlayer()->GetGUID()) { sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } // remove in from invites in any case group->RemoveInvite(GetPlayer()); /** error handling **/ /********************/ // not have place if(group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGUID()); if(leader && leader->InBattleGround()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_INVITE_RESTRICTED); return; } // forming a new group, create it if(!group->IsCreated()) { if (leader) group->RemoveInvite(leader); if (group->Create(group->GetLeaderGUID(), group->GetLeaderName())) sObjectMgr.AddGroup(group); else return; } // everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName())) return; }
//////////////////////////////////////////////////////////////// ///This function handles CMSG_GROUP_ACCEPT: //////////////////////////////////////////////////////////////// void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data ) { WorldPacket data; Player * player; player = objmgr.GetObject<Player>( GetPlayer()->GetGroupLeader() ); if ( !player ) return; if ( !GetPlayer()->IsInvited() ) return; GetPlayer()->UnSetInvited(); if ( player->IsInGroup() && (player->GetGroupLeader() == player->GetGUID()) ) { GetPlayer()->SetInGroup(); Group *group = objmgr.GetGroupByLeader( GetPlayer()->GetGroupLeader() ); ASSERT(group); group->AddMember( GetPlayer()->GetGUID(), GetPlayer()->GetName() ); group->SendUpdate(); return; } else if ( !player->IsInGroup() ) { player->SetInGroup(); player->SetLeader( player->GetGUID() ); GetPlayer()->SetInGroup(); GetPlayer()->SetLeader( player->GetGUID() ); // creating group Group * group = new Group; ASSERT(group); group->Create(player->GetGUID(), player->GetName()); // adding our client group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName()); objmgr.AddGroup(group); group->SendUpdate(); } }
void WorldSession::HandleGroupAcceptOpcode( WorldPacket & recv_data ) { recv_data.read_skip<uint32>(); // value received in WorldSession::HandleGroupInviteOpcode and also skipeed currently? Group *group = GetPlayer()->GetGroupInvite(); if (!group) return; if(group->GetLeaderGUID() == GetPlayer()->GetGUID()) { sLog.outError("HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow()); return; } // remove in from ivites in any case group->RemoveInvite(GetPlayer()); /** error handling **/ /********************/ // not have place if(group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); return; } Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGUID()); // forming a new group, create it if(!group->IsCreated()) { if( leader ) group->RemoveInvite(leader); group->Create(group->GetLeaderGUID(), group->GetLeaderName()); sObjectMgr.AddGroup(group); } // everything's fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if(!group->AddMember(GetPlayer()->GetGUID(), GetPlayer()->GetName())) return; }
bool Battlefield::AddPlayerToGroup(Player * player) { Group* grp; if(player->GetTeam() == ALLIANCE) grp = m_raidGroup[TEAM_ALLIANCE]; else grp = m_raidGroup[TEAM_HORDE]; if(!grp->IsCreated()) { grp->Create(player->GetObjectGuid(),player->GetName()); grp->ConvertToRaid(); grp->AddMember(player->GetObjectGuid(),player->GetName()); } else if(!grp->IsFull()) { grp->AddMember(player->GetObjectGuid(),player->GetName()); } else return false; return true; }
void WorldSession::HandleMoveWorldportAckOpcode() { // ignore unexpected far teleports if(!GetPlayer()->IsBeingTeleportedFar()) return; // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player got's teleported far to a not valid location. (map:%u, x:%f, y:%f, z:%f) We log him out and don't save him..", loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); // stop teleportation else we would try this again in the beginning of WorldSession::LogoutPlayer... GetPlayer()->SetSemaphoreTeleportFar(false); // player don't gets saved - so his coords will stay at the point where // he was last saved LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = ObjectMgr::GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleportFar(false); // relocate the player to the teleport destination GetPlayer()->SetMap(MapManager::Instance().CreateMap(loc.mapid, GetPlayer())); GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // check this before Map::Add(player), because that will create the instance save! bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId()) == NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if(!GetPlayer()->GetMap()->Add(GetPlayer())) { //if player wasn't added to map, reset his map pointer! GetPlayer()->ResetMap(); DEBUG_LOG("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); // teleport the player home GetPlayer()->TeleportToHomebind(); return; } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Reset(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->m_taxi.ClearTaxiDestinations(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry->IsDungeon() ) { GetPlayer()->ResurrectPlayer(0.5f); GetPlayer()->SpawnCorpseBones(); } } if(mEntry->IsRaid() && mInstance) { if(reset_notify) { uint32 timeleft = sInstanceSaveMgr.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance } } // mount allow check if(!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // battleground state prepare // only add to bg group and object, if the player was invited (else he entered through command) if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) { BattleGround *bg = _player->GetBattleGround(); if(bg) { bg->AddPlayer(_player); if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg { // get the team this way, because arenas might 'override' the teams. uint32 team = bg->GetPlayerTeam(_player->GetGUID()); if(!team) team = _player->GetTeam(); if(!bg->GetBgRaid(team)) // first player joined { Group *group = new Group; bg->SetBgRaid(team, group); group->Create(_player->GetGUIDLow(), _player->GetName()); } else // raid already exist { bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName()); } } } } // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); }
void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_GROUP_INVITE_RESPONSE"); recvData.ReadBit(); // unk always 0 bool accept = recvData.ReadBit(); // Never actually received? /*if (accept) recvData.read_skip<uint32>(); // unk*/ Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; if (accept) { // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); return; } // Group is full if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); // Forming a new group, create it if (!group->IsCreated()) { // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented if (!leader) { group->RemoveAllInvites(); return; } // If we're about to create a group there really should be a leader present ASSERT(leader); group->RemoveInvite(leader); group->Create(leader); sGroupMgr->AddGroup(group); } // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer())) return; group->BroadcastGroupUpdate(); } else { // Remember leader if online (group pointer will be invalid if group gets disbanded) Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); // uninvite, group can be deleted GetPlayer()->UninviteFromGroup(); if (!leader || !leader->GetSession()) return; // report WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().size()); data << GetPlayer()->GetName(); leader->GetSession()->SendPacket(&data); } }
void WorldSession::HandleMoveWorldportAckOpcode() { // get the teleport destination WorldLocation &loc = GetPlayer()->GetTeleportDest(); // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid,loc.x,loc.y,loc.z,loc.o)) { LogoutPlayer(false); return; } // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.mapid); // reset instance validity, except if going to an instance inside an instance if(GetPlayer()->m_InstanceValid == false && !mInstance) GetPlayer()->m_InstanceValid = true; GetPlayer()->SetSemaphoreTeleport(false); // relocate the player to the teleport destination GetPlayer()->SetMapId(loc.mapid); GetPlayer()->Relocate(loc.x, loc.y, loc.z, loc.o); // since the MapId is set before the GetInstance call, the InstanceId must be set to 0 // to let GetInstance() determine the proper InstanceId based on the player's binds GetPlayer()->SetInstanceId(0); // check this before Map::Add(player), because that will create the instance save! bool reset_notify = (GetPlayer()->GetBoundInstance(GetPlayer()->GetMapId(), GetPlayer()->GetDifficulty()) == NULL); GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if(!GetPlayer()->GetMap()->Add(GetPlayer())) { sLog.outDebug("WORLD: teleport of player %s (%d) to location %d,%f,%f,%f,%f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.x, loc.y, loc.z, loc.o); // teleport the player home GetPlayer()->SetDontMove(false); if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation())) { // the player must always be able to teleport home sLog.outError("WORLD: failed to teleport player %s (%d) to homebind location %d,%f,%f,%f,%f!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); assert(false); } return; } GetPlayer()->SendInitialPacketsAfterAddToMap(); // flight fast teleport case if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) { if(!_player->InBattleGround()) { // short preparations to continue flight GetPlayer()->SetDontMove(false); FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Initialize(*GetPlayer()); return; } // battleground state prepare, stop flight GetPlayer()->GetMotionMaster()->MovementExpired(); GetPlayer()->m_taxi.ClearTaxiDestinations(); } // resurrect character at enter into instance where his corpse exist after add to map Corpse *corpse = GetPlayer()->GetCorpse(); if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) { if( mEntry->IsDungeon() ) { GetPlayer()->ResurrectPlayer(0.5f); GetPlayer()->SpawnCorpseBones(); GetPlayer()->SaveToDB(); } } if(mEntry->IsRaid() && mInstance) { if(reset_notify) { uint32 timeleft = sInstanceSaveManager.GetResetTimeFor(GetPlayer()->GetMapId()) - time(NULL); GetPlayer()->SendInstanceResetWarning(GetPlayer()->GetMapId(), timeleft); // greeting at the entrance of the resort raid instance } } // mount allow check if(!mEntry->IsMountAllowed()) _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); // battleground state prepare // only add to bg group and object, if the player was invited (else he entered through command) if(_player->InBattleGround() && _player->IsInvitedForBattleGroundInstance(_player->GetBattleGroundId())) { BattleGround *bg = _player->GetBattleGround(); if(bg) { bg->AddPlayer(_player); if(bg->GetMapId() == _player->GetMapId()) // we teleported to bg { // get the team this way, because arenas might 'override' the teams. uint32 team = bg->GetPlayerTeam(_player->GetGUID()); if(!team) team = _player->GetTeam(); if(!bg->GetBgRaid(team)) // first player joined { Group *group = new Group; bg->SetBgRaid(team, group); group->Create(_player->GetGUIDLow(), _player->GetName()); } else // raid already exist { bg->GetBgRaid(team)->AddMember(_player->GetGUID(), _player->GetName()); } } } } // honorless target if(GetPlayer()->pvpInfo.inHostileArea) GetPlayer()->CastSpell(GetPlayer(), 2479, true); // resummon pet if(GetPlayer()->m_temporaryUnsummonedPetNumber) { Pet* NewPet = new Pet; if(!NewPet->LoadPetFromDB(GetPlayer(), 0, GetPlayer()->m_temporaryUnsummonedPetNumber, true)) delete NewPet; GetPlayer()->m_temporaryUnsummonedPetNumber = 0; } GetPlayer()->SetDontMove(false); }
void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recv_data) { bool unk = recv_data.ReadBit(); bool accepted = recv_data.ReadBit(); if (unk) recv_data.read_skip<uint32>(); Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; if (accepted) { // remove in from invites in any case group->RemoveInvite(GetPlayer()); if (group->GetLeaderGuid() == GetPlayer()->GetObjectGuid()) { sLog.outError("HandleGroupInviteResponseOpcode: %s tried to accept an invite to his own group", GetPlayer()->GetGuidStr().c_str()); return; } /** error handling **/ /********************/ // not have place if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid()); // forming a new group, create it if (!group->IsCreated()) { if (leader) group->RemoveInvite(leader); if (group->Create(group->GetLeaderGuid(), group->GetLeaderName())) sObjectMgr.AddGroup(group); else return; } // everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer()->GetObjectGuid(), GetPlayer()->GetName())) return; } else { // uninvite, group can be deleted GetPlayer()->UninviteFromGroup(); // remember leader if online Player* leader = sObjectMgr.GetPlayer(group->GetLeaderGuid()); if (!leader || !leader->GetSession()) return; // report WorldPacket data(SMSG_GROUP_DECLINE, 10); // guess size data << GetPlayer()->GetName(); leader->GetSession()->SendPacket(&data); } }
void LFGQueue::Update(uint32 diff) { if(m_QueuedGroups.empty() && m_QueuedPlayers.empty()) return; // Iterate over QueuedPlayersMap to update players timers and remove offline/disconnected players. for(QueuedPlayersMap::iterator qPlayer = m_QueuedPlayers.begin(); qPlayer != m_QueuedPlayers.end(); ++qPlayer) { Player* plr = sObjectMgr.GetPlayer(qPlayer->first); // Player could have been disconnected if(!plr ||!plr->IsInWorld()) { m_OfflinePlayers[qPlayer->first] = qPlayer->second; m_QueuedPlayers.erase(qPlayer); break; } qPlayer->second.timeInLFG += diff; // Update player timer and give him queue priority. if(qPlayer->second.timeInLFG >= (30 * MINUTE * IN_MILLISECONDS)) { qPlayer->second.hasQueuePriority = true; } } if(!m_QueuedGroups.empty()) { // Iterate over QueuedGroupsMap to fill groups with roles they're missing. for(QueuedGroupsMap::iterator qGroup = m_QueuedGroups.begin(); qGroup != m_QueuedGroups.end(); ++qGroup) { Group* grp = sObjectMgr.GetGroupById(qGroup->first); // Safe check if(!grp) return; // Remove group from Queue if it's full if(grp->IsFull()) { RemoveGroupFromQueue(qGroup->first, GROUP_SYSTEM_LEAVE); break; } // Iterate over QueuedPlayersMap to find suitable player to join group for(QueuedPlayersMap::iterator qPlayer = m_QueuedPlayers.begin(); qPlayer != m_QueuedPlayers.end(); ++qPlayer) { Player* plr = sObjectMgr.GetPlayer(qPlayer->first); // Check here that players team and areaId they're in queue are same if(qPlayer->second.team == qGroup->second.team && qPlayer->second.areaId == qGroup->second.areaId) { // Check if player can perform tank role if((canPerformRole(qPlayer->second.roleMask, LFG_ROLE_TANK) & qGroup->second.availableRoles) == LFG_ROLE_TANK) { if(FindRoleToGroup(plr, grp, LFG_ROLE_TANK)) { break; } else { continue; } } // Check if player can perform healer role if((canPerformRole(qPlayer->second.roleMask, LFG_ROLE_HEALER) & qGroup->second.availableRoles) == LFG_ROLE_HEALER) { if(FindRoleToGroup(plr, grp, LFG_ROLE_HEALER)) { break; } else { continue; } } // Check if player can perform dps role if((canPerformRole(qPlayer->second.roleMask, LFG_ROLE_DPS) & qGroup->second.availableRoles) == LFG_ROLE_DPS) { if(FindRoleToGroup(plr, grp, LFG_ROLE_DPS)) { break; } else { continue; } } // Check if group is full, no need to try to iterate same group if it's already full. if(grp->IsFull()) { RemoveGroupFromQueue(qGroup->first, GROUP_SYSTEM_LEAVE); break; } } } // Update group timer. After each 5 minutes group will be broadcasted they're still waiting more members. if (qGroup->second.groupTimer <= diff) { WorldPacket data; BuildInProgressPacket(data); grp->BroadcastPacket(&data, true); qGroup->second.groupTimer = 5 * MINUTE * IN_MILLISECONDS; } else { qGroup->second.groupTimer -= diff; } } } // Pick first 2 players and form group out of them also inserting them into queue as group. if(m_QueuedPlayers.size() > 5) { // Pick Leader as first target. QueuedPlayersMap::iterator nPlayer1 = m_QueuedPlayers.begin(); if(findInArea(nPlayer1->second.areaId) > 5) { Group* newQueueGroup = new Group; // Iterate of QueuedPlayersMap and pick first member to accompany leader. for(QueuedPlayersMap::iterator nPlayer2 = m_QueuedPlayers.begin(); nPlayer2 != m_QueuedPlayers.end(); ++nPlayer2) { if(nPlayer1->first == nPlayer2->first) continue; if(nPlayer1->second.team == nPlayer2->second.team && nPlayer1->second.areaId == nPlayer2->second.areaId) { Player* leader = sObjectMgr.GetPlayer(nPlayer1->first); Player* member = sObjectMgr.GetPlayer(nPlayer2->first); uint32 areaId = nPlayer1->second.areaId; if(!newQueueGroup->IsCreated()) { if(newQueueGroup->Create(leader->GetObjectGuid(), leader->GetName())) sObjectMgr.AddGroup(newQueueGroup); else return; } WorldPacket data; BuildMemberAddedPacket(data, member->GetGUID()); leader->GetSession()->SendPacket(&data); // Add member to the group. Leader is already added upon creation of group. newQueueGroup->AddMember(member->GetObjectGuid(), member->GetName(), GROUP_LFG); // Add this new group to GroupQueue now and remove players from PlayerQueue RemovePlayerFromQueue(nPlayer1->first, PLAYER_SYSTEM_LEAVE); RemovePlayerFromQueue(nPlayer2->first, PLAYER_SYSTEM_LEAVE); AddToQueue(leader, areaId); break; } } } } }
void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data ) { std::string membername; recv_data >> membername; // attempt add selected player // cheating if(membername.empty()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } normalizePlayerName(membername); Player *player = objmgr.GetPlayer(membername.c_str()); // no player if(!player) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_CANT_FIND_TARGET); return; } // can't group with if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam()) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_UNFRIENDLY); return; } // just ignore us if(player->HasInIgnoreList(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_TARGET_IGNORE_YOU); return; } // player already in another group or invited if(player->GetGroup() || player->GetGroupInvite() ) { SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_ALREADY_IN_GROUP); return; } Group *group = GetPlayer()->GetGroup(); if(group) { // not have permissions for invite if(!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_YOU_NOT_LEADER); return; } // not have place if(group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", PARTY_RESULT_PARTY_FULL); return; } } // ok, but group not exist, creating new if(!group) { group = new Group; if(!group->Create(GetPlayer()->GetGUID(), GetPlayer()->GetName())) { delete group; return; } objmgr.AddGroup(group); // new group: if can't add then delete if(!group->AddInvite(player)) { group->Disband(true); objmgr.RemoveGroup(group); delete group; return; } } else { // already existed group: if can't add then just leave if(!group->AddInvite(player)) { return; } } // ok, we do it WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size data << GetPlayer()->GetName(); player->GetSession()->SendPacket(&data); SendPartyResult(PARTY_OP_INVITE, membername, PARTY_RESULT_OK); }
void WorldSession::LFGLoop() { QueryResult *result = WorldDatabase.Query("SELECT guid,zoneid,is_group FROM lfg_queue"); if (result) { do { Field* fields = result->Fetch(); //is this entry a group? if(fields[2].GetUInt32() == 1) { //is there anyone in the queue looking for a group for this groups instance? QueryResult *resultLFG = WorldDatabase.PQuery("SELECT guid,zoneid,is_group,player_name FROM lfg_queue WHERE zoneid = '%u' AND is_group = 0", fields[1].GetUInt32()); if (resultLFG) { do { Field* fieldsLFG = resultLFG->Fetch(); Player *plr = sObjectAccessor.FindPlayerByName(fieldsLFG[3].GetString()); Group *grp = sObjectMgr.GetGroupById(fields[0].GetUInt32()); if(!grp->IsFull()) { //check for roles if(GroupHasRole(ROLE_TANK, grp) && GroupHasRole(ROLE_HEALER, grp)) { //group has both dps & tank, add anyone. grp->AddMember(plr->GetGUID(), plr->GetName()); RemovePlayerFromQueue(plr->GetGUIDLow()); if(grp->IsFull()) { SendMeetingStoneCompleteToParty(grp); } } else if(GroupHasRole(ROLE_TANK, grp) && !GroupHasRole(ROLE_HEALER, grp)) { //tank but healers missing //is player healer? if(isPlayerHealer(plr)) { grp->AddMember(plr->GetGUID(), plr->GetName()); RemovePlayerFromQueue(plr->GetGUIDLow()); if(grp->IsFull()) { SendMeetingStoneCompleteToParty(grp); } } //player is not healer but group can take one more random.. else if(!isPlayerHealer(plr) && grp->GetMembersCount() < 4) { grp->AddMember(plr->GetGUID(), plr->GetName()); RemovePlayerFromQueue(plr->GetGUIDLow()); if(grp->IsFull()) { SendMeetingStoneCompleteToParty(grp); } } } else if(!GroupHasRole(ROLE_TANK, grp) && !GroupHasRole(ROLE_HEALER, grp)) { //group has neither tank or healer if(isPlayerHealer(plr) || isPlayerTank(plr)) { grp->AddMember(plr->GetGUID(), plr->GetName()); RemovePlayerFromQueue(plr->GetGUIDLow()); if(grp->IsFull()) { SendMeetingStoneCompleteToParty(grp); } } else { if(grp->GetMembersCount() < 3) { //theres room for 1 more random, let the player join. grp->AddMember(plr->GetGUID(), plr->GetName()); RemovePlayerFromQueue(plr->GetGUIDLow()); if(grp->IsFull()) { SendMeetingStoneCompleteToParty(grp); } } } } } } while (resultLFG->NextRow()); } } else { //its a player, is there any other non-grouped players thats looking for the same instance? QueryResult *result_mp = WorldDatabase.PQuery("SELECT guid,zoneid,is_group,player_name FROM lfg_queue WHERE zoneid = '%u' AND is_group = 0", fields[1].GetUInt32()); if(result_mp->GetRowCount() > 1) { int i = 1; Group* grp; grp = new Group; do { Field* fields_mp = result_mp->Fetch(); Player *plr = sObjectAccessor.FindPlayerByName(fields_mp[3].GetString()); if(!grp->IsCreated()) { if (grp->Create(plr->GetGUID(), plr->GetName())) { sObjectMgr.AddGroup(grp); RemovePlayerFromQueue(plr->GetGUIDLow()); } } else { grp->AddMember(plr->GetGUID(), plr->GetName()); RemovePlayerFromQueue(plr->GetGUIDLow()); } plr = NULL; } while (result_mp->NextRow()); //if this group did not fill up, add it into LFM queue if(!grp->IsFull()) { AddGroupToQueue(grp->GetId(), fields[1].GetUInt32()); } } } } while (result->NextRow()); } }
void WorldSession::HandlePartyInviteResponseOpcode(WorldPackets::Party::PartyInviteResponse& packet) { Group* group = GetPlayer()->GetGroupInvite(); if (!group) return; if (packet.Accept) { // Remove player from invitees in any case group->RemoveInvite(GetPlayer()); if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s (%s) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str()); return; } // Group is full if (group->IsFull()) { SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL); return; } Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID()); // Forming a new group, create it if (!group->IsCreated()) { // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented if (!leader) { group->RemoveAllInvites(); return; } // If we're about to create a group there really should be a leader present ASSERT(leader); group->RemoveInvite(leader); group->Create(leader); sGroupMgr->AddGroup(group); } // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!! if (!group->AddMember(GetPlayer())) return; group->BroadcastGroupUpdate(); } else { // Remember leader if online (group pointer will be invalid if group gets disbanded) Player* leader = ObjectAccessor::FindConnectedPlayer(group->GetLeaderGUID()); // uninvite, group can be deleted GetPlayer()->UninviteFromGroup(); if (!leader || !leader->GetSession()) return; // report WorldPackets::Party::GroupDecline decline(GetPlayer()->GetName()); leader->GetSession()->SendPacket(decline.Write()); } }