/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { /*WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3 + 4 + 2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data);*/ return; } Pet* pet = player->GetPet(); /*WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_AURAS | GROUP_UPDATE_FLAG_PHASE; if (pet) mask1 = 0x7FEFFEFF; // full mask & ~(GROUP_UPDATE_FLAG_VEHICLE_SEAT | GROUP_UPDATE_FLAG_UNK) Powers powerType = player->GetPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; uint16 iCoordZ = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); iCoordZ = player->GetPositionZ(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; iCoordZ = loc.coord_z; } else { // unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordZ); // GROUP_UPDATE_FLAG_POSITION data << uint8(1); // if true, client clears all auras that are not in auramask and whose index is lower amount sent below uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder, server sends 0xFFFFFFFFFFFFFFFF here, but with 1 above it seems no difference data << uint32(MAX_AURAS); // server sends here number of visible auras, but client checks // if aura is in auramask, so it seems no difference if there will be MAX_AURAS for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolder* holder = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint16(holder->GetAuraFlags()); if (holder->GetAuraFlags() & AFLAG_EFFECT_AMOUNT_SEND) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) if (Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) data << int32(aura->GetModifier()->m_amount); else data << int32(0); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->GetPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER data << uint8(1); // if true, client clears all auras that are not in auramask and whose index is lower amount sent below uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder, server sends 0xFFFFFFFFFFFFFFFF here, but with 1 above it seems no difference data << uint32(MAX_AURAS); // server sends here number of visible auras, but client checks // if aura is in auramask, so it seems no difference if there will be MAX_AURAS for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolder* holder = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint16(holder->GetAuraFlags()); if (holder->GetAuraFlags() & AFLAG_EFFECT_AMOUNT_SEND) for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i) if (Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i))) data << int32(aura->GetModifier()->m_amount); else data << int32(0); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint8(1); // GROUP_UPDATE_FLAG_PET_AURAS data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint32(0); // GROUP_UPDATE_FLAG_PET_AURAS } if (player->GetTransportInfo()) // GROUP_UPDATE_FLAG_VEHICLE_SEAT data << uint32(((Unit*)player->GetTransportInfo()->GetTransport())->GetVehicleInfo()->GetVehicleEntry()->m_seatID[player->GetTransportInfo()->GetTransportSeat()]); data << uint32(8); // GROUP_UPDATE_FLAG_PHASE data << uint32(0); // GROUP_UPDATE_FLAG_PHASE data << uint8(0); // GROUP_UPDATE_FLAG_PHASE SendPacket(&data);*/ }
Map* MapInstanced::GetInstance(const WorldObject* obj) { uint32 InstanceId = obj->GetInstanceId(); Map* map = NULL; if (InstanceId != 0) map = _FindMap(InstanceId); // return map for non-player objects if (map && obj->GetTypeId() != TYPEID_PLAYER) return(map); if (obj->GetTypeId() != TYPEID_PLAYER) { sLog.outDebug("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) is requesting instance '%u' of map '%u', instantiating", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), InstanceId, GetId()); if (InstanceId == 0) { sLog.outError("MAPINSTANCED: WorldObject '%u' (Entry: %u Type: %u) requested base map instance of map '%u', this must not happen", obj->GetGUIDLow(), obj->GetEntry(), obj->GetTypeId(), GetId()); return(this); } // short instantiate process for world object CreateInstance(InstanceId, map); return(map); } // here we do additionally verify, if the player is allowed in instance by leader // and if it has current instance bound correctly Player* player = (Player*)obj; // reset instance validation flag player->m_InstanceValid = true; BoundInstancesMap::iterator i = player->m_BoundInstances.find(GetId()); if (i != player->m_BoundInstances.end()) { // well, we have an instance bound, really, verify self or group leader if (!((player->GetGUIDLow() == i->second.second) || (player->GetGroup() && (GUID_LOPART(player->GetGroup()->GetLeaderGUID()) == i->second.second)))) { // well, we are bound to instance, but are not a leader and are not in the correct group // we must not rebind us or the instantiator (which can surely be the same) // will remain bound if accepted into group or will be unbound, if we go to homebind InstanceId = i->second.first; // restore the instance bound player->m_InstanceValid = false; // player instance is invalid if (InstanceId != 0) map = _FindMap(InstanceId);// restore the map bound } } else { // the player has no map bindings, we can proceed safely creating a new one map = NULL; } if (map) return(map); // here we go, the map is found and we are correctly bound Player* instantiator = NULL; uint32 instantiator_id = 0; bool instantiator_online = true; bool instantiator_bound = false; // we do need to scan for the instantiator, if the instance we scan for is valid, not temporary if (player->m_InstanceValid) { // either we are not bound to the instance, or we have to create new instance, do it InstanceId = 0; // determine the instantiator which designates the instance id if (player->GetGroup()) { // instantiate map for group leader (possibly got from the database) sLog.outDebug("MAPINSTANCED: Player '%s' is in group, instantiating map for group leader", player->GetName()); instantiator = objmgr.GetPlayer(player->GetGroup()->GetLeaderGUID()); if (!instantiator) { // the very special case: leader is not online, read instance map from DB instantiator_online = false; } } if (!instantiator && instantiator_online) { sLog.outDebug("MAPINSTANCED: Player '%s' is not in group, instantiating map for player", player->GetName()); instantiator = player; } // now, get the real instance id from the instantiator if (instantiator_online) { // player online, normal instantianting sLog.outDebug("MAPINSTANCED: Instantiating map for player '%s' (group leader '%s')", player->GetName(), instantiator->GetName()); instantiator_id = instantiator->GetGUIDLow(); BoundInstancesMap::iterator i = instantiator->m_BoundInstances.find(GetId()); if (i != instantiator->m_BoundInstances.end()) { // the instantiator has his instance bound InstanceId = i->second.first; // this check is to avoid the case where remote instantiator has his instance // bound to another remote instantiator (e.g. exited from group recently) // if that is the case, the instance for him will be regenerated and rebound if ((instantiator == player) || (i->second.second == instantiator_id)) { // player is instantiator or instantiator has his instance bound to himself instantiator_bound = true; } } } else { // the aforementioned "very special" case of leader being not online sLog.outDebug("MAPINSTANCED: Instantiating map for player '%s' (group leader is not online, querying DB)", player->GetName()); instantiator_id = GUID_LOPART(player->GetGroup()->GetLeaderGUID()); QueryResult* result = CharacterDatabase.PQuery("SELECT instance FROM character_instance WHERE (guid = '%u') AND (map = '%u') AND (leader = '%u')", instantiator_id, GetId(), instantiator_id); if (result) { // the instantiator has his instance bound InstanceId = result->Fetch()[0].GetUInt32(); instantiator_bound = true; delete result; } } // check, if we have to generate new instance if (!instantiator_bound || (InstanceId == 0)) { // yes, new instance id has to be generated InstanceId = MapManager::Instance().GenerateInstanceId(); } else { // find map of the designated instance and verify it map = _FindMap(InstanceId); } } // now create the instance CreateInstance(InstanceId, map); // we do need to bind instance, if the instance we use is valid, not temporary if (player->m_InstanceValid) { // bind instance to instantiator (only if needed) if (!instantiator_bound) { CharacterDatabase.BeginTransaction(); if (instantiator_online) { // player online, normal bind instantiator->m_BoundInstances[GetId()] = std::pair< uint32, uint32 >(InstanceId, instantiator_id); CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", instantiator_id, GetId()); CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", instantiator_id, GetId(), InstanceId, instantiator_id); } else { // the aforementioned "very special" case of leader being not online CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", GUID_LOPART(player->GetGroup()->GetLeaderGUID()), GetId()); CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(player->GetGroup()->GetLeaderGUID()), GetId(), InstanceId, GUID_LOPART(player->GetGroup()->GetLeaderGUID())); } CharacterDatabase.CommitTransaction(); } // bind instance to player (avoid duplicate binding) if (instantiator != player) { CharacterDatabase.BeginTransaction(); if (instantiator_online) { player->m_BoundInstances[GetId()] = std::pair< uint32, uint32 >(InstanceId, instantiator_id); CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", player->GetGUIDLow(), GetId()); CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", player->GetGUIDLow(), GetId(), InstanceId, instantiator_id); } else { // the aforementioned "very special" case of leader being not online player->m_BoundInstances[GetId()] = std::pair< uint32, uint32 >(InstanceId, GUID_LOPART(player->GetGroup()->GetLeaderGUID())); CharacterDatabase.PExecute("DELETE FROM character_instance WHERE (guid = '%u') AND (map = '%u')", player->GetGUIDLow(), GetId()); CharacterDatabase.PExecute("INSERT INTO character_instance VALUES ('%u', '%u', '%u', '%u')", player->GetGUIDLow(), GetId(), InstanceId, GUID_LOPART(player->GetGroup()->GetLeaderGUID())); } CharacterDatabase.CommitTransaction(); } } // set instance id for instantiating player if (player->GetPet()) player->GetPet()->SetInstanceId(InstanceId); player->SetInstanceId(InstanceId); return(map); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { CHECK_PACKET_SIZE(recv_data, 8); sLog.outDebug("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player *player = objmgr.GetPlayer(Guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint16) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint16) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) { auramask |= (uint64(1) << i); data << uint16(aura); data << uint8(1); } } data.put<uint64>(maskPos,auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint16) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint16) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) { petauramask |= (uint64(1) << i); data << (uint16) petaura; data << (uint8) 1; } } data.put<uint64>(petMaskPos,petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
static bool HandleSpectateCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* player = handler->GetSession()->GetPlayer(); if (target == player || target_guid == player->GetGUID()) { handler->PSendSysMessage("Вы не можете смотреть на себя."); handler->SetSentErrorMessage(true); return false; } if (player->IsInCombat()) { handler->PSendSysMessage("Вы находитесь в Бою."); handler->SetSentErrorMessage(true); return false; } if (!target) { handler->PSendSysMessage("Цель не существует."); handler->SetSentErrorMessage(true); return false; } if (player->IsMounted()) { handler->PSendSysMessage("Не можете смотреть сидя верхом."); handler->SetSentErrorMessage(true); return false; } if (target && (target->HasAura(ARENA_PREPARATION) || target->HasAura(ARENA_PREPARATION_2))) { handler->PSendSysMessage("Не могу этого сделать. Арена не началась."); handler->SetSentErrorMessage(true); return false; } if (player->GetPet()) { handler->PSendSysMessage("Вы должны скрыть своего питомца."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattlegroundOrArena() && !player->isSpectator()) { handler->PSendSysMessage("Вы уже находитесь на поле битвы или арене."); handler->SetSentErrorMessage(true); return false; } Map* map = target->GetMap(); if (!map->IsBattleArena()) { handler->PSendSysMessage("Игрок не на арене."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattleground()) { handler->PSendSysMessage("Не могу сделать это, в то время как вы находитесь на поле боя."); handler->SetSentErrorMessage(true); return false; } // all's well, set bg id // when porting out from the bg, it will be reset to 0 player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!player->GetMap()->IsBattlegroundOrArena()) player->SetBattlegroundEntryPoint(); if (target->isSpectator()) { handler->PSendSysMessage("Не могу сделать этого. Ваша цель - зритель."); handler->SetSentErrorMessage(true); return false; } // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // search for two teams Battleground *bGround = target->GetBattleground(); if (bGround->isRated()) { uint32 slot = bGround->GetArenaType() - 2; if (bGround->GetArenaType() > 3) slot = 2; uint32 firstTeamID = target->GetArenaTeamId(slot); uint32 secondTeamID = 0; Player *firstTeamMember = target; Player *secondTeamMember = NULL; for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr) if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first)) { if (tmpPlayer->isSpectator()) continue; uint32 tmpID = tmpPlayer->GetArenaTeamId(slot); if (tmpID != firstTeamID && tmpID > 0) { secondTeamID = tmpID; secondTeamMember = tmpPlayer; break; } } if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember) { ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID); ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID); if (firstTeam && secondTeam) { handler->PSendSysMessage("Вы вошли на Арену."); handler->PSendSysMessage("Команды:"); handler->PSendSysMessage("%s - %s", firstTeam->GetName().c_str(), secondTeam->GetName().c_str()); handler->PSendSysMessage("%u(%u) - %u(%u)", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()), secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup())); } } } // to point to see at target with same orientation float x, y, z; target->GetContactPoint(player, x, y, z); player->TeleportTo(target->GetMapId(), x, y, z, player->GetAngle(target), TELE_TO_GM_MODE); player->SetPhaseMask(target->GetPhaseMask(), true); player->SetSpectate(true); target->GetBattleground()->AddSpectator(player->GetGUID()); return true; }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received opcode CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3 + 4 + 2); data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4 + 2 + 2 + 2 + 1 + 2 * 6 + 8 + 1 + 8); data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if (pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->GetPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint16(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint16(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); iCoordX = loc.coord_x; iCoordY = loc.coord_y; } else { // unknown player status. } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) { auramask |= (uint64(1) << i); data << uint16(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->GetPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint16(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint16(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) { petauramask |= (uint64(1) << i); data << uint16(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data ) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player *player = sObjectMgr.GetPlayer(guid); if(!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if(pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8(powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 aura = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aura); data << uint8(1); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petpowertype = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder for(uint8 i = 0; i < MAX_AURAS; ++i) { if(uint32 petaura = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(petaura); data << uint8(1); } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
void WorldSession::HandleLoadPetFromDBSecondCallback(LoadPetFromDBQueryHolder* holder) { if (!GetPlayer()) return; Player* owner = GetPlayer(); Pet* pet = owner->GetPet(); if (!pet) return; pet->_LoadAuras(holder->GetPreparedResult(PET_LOAD_QUERY_LOADAURAS), holder->GetDiffTime()); bool current = holder->GetCurrent(); uint32 summon_spell_id = pet->GetUInt32Value(UNIT_CREATED_BY_SPELL); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summon_spell_id); // CANT BE NULL bool is_temporary_summoned = spellInfo && spellInfo->GetDuration() > 0; // load action bar, if data broken will fill later by default spells. if (!is_temporary_summoned) { pet->_LoadSpells(holder->GetPreparedResult(PET_LOAD_QUERY_LOADSPELLS)); pet->InitTalentForLevel(); // re-init to check talent count pet->_LoadSpellCooldowns(holder->GetPreparedResult(PET_LOAD_QUERY_LOADSPELLCOOLDOWN)); pet->LearnPetPassives(); pet->InitLevelupSpellsForLevel(); pet->CastPetAuras(current); pet->GetCharmInfo()->LoadPetActionBar(holder->GetActionBar()); // action bar stored in already read string } pet->CleanupActionBar(); // remove unknown spells from action bar after load owner->PetSpellInitialize(); owner->SendTalentsInfoData(true); if (owner->GetGroup()) owner->SetGroupUpdateFlag(GROUP_UPDATE_PET); //set last used pet number (for use in BG's) if (owner->GetTypeId() == TYPEID_PLAYER && pet->isControlled() && !pet->isTemporarySummoned() && (pet->getPetType() == SUMMON_PET || pet->getPetType() == HUNTER_PET)) { owner->ToPlayer()->SetLastPetNumber(holder->GetPetNumber()); owner->SetLastPetSpell(pet->GetUInt32Value(UNIT_CREATED_BY_SPELL)); } if (pet->getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current { pet->SetPower(POWER_MANA, pet->GetMaxPower(POWER_MANA)); pet->SetHealth(pet->GetMaxHealth()); } else { if (!holder->GetSavedHealth() && pet->getPetType() == HUNTER_PET && pet->GetAsynchLoadType() != PET_LOAD_SUMMON_DEAD_PET) pet->setDeathState(JUST_DIED); else { pet->SetHealth(holder->GetSavedHealth() > pet->GetMaxHealth() ? pet->GetMaxHealth() : holder->GetSavedHealth()); pet->SetPower(POWER_MANA, holder->GetSavedMana() > pet->GetMaxPower(POWER_MANA) ? pet->GetMaxPower(POWER_MANA) : holder->GetSavedMana()); } } pet->SetLoading(false); owner->SetTemporaryUnsummonedPetNumber(0); // clear this only if pet is loaded successfuly // current if (current && owner->IsPetNeedBeTemporaryUnsummoned()) { owner->UnsummonPetTemporaryIfAny(); return; } pet->HandleAsynchLoadSucceed(); return; }
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Player* player = GetTarget()->ToPlayer(); if (player->GetPet()) player->CastSpell(player, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true); }
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket) { ObjectGuid guid; recvPacket >> guid; if(!GetPlayer()->duel) // ignore accept from duel-sender return; Player *pl = GetPlayer(); Player *plTarget = pl->duel->opponent; if(pl == pl->duel->initiator || !plTarget || pl == plTarget || pl->duel->startTime != 0 || plTarget->duel->startTime != 0) return; DEBUG_FILTER_LOG(LOG_FILTER_COMBAT, "WORLD: received CMSG_DUEL_ACCEPTED" ); DEBUG_FILTER_LOG(LOG_FILTER_COMBAT, "Player 1 is: %u (%s)", pl->GetGUIDLow(), pl->GetName()); DEBUG_FILTER_LOG(LOG_FILTER_COMBAT, "Player 2 is: %u (%s)", plTarget->GetGUIDLow(), plTarget->GetName()); time_t now = time(NULL); pl->duel->startTimer = now; plTarget->duel->startTimer = now; pl->SendDuelCountdown(3000); plTarget->SendDuelCountdown(3000); /** * Duel reset script * */ uint32 areaId = pl->GetAreaId(); if(sWorld.getConfig(CONFIG_BOOL_RESET_DUEL_AREA_ENABLED) && sWorld.IsAreaIdEnabledDuelReset(areaId)){ //remove arena cds pl->RemoveArenaSpellCooldowns(); plTarget->RemoveArenaSpellCooldowns(); //remove negative arena auras pl->RemoveArenaAuras(true); plTarget->RemoveArenaAuras(true); //set max mana and hp pl->SetHealth(pl->GetMaxHealth()); pl->SetPower(POWER_MANA, pl->GetMaxPower(POWER_MANA)); plTarget->SetHealth(plTarget->GetMaxHealth()); plTarget->SetPower(POWER_MANA, plTarget->GetMaxPower(POWER_MANA)); // set max hp, mana and remove buffs of players' pet if they have Pet* plPet = pl->GetPet(); if(plPet != NULL) { plPet->SetHealth(plPet->GetMaxHealth()); plPet->SetPower(plPet->getPowerType(), plPet->GetMaxPower(plPet->getPowerType())); plPet->RemoveArenaAuras(true); } Pet* plPetTarget = plTarget->GetPet(); if(plPetTarget != NULL) { plPetTarget->SetHealth(plPetTarget->GetMaxHealth()); plPetTarget->SetPower(plPetTarget->getPowerType(), plPetTarget->GetMaxPower(plPetTarget->getPowerType())); plPetTarget->RemoveArenaAuras(true); } } }
void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData) { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK"); #endif uint64 guid; recvData.readPackGUID(guid); uint32 flags, time; recvData >> flags >> time; // unused #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outStaticDebug("Guid " UI64FMTD, guid); #endif #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outStaticDebug("Flags %u, time %u", flags, time/IN_MILLISECONDS); #endif Player* plMover = _player->m_mover->ToPlayer(); if (!plMover || !plMover->IsBeingTeleportedNear()) return; if (guid != plMover->GetGUID()) return; plMover->SetSemaphoreTeleportNear(0); uint32 old_zone = plMover->GetZoneId(); WorldLocation const& dest = plMover->GetTeleportDest(); Position oldPos(*plMover); plMover->UpdatePosition(dest, true); // xinef: teleport pets if they are not unsummoned if (Pet* pet = plMover->GetPet()) { if (!pet->IsWithinDist3d(plMover, plMover->GetMap()->GetVisibilityRange()-5.0f)) pet->NearTeleportTo(plMover->GetPositionX(), plMover->GetPositionY(), plMover->GetPositionZ(), pet->GetOrientation()); } if (oldPos.GetExactDist2d(plMover) > 100.0f) { uint32 newzone, newarea; plMover->GetZoneAndAreaId(newzone, newarea, true); plMover->UpdateZone(newzone, newarea); // new zone if (old_zone != newzone) { // honorless target if (plMover->pvpInfo.IsHostile) plMover->CastSpell(plMover, 2479, true); // in friendly area else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) plMover->UpdatePvP(false, false); } } // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); //lets process all delayed operations on successful teleport GetPlayer()->ProcessDelayedOperations(); plMover->GetMotionMaster()->ReinitializeMovement(); // pussywizard: client forgets about losing control, resend it if (plMover->HasUnitState(UNIT_STATE_FLEEING|UNIT_STATE_CONFUSED) || plMover->IsCharmed()) // only in such cases SetClientControl(self, false) is sent plMover->SetClientControl(plMover, false, true); }
static bool HandleSpectateCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* player = handler->GetSession()->GetPlayer(); if (target == player || target_guid == player->GetGUID()) { handler->PSendSysMessage("You can't spectate yourself."); handler->SetSentErrorMessage(true); return false; } if (player->IsInCombat()) { handler->PSendSysMessage("You are in combat."); handler->SetSentErrorMessage(true); return false; } if (!target) { handler->PSendSysMessage("Target is not online or does not exist."); handler->SetSentErrorMessage(true); return false; } if (player->GetPet()) { handler->PSendSysMessage("You must hide your pet."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattlegroundOrArena() && !player->IsSpectator()) { handler->PSendSysMessage("You are already in a battleground or arena."); handler->SetSentErrorMessage(true); return false; } Map* cMap = target->GetMap(); if (!cMap->IsBattleArena()) { handler->PSendSysMessage("Player is not in an Arena match."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattleground()) { handler->PSendSysMessage("You can't do that while in a battleground."); handler->SetSentErrorMessage(true); return false; } if (target->HasAura(32728) || target->HasAura(32727)) { handler->PSendSysMessage("You can't do that. The Arena match didn't start yet."); handler->SetSentErrorMessage(true); return false; } if (target->IsSpectator()) { handler->PSendSysMessage("You can't do that. Your target is a spectator."); handler->SetSentErrorMessage(true); return false; } if (player->IsMounted()) { handler->PSendSysMessage("Cannot Spectate while mounted."); handler->SetSentErrorMessage(true); return false; } // all's well, set bg id // when porting out from the bg, it will be reset to 0 player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!player->GetMap()->IsBattlegroundOrArena()) player->SetBattlegroundEntryPoint(); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // search for two teams Battleground *bGround = target->GetBattleground(); if (bGround->isRated()) { uint32 slot = bGround->GetArenaType() - 2; if (bGround->GetArenaType() > 3) slot = 2; uint32 firstTeamID = target->GetArenaTeamId(slot); uint32 secondTeamID = 0; Player *firstTeamMember = target; Player *secondTeamMember = NULL; for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr) if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first)) { if (tmpPlayer->IsSpectator()) continue; uint32 tmpID = tmpPlayer->GetArenaTeamId(slot); if (tmpID != firstTeamID && tmpID > 0) { secondTeamID = tmpID; secondTeamMember = tmpPlayer; break; } } if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember) { ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID); ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID); if (firstTeam && secondTeam) { handler->PSendSysMessage("You entered a Rated Arena."); handler->PSendSysMessage("Teams:"); handler->PSendSysMessage("|cFFffffff%s|r vs |cFFffffff%s|r", firstTeam->GetName().c_str(), secondTeam->GetName().c_str()); handler->PSendSysMessage("|cFFffffff%u(%u)|r -- |cFFffffff%u(%u)|r", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()), secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup())); } } } // to point to see at target with same orientation float x, y, z; target->GetContactPoint(player, x, y, z); player->TeleportTo(target->GetMapId(), x, y, z, player->GetAngle(target), TELE_TO_GM_MODE); player->SetPhaseMask(target->GetPhaseMask(), true); player->SetSpectate(true); target->GetBattleground()->AddSpectator(player->GetGUID()); return true; }
// ================================================================================================================================================================================== bool ChatHandler::HandleFreezeCommand(char *args) { std::string name; Player* player; char* TargetName = strtok((char*)args, " "); //get entered #name if (!TargetName) //if no #name entered use target { player = getSelectedPlayer(); if (player) //prevent crash with creature as target { name = player->GetName(); normalizePlayerName(name); } } else // if #name entered { name = TargetName; normalizePlayerName(name); player = sObjectMgr.GetPlayer(name.c_str()); //get player by #name } //effect if ((player) && (!(player == m_session->GetPlayer()))) { PSendSysMessage(LANG_COMMAND_FREEZE, name.c_str()); //stop combat + unattackable + duel block + stop some spells player->setFaction(35); player->CombatStop(); if (player->IsNonMeleeSpellCasted(true)) player->InterruptNonMeleeSpells(true); player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); player->SetUInt32Value(PLAYER_DUEL_TEAM, 1); //if player class = hunter || warlock remove pet if alive if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) { if (Pet* pet = player->GetPet()) { pet->SavePetToDB(PET_SAVE_AS_CURRENT); // not let dismiss dead pet if (pet && pet->isAlive()) player->RemovePet(PET_SAVE_NOT_IN_SLOT); } } //stop movement and disable spells uint32 spellID = 9454; // uint32 spellID1 = 23775; // Stun Forever player->CastSpell(player, spellID, true); //save player player->SaveToDB(); } if (!player) { SendSysMessage(LANG_COMMAND_FREEZE_WRONG); return true; } if (player == m_session->GetPlayer()) { SendSysMessage(LANG_COMMAND_FREEZE_ERROR); return true; } return true; }
void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket) { uint64 guid; Player* player; Player* plTarget; recvPacket >> guid; if (!GetPlayer()->duel) // ignore accept from duel-sender return; player = GetPlayer(); plTarget = player->duel->opponent; if (player == player->duel->initiator || !plTarget || player == plTarget || player->duel->startTime != 0 || plTarget->duel->startTime != 0) return; //TC_LOG_DEBUG("network", "WORLD: Received CMSG_DUEL_ACCEPTED"); TC_LOG_DEBUG("network", "Player 1 is: %u (%s)", player->GetGUIDLow(), player->GetName().c_str()); TC_LOG_DEBUG("network", "Player 2 is: %u (%s)", plTarget->GetGUIDLow(), plTarget->GetName().c_str()); time_t now = time(NULL); player->duel->startTimer = now; plTarget->duel->startTimer = now; // Reiniciar Cooldowns, vida y mana en una zona especifica. if (player->GetAreaId() == 4570 || player->GetAreaId() == 14 || player->GetAreaId() == 12) { player->SetHealth(player->GetMaxHealth()); plTarget->SetHealth(plTarget->GetMaxHealth()); player->RemoveArenaSpellCooldowns(true); plTarget->RemoveArenaSpellCooldowns(true); // Debuffs player->RemoveAura(57723); player->RemoveAura(57724); player->RemoveAura(25771); player->RemoveAura(41425); player->RemoveAura(61987); player->RemoveAura(66233); player->RemoveAura(11196); player->RemoveAura(47986); plTarget->RemoveAura(57723); plTarget->RemoveAura(57724); plTarget->RemoveAura(25771); plTarget->RemoveAura(41425); plTarget->RemoveAura(61987); plTarget->RemoveAura(66233); plTarget->RemoveAura(11196); plTarget->RemoveAura(47986); if (player->getPowerType() == POWER_MANA) player->SetPower(POWER_MANA, player->GetMaxPower(POWER_MANA)); if (plTarget->getPowerType() == POWER_MANA) plTarget->SetPower(POWER_MANA, plTarget->GetMaxPower(POWER_MANA)); if (player->getPowerType() == POWER_RAGE) player->SetPower(POWER_RAGE, 0); if (plTarget->getPowerType() == POWER_RAGE) plTarget->SetPower(POWER_RAGE, 0); if (player->getPowerType() == POWER_RUNIC_POWER) player->SetPower(POWER_RUNIC_POWER, 0); if (plTarget->getPowerType() == POWER_RUNIC_POWER) plTarget->SetPower(POWER_RUNIC_POWER, 0); // Reset Pet Cooldown HP, Power, and Summon. if (player->getClass() == CLASS_HUNTER) player->CastSpell(player, 883, true); Pet* plPet = player->GetPet(); if(plPet != NULL) { if (plPet->isDead()) player->CastSpell(player, 35182, true); player->CastSpell(player, 982, true); player->RemoveAura(35182); plPet->SetHealth(plPet->GetMaxHealth()); plPet->SetPower(plPet->getPowerType(), plPet->GetMaxPower(plPet->getPowerType())); plPet->RemoveArenaAuras(); plPet->m_CreatureSpellCooldowns.clear(); plPet->RemoveAura(55711); } if (plTarget->getClass() == CLASS_HUNTER) plTarget->CastSpell(plTarget, 883, true); Pet* plPetTarget = plTarget->GetPet(); if(plPetTarget != NULL) { if (plPetTarget->isDead()) plTarget->CastSpell(plTarget, 35182, true); plTarget->CastSpell(plTarget, 982, true); plTarget->RemoveAura(35182); plPetTarget->SetHealth(plPetTarget->GetMaxHealth()); plPetTarget->SetPower(plPetTarget->getPowerType(), plPetTarget->GetMaxPower(plPetTarget->getPowerType())); plPetTarget->RemoveArenaAuras(); plPetTarget->m_CreatureSpellCooldowns.clear(); plPetTarget->RemoveAura(55711); } } player->SendDuelCountdown(3000); plTarget->SendDuelCountdown(3000); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid Guid; recvData >> Guid; Player* player = ObjectAccessor::FindConnectedPlayer(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << Guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auraMask = 0; size_t maskPos = data.wpos(); data << uint64(auraMask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); uint64 petAuraMask = 0; maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= uint64(1) << i; data << uint32(aurApp->GetBase()->GetId()); data << uint8(aurApp->GetFlags()); } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recvData >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = GROUP_UPDATE_FULL; // common mask, real flags used 0x000040BFF if (!pet) mask1 &= ~GROUP_UPDATE_PET; // for hunters and other classes with pets, real flags used 0x7FFFFFFF Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; // GROUP_UPDATE_FLAG_AURAS // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. data << uint8(0); size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // if true client clears auras that are not covered by auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; // GROUP_UPDATE_FLAG_PET_AURAS // if true client clears auras that are not covered by auramask // TODO: looks like now client requires all active auras to be in the beginning of the auramask // e.g. if you have holes in the aura mask the values after are ignored. data << uint8(0); size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder data << uint32(MAX_AURAS); // client reads (64) Bits from auramask for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint8(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS data << uint32(0); } SendPacket(&data); }
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { Player* player = GetTarget()->ToPlayer(); if (Pet* pet = player->GetPet()) pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET); }
void UpdateAI(const uint32 uiDiff) { if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; /** Techniques changes depending on the distance of his target */ if (m_creature->GetDistance2d(m_creature->getVictim()) > 8.0f && m_creature->GetDistance2d(m_creature->getVictim()) < 25.0f) { m_creature->addUnitState(UNIT_STAT_ROOT); m_bIsOutOfRange = true; } else { m_creature->clearUnitState(UNIT_STAT_ROOT); m_bIsOutOfRange = false; } /* A druid in changeform is also condisered as a pet. * * Source : "Apparently, he is impossible to tank as a bear. * I got feared by his Flash Bomb attack four times over the * course of the fight - each time for a full 9 seconds."*/ if (m_uiFlashBomb_Timer < uiDiff) { m_bIsBombLaunched = false; Map* pMap = m_creature->GetMap(); if (!pMap) return; Map::PlayerList const &PlayerList = pMap->GetPlayers(); for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end() && !m_bIsBombLaunched; ++itr) { Player* pPlayer = itr->getSource(); if(!pPlayer) continue; Unit* pPet = pPlayer->GetPet(); /** Range limit set to 35 meters/yards */ if (pPlayer->IsInFeralForm() && m_creature->GetDistance2d(pPlayer) < 35.0f) { if (DoCastSpellIfCan(pPlayer, SPELL_FLASH_BOMB) == CAST_OK) m_uiFlashBomb_Timer = 7500; m_bIsBombLaunched = true; } else if (pPet && m_creature->GetDistance2d(pPet) < 35.0f) { if (DoCastSpellIfCan(pPet, SPELL_FLASH_BOMB) == CAST_OK) m_uiFlashBomb_Timer = 7500; m_bIsBombLaunched = true; } } } else m_uiFlashBomb_Timer -= uiDiff; switch (m_bIsOutOfRange) { case 0: if (m_uiGoblinDragonGun_Timer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_GOBLIN_DRAGON_GUN) == CAST_OK) m_uiGoblinDragonGun_Timer = urand(7500, 10000); } else m_uiGoblinDragonGun_Timer -= uiDiff; break; case 1: /** Launch a Bomb on random target */ if (m_uiBomb_Timer < uiDiff) { Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0); if (target) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_BOMB); m_uiBomb_Timer = 7500; } } else m_uiBomb_Timer -= uiDiff; if (m_uiShoot_Timer < uiDiff) { if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOOT) == CAST_OK) m_uiShoot_Timer = 3000; } else m_uiShoot_Timer -= uiDiff; break; } DoMeleeAttackIfReady(); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recv_data) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 Guid; recv_data >> Guid; Player* player = HashMapHolder<Player>::Find(Guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(Guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet *pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = 0x00040BFF; // common mask, real flags used 0x000040BFF if (pet) mask1 = 0x7FFFFFFF; // for hunters and other classes with pets Powers powerType = player->getPowerType(); data << (uint32) mask1; // group update mask data << (uint16) MEMBER_STATUS_ONLINE; // member's online status data << (uint32) player->GetHealth(); // GROUP_UPDATE_FLAG_CUR_HP data << (uint32) player->GetMaxHealth(); // GROUP_UPDATE_FLAG_MAX_HP data << (uint8) powerType; // GROUP_UPDATE_FLAG_POWER_TYPE data << (uint16) player->GetPower(powerType); // GROUP_UPDATE_FLAG_CUR_POWER data << (uint16) player->GetMaxPower(powerType); // GROUP_UPDATE_FLAG_MAX_POWER data << (uint16) player->getLevel(); // GROUP_UPDATE_FLAG_LEVEL data << (uint16) player->GetZoneId(); // GROUP_UPDATE_FLAG_ZONE data << (uint16) player->GetPositionX(); // GROUP_UPDATE_FLAG_POSITION data << (uint16) player->GetPositionY(); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << (uint64) auramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << (uint32) aurApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << (uint64) pet->GetGUID(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << (uint16) pet->GetDisplayId(); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << (uint32) pet->GetHealth(); // GROUP_UPDATE_FLAG_PET_CUR_HP data << (uint32) pet->GetMaxHealth(); // GROUP_UPDATE_FLAG_PET_MAX_HP data << (uint8) petpowertype; // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << (uint16) pet->GetPower(petpowertype); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << (uint16) pet->GetMaxPower(petpowertype); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << (uint64) petauramask; // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication * auraApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << (uint32) auraApp->GetBase()->GetId(); data << (uint8) 1; } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << (uint8) 0; // GROUP_UPDATE_FLAG_PET_NAME data << (uint64) 0; // GROUP_UPDATE_FLAG_PET_AURAS } SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 guid; recvData >> guid; Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(guid); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); std::set<uint16> phaseIds = player->GetPhaseIds(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; if (!phaseIds.empty()) updateFlags |= GROUP_UPDATE_FLAG_PHASE; uint16 playerStatus = MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->IsAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->IsFFAPvP()) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID) data << uint64(pet->GetGUID()); data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP) data << uint32(pet->GetHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP) data << uint32(pet->GetMaxHealth()); if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE) data << (uint8)pet->getPowerType(); if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER) data << uint16(pet->GetPower(pet->getPowerType())); if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER) data << uint16(pet->GetMaxPower(pet->getPowerType())); // GROUP_UPDATE_FLAG_PET_AURAS uint64 petAuraMask = 0; data << uint8(1); maskPos = data.wpos(); data << uint64(petAuraMask); // placeholder data << uint32(MAX_AURAS); // count if (pet) { for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petAuraMask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } } data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]); if (updateFlags & GROUP_UPDATE_FLAG_PHASE) { data << uint32(phaseIds.empty() ? 8 : 0); data << uint32(phaseIds.size()); for (std::set<uint16>::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr) data << uint16(*itr); } SendPacket(&data); }
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); uint64 guid; recvData >> guid; Player* player = HashMapHolder<Player>::Find(guid); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.appendPackGUID(guid); data << (uint32) GROUP_UPDATE_FLAG_STATUS; data << (uint16) MEMBER_STATUS_OFFLINE; SendPacket(&data); return; } Pet* pet = player->GetPet(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data.append(player->GetPackGUID()); uint32 mask1 = GROUP_UPDATE_FULL; if (!pet) mask1 &= ~GROUP_UPDATE_PET; Powers powerType = player->getPowerType(); data << uint32(mask1); // group update mask data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION // GROUP_UPDATE_FLAG_AURAS data << uint8(1); uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if (pet) { Powers petpowertype = pet->getPowerType(); data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER // GROUP_UPDATE_FLAG_PET_AURAS data << uint8(1); uint64 petauramask = 0; size_t petMaskPos = data.wpos(); data << uint64(petauramask); // placeholder data << uint32(MAX_AURAS); // count for (uint8 i = 0; i < MAX_AURAS; ++i) { if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) { petauramask |= (uint64(1) << i); data << uint32(aurApp->GetBase()->GetId()); data << uint16(aurApp->GetFlags()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i)) data << int32(eff->GetAmount()); else data << int32(0); } } } } data.put<uint64>(petMaskPos, petauramask); // GROUP_UPDATE_FLAG_PET_AURAS } // else not needed, flags do not include any PET_ update // GROUP_UPDATE_FLAG_PHASE data << uint32(8); // either 0 or 8, same unk found in SMSG_PHASESHIFT data << uint32(0); // count // for (count) *data << uint16(phaseId) SendPacket(&data); }
static bool HandleSpectateCommand(ChatHandler* handler, char const* args) { Player* target; ObjectGuid target_guid; std::string target_name; if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; Player* player = handler->GetSession()->GetPlayer(); if (target == player || target_guid == player->GetGUID()) { handler->PSendSysMessage("你不能观察你自己."); handler->SetSentErrorMessage(true); return false; } if (player->IsInCombat()) { handler->PSendSysMessage("你在战斗状态."); handler->SetSentErrorMessage(true); return false; } if (!target) { handler->PSendSysMessage("目标不在线或不存在."); handler->SetSentErrorMessage(true); return false; } if (player->GetPet()) { handler->PSendSysMessage("你必须先解散你的宠物."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattlegroundOrArena() && !player->IsSpectator()) { handler->PSendSysMessage("你已经在战场或者竞技场了."); handler->SetSentErrorMessage(true); return false; } Map* cMap = target->GetMap(); if (!cMap->IsBattleArena()) { handler->PSendSysMessage("玩家还不在竞技场里."); handler->SetSentErrorMessage(true); return false; } if (player->GetMap()->IsBattleground()) { handler->PSendSysMessage("你在战场里不能同时观察."); handler->SetSentErrorMessage(true); return false; } if (target->HasAura(32728) || target->HasAura(32727)) { handler->PSendSysMessage("你还不能观察,竞技场还没有开始."); handler->SetSentErrorMessage(true); return false; } if (target->IsSpectator()) { handler->PSendSysMessage("不能进入,目标在观察状态."); handler->SetSentErrorMessage(true); return false; } if (player->IsMounted()) { handler->PSendSysMessage("不能在有坐骑的情况下观察."); handler->SetSentErrorMessage(true); return false; } // all's well, set bg id // when porting out from the bg, it will be reset to 0 player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); // remember current position as entry point for return at bg end teleportation if (!player->GetMap()->IsBattlegroundOrArena()) player->SetBattlegroundEntryPoint(); // stop flight if need if (player->IsInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); // search for two teams Battleground *bGround = target->GetBattleground(); if (bGround->isRated()) { uint32 slot = bGround->GetArenaType() - 2; if (bGround->GetArenaType() > 3) slot = 2; uint32 firstTeamID = target->GetArenaTeamId(slot); uint32 secondTeamID = 0; Player *firstTeamMember = target; Player *secondTeamMember = NULL; for (Battleground::BattlegroundPlayerMap::const_iterator itr = bGround->GetPlayers().begin(); itr != bGround->GetPlayers().end(); ++itr) if (Player* tmpPlayer = ObjectAccessor::FindPlayer(itr->first)) { if (tmpPlayer->IsSpectator()) continue; uint32 tmpID = tmpPlayer->GetArenaTeamId(slot); if (tmpID != firstTeamID && tmpID > 0) { secondTeamID = tmpID; secondTeamMember = tmpPlayer; break; } } if (firstTeamID > 0 && secondTeamID > 0 && secondTeamMember) { ArenaTeam *firstTeam = sArenaTeamMgr->GetArenaTeamById(firstTeamID); ArenaTeam *secondTeam = sArenaTeamMgr->GetArenaTeamById(secondTeamID); if (firstTeam && secondTeam) { handler->PSendSysMessage("你进入了竞技场积分赛."); handler->PSendSysMessage("队伍:"); handler->PSendSysMessage("|cFFffffff%s|r vs |cFFffffff%s|r", firstTeam->GetName().c_str(), secondTeam->GetName().c_str()); handler->PSendSysMessage("|cFFffffff%u(%u)|r -- |cFFffffff%u(%u)|r", firstTeam->GetRating(), firstTeam->GetAverageMMR(firstTeamMember->GetGroup()), secondTeam->GetRating(), secondTeam->GetAverageMMR(secondTeamMember->GetGroup())); } } } // to point to see at target with same orientation float x, y, z; target->GetContactPoint(player, x, y, z); player->TeleportTo(target->GetMapId(), x, y, z, player->GetAngle(target), TELE_TO_GM_MODE); player->SetPhaseMask(target->GetPhaseMask(), true); player->SetSpectate(true); target->GetBattleground()->AddSpectator(player->GetGUID()); return true; }
static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/) { Player* player = handler->GetSession()->GetPlayer(); Pet* pet = player->GetPet(); if (!pet) { handler->SendSysMessage(LANG_NO_PET_FOUND); handler->SetSentErrorMessage(true); return false; } CreatureTemplate const* creatureInfo = pet->GetCreatureTemplate(); if (!creatureInfo) { handler->SendSysMessage(LANG_WRONG_PET_TYPE); handler->SetSentErrorMessage(true); return false; } CreatureFamilyEntry const* petFamily = sCreatureFamilyStore.LookupEntry(creatureInfo->family); if (!petFamily) { handler->SendSysMessage(LANG_WRONG_PET_TYPE); handler->SetSentErrorMessage(true); return false; } if (petFamily->petTalentType < 0) // not hunter pet { handler->SendSysMessage(LANG_WRONG_PET_TYPE); handler->SetSentErrorMessage(true); return false; } for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); if (!talentInfo) continue; TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); if (!talentTabInfo) continue; // prevent learn talent for different family (cheating) if (((1 << petFamily->petTalentType) & talentTabInfo->petTalentMask) == 0) continue; // search highest talent rank uint32 spellId = 0; for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank) { if (talentInfo->RankID[rank] != 0) { spellId = talentInfo->RankID[rank]; break; } } if (!spellId) // ??? none spells in talent continue; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false)) continue; // learn highest rank of talent and learn all non-talent spell ranks (recursive by tree) pet->learnSpellHighRank(spellId); } pet->SetFreeTalentPoints(0); handler->SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS); return true; }
// this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS"); ObjectGuid guid; recv_data >> guid; Player* player = ObjectAccessor::FindPlayer(guid, false); if (!player) { WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 1 + 8 + 4 + 2); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << guid.WriteAsPacked(); data << uint32(GROUP_UPDATE_FLAG_STATUS); data << uint16(MEMBER_STATUS_OFFLINE); SendPacket(&data); return; } Powers powerType = player->getPowerType(); uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS; if (powerType != POWER_MANA) updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE; Pet* pet = player->GetPet(); if (pet) updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER; if (player->GetVehicle()) updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT; uint16 playerStatus = player->IsReferAFriendLinked(player) ? (MEMBER_STATUS_ONLINE | MEMBER_STATUS_RAF) : MEMBER_STATUS_ONLINE; if (player->IsPvP()) playerStatus |= MEMBER_STATUS_PVP; if (!player->isAlive()) { if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) playerStatus |= MEMBER_STATUS_GHOST; else playerStatus |= MEMBER_STATUS_DEAD; } if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP)) playerStatus |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) playerStatus |= MEMBER_STATUS_AFK; if (player->isDND()) playerStatus |= MEMBER_STATUS_DND; WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 255); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related data << player->GetPackGUID(); data << uint32(updateFlags); data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE) data << uint8(powerType); data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL // verify player coordinates and zoneid to send to teammates uint16 iZoneId = 0; uint16 iCoordX = 0; uint16 iCoordY = 0; if (player->IsInWorld()) { iZoneId = player->GetZoneId(); iCoordX = player->GetPositionX(); iCoordY = player->GetPositionY(); } else if (player->IsBeingTeleported()) // Player is in teleportation { WorldLocation& loc = player->GetTeleportDest(); // So take teleportation destination iZoneId = sTerrainMgr.GetZoneId(loc.GetMapId(), loc.x, loc.y, loc.z); iCoordX = loc.x; iCoordY = loc.y; } data << uint16(iZoneId); // GROUP_UPDATE_FLAG_ZONE data << uint16(iCoordX); // GROUP_UPDATE_FLAG_POSITION data << uint16(iCoordY); // GROUP_UPDATE_FLAG_POSITION uint64 auramask = 0; size_t maskPos = data.wpos(); data << uint64(auramask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolderPtr holder = player->GetVisibleAura(i)) { auramask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint8(holder->GetAuraFlags()); } } data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS if(pet) { Powers petPowerType = pet->getPowerType(); data << pet->GetObjectGuid(); // GROUP_UPDATE_FLAG_PET_GUID data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP data << uint8(petPowerType); // GROUP_UPDATE_FLAG_PET_POWER_TYPE data << uint16(pet->GetPower(petPowerType)); // GROUP_UPDATE_FLAG_PET_CUR_POWER data << uint16(pet->GetMaxPower(petPowerType)); // GROUP_UPDATE_FLAG_PET_MAX_POWER uint64 petAuraMask = 0; size_t petMaskPos = data.wpos(); data << uint64(petAuraMask); // placeholder for (uint8 i = 0; i < MAX_AURAS; ++i) { if (SpellAuraHolderPtr holder = pet->GetVisibleAura(i)) { petAuraMask |= (uint64(1) << i); data << uint32(holder->GetId()); data << uint8(holder->GetAuraFlags()); } } data.put<uint64>(petMaskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS } else { data << uint8(0); // GROUP_UPDATE_FLAG_PET_NAME data << uint16(0); // GROUP_UPDATE_FLAG_PET_MODEL_ID data << uint64(0); // GROUP_UPDATE_FLAG_PET_AURAS } if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT) data << uint32(player->m_movementInfo.GetTransportDBCSeat()); SendPacket(&data); }