Esempio n. 1
0
void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
{
    sLog.outDetail("CMSG_PET_UNLEARN");
    uint64 guid;
    recvPacket >> guid;                 // Pet guid

    Pet* pet = _player->GetPet();

    if(!pet || pet->getPetType() != HUNTER_PET || pet->m_usedTalentCount == 0)
        return;

    if(guid != pet->GetGUID())
    {
        sLog.outError( "HandlePetUnlearnOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
        return;
    }

    CharmInfo *charmInfo = pet->GetCharmInfo();
    if(!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetUnlearnOpcode: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId());
        return;
    }
    pet->resetTalents();
    _player->SendTalentsInfoData(true);
}
Esempio n. 2
0
void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
{
    DETAIL_LOG("CMSG_PET_UNLEARN");

    ObjectGuid guid;
    recvPacket >> guid;                 // Pet guid

    Pet* pet = _player->GetPet();

    if (!pet || guid != pet->GetObjectGuid())
    {
        sLog.outError("HandlePetUnlearnOpcode. %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
        return;
    }

    if (pet->getPetType() != HUNTER_PET || pet->m_usedTalentCount == 0)
        return;

    CharmInfo* charmInfo = pet->GetCharmInfo();
    if (!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetUnlearnOpcode: %s is considered pet-like but doesn't have a charminfo!", pet->GetGuidStr().c_str());
        return;
    }
    pet->resetTalents();
    _player->SendTalentsInfoData(true);
}
Esempio n. 3
0
void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
{
    CHECK_PACKET_SIZE(recvPacket,8);

    sLog.outDetail("CMSG_PET_UNLEARN");
    uint64 guid;
    recvPacket >> guid;

    Pet* pet = _player->GetPet();

    if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1)
        return;

    if(guid != pet->GetGUID())
    {
        sLog.outError( "HandlePetUnlearnOpcode.Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
        return;
    }

    CharmInfo *charmInfo = pet->GetCharmInfo();
    if(!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetUnlearnOpcode: object "I64FMTD" is considered pet-like but doesn't have a charminfo!", pet->GetGUID());
        return;
    }

    uint32 cost = pet->resetTalentsCost();

    if (GetPlayer()->GetMoney() < cost)
    {
        GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
        return;
    }

    for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();)
    {
        uint32 spell_id = itr->first;                       // Pet::removeSpell can invalidate iterator at erase NEW spell
        ++itr;
        pet->removeSpell(spell_id);
    }

    pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1));

    for(uint8 i = 0; i < 10; i++)
    {
        if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED)
            charmInfo->GetActionBarEntry(i)->SpellOrAction = 0;
    }

    // relearn pet passives
    pet->LearnPetPassives();

    pet->m_resetTalentsTime = time(NULL);
    pet->m_resetTalentsCost = cost;
    GetPlayer()->ModifyMoney(-(int32)cost);

    GetPlayer()->PetSpellInitialize();
}
Esempio n. 4
0
void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
{
    DETAIL_LOG("CMSG_PET_UNLEARN");

    ObjectGuid guid;
    recvPacket >> guid;                 // Pet guid

    Pet* pet = _player->GetPet();

    if (!pet || guid != pet->GetObjectGuid())
    {
        sLog.outError("HandlePetUnlearnOpcode. %s isn't pet of %s .", guid.GetString().c_str(), _player->GetGuidStr().c_str());
        return;
    }

    if (pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1)
        return;

    CharmInfo* charmInfo = pet->GetCharmInfo();
    if (!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetUnlearnOpcode: %s is considered pet-like but doesn't have a charminfo!", pet->GetGuidStr().c_str());
        return;
    }

    uint32 cost = pet->resetTalentsCost();

    if (_player->GetMoney() < cost)
    {
        _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
        return;
    }

    for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();)
    {
        uint32 spell_id = itr->first;                       // Pet::removeSpell can invalidate iterator at erase NEW spell
        ++itr;
        pet->unlearnSpell(spell_id, false);
    }

    pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1));

    for (int i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
        if (UnitActionBarEntry const* ab = charmInfo->GetActionBarEntry(i))
            if (ab->GetAction() && ab->IsActionBarForSpell())
                charmInfo->SetActionBar(i, 0, ACT_DISABLED);

    // relearn pet passives
    pet->LearnPetPassives();

    pet->m_resetTalentsTime = time(nullptr);
    pet->m_resetTalentsCost = cost;
    _player->ModifyMoney(-(int32)cost);

    _player->PetSpellInitialize();
}
Esempio n. 5
0
void WorldSession::SendStablePetCallback(PreparedQueryResult result, uint64 guid)
{
    if (!GetPlayer())
        return;

    TC_LOG_DEBUG("network", "WORLD: Recv MSG_LIST_STABLED_PETS Send.");

    WorldPacket data(MSG_LIST_STABLED_PETS, 200);           // guess size

    data << uint64 (guid);

    Pet* pet = _player->GetPet();

    size_t wpos = data.wpos();
    data << uint8(0);                                       // place holder for slot show number

    data << uint8(GetPlayer()->m_stableSlots);

    uint8 num = 0;                                          // counter for place holder

    // not let move dead pet in slot
    if (pet && pet->IsAlive() && pet->getPetType() == HUNTER_PET)
    {
        data << uint32(num);                                // 4.x unknown, some kind of order?
        data << uint32(pet->GetCharmInfo()->GetPetNumber());
        data << uint32(pet->GetEntry());
        data << uint32(pet->getLevel());
        data << pet->GetName();                             // petname
        data << uint8(1);                                   // 1 = current, 2/3 = in stable (any from 4, 5, ... create problems with proper show)
        ++num;
    }

    if (result)
    {
        do
        {
            Field* fields = result->Fetch();


            data << uint32(num);	    
            data << uint32(fields[1].GetUInt32());          // petnumber
            data << uint32(fields[2].GetUInt32());          // creature entry
            data << uint32(fields[3].GetUInt16());          // level
            data << fields[4].GetString();                  // name
            data << uint8(2);                               // 1 = current, 2/3 = in stable (any from 4, 5, ... create problems with proper show)

            ++num;
        }
        while (result->NextRow());
    }

    data.put<uint8>(wpos, num);                             // set real data to placeholder
    SendPacket(&data);

    SendStableResult(STABLE_ERR_NONE);
}
Esempio n. 6
0
void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
{
    sLog.outDetail("CMSG_PET_UNLEARN");
    uint64 guid;
    recvPacket >> guid;

    Pet* pet = _player->GetPet();

    if(!pet || pet->getPetType() != HUNTER_PET || pet->m_spells.size() <= 1)
        return;

    if(guid != pet->GetGUID())
    {
        sLog.outError( "HandlePetUnlearnOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
        return;
    }

    CharmInfo *charmInfo = pet->GetCharmInfo();
    if(!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetUnlearnOpcode: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId());
        return;
    }

    uint32 cost = pet->resetTalentsCost();

    if (GetPlayer()->GetMoney() < cost)
    {
        GetPlayer()->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
        return;
    }

    for(PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end();)
    {
        uint32 spell_id = itr->first;                       // Pet::removeSpell can invalidate iterator at erase NEW spell
        ++itr;
        pet->unlearnSpell(spell_id,false);
    }

    pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1));

    for(int i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i)
        if(UnitActionBarEntry const* ab = charmInfo->GetActionBarEntry(i))
            if(ab->GetAction() && ab->IsActionBarForSpell())
                charmInfo->SetActionBar(i,0,ACT_DISABLED);

    // relearn pet passives
    pet->LearnPetPassives();

    pet->m_resetTalentsTime = time(NULL);
    pet->m_resetTalentsCost = cost;
    GetPlayer()->ModifyMoney(-(int32)cost);

    GetPlayer()->PetSpellInitialize();
}
Esempio n. 7
0
void WorldSession::HandleStableSwapPet(WorldPacket & recv_data)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_STABLE_SWAP_PET.");
    uint64 npcGUID;
    uint32 pet_number;
    uint8 new_slot;
    recv_data >> new_slot >> pet_number >> npcGUID;

    if (!CheckStableMaster(npcGUID))
    {
        SendStableResult(STABLE_ERR_STABLE);
        return;
    }

    // remove fake death
    if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
        GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

    Pet* pet = _player->GetPet();

   /* if (!pet || pet->getPetType() != HUNTER_PET)
    {
        SendStableResult(STABLE_ERR_STABLE);
        return;
    }
    */

    //If we move the pet already summoned...
    if (pet && pet->GetCharmInfo() && pet->GetCharmInfo()->GetPetNumber() == pet_number)
        _player->RemovePet(pet, PET_SLOT_ACTUAL_PET_SLOT);

    //If we move to the pet already summoned...
    if (pet && GetPlayer()->_currentPetSlot == new_slot)
        _player->RemovePet(pet, PET_SLOT_ACTUAL_PET_SLOT);

    // find swapped pet slot in stable
    _stableSwapCallback.SetParam(new_slot);
    _stableSwapCallback.SetFutureResult(
            CharacterDatabase.AsyncPQuery("SELECT slot, entry, id FROM character_pet WHERE owner = '%u' AND id = '%u'",
                _player->GetGUIDLow(), pet_number)
            );
}
Esempio n. 8
0
void WorldSession::HandleStableChangeSlot(WorldPacket & recv_data)
{
    sLog->outDebug("WORLD: Recv CMSG_STABLE_CHANGE_SLOT.");
    uint32 pet_number;
    uint64 npcGUID;
    uint8 new_slot;

    recv_data >> pet_number >> npcGUID >> new_slot;

    if (!CheckStableMaster(npcGUID))
    {
        SendStableResult(STABLE_ERR_STABLE);
        return;
    }

    if(new_slot > MAX_PET_STABLES)
    {
        SendStableResult(STABLE_ERR_STABLE);
        return;
    }
    
    // remove fake death
    if (GetPlayer()->HasUnitState(UNIT_STAT_DIED))
        GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

    Pet* pet = _player->GetPet();
    
    //If we move the pet already summoned...
    if(pet && pet->GetCharmInfo() && pet->GetCharmInfo()->GetPetNumber() == pet_number)
        _player->RemovePet(pet, PET_SLOT_ACTUAL_PET_SLOT);

    //If we move to the pet already summoned...
    if(pet && GetPlayer()->m_currentPetSlot == new_slot)
        _player->RemovePet(pet, PET_SLOT_ACTUAL_PET_SLOT);
    
    m_stableChangeSlotCallback.SetParam(new_slot);
    m_stableChangeSlotCallback.SetFutureResult(
                                               CharacterDatabase.PQuery("SELECT slot,entry,id FROM character_pet WHERE owner = '%u' AND id = '%u'",
                                                                        _player->GetGUIDLow(), pet_number)
                                               );
}
Esempio n. 9
0
void WorldSession::SendStablePetCallback(QueryResult result, uint64 guid)
{
    if (!GetPlayer())
        return;

    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv MSG_LIST_STABLED_PETS Send.");

    WorldPacket data(MSG_LIST_STABLED_PETS, 200);           // guess size

    data << uint64 (guid);

    Pet* pet = _player->GetPet();

    size_t wpos = data.wpos();
    data << uint8(0);                                       // place holder for slot show number

    data << uint8(GetPlayer()->_petSlotUsed);

    uint8 num = 0;                                          // counter for place holder

    // not let move dead pet in slot
    if (pet && pet->isAlive() && pet->getPetType() == HUNTER_PET)
    {
        data << uint32(_player->_currentPetSlot);
        data << uint32(pet->GetCharmInfo()->GetPetNumber());
        data << uint32(pet->GetEntry());
        data << uint32(pet->getLevel());
        data << pet->GetName();                             // petname
        data << uint8(1);                                   // 1 = current, 2/3 = in stable (any from 4, 5, ... create problems with proper show)
        ++num;
    }

    if (result)
    {
        do
        {
            Field *fields = result->Fetch();

            data << uint32(fields[1].GetUInt32());          // slot
            data << uint32(fields[2].GetUInt32());          // petnumber
            data << uint32(fields[3].GetUInt32());          // creature entry
            data << uint32(fields[4].GetUInt16());          // level
            data << fields[5].GetString();                  // name
            data << uint8(fields[1].GetUInt32() <= PET_SLOT_STABLE_FIRST ? 1 : 2);       // 1 = current, 2/3 = in stable (any from 4, 5, ... create problems with proper show)

            ++num;
        }
        while (result->NextRow());
    }

    data.put<uint8>(wpos, num);                             // set real data to placeholder
    SendPacket(&data);
}
Esempio n. 10
0
    void CreatePet(Player *player, Creature * m_creature, uint32 entry) {
     
            if(player->getClass() != CLASS_HUNTER) 
			{
                player->PlayerTalkClass->SendCloseGossip();
                return;
            }
     
            if(player->GetPet()) 
			{
                player->PlayerTalkClass->SendCloseGossip();
                return;
            }
     
            Creature *creatureTarget = m_creature->SummonCreature(entry, player->GetPositionX(), player->GetPositionY()+2, player->GetPositionZ(), player->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 500);
            if(!creatureTarget) return;
           
            Pet* pet = player->CreateTamedPetFrom(creatureTarget, 0);
			
            if (!pet)
			    return;
     
            // kill original creature
            creatureTarget->setDeathState(JUST_DIED);
            creatureTarget->RemoveCorpse();
            creatureTarget->SetHealth(0);                       // just for nice GM-mode view
     
            pet->SetPower(POWER_HAPPINESS, 1048000);
     
            pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
            pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());
     
            // prepare visual effect for levelup
            pet->SetUInt32Value(UNIT_FIELD_LEVEL, player->getLevel() - 1);
            pet->GetMap()->AddToMap(pet->ToCreature());
            // visual effect for levelup for lulz
            pet->SetUInt32Value(UNIT_FIELD_LEVEL, player->getLevel());
                   
            pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
            if (!pet->InitStatsForLevel(player->getLevel()))
                pet->UpdateAllStats();
         
            // caster has pet now
            player->SetMinion(pet, true);
     
            pet->SavePetToDB(PET_SAVE_AS_CURRENT);
            pet->InitTalentForLevel();
            player->PetSpellInitialize();
           
            //inform that has da pet
            player->PlayerTalkClass->SendCloseGossip();
        }
