void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data) { uint32 mask = player->GetGroupUpdateFlag(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); uint32 byteCount = 0; for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i) if (mask & (1 << i)) byteCount += GroupUpdateLength[i]; data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount); *data << player->GetPackGUID(); *data << uint32(mask); if (mask & GROUP_UPDATE_FLAG_STATUS) { if (player->IsPvP()) *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP); else *data << uint16(MEMBER_STATUS_ONLINE); } if (mask & GROUP_UPDATE_FLAG_CUR_HP) *data << (uint16) player->GetHealth(); if (mask & GROUP_UPDATE_FLAG_MAX_HP) *data << (uint16) player->GetMaxHealth(); Powers powerType = player->GetPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) *data << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) *data << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) *data << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) *data << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) *data << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_POSITION) *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()); if (mask & GROUP_UPDATE_FLAG_AURAS) { const uint64& auramask = player->GetAuraUpdateMask(); *data << uint64(auramask); for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { *data << uint16(player->GetUInt32Value(UNIT_FIELD_AURA + i)); *data << uint8(1); } } } Pet* pet = player->GetPet(); if (mask & GROUP_UPDATE_FLAG_PET_GUID) *data << (pet ? pet->GetObjectGuid() : ObjectGuid()); if (mask & GROUP_UPDATE_FLAG_PET_NAME) { if (pet) *data << pet->GetName(); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if (pet) *data << uint16(pet->GetDisplayId()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if (pet) *data << uint16(pet->GetHealth()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if (pet) *data << uint16(pet->GetMaxHealth()); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if (pet) *data << uint8(pet->GetPowerType()); else *data << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if (pet) *data << uint16(pet->GetPower(pet->GetPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if (pet) *data << uint16(pet->GetMaxPower(pet->GetPowerType())); else *data << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if (pet) { const uint64& auramask = pet->GetAuraUpdateMask(); *data << uint64(auramask); for (uint32 i = 0; i < MAX_AURAS; ++i) { if (auramask & (uint64(1) << i)) { *data << uint16(pet->GetUInt32Value(UNIT_FIELD_AURA + i)); *data << uint8(1); } } } else *data << uint64(0); } }
/*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) { sLog.outDebug("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.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 << 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); }
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 WorldSession::HandleStableSwapPet( WorldPacket & recv_data ) { sLog.outDetail("WORLD: Recv CMSG_STABLE_SWAP_PET."); uint64 npcGUID; uint32 pet_number; recv_data >> npcGUID >> pet_number; if(!GetPlayer()->isAlive()) return; Creature *unit = ObjectAccessor::Instance().GetCreature(*_player, npcGUID); if (!unit) { sLog.outDebug( "WORLD: CMSG_STABLE_SWAP_PET - NO SUCH UNIT! (GUID: %u)", uint32(GUID_LOPART(npcGUID)) ); return; } if( unit->IsHostileTo(_player)) // do not talk with enemies return; WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size Pet* pet = _player->GetPet(); if(!pet) return; if(!pet->GetUInt32Value(UNIT_FIELD_PETNUMBER)) return; QueryResult *result; result = sDatabase.PQuery("SELECT `owner`,`slot`,`petnumber`,`entry`,`level`,`loyalty`,`trainpoint` FROM `character_stable` WHERE `owner` = '%u' AND `petnumber` = '%u'",_player->GetGUIDLow(),pet_number); if(!result) { delete result; return; } Field *fields = result->Fetch(); uint32 slot = fields[1].GetUInt32(); uint32 petentry = fields[3].GetUInt32(); delete result; // move alive pet to slot if(pet->isAlive()) { sDatabase.BeginTransaction(); sDatabase.PExecute("DELETE FROM `character_stable` WHERE `owner` = '%u' AND `slot` = '%u'", _player->GetGUIDLow(),slot); sDatabase.PExecute("INSERT INTO `character_stable` (`owner`,`slot`,`petnumber`,`entry`,`level`,`loyalty`,`trainpoint`) VALUES (%u,%u,%u,%u,%u,%u,%u)", _player->GetGUIDLow(),slot,pet->GetUInt32Value(UNIT_FIELD_PETNUMBER),pet->GetEntry(),pet->getLevel(),pet->getloyalty(),pet->getUsedTrainPoint()); sDatabase.CommitTransaction(); _player->RemovePet(pet,PET_SAVE_AS_STORED); } // delele dead pet and free slot else { sDatabase.PExecute("UPDATE `character_stable` SET `petnumber` = '0',`entry` = '0',`level` = '0',`loyalty` = '0',`trainpoint` = '0' WHERE `owner` = '%u' AND `slot` = '%u'",_player->GetGUIDLow(), slot); _player->RemovePet(pet,PET_SAVE_AS_DELETED); } // summon unstabled pet Pet *newpet = new Pet(_player->getClass()==CLASS_HUNTER?HUNTER_PET:SUMMON_PET); if(!newpet->LoadPetFromDB(_player,petentry)) { delete newpet; data << uint8(0x06); } else data << uint8(0x09); SendPacket(&data); }
void WorldSession::HandleStablePet( WorldPacket & recv_data ) { sLog.outDetail("WORLD: Recv CMSG_STABLE_PET not dispose."); uint64 npcGUID; recv_data >> npcGUID; if(!GetPlayer()->isAlive()) return; Creature *unit = ObjectAccessor::Instance().GetCreature(*_player, npcGUID); if (!unit) { sLog.outDebug( "WORLD: CMSG_STABLE_PET - NO SUCH UNIT! (GUID: %u)", uint32(GUID_LOPART(npcGUID)) ); return; } if( unit->IsHostileTo(_player)) // do not talk with enemies return; Pet *pet = _player->GetPet(); WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size // can't place in stable dead pet if(!pet||!pet->isAlive()) { data << uint8(0x06); SendPacket(&data); return; } if(!pet->GetUInt32Value(UNIT_FIELD_PETNUMBER)) return; QueryResult *result; bool flag = false; result = sDatabase.PQuery("SELECT `owner`,`slot`,`petnumber` FROM `character_stable` WHERE `owner` = '%u' ORDER BY `slot` ",_player->GetGUIDLow()); if(result) { do { Field *fields = result->Fetch(); uint32 slot = fields[1].GetUInt32(); if(fields[2].GetUInt32()) continue; else if(pet->GetUInt32Value(UNIT_FIELD_PETNUMBER) == fields[2].GetUInt32()) break; else if( slot == 1 || slot == 2) { sDatabase.BeginTransaction(); sDatabase.PExecute("DELETE FROM `character_stable` WHERE `owner` = '%u' AND `slot` = '%u'", _player->GetGUIDLow(),slot); sDatabase.PExecute("INSERT INTO `character_stable` (`owner`,`slot`,`petnumber`,`entry`,`level`,`loyalty`,`trainpoint`) VALUES (%u,%u,%u,%u,%u,%u,%u)", _player->GetGUIDLow(),slot,pet->GetUInt32Value(UNIT_FIELD_PETNUMBER),pet->GetEntry(),pet->getLevel(),pet->getloyalty(),pet->getUsedTrainPoint()); sDatabase.CommitTransaction(); data << uint8(0x08); flag = true; _player->RemovePet(pet,PET_SAVE_AS_STORED); break; } }while( result->NextRow() ); } delete result; if(!flag) data << uint8(0x06); SendPacket(&data); }
void WorldSession::SendStablePet(uint64 guid ) { sLog.outDetail("WORLD: Recv MSG_LIST_STABLED_PETS Send."); WorldPacket data(MSG_LIST_STABLED_PETS, 200); // guess size data << uint64 ( guid ); QueryResult *result,*result_1; uint8 max_slot = 0; uint8 num = 0; result_1 = sDatabase.PQuery("SELECT `slot`,`petnumber` FROM `character_stable` WHERE `owner` = '%u'",_player->GetGUIDLow()); if(result_1) { do { Field *fields = result_1->Fetch(); uint8 cur_slot = fields[0].GetUInt32(); if(max_slot < cur_slot) max_slot = cur_slot; if(fields[1].GetUInt32()) num++; }while( result_1->NextRow() ); } delete result_1; Pet *pet = _player->GetPet(); // count only alive pet if(pet && pet->isAlive()) num++; data << uint8(num) << uint8(max_slot); // not let move dead pet in slot if(pet && pet->isAlive()) { if(!pet->GetUInt32Value(UNIT_FIELD_PETNUMBER)) return; // petnumber data << uint32(pet->GetUInt32Value(UNIT_FIELD_PETNUMBER)); data << uint32(pet->GetEntry()); data << uint32(pet->getLevel()); //data << cinfo->Name; // petname data << uint8(0x00); data << uint32(pet->getloyalty()); // loyalty data << uint8(0x01); // slot } result = sDatabase.PQuery("SELECT `owner`,`slot`,`petnumber`,`entry`,`level`,`loyalty`,`trainpoint` FROM `character_stable` WHERE `owner` = '%u'",_player->GetGUIDLow()); if(result) { do { Field *fields = result->Fetch(); uint32 petentry = fields[3].GetUInt32(); if(petentry) { CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(petentry); data << uint32(fields[2].GetUInt32()); // petnumber data << uint32(petentry); data << uint32(fields[4].GetUInt32()); data << cinfo->Name; data << uint32(fields[5].GetUInt32()); // loyalty data << uint8(fields[1].GetUInt32()+1); // slot } }while( result->NextRow() ); } delete result; SendPacket(&data); }