void WorldSession::HandlePetAction(WorldPacket & recvData) { uint64 guid1; uint32 data; uint64 guid2; recvData >> guid1; //pet guid recvData >> data; recvData >> guid2; //tag guid uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 // used also for charmed creature Unit* pet= ObjectAccessor::GetUnit(*_player, guid1); ;//sLog->outDetail("HandlePetAction: Pet %u - flag: %u, spellid: %u, target: %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2))); if (!pet) { sLog->outError("HandlePetAction: Pet (GUID: %u) doesn't exist for player '%s'", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str()); return; } if (pet != GetPlayer()->GetFirstControlled()) { sLog->outError("HandlePetAction: Pet (GUID: %u) does not belong to player '%s'", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str()); return; } if (!pet->IsAlive()) { // xinef: allow dissmis dead pets SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellid) : NULL; if ((flag != ACT_COMMAND || spellid != COMMAND_ABANDON) && (!spell || !spell->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD))) return; } // Xinef: allow to controll players if (pet->GetTypeId() == TYPEID_PLAYER && flag != ACT_COMMAND && flag != ACT_REACTION) return; if (GetPlayer()->m_Controlled.size() == 1) HandlePetActionHelper(pet, guid1, spellid, flag, guid2); else { //If a pet is dismissed, m_Controlled will change std::vector<Unit*> controlled; for (Unit::ControlSet::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) { // xinef: allow to dissmis dead pets if ((*itr)->GetEntry() == pet->GetEntry() && ((*itr)->IsAlive() || (flag == ACT_COMMAND && spellid == COMMAND_ABANDON))) controlled.push_back(*itr); // xinef: mirror image blizzard crappness else if ((*itr)->GetEntry() == NPC_MIRROR_IMAGE && flag == ACT_COMMAND && spellid == COMMAND_FOLLOW) { (*itr)->InterruptNonMeleeSpells(false); } } for (std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr) HandlePetActionHelper(*itr, guid1, spellid, flag, guid2); } }
void WorldSession::HandlePetAction(WorldPacket & recv_data) { uint64 guid1; uint32 data; uint64 guid2; recv_data >> guid1; //pet guid recv_data >> data; recv_data >> guid2; //tag guid uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 Unit* pet= ObjectAccessor::GetUnit(*_player, guid1); float pos_x = pet->GetPositionX(); float pos_y = pet->GetPositionY(); float pos_z = pet->GetPositionZ(); recv_data >> pos_x; // 4.0.3, x recv_data >> pos_y; // 4.0.3, y recv_data >> pos_z; // 4.0.3, z // used also for charmed creature sLog->outDetail("HandlePetAction: Pet %u - flag: %u, spellid: %u, target: %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2))); if (!pet) { sLog->outError("Pet %u not exist.", uint32(GUID_LOPART(guid1))); return; } if (pet != GetPlayer()->GetFirstControlled()) { sLog->outError("HandlePetAction.Pet %u isn't pet of player %s.", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName()); return; } if (!pet->isAlive()) { SpellEntry const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellStore.LookupEntry(spellid) : NULL; if (!spell) return; if (!(spell->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD)) return; } //TODO: allow control charmed player? if (pet->GetTypeId() == TYPEID_PLAYER && !(flag == ACT_COMMAND && spellid == COMMAND_ATTACK)) return; if (GetPlayer()->m_Controlled.size() == 1) HandlePetActionHelper(pet, guid1, spellid, flag, guid2); else { //If a pet is dismissed, m_Controlled will change std::vector<Unit*> controlled; for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) if ((*itr)->GetEntry() == pet->GetEntry() && (*itr)->isAlive()) controlled.push_back(*itr); for (std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr) HandlePetActionHelper(*itr, guid1, spellid, flag, guid2); } }
void WorldSession::HandlePetAction(WorldPacket & recvData) { ObjectGuid guid1; ObjectGuid guid2; uint32 data; float x, y, z; recvData >> data; // Position recvData >> x; recvData >> z; recvData >> y; recvData.ReadBitSeq<0, 2, 6, 1>(guid1); recvData.ReadBitSeq<6, 4, 0, 1, 3>(guid2); recvData.ReadBitSeq<3>(guid1); recvData.ReadBitSeq<2>(guid2); recvData.ReadBitSeq<4>(guid1); recvData.ReadBitSeq<5, 7>(guid2); recvData.ReadBitSeq<5, 7>(guid1); recvData.ReadByteSeq<7>(guid2); recvData.ReadByteSeq<7>(guid1); recvData.ReadByteSeq<6, 0, 3>(guid2); recvData.ReadByteSeq<1>(guid1); recvData.ReadByteSeq<2, 1>(guid2); recvData.ReadByteSeq<2, 5, 6, 0, 3>(guid1); recvData.ReadByteSeq<4, 5>(guid2); recvData.ReadByteSeq<4>(guid1); uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 // used also for charmed creature Unit* pet= ObjectAccessor::GetUnit(*_player, guid1); TC_LOG_INFO("network", "HandlePetAction: Pet %u - flag: %u, spellid: %u, target: %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2))); if (!pet) { TC_LOG_ERROR("network", "HandlePetAction: Pet (GUID: %u) doesn't exist for player '%s'", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str()); return; } if (pet != GetPlayer()->GetFirstControlled()) { TC_LOG_ERROR("network", "HandlePetAction: Pet (GUID: %u) does not belong to player '%s'", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str()); return; } if (!pet->IsAlive()) { SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellid) : NULL; if (!spell) return; if (!(spell->Attributes & SPELL_ATTR0_CASTABLE_WHILE_DEAD)) return; } //TODO: allow control charmed player? if (pet->GetTypeId() == TYPEID_PLAYER && !(flag == ACT_COMMAND && spellid == COMMAND_ATTACK)) return; if (GetPlayer()->m_Controlled.size() == 1) HandlePetActionHelper(pet, guid1, spellid, flag, guid2, x, y ,z); else { //If a pet is dismissed, m_Controlled will change std::vector<Unit*> controlled; for (Unit::ControlList::iterator itr = GetPlayer()->m_Controlled.begin(); itr != GetPlayer()->m_Controlled.end(); ++itr) if ((*itr)->GetEntry() == pet->GetEntry() && (*itr)->IsAlive()) controlled.push_back(*itr); for (std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr) HandlePetActionHelper(*itr, guid1, spellid, flag, guid2, x, y, z); } }