Esempio n. 11
0
void WorldSession::SendStablePet(uint64 guid )
{
    sLog.outDebug("WORLD: Recv MSG_LIST_STABLED_PETS Send.");

    WorldPacket data(MSG_LIST_STABLED_PETS, 200);           // guess size
    data << uint64 ( guid );

    Pet *pet = _player->GetPet();

    size_t wpos = data.wpos();
    data << uint8(0);                                       // place holder for slot show number

    data << uint8(GetPlayer()->m_stableSlots);

    uint8 num = 0;                                          // counter for place holder

    // not let move dead pet in slot
    if(pet && pet->isAlive() && pet->getPetType()==HUNTER_PET)
    {
        data << uint32(pet->GetCharmInfo()->GetPetNumber());
        data << uint32(pet->GetEntry());
        data << uint32(pet->getLevel());
        data << pet->GetName();                             // petname
        data << uint8(1);                                   // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)
        ++num;
    }

    //                                                     0      1   2      3      4
    QueryResult* result = CharacterDatabase.PQuery("SELECT owner, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot >= '%u' AND slot <= '%u' ORDER BY slot",
        _player->GetGUIDLow(),PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT);

    if(result)
    {
        do
        {
            Field *fields = result->Fetch();

            data << uint32(fields[1].GetUInt32());          // petnumber
            data << uint32(fields[2].GetUInt32());          // creature entry
            data << uint32(fields[3].GetUInt32());          // level
            data << fields[4].GetString();                  // name
            data << uint8(2);                               // 1 = current, 2/3 = in stable (any from 4,5,... create problems with proper show)

            ++num;
        }while( result->NextRow() );

        delete result;
    }

    data.put<uint8>(wpos, num);                             // set real data to placeholder
    SendPacket(&data);
}
void CreatePet(Player *player, Creature * m_creature, uint32 entry) {

        if(player->getClass() != CLASS_HUNTER) {
            player->PlayerTalkClass->SendCloseGossip();
            return;
        }
 
        if(player->GetPet()) {
            m_creature->MonsterWhisper("First you must drop your Pet!", player->GetGUID());
            m_creature->MonsterWhisper("First you must drop your Pet!", player->GetGUID(), true);
            player->PlayerTalkClass->SendCloseGossip();
            return;
        }
 
        Creature *creatureTarget = m_creature->SummonCreature(entry, player->GetPositionX(), player->GetPositionY()+2, player->GetPositionZ(), player->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 500);
        if(!creatureTarget) return;
        
        Pet* pet = player->CreateTamedPetFrom(creatureTarget, 0);
        if(!pet) return;
 
        // kill original creature
        creatureTarget->setDeathState(JUST_DIED);
        creatureTarget->RemoveCorpse();
        creatureTarget->SetHealth(0);                       // just for nice GM-mode view

		pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
		pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());
 
        // prepare visual effect for levelup
        pet->SetUInt32Value(UNIT_FIELD_LEVEL, player->getLevel() - 1);
        pet->GetMap()->AddToMap(pet->ToCreature());
        // visual effect for levelup
        pet->SetUInt32Value(UNIT_FIELD_LEVEL, player->getLevel());
		
		pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
        if(!pet->InitStatsForLevel(player->getLevel()))
			sLog->outInfo(LOG_FILTER_PETS, "Pet Create fail: no init stats for entry %u", entry);
 
        pet->UpdateAllStats();
        
        // caster have pet now
		player->SetMinion(pet, true);
 
        pet->SavePetToDB(PET_SAVE_AS_CURRENT);
        pet->InitTalentForLevel();
        player->PetSpellInitialize();
        
        //end
        player->PlayerTalkClass->SendCloseGossip();
        m_creature->MonsterWhisper("Pet added. You might want to feed it and name it somehow.", player->GetGUID());
        m_creature->MonsterWhisper("Pet added. You might want to feed it and name it somehow.", player->GetGUID(), true);
    }
void WorldSession::HandleStableSwapPet(WorldPacket& recvData)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recv CMSG_STABLE_SWAP_PET.");
    uint64 npcGUID;
    uint32 pet_number;
    uint8 new_slot;
    recvData >> new_slot >> pet_number >> npcGUID;

    if (!CheckStableMaster(npcGUID))
    {
        SendStableResult(STABLE_ERR_STABLE);
        return;
    }

    // remove fake death
    if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
        GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);

    Pet* pet = _player->GetPet();
    /*
    if (!pet || pet->getPetType() != HUNTER_PET)
    {
        SendStableResult(STABLE_ERR_STABLE);
        return;
    }
    */

    //If we move the pet already summoned...
    if (pet && pet->GetCharmInfo() && pet->GetCharmInfo()->GetPetNumber() == pet_number)
        _player->RemovePet(pet, PET_SAVE_AS_CURRENT);

    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHARACTER_SELECT_PET_SLOT_BY_ID);

    stmt->setUInt32(0, _player->GetGUIDLow());
    stmt->setUInt32(1, pet_number);

    _stableSwapCallback.SetParam(new_slot);
    _stableSwapCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
}
Esempio n. 14
0
void WorldSession::SendStablePetCallback(ObjectGuid guid, PreparedQueryResult result)
{
    if (!GetPlayer())
        return;

    WorldPackets::Pet::PetStableList packet;

    packet.StableMaster = guid;

    Pet* pet = _player->GetPet();

    int32 petSlot = 0;
    // not let move dead pet in slot
    if (pet && pet->IsAlive() && pet->getPetType() == HUNTER_PET)
    {
        WorldPackets::Pet::PetStableInfo stableEntry;
        stableEntry.PetSlot = petSlot;
        stableEntry.PetNumber = pet->GetCharmInfo()->GetPetNumber();
        stableEntry.CreatureID = pet->GetEntry();
        stableEntry.DisplayID = pet->GetDisplayId();
        stableEntry.ExperienceLevel = pet->getLevel();
        stableEntry.PetFlags = PET_STABLE_ACTIVE;
        stableEntry.PetName = pet->GetName();
        ++petSlot;

        packet.Pets.push_back(stableEntry);
    }

    if (result)
    {
        do
        {
            Field* fields = result->Fetch();
            WorldPackets::Pet::PetStableInfo stableEntry;

            stableEntry.PetSlot = petSlot;
            stableEntry.PetNumber = fields[1].GetUInt32();          // petnumber
            stableEntry.CreatureID = fields[2].GetUInt32();         // creature entry
            stableEntry.DisplayID = fields[5].GetUInt32();          // creature displayid
            stableEntry.ExperienceLevel = fields[3].GetUInt16();    // level
            stableEntry.PetFlags = PET_STABLE_INACTIVE;
            stableEntry.PetName = fields[4].GetString();            // Name

            ++petSlot;
            packet.Pets.push_back(stableEntry);
        }
        while (result->NextRow());
    }

    SendPacket(packet.Write());
}
Esempio n. 15
0
void WorldSession::SendStablePet(uint64 guid)
{
    sLog->outDebug("WORLD: Recv MSG_LIST_STABLED_PETS Send.");

    WorldPacket data(MSG_LIST_STABLED_PETS, 200);           // guess size
    data << uint64 (guid);

    Pet *pet = _player->GetPet();

    data << uint8(0);                                       // place holder for slot show number
    data << uint8(GetPlayer()->m_stableSlots);

    uint8 num = 0;                                          // counter for place holder

    // not let move dead pet in slot
    if (pet && pet->isAlive() && pet->getPetType() == HUNTER_PET)
    {
        data << uint32(pet->GetCharmInfo()->GetPetNumber());
        data << uint32(pet->GetEntry());
        data << uint32(pet->getLevel());
        data << pet->GetName();                             // petname
        data << uint32(pet->GetLoyaltyLevel());             // loyalty
        data << uint8(0x01);                                // client slot 1 == current pet (0)
        ++num;
    }

    //                                                            0      1     2   3      4      5        6
    QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3", _player->GetGUIDLow());

    if (result)
    {
        do
        {
            Field *fields = result->Fetch();

            data << uint32(fields[2].GetUInt32());          // petnumber
            data << uint32(fields[3].GetUInt32());          // creature entry
            data << uint32(fields[4].GetUInt32());          // level
            data << fields[6].GetString();                  // name
            data << uint32(fields[5].GetUInt32());          // loyalty
            data << uint8(fields[1].GetUInt32()+1);         // slot

            ++num;
        }while (result->NextRow());
    }

    data.put<uint8>(8, num);                                // set real data to placeholder
    SendPacket(&data);
}
Esempio n. 16
0
void WorldSession::HandlePetRename( WorldPacket & recv_data )
{
    sLog.outDetail( "HandlePetRename. CMSG_PET_RENAME" );

    uint64 petguid;

    std::string name;

    recv_data >> petguid;
    recv_data >> name;

    Pet* pet = ObjectAccessor::GetPet(petguid);
                                                            // check it!
    if( !pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
        pet->GetByteValue(UNIT_FIELD_BYTES_2, 2) != UNIT_RENAME_ALLOWED ||
        pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() )
        return;

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name);
    if(res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name);
        return;
    }

    if(sObjectMgr.IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name);
        return;
    }

    pet->SetName(name);

    Unit *owner = pet->GetOwner();
    if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
        ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED);

    CharacterDatabase.BeginTransaction();
    CharacterDatabase.escape_string(name);
    CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
    CharacterDatabase.CommitTransaction();

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL)));
}
Esempio n. 17
0
void WorldSession::HandlePetRename(WorldPacket& recv_data)
{
    DETAIL_LOG("HandlePetRename. CMSG_PET_RENAME");

    ObjectGuid petGuid;
    std::string name;

    recv_data >> petGuid;
    recv_data >> name;

    Pet* pet = _player->GetMap()->GetPet(petGuid);
    // check it!
    if (!pet || pet->getPetType() != HUNTER_PET ||
            !pet->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_RENAME) ||
            pet->GetOwnerGuid() != _player->GetObjectGuid() || !pet->GetCharmInfo())
        return;

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name);
    if (res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name);
        return;
    }

    if (sObjectMgr.IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name);
        return;
    }

    pet->SetName(name);

    if (_player->GetGroup())
        _player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_RENAME);

    CharacterDatabase.BeginTransaction();
    CharacterDatabase.escape_string(name);
    CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
    CharacterDatabase.CommitTransaction();

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr)));
}
Esempio n. 18
0
void WorldSession::HandlePetRename( WorldPacket & recv_data )
{
    DETAIL_LOG( "HandlePetRename. CMSG_PET_RENAME" );

    uint64 petguid;
    uint8 isdeclined;

    std::string name;
    DeclinedName declinedname;

    recv_data >> petguid;
    recv_data >> name;
    recv_data >> isdeclined;

    Pet* pet = _player->GetMap()->GetPet(petguid);
                                                            // check it!
    if( !pet || pet->getPetType() != HUNTER_PET ||
        !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ||
        pet->GetOwnerGuid() != _player->GetObjectGuid() || !pet->GetCharmInfo() )
        return;

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name);
    if(res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name, NULL);
        return;
    }

    if(sObjectMgr.IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name, NULL);
        return;
    }

    pet->SetName(name);

    if(_player->GetGroup())
        _player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);

    if(isdeclined)
    {
        for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
        {
            recv_data >> declinedname.name[i];
        }

        std::wstring wname;
        Utf8toWStr(name, wname);
        if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname,0),declinedname))
        {
            SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
            return;
        }
    }

    CharacterDatabase.BeginTransaction();
    if(isdeclined)
    {
        for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
            CharacterDatabase.escape_string(declinedname.name[i]);
        CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
        CharacterDatabase.PExecute("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%u','%s','%s','%s','%s','%s')",
            pet->GetCharmInfo()->GetPetNumber(), _player->GetGUIDLow(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str());
    }

    CharacterDatabase.escape_string(name);
    CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
    CharacterDatabase.CommitTransaction();

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL)));
}
Esempio n. 19
0
void WorldSession::HandlePetRename(WorldPacket& recvData)
{
    sLog->outInfo(LOG_FILTER_NETWORKIO, "HandlePetRename. CMSG_PET_RENAME");

    uint64 petguid;
    uint8 isdeclined;

    std::string name;
    DeclinedName declinedname;

    recvData >> petguid;
    recvData >> name;
    recvData >> isdeclined;

    Pet* pet = ObjectAccessor::FindPet(petguid);
                                                            // check it!
    if (!pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
        !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ||
        pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo())
        return;

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name);
    if (res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name, NULL);
        return;
    }

    if (sObjectMgr->IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name, NULL);
        return;
    }

    pet->SetName(name);

    Unit* owner = pet->GetOwner();
    if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
        owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);

    if (isdeclined)
    {
        for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
        {
            recvData >> declinedname.name[i];
        }

        std::wstring wname;
        Utf8toWStr(name, wname);
        if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
        {
            SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
            return;
        }
    }

    SQLTransaction trans = CharacterDatabase.BeginTransaction();
    if (isdeclined)
    {
        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
        stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber());
        trans->Append(stmt);

        stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_CHAR_PET_DECLINEDNAME);
        stmt->setUInt32(0, _player->GetGUIDLow());

        for (uint8 i = 0; i < 5; i++)
            stmt->setString(i+1, declinedname.name[i]);

        trans->Append(stmt);
    }
    CharacterDatabase.CommitTransaction(trans);

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped
}
Esempio n. 20
0
void PlayerbotHunterAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    Pet *pet = m_bot->GetPet();
    if (m_tank->GetGUID() == m_bot->GetGUID() && pet && pet->isAlive() && pet->isInCombat()) { m_tank = pet; }
    uint8 petThreat = 0;
    if (pet) { GetThreatPercent(pTarget,pet); }

 //   switch (ai->GetScenarioType())
//    {
//        case PlayerbotAI::SCENARIO_DUEL:
 //           ai->CastSpell(RAPTOR_STRIKE);
 //           return;
//    }

    // ------- Non Duel combat ----------


    #pragma region Choose Target
    // Choose Target
    if (isUnderAttack()) // I am under attack
    {
        if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
        else //Have to select nearest target
        {
            Unit *curAtt = GetNearestAttackerOf(m_bot);
            if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
            {
                m_bot->SetSelection(curAtt->GetGUID());
                //ai->AddLootGUID(curAtt->GetGUID());
                DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                return;
            }
        }
        //my target is attacking me
    }

    #pragma endregion

    #pragma region Pet Actions
    // Pet's own Actions
    if( pet && pet->isAlive() )
    {
        // Setup pet
        if (pet->GetCharmInfo()->IsAtStay()) {pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); }

        //Heal pet
        if ( ( ((float)pet->GetHealth()/(float)pet->GetMaxHealth()) < 0.5f )
        && ( PET_MEND>0 && !pet->getDeathState() != ALIVE && pVictim != m_bot
        && CastSpell(PET_MEND,m_bot) )) { return; }

        // Set pet to attack hunter's attacker > its own attackers > hunter's target
        if (!pet->getVictim()) { pet->AI()->AttackStart(pTarget); }
        else if (isUnderAttack(m_bot)) { pet->AI()->AttackStart(pTarget); }  //Always help hunter if she's under attack
        else if (pet->getVictim()->GetGUID() != pTarget->GetGUID() && !isUnderAttack(pet)) { pet->AI()->AttackStart(pTarget); }
        else if (isUnderAttack(pet)) // Pet is under attack and hunter has no attackers
        {
            if ( pet->getVictim()->getVictim() && pet->getVictim()->getVictim()->GetGUID() == pet->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(pet,true);
                if (curAtt && (!pet->getVictim() || curAtt->GetGUID() != pet->getVictim()->GetGUID()))
                {
                    pet->AI()->AttackStart(curAtt); //Attack nearest attacker
                }
            }
            //Actions to do under attack (Always tank it, and try to kill it, until someone (!= hunter) takes aggro back)
            //Hunter should help her pet whether main tank or not, unless she's being attacked (BEWARE Targeting Loop possibility)
            if (pet->getVictim() && !isUnderAttack(m_bot) && pet->getVictim()->GetGUID() != pTarget->GetGUID())
            {
                m_bot->SetSelection(pet->getVictim()->GetGUID());
                DoNextCombatManeuver(pet->getVictim()); //Restart new update to get variables fixed..
                return;
            }

        }
        // Pet tanking behaviour
        if (pet->GetGUID() == m_tank->GetGUID() || isUnderAttack(m_bot) || isUnderAttack(pet))
        {
            if (GROWL) pet->GetCharmInfo()->SetSpellAutocast(GROWL,true); //Autocast growl
            if (BAD_ATTITUDE) pet->GetCharmInfo()->SetSpellAutocast(BAD_ATTITUDE,true);
            if (COWER) pet->GetCharmInfo()->SetSpellAutocast(COWER,false);
            if (CastSpell(INTIMIDATION,m_bot)) { return; }
        }
        else
        {
            if (GROWL) pet->GetCharmInfo()->SetSpellAutocast(GROWL,false); //Do not try to get aggro
            if (BAD_ATTITUDE) pet->GetCharmInfo()->SetSpellAutocast(BAD_ATTITUDE,false);
            if (COWER) pet->GetCharmInfo()->SetSpellAutocast(COWER,true); //Autocast cower
        }
        // NORMAL PET dps attacks
        if (petThreat < threatThreshold || pet->GetGUID() == m_tank->GetGUID() || isUnderAttack(m_bot))
        {
            if (CastSpell(KILL_COMMAND,m_bot)) { }
            else if (CastSpell(BESTIAL_WRATH,m_bot)) { }
        }
        // NETHERSHOCK DEMORALIZINGSCREECH
    }
    #pragma endregion

    // If there's a cast stop
    if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return;

    // Cast CC breakers if any match found  (does not work yet)
    // uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM };
    // if (castSelfCCBreakers(ccSpells)) { } //most of them dont have gcd

    #pragma region Evasive manuevers
    // Do evasive manuevers if under attack
    if (isUnderAttack())
    {
        if (m_tank->GetGUID() == m_bot->GetGUID()) { } // i am tank and my pet is probably dead, so i have to face the attackers
        else if (CastSpell(FEIGN_DEATH,m_bot)) { return; } //avoid attack
        //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot) ) { return; }
        else if (CastSpell(CONCUSSIVE_SHOT,pTarget)) { return; }
        else if (CastSpell(WYVERN_STING,pTarget)) { return; }
        else if (CastSpell(SCATTER_SHOT,pTarget)) { return; }
        else if (CastSpell(FREEZING_ARROW,pTarget)) { return; }
        else if (CastSpell(MISDIRECTION,m_tank)) { return; }
        else if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget) ) { return; } //no gcd but is cast
        else if (pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST && CastSpell(SCARE_BEAST,pTarget)) { return; }
        else if (pDist <= 2 && CastSpell(FREEZING_TRAP,pTarget)) { return; }
    }
    #pragma endregion

    //Select combat mode
    m_role = BOT_ROLE_DPS_RANGED;
    if ((isUnderAttack()  && pDist <= ATTACK_DISTANCE) || !m_bot->GetUInt32Value(PLAYER_AMMO_ID) ) { m_role = BOT_ROLE_DPS_MELEE; }

    TakePosition(pTarget);

    #pragma region Buff / Protect
    //Buff UP
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot) ) {  } //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot) ) { } //no GCD
    if (CastSpell(TRUESHOT_AURA, m_bot)) { return; }
    if (CastSpell(RAPID_FIRE,m_bot)) { return; }
    if (CastSpell(HUNTERS_MARK,pTarget)) { return; }
    if ((ai->GetHealthPercent() < 80 || ai->GetManaPercent() < 60 ) && CastSpell(READINESS,m_bot)) { } //no gcd


    //Protect yourself if needed
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot) ) { } //no gcd
    if (ai->GetHealthPercent() < 20 && CastSpell(DETERRENCE,m_bot)) {} //No GCD
    if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return;  }

    //Break Spells
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && ( pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 20 ) && CastSpell(R_ARCANE_TORRENT, pTarget) ) { } //no gcd
    if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(SILENCING_SHOT, pTarget) ) { return; }
    if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(SCATTER_SHOT, pTarget) ) { return; }

    //Catch
    if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
    {
        if (CastSpell(WING_CLIP,pTarget)) return;
        if (CastSpell(CONCUSSIVE_SHOT,pTarget)) return;
        if (CastSpell(SCATTER_SHOT, pTarget) ) { return; }
    }
    #pragma endregion

    //Do combat
    switch (m_role)
    {
        #pragma region BOT_ROLE_DPS_MELEE
        case BOT_ROLE_DPS_MELEE:
            if (AUTO_SHOT) { m_bot->InterruptNonMeleeSpells( true, AUTO_SHOT ); } //Stop autoshot
            if (CastSpell(ASPECT_OF_THE_MONKEY,m_bot)) { return; } //Get Monkey aspect

            if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast

            // Threat control
            if (pThreat < threatThreshold || m_tank->GetGUID() == m_bot->GetGUID() || m_bot->HasAura(MISDIRECTION) ) { } //Continue attack
            else
            {
                if (pet && isUnderAttack(pet) && pet->getVictim() && pet->getVictim()->GetGUID() != pTarget->GetGUID()) //Should be helping pet
                {
                    m_bot->SetSelection(pet->getVictim()->GetGUID());
                    return;
                }
                else if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
                {
                    m_bot->SetSelection(m_tank->getVictim()->GetGUID());
                    return;
                }
                else if (CastSpell(FEIGN_DEATH,m_bot)) { return; }
                else { return; } // No more threat reducing spells, just slow down
            }

            if (CastSpell(RAPTOR_STRIKE,pTarget,true,true)) {} //No gcd
            if (CastSpell(MONGOOSE_BITE,pTarget,true,true)) { return; } // Cannot be sure if casted or not
            else if (CastSpell(COUNTERATTACK,pTarget,true,true)) { return; } // Cannot be sure if casted or not
            if (CastSpell(WING_CLIP,pTarget)) { return; }
            if (isUnderAttack(m_tank,6) && CastSpell(SNAKE_TRAP,m_bot)) { return; }
            if (isUnderAttack(m_tank,4) && CastSpell(EXPLOSIVE_TRAP,m_bot)) { return; }
            if (CastSpell(IMMOLATION_TRAP,m_bot)) { return; }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_RANGED
        case BOT_ROLE_DPS_RANGED:
            if (m_pulling) {
                if (GetAI()->CastSpell(CONCUSSIVE_SHOT,pTarget) ||
                    GetAI()->CastSpell(AUTO_SHOT,pTarget)) {
                    m_pulling = false;
                    GetAI()->SetCombatOrder(ORDERS_NONE);
                    GetAI()->Follow(*GetMaster());
                    GetAI()->SetIgnoreUpdateTime(2);

                    if(HasPet(GetPlayerBot()))
                        m_bot->GetPet()->SetReactState(REACT_DEFENSIVE);
                }
                return;
            }
            if (AUTO_SHOT && !m_bot->FindCurrentSpellBySpellId(AUTO_SHOT)) { ai->CastSpell(AUTO_SHOT,pTarget); } //Start autoshot
            if (!(ai->GetManaPercent() < 85 && m_bot->HasAura(ASPECT_OF_THE_VIPER)) && CastSpell(ASPECT_OF_THE_HAWK,m_bot)) { return; } //Get Hawk aspect
            if ((ai->GetManaPercent() < 25) && CastSpell(ASPECT_OF_THE_VIPER,m_bot,true,false,true)) { return; } //Build up mana

            // if i am main tank, protect master by taunt
            if(m_tank->GetGUID() == m_bot->GetGUID())
            {
                // Taunt if needed (Only for master)
                Unit *curAtt = GetAttackerOf(GetMaster());
                if (curAtt && CastSpell(DISTRACTING_SHOT, curAtt))  { return; }
                // My target is not attacking me, taunt..
                if (pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(DISTRACTING_SHOT, pTarget) )  { return; }
            }
            // If i am not tank, transfer threat to tank or pet..
            else
            {
                if (CastSpell(MISDIRECTION,m_tank)) { return; }
                if (pet && pet->isAlive() && CastSpell(MISDIRECTION,pet)) { return; }

                // Threat control
                if (pThreat < threatThreshold || m_bot->HasAura(MISDIRECTION) ) { } //Continue attack
                else
                {
                    if (pet && isUnderAttack(pet) && pet->getVictim() && pet->getVictim()->GetGUID() != pTarget->GetGUID()) //Should be helping pet
                    {
                        m_bot->SetSelection(pet->getVictim()->GetGUID());
                        return;
                    }
                    else if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
                    {
                        m_bot->SetSelection(m_tank->getVictim()->GetGUID());
                        return;
                    }
                    else if (CastSpell(FEIGN_DEATH,m_bot)) { return; }
                    else { return; } // No more threat reducing spells, just slow down
                }
            }

            // DO dps
            if (ai->GetHealthPercent(*pTarget) < 20 && CastSpell(KILL_SHOT,pTarget)) { return; }
            if (isUnderAttack(m_tank,4) && CastSpell(MULTI_SHOT,pTarget)) { return; }
            if (isUnderAttack(m_tank,4) && CastSpell(VOLLEY,pTarget)) { GetAI()->SetIgnoreUpdateTime(7); return; }
            if (CanCast(CHIMERA_SHOT,pTarget) &&
                (pTarget->HasAura(VIPER_STING,m_bot->GetGUID()) || pTarget->HasAura(SERPENT_STING,m_bot->GetGUID()) )
                && CastSpell(CHIMERA_SHOT,pTarget,false) ) { return; }
            if (ai->GetManaPercent() < 60 && ai->GetManaPercent(*pTarget) > 4 && CastSpell(VIPER_STING,pTarget)) { return; }
            if (!pTarget->HasAura(VIPER_STING,m_bot->GetGUID()) && CastSpell(SERPENT_STING,pTarget)) { return; }
            if (CastSpell(ARCANE_SHOT,pTarget)) { return; }
            if (CastSpell(BLACK_ARROW,pTarget)) { return; }
            if (CastSpell(EXPLOSIVE_SHOT,pTarget)) { return; }
            if (CastSpell(STEADY_SHOT,pTarget)) { return; }
            break;
        #pragma endregion
    }

    /*// drink potion if support / healer (Other builds simply overuse mana and waste mana pots)
    if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }*/
} // end DoNextCombatManeuver
Esempio n. 21
0
void WorldSession::HandlePetRename( WorldPacket & recv_data )
{
    CHECK_PACKET_SIZE(recv_data, 8+1);

    sLog.outDetail( "HandlePetRename. CMSG_PET_RENAME\n" );

    uint64 petguid;
    uint8 isdeclined;

    std::string name;
    DeclinedName declinedname;

    recv_data >> petguid;
    recv_data >> name;
    CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1);
    recv_data >> isdeclined;

    Pet* pet = ObjectAccessor::GetPet(petguid);
                                                            // check it!
    if( !pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
        pet->GetByteValue(UNIT_FIELD_BYTES_2, 2) != UNIT_RENAME_ALLOWED ||
        pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo() )
        return;

    if(!ObjectMgr::IsValidPetName(name))
    {
        SendPetNameInvalid(PET_NAME_INVALID, name, NULL);
        return;
    }

    if(objmgr.IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name, NULL);
        return;
    }

    pet->SetName(name);

    Unit *owner = pet->GetOwner();
    if(owner && (owner->GetTypeId() == TYPEID_PLAYER) && ((Player*)owner)->GetGroup())
        ((Player*)owner)->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED);

    if(isdeclined)
    {
        for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
        {
            CHECK_PACKET_SIZE(recv_data, recv_data.rpos() + 1);
            recv_data >> declinedname.name[i];
        }

        std::wstring wname;
        Utf8toWStr(name, wname);
        if(!ObjectMgr::CheckDeclinedNames(GetMainPartOfName(wname,0),declinedname))
        {
            SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
            return;
        }
    }

    CharacterDatabase.BeginTransaction();
    if(isdeclined)
    {
        for(int i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
            CharacterDatabase.escape_string(declinedname.name[i]);
        CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
        CharacterDatabase.PExecute("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u','%u','%s','%s','%s','%s','%s')",
            pet->GetCharmInfo()->GetPetNumber(), _player->GetGUIDLow(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str());
    }

    CharacterDatabase.escape_string(name);
    CharacterDatabase.PExecute("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
    CharacterDatabase.CommitTransaction();

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
}
Esempio n. 22
0
void WorldSession::HandlePetAction(WorldPacket& recv_data)
{
    ObjectGuid petGuid;
    uint32 data;
    ObjectGuid targetGuid;
    recv_data >> petGuid;
    recv_data >> data;
    recv_data >> targetGuid;

    uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data);
    uint8 flag = UNIT_ACTION_BUTTON_TYPE(data);             // delete = 0x07 CastSpell = C1

    DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str());

    // used also for charmed creature/player
    Unit* petUnit = _player->GetMap()->GetUnit(petGuid);
    if (!petUnit)
    {
        sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str());
        return;
    }

    if (_player->GetObjectGuid() != petUnit->GetCharmerOrOwnerGuid())
    {
        sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), _player->GetGuidStr().c_str());
        return;
    }

    if (!petUnit->isAlive())
        return;

    CharmInfo* charmInfo = petUnit->GetCharmInfo();
    if (!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", petUnit->GetGUIDLow(), petUnit->GetTypeId());
        return;
    }

    Pet* pet = nullptr;
    Creature* creature = nullptr;

    if (petUnit->GetTypeId() == TYPEID_UNIT)
    {
        creature = static_cast<Creature*>(petUnit);

        if (creature->IsPet())
        {
            pet = static_cast<Pet*>(petUnit);

            if (pet->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
                return;
        }
    }

    if (!pet && petUnit->hasUnitState(UNIT_STAT_CONTROLLED))
    {
        // possess case
        if (flag != uint8(ACT_COMMAND))
        {
            sLog.outError("PetHAndler: unknown PET flag Action %i and spellid %i. For possessed %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str());
            return;
        }

        switch (spellid)
        {
            case COMMAND_STAY:
            case COMMAND_FOLLOW:
                charmInfo->SetCommandState(CommandStates(spellid));
                break;
            case COMMAND_ATTACK:
            {
                Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr;

                if (targetUnit && targetUnit != petUnit && targetUnit->isTargetableForAttack())
                {
                    _player->SetInCombatState(true, targetUnit);

                    // This is true if pet has no target or has target but targets differs.
                    if (petUnit->getVictim() != targetUnit)
                        petUnit->Attack(targetUnit, true);
                }
                break;
            }
            case COMMAND_ABANDON:
                _player->Uncharm();
                break;
            default:
                sLog.outError("PetHandler: Not allowed action %i and spellid %i. Pet %s owner is %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str(), _player->GetGuidStr().c_str());
                break;
        }
        return;
    }
    
    // only real pet should go there
    if (!pet)
    {
        sLog.outError("PetHandler: A not pet trying to do unknown Action %i and spellid %i. Pet %s owner is %s", uint32(flag), spellid, petUnit->GetGuidStr().c_str(), _player->GetGuidStr().c_str());
        return;
    }

    switch (flag)
    {
        case ACT_COMMAND:                                   // 0x07
            switch (spellid)
            {
                case COMMAND_STAY:                          // flat=1792  // STAY
                {
                    if (!petUnit->hasUnitState(UNIT_STAT_CONTROLLED))
                    {
                        petUnit->StopMoving();
                        petUnit->GetMotionMaster()->Clear();
                    }
                    petUnit->AttackStop(true, true);
                    pet->SetIsRetreating();
                    pet->SetStayPosition(true);
                    pet->SetSpellOpener();
                    charmInfo->SetCommandState(COMMAND_STAY);
                    break;
                }
                case COMMAND_FOLLOW:                        // spellid=1792  // FOLLOW
                {
                    if (!petUnit->hasUnitState(UNIT_STAT_CONTROLLED))
                    {
                        petUnit->StopMoving();
                        petUnit->GetMotionMaster()->Clear();
                        pet->SetIsRetreating(true);
                    }
                    petUnit->AttackStop(true, true);
                    pet->SetStayPosition();
                    pet->SetSpellOpener();
                    charmInfo->SetCommandState(COMMAND_FOLLOW);
                    break;
                }
                case COMMAND_ATTACK:                        // spellid=1792  // ATTACK
                {
                    pet->SetIsRetreating();
                    pet->SetSpellOpener();

                    Unit* targetUnit = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr;

                    if (targetUnit && targetUnit != petUnit && targetUnit->isTargetableForAttack() && targetUnit->isInAccessablePlaceFor((Creature*)petUnit))
                    {
                        _player->SetInCombatState(true, targetUnit);

                        // This is true if pet has no target or has target but targets differs.
                        if (petUnit->getVictim() != targetUnit)
                        {
                            petUnit->AttackStop();
                            if (!petUnit->hasUnitState(UNIT_STAT_CONTROLLED))
                            {
                                petUnit->GetMotionMaster()->Clear();

                                pet->AI()->AttackStart(targetUnit);
                                // 10% chance to play special warlock pet attack talk, else growl
                                if (pet->getPetType() == SUMMON_PET && roll_chance_i(10))
                                    pet->SendPetTalk((uint32)PET_TALK_ATTACK);

                                pet->SendPetAIReaction();
                            }
                            else
                                pet->Attack(targetUnit, true);
                        }
                    }
                    break;
                }
                case COMMAND_ABANDON:                       // abandon (hunter pet) or dismiss (summoned pet)
                {
                    if (pet->getPetType() == HUNTER_PET)
                        pet->Unsummon(PET_SAVE_AS_DELETED, _player);
                    else
                        // dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
                        pet->SetDeathState(CORPSE);

                    pet->SetStayPosition();
                    break;
                }
                default:
                    sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
            }
            break;
        case ACT_REACTION:                                  // 0x6
            switch (spellid)
            {
                case REACT_PASSIVE:                         // passive
                {
                    pet->AttackStop(true, true);
                    pet->SetSpellOpener();
                }
                case REACT_DEFENSIVE:                       // recovery
                case REACT_AGGRESSIVE:                      // activete
                {
                    charmInfo->SetReactState(ReactStates(spellid));
                    break;
                }
            }
            break;
        case ACT_DISABLED:                                  // 0x81    spell (disabled), ignore
        case ACT_PASSIVE:                                   // 0x01
        case ACT_ENABLED:                                   // 0xC1    spell
        {
            pet->SetIsRetreating();
            pet->SetSpellOpener();

            Unit* unit_target = targetGuid ? _player->GetMap()->GetUnit(targetGuid) : nullptr;

            // do not cast unknown spells
            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
            if (!spellInfo)
            {
                sLog.outError("WORLD: unknown PET spell id %i", spellid);
                return;
            }

            if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                return;

            for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
            {
                if (spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA
                    || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT
                    || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                    return;
            }

            // do not cast not learned spells
            if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
                return;

            _player->SetInCombatState(true, unit_target);

            pet->clearUnitState(UNIT_STAT_MOVING);

            Spell* spell = new Spell(pet, spellInfo, false);

            SpellCastResult result = spell->CheckPetCast(unit_target);

            const SpellRangeEntry* sRange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);

            if (unit_target && !(pet->IsWithinDistInMap(unit_target, sRange->maxRange) && pet->IsWithinLOSInMap(unit_target)) 
                && !(GetPlayer()->IsFriendlyTo(unit_target) || pet->HasAuraType(SPELL_AURA_MOD_POSSESS)))
            {
                pet->SetSpellOpener(spellid, sRange->minRange, sRange->maxRange);
                spell->finish(false);
                delete spell;

                pet->AttackStop();

                if (!pet->hasUnitState(UNIT_STAT_CONTROLLED))
                {
                    pet->GetMotionMaster()->Clear();

                    pet->AI()->AttackStart(unit_target);
                    // 10% chance to play special warlock pet attack talk, else growl
                    if (pet->IsPet() && pet->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10))
                        pet->SendPetTalk((uint32)PET_TALK_ATTACK);

                    pet->SendPetAIReaction();
                }
                else
                    petUnit->Attack(unit_target, true);

                return;
            }

            // auto turn to target unless possessed
            if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->hasUnitState(UNIT_STAT_CONTROLLED))
            {
                if (unit_target)
                {
                    pet->SetInFront(unit_target);
                    if (unit_target->GetTypeId() == TYPEID_PLAYER)
                        pet->SendCreateUpdateToPlayer((Player*)unit_target);
                }
                else if (Unit* unit_target2 = spell->m_targets.getUnitTarget())
                {
                    pet->SetInFront(unit_target2);
                    if (unit_target2->GetTypeId() == TYPEID_PLAYER)
                        pet->SendCreateUpdateToPlayer((Player*)unit_target2);
                }
                if (Unit* powner = pet->GetCharmerOrOwner())
                    if (powner->GetTypeId() == TYPEID_PLAYER)
                        pet->SendCreateUpdateToPlayer((Player*)powner);
                result = SPELL_CAST_OK;
            }

            if (result == SPELL_CAST_OK)
            {
                pet->AddCreatureSpellCooldown(spellid);

                unit_target = spell->m_targets.getUnitTarget();

                pet->SetSpellOpener();
                spell->SpellStart(&(spell->m_targets));
            }
            else
            {
                if (pet->hasUnitState(UNIT_STAT_CONTROLLED))
                    Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
                else
                {
                    Unit* owner = pet->GetCharmerOrOwner();
                    if (owner && owner->GetTypeId() == TYPEID_PLAYER)
                        Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true);
                }

                if (!pet->HasSpellCooldown(spellid))
                    GetPlayer()->SendClearCooldown(spellid, pet);

                pet->SetSpellOpener();
                spell->finish(false);
                delete spell;
            }
            break;
        }
        default:
            sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
    }
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
void WorldSession::HandlePetRename(WorldPacket& recvData)
{
    TC_LOG_DEBUG("network", "WORLD: Received CMSG_PET_RENAME");

    ObjectGuid petguid;
    uint8 isdeclined;

    std::string name;
    DeclinedName declinedname;

    recvData >> petguid;
    recvData >> name;
    recvData >> isdeclined;

    Pet* pet = ObjectAccessor::GetPet(*_player, petguid);
                                                            // check it!
    if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
        !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ||
        pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo())
        return;

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name, GetSessionDbcLocale());
    if (res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name, NULL);
        return;
    }

    if (sObjectMgr->IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name, NULL);
        return;
    }

    pet->SetName(name);

    if (pet->GetOwner()->GetGroup())
        pet->GetOwner()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);

    if (isdeclined)
    {
        for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
        {
            recvData >> declinedname.name[i];
        }

        std::wstring wname;
        if (!Utf8toWStr(name, wname))
            return;

        if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
        {
            SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
            return;
        }
    }

    SQLTransaction trans = CharacterDatabase.BeginTransaction();
    if (isdeclined)
    {
        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_PET_DECLINEDNAME);
        stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber());
        trans->Append(stmt);

        stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_PET_DECLINEDNAME);
        stmt->setUInt32(0, _player->GetGUID().GetCounter());

        for (uint8 i = 0; i < 5; i++)
            stmt->setString(i + 1, declinedname.name[i]);

        trans->Append(stmt);
    }

    PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME);
    stmt->setString(0, name);
    stmt->setUInt32(1, _player->GetGUID().GetCounter());
    stmt->setUInt32(2, pet->GetCharmInfo()->GetPetNumber());
    trans->Append(stmt);

    CharacterDatabase.CommitTransaction(trans);

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped
}
Esempio n. 25
0
uint8 WorldSession::HandleLoadPetFromDBFirstCallback(PreparedQueryResult result, uint8 asynchLoadType)
{
    if (!GetPlayer() || GetPlayer()->GetPet() || GetPlayer()->GetVehicle() || GetPlayer()->IsSpectator())
        return PET_LOAD_ERROR;

    if (!result)
        return PET_LOAD_NO_RESULT;

    Field* fields = result->Fetch();

	// Xinef: this can happen if fetch is called twice, impossibru.
	if (!fields)
		return PET_LOAD_ERROR;

	Player* owner = GetPlayer();

    // update for case of current pet "slot = 0"
    uint32 petentry = fields[1].GetUInt32();
    if (!petentry)
        return PET_LOAD_NO_RESULT;

	uint8 petSlot = fields[7].GetUInt8();
	bool current = petSlot == PET_SAVE_AS_CURRENT;
    uint32 summon_spell_id = fields[15].GetUInt32();
    SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summon_spell_id); // CANT BE NULL
    bool is_temporary_summoned = spellInfo && spellInfo->GetDuration() > 0;
    uint32 pet_number = fields[0].GetUInt32();
	uint32 savedhealth = fields[10].GetUInt32();
    uint32 savedmana = fields[11].GetUInt32();
	PetType pet_type = PetType(fields[16].GetUInt8());

	// xinef: BG resurrect, overwrite saved value
	if (asynchLoadType == PET_LOAD_BG_RESURRECT)
		savedhealth = 1;

	if (pet_type == HUNTER_PET && savedhealth == 0 && asynchLoadType != PET_LOAD_SUMMON_DEAD_PET)
	{
		WorldPacket data(SMSG_CAST_FAILED, 1+4+1+4);
        data << uint8(0);
        data << uint32(883);
        data << uint8(SPELL_FAILED_TARGETS_DEAD);
        SendPacket(&data);
		owner->RemoveSpellCooldown(883, false);
		return PET_LOAD_ERROR;
	}

    // check temporary summoned pets like mage water elemental
    if (current && is_temporary_summoned)
        return PET_LOAD_ERROR;

    if (pet_type == HUNTER_PET)
    {
        CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petentry);
        if (!creatureInfo || !creatureInfo->IsTameable(owner->CanTameExoticPets()))
            return PET_LOAD_ERROR;
    }

    Map* map = owner->GetMap();
    uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_PET);
	Pet* pet = new Pet(owner, pet_type);
	LoadPetFromDBQueryHolder* holder = new LoadPetFromDBQueryHolder(pet_number, current, uint32(time(NULL) - fields[14].GetUInt32()), fields[13].GetString(), savedhealth, savedmana);
    if (!pet->Create(guid, map, owner->GetPhaseMask(), petentry, pet_number) || !holder->Initialize())
	{
		delete pet;
		delete holder;
        return PET_LOAD_ERROR;
	}

    float px, py, pz;
    owner->GetClosePoint(px, py, pz, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
    if (!pet->IsPositionValid())
    {
        sLog->outError("Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", pet->GetGUIDLow(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY());
		delete pet;
		delete holder;
        return PET_LOAD_ERROR;
    }

	pet->SetLoading(true);
    pet->Relocate(px, py, pz, owner->GetOrientation());
    pet->setPetType(pet_type);
    pet->setFaction(owner->getFaction());
    pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);

    if (pet->IsCritter())
    {
        map->AddToMap(pet->ToCreature(), true);
		pet->SetLoading(false); // xinef, mine
		delete holder;
        return PET_LOAD_OK;
    }

    pet->GetCharmInfo()->SetPetNumber(pet_number, pet->IsPermanentPetFor(owner));

    pet->SetDisplayId(fields[3].GetUInt32());
    pet->SetNativeDisplayId(fields[3].GetUInt32());
    uint32 petlevel = fields[4].GetUInt8();
    pet->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
    pet->SetName(fields[8].GetString());

    switch (pet->getPetType())
    {
        case SUMMON_PET:
            petlevel = owner->getLevel();

			if (pet->IsPetGhoul())
				pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 0x400); // class = rogue
			else
				pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 0x800); // class = mage

            pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
                                                            // this enables popup window (pet dismiss, cancel)
            break;
        case HUNTER_PET:
            pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); // class = warrior, gender = none, power = focus
            pet->SetSheath(SHEATH_STATE_MELEE);
            pet->SetByteFlag(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_CAN_BE_ABANDONED : UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);

            pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
                                                            // this enables popup window (pet abandon, cancel)
            pet->SetMaxPower(POWER_HAPPINESS, pet->GetCreatePowers(POWER_HAPPINESS));
            pet->SetPower(POWER_HAPPINESS, fields[12].GetUInt32());
            pet->setPowerType(POWER_FOCUS);
            break;
        default:
            if (!pet->IsPetGhoul())
                sLog->outError("Pet have incorrect type (%u) for pet loading.", pet->getPetType());
            break;
    }

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped here
    pet->SetCreatorGUID(owner->GetGUID());
	owner->SetMinion(pet, true);

    pet->InitStatsForLevel(petlevel);
    pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32());

    pet->SynchronizeLevelWithOwner();

    pet->SetReactState(ReactStates(fields[6].GetUInt8()));
    pet->SetCanModifyStats(true);

    // set current pet as current
    // 0=current
    // 1..MAX_PET_STABLES in stable slot
    // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
    if (petSlot)
    {
        SQLTransaction trans = CharacterDatabase.BeginTransaction();

        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID);
        stmt->setUInt8(0, uint8(PET_SAVE_NOT_IN_SLOT));
        stmt->setUInt32(1, owner->GetGUIDLow());
        stmt->setUInt8(2, uint8(PET_SAVE_AS_CURRENT));
        stmt->setUInt32(3, pet_number);
        trans->Append(stmt);

        stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID);
        stmt->setUInt8(0, uint8(PET_SAVE_AS_CURRENT));
        stmt->setUInt32(1, owner->GetGUIDLow());
        stmt->setUInt32(2, pet_number);
        trans->Append(stmt);

        CharacterDatabase.CommitTransaction(trans);
    }

    // Send fake summon spell cast - this is needed for correct cooldown application for spells
    // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside
    // TODO: pets should be summoned from real cast instead of just faking it?
    if (summon_spell_id)
    {
        WorldPacket data(SMSG_SPELL_GO, (8+8+4+4+2));
        data.append(owner->GetPackGUID());
        data.append(owner->GetPackGUID());
        data << uint8(0);
        data << uint32(summon_spell_id);
        data << uint32(256); // CAST_FLAG_UNKNOWN3
        data << uint32(0);
        owner->SendMessageToSet(&data, true);
    }

	// do it as early as possible!
	pet->InitTalentForLevel();                                   // set original talents points before spell loading
	if (!is_temporary_summoned)
		pet->GetCharmInfo()->InitPetActionBar();

    map->AddToMap(pet->ToCreature(), true);
    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));
    else
    {
        pet->SetHealth(savedhealth > pet->GetMaxHealth() ? pet->GetMaxHealth() : savedhealth);
        pet->SetPower(POWER_MANA, savedmana > pet->GetMaxPower(POWER_MANA) ? pet->GetMaxPower(POWER_MANA) : savedmana);
    }

	pet->SetAsynchLoadType(asynchLoadType);

	// xinef: clear any old result
	if (_loadPetFromDBSecondCallback.ready())
	{
		SQLQueryHolder* param;
		_loadPetFromDBSecondCallback.get(param);
		delete param;
	}
	_loadPetFromDBSecondCallback.cancel();

    _loadPetFromDBSecondCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
	return PET_LOAD_OK;
}
Esempio n. 26
0
void CPlayer::CreatePet(uint32 entry, bool classcheck)
{
    if (classcheck && getClass() != CLASS_HUNTER)
        return;

    CreatureInfo const *cinfo = sObjectMgr.GetCreatureTemplate(entry);
    if (!cinfo)
    {
        BoxChat << MSG_COLOR_WHITE << " This pet doesn't exist in our database. Please report that creature " << entry << " is missing." << std::endl;
        return;
    }

    CreatureCreatePos pos(GetSession()->GetPlayer(), GetOrientation());

    Creature* pCreature = new Creature;

    // used guids from specially reserved range (can be 0 if no free values)
    uint32 lowguid = sObjectMgr.GenerateStaticCreatureLowGuid();
    if (!lowguid)
        return;

    if (!pCreature->Create(lowguid, pos, cinfo))
    {
        delete pCreature;
        return;
    }

    //--------------------------------------------------

    if (GetPetGuid())
        UnsummonPetTemporaryIfAny();

    Pet* pet = new Pet(HUNTER_PET);

    if (!pet->CreateBaseAtCreature(pCreature))
    {
        delete pet;
        return;
    }

    pet->SetOwnerGuid(GetObjectGuid());
    pet->SetCreatorGuid(GetObjectGuid());
    pet->setFaction(getFaction());
    pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, 13481);

    if (IsPvP())
        pet->SetPvP(true);

    if (!pet->InitStatsForLevel(pCreature->getLevel()))
    {
        sLog.outError("Pet::InitStatsForLevel() failed for creature (Entry: %u)!", pCreature->GetEntry());
        delete pet;
        return;
    }

    pet->GetCharmInfo()->SetPetNumber(sObjectMgr.GeneratePetNumber(), true);
    // this enables pet details window (Shift+P)
    pet->AIM_Initialize();
    pet->InitPetCreateSpells();
    pet->SetHealth(pet->GetMaxHealth());

    // add to world
    pet->GetMap()->Add((Creature*)pet);

    // visual effect for levelup
    pet->SetUInt32Value(UNIT_FIELD_LEVEL, 70);

    for (auto x = 0; x < 6; x++)
    {
        pet->SetPower(POWER_HAPPINESS, 66600000);
        pet->ModifyLoyalty(150000);
        pet->TickLoyaltyChange();
        pet->SetTP(350);
    }

    // caster have pet now
    SetPet(pet);

    pet->SavePetToDB(PET_SAVE_AS_CURRENT);
    PetSpellInitialize();
    pet->learnSpell(27052);
    pet->learnSpell(35698);
    pet->learnSpell(25076);
    pet->learnSpell(27048);
    pet->learnSpell(27053);
    pet->learnSpell(27054);
    pet->learnSpell(27062);
    pet->learnSpell(27047);
    pet->learnSpell(24551);
    delete pCreature;
}
Esempio n. 27
0
void WorldSession::HandlePetRename(WorldPacket & recv_data)
{
    sLog->outDetail("HandlePetRename. CMSG_PET_RENAME");

    uint64 petguid;
    uint8 isdeclined;

    std::string name;
    DeclinedName declinedname;

    recv_data >> petguid;
    recv_data >> name;
    recv_data >> isdeclined;

    Pet* pet = ObjectAccessor::FindPet(petguid);
                                                            // check it!
    if (!pet || !pet->isPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET ||
        !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ||
        pet->GetOwnerGUID() != _player->GetGUID() || !pet->GetCharmInfo())
        return;

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name);
    if (res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name, NULL);
        return;
    }

    if (sObjectMgr->IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name, NULL);
        return;
    }

    pet->SetName(name);

    Unit* owner = pet->GetOwner();
    if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
        owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);

    if (isdeclined)
    {
        for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
        {
            recv_data >> declinedname.name[i];
        }

        std::wstring wname;
        Utf8toWStr(name, wname);
        if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
        {
            SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
            return;
        }
    }

    SQLTransaction trans = CharacterDatabase.BeginTransaction();
    if (isdeclined)
    {
        for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
            CharacterDatabase.EscapeString(declinedname.name[i]);
        trans->PAppend("DELETE FROM character_pet_declinedname WHERE owner = '%u' AND id = '%u'", _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
        trans->PAppend("INSERT INTO character_pet_declinedname (id, owner, genitive, dative, accusative, instrumental, prepositional) VALUES ('%u', '%u', '%s', '%s', '%s', '%s', '%s')",
            pet->GetCharmInfo()->GetPetNumber(), _player->GetGUIDLow(), declinedname.name[0].c_str(), declinedname.name[1].c_str(), declinedname.name[2].c_str(), declinedname.name[3].c_str(), declinedname.name[4].c_str());
    }

    CharacterDatabase.EscapeString(name);
    trans->PAppend("UPDATE character_pet SET name = '%s', renamed = '1' WHERE owner = '%u' AND id = '%u'", name.c_str(), _player->GetGUIDLow(), pet->GetCharmInfo()->GetPetNumber());
    CharacterDatabase.CommitTransaction(trans);

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped
}
Esempio n. 28
0
bool ChatHandler::HandleCreatePetCommand(const char* /*args*/)
{
    Player* player = m_session->GetPlayer();
    Creature* creatureTarget = getSelectedCreature();

    if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER)
    {
        PSendSysMessage(LANG_SELECT_CREATURE);
        SetSentErrorMessage(true);
        return false;
    }

    CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry());
    // Creatures with family 0 crashes the server
    if (cInfo->family == 0)
    {
        PSendSysMessage("This creature cannot be tamed. (family id: 0).");
        SetSentErrorMessage(true);
        return false;
    }

    if (player->GetPetGUID())
    {
        PSendSysMessage("You already have a pet");
        SetSentErrorMessage(true);
        return false;
    }

    // Everything looks OK, create new pet
    Pet* pet = new Pet(player, HUNTER_PET);
    if (!pet->CreateBaseAtCreature(creatureTarget))
    {
        delete pet;
        PSendSysMessage("Error 1");
        return false;
    }

    creatureTarget->setDeathState(JUST_DIED);
    creatureTarget->RemoveCorpse();
    creatureTarget->SetHealth(0); // just for nice GM-mode view

    pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID());
    pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction());

    if (!pet->InitStatsForLevel(creatureTarget->getLevel()))
    {
        sLog->outError("InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
        PSendSysMessage("Error 2");
        delete pet;
        return false;
    }

    // prepare visual effect for levelup
    pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1);

    pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
    // this enables pet details window (Shift+P)
    pet->InitPetCreateSpells();
    pet->SetFullHealth();

    pet->GetMap()->AddToMap(pet->ToCreature());

    // visual effect for levelup
    pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel());

    player->SetMinion(pet, true);
    pet->SavePetToDB(PET_SAVE_AS_CURRENT);
    player->PetSpellInitialize();

    return true;
}
Esempio n. 29
0
void WorldSession::HandlePetRename(WorldPacket & recvData)
{
    TC_LOG_INFO("network", "HandlePetRename. CMSG_PET_RENAME");

    std::string name;
    DeclinedName declinedname;
    uint8 declinedNameLength[MAX_DECLINED_NAME_CASES] = {0, 0, 0, 0, 0};

    recvData.read_skip<uint32>();   // unk, client send 2048, maybe flags ?
    bool hasName = !recvData.ReadBit();
    bool isdeclined = recvData.ReadBit();

    if (isdeclined)
        for(int i = 0; i < MAX_DECLINED_NAME_CASES; i++)
            declinedNameLength[i] = recvData.ReadBits(7);

    if (hasName)
    {
        uint8 nameLenght = recvData.ReadBits(8);
        name = recvData.ReadString(nameLenght);
    }

    Pet* pet = GetPlayer()->GetPet();
                                                            // check it!
    if (!pet || !pet->isPet() || pet->getPetType() != HUNTER_PET
            || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED)
            || pet->GetOwnerGUID() != _player->GetGUID()
            || !pet->GetCharmInfo())
    {
        return;
    }

    PetNameInvalidReason res = ObjectMgr::CheckPetName(name);
    if (res != PET_NAME_SUCCESS)
    {
        SendPetNameInvalid(res, name, NULL);
        return;
    }

    if (sObjectMgr->IsReservedName(name))
    {
        SendPetNameInvalid(PET_NAME_RESERVED, name, NULL);
        return;
    }

    pet->SetName(name);

    Player* owner = pet->GetOwner();
    if (owner && owner->GetGroup())
        owner->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_NAME);

    pet->RemoveByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);

    if (isdeclined)
    {
        for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
            declinedname.name[i] = recvData.ReadString(declinedNameLength[i]);

        std::wstring wname;
        Utf8toWStr(name, wname);
        if (!ObjectMgr::CheckDeclinedNames(wname, declinedname))
        {
            SendPetNameInvalid(PET_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME, name, &declinedname);
            return;
        }
    }

    SQLTransaction trans = CharacterDatabase.BeginTransaction();
    if (isdeclined)
    {
        PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PET_DECLINED_NAME);
        stmt->setUInt32(0, pet->GetCharmInfo()->GetPetNumber());
        trans->Append(stmt);

        stmt = CharacterDatabase.GetPreparedStatement(CHAR_ADD_PET_DECLINED_NAME);
        stmt->setUInt32(0, _player->GetGUIDLow());

        for (uint8 i = 0; i < 5; i++)
            stmt->setString(i+1, declinedname.name[i]);

        trans->Append(stmt);
    }

    CharacterDatabase.CommitTransaction(trans);

    pet->SavePetToDB();

    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped
}