示例#1
0
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);
    }
}
示例#2
0
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);
    }
}
示例#3
0
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);
    }
}