diff options
author | megamage <none@none> | 2009-06-06 20:31:23 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-06-06 20:31:23 -0500 |
commit | ebfb4c05586498e9a2796bd64b923a82bbeb7004 (patch) | |
tree | e13aa0c3c6232b194f84e9aacf491b2d0ad5fb58 /src | |
parent | 724e5fe5ce7c91f9f144602a94720a33da845777 (diff) |
[7971] Implement support exotic pets limtations related to hunter telent 53270. Author: VladimirMangos
Note: before this commit hunters can tame exotic pets like any other.
After patch like not propertly contriolled pets will auto-dismiss at loading
if talent not learned.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/CharacterHandler.cpp | 4 | ||||
-rw-r--r-- | src/game/Creature.h | 8 | ||||
-rw-r--r-- | src/game/Level2.cpp | 2 | ||||
-rw-r--r-- | src/game/NPCHandler.cpp | 90 | ||||
-rw-r--r-- | src/game/Pet.cpp | 15 | ||||
-rw-r--r-- | src/game/Player.cpp | 8 | ||||
-rw-r--r-- | src/game/Player.h | 1 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 9 | ||||
-rw-r--r-- | src/game/Spell.cpp | 9 |
9 files changed, 109 insertions, 37 deletions
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 51731c11a98..e8a0e2b6bf1 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -164,7 +164,7 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) // ------- Query Without Declined Names -------- // 0 1 2 3 4 5 6 7 8 "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " - // 9 10 11 12 13 14 + // 9 10 11 12 13 14 "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN guild_member ON characters.guid = guild_member.guid " @@ -173,7 +173,7 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) // --------- Query With Declined Names --------- // 0 1 2 3 4 5 6 7 8 "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " - // 9 10 11 12 13 14 15 + // 9 10 11 12 13 14 15 "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " diff --git a/src/game/Creature.h b/src/game/Creature.h index 68c353205f7..6c966f50aea 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -258,9 +258,13 @@ struct CreatureInfo return SKILL_SKINNING; // normal case } - bool isTameable() const + bool isTameable(bool exotic) const { - return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEABLE); + if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE)==0) + return false; + + // if can tame exotic then can tame any temable + return exotic || (type_flags & CREATURE_TYPEFLAGS_EXOTIC)==0; } }; diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 31834fce8ea..12727bd6f82 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1827,7 +1827,7 @@ bool ChatHandler::HandleNpcTameCommand(const char* /*args*/) CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); - if (!cInfo->isTameable ()) + if (!cInfo->isTameable (player->CanTameExoticPets())) { PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); SetSentErrorMessage (true); diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 7257a8d2682..72fa626fdcb 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -593,11 +593,10 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) Pet *pet = _player->GetPet(); - WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size - // can't place in stable dead pet if(!pet||!pet->isAlive()||pet->getPetType()!=HUNTER_PET) { + WorldPacket data(SMSG_STABLE_RESULT, 1); data << uint8(0x06); SendPacket(&data); return; @@ -626,6 +625,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data ) delete result; } + WorldPacket data(SMSG_STABLE_RESULT, 1); if( free_slot > 0 && free_slot <= GetPlayer()->m_stableSlots) { _player->RemovePet(pet,PetSaveMode(free_slot)); @@ -658,11 +658,40 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - WorldPacket data(SMSG_STABLE_RESULT, 200); // guess size + uint32 creature_id = 0; + + { + QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'", + _player->GetGUIDLow(),petnumber,PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT); + if(result) + { + Field *fields = result->Fetch(); + creature_id = fields[0].GetUInt32(); + delete result; + } + } + + if(!creature_id) + { + WorldPacket data(SMSG_STABLE_RESULT, 1); + data << uint8(0x06); + SendPacket(&data); + return; + } + + CreatureInfo const* creatureInfo = objmgr.GetCreatureTemplate(creature_id); + if(!creatureInfo || !creatureInfo->isTameable(_player->CanTameExoticPets())) + { + WorldPacket data(SMSG_STABLE_RESULT, 1); + data << uint8(0x06); + SendPacket(&data); + return; + } Pet* pet = _player->GetPet(); if(pet && pet->isAlive()) { + WorldPacket data(SMSG_STABLE_RESULT, 1); data << uint8(0x06); SendPacket(&data); return; @@ -672,28 +701,19 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data ) if(pet) _player->RemovePet(pet,PET_SAVE_AS_DELETED); - Pet *newpet = NULL; - - QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot >='%u' AND slot <= '%u'", - _player->GetGUIDLow(),petnumber,PET_SAVE_FIRST_STABLE_SLOT,PET_SAVE_LAST_STABLE_SLOT); - if(result) + Pet *newpet = new Pet(_player, HUNTER_PET); + if(!newpet->LoadPetFromDB(_player,creature_id,petnumber)) { - Field *fields = result->Fetch(); - uint32 petentry = fields[0].GetUInt32(); - - newpet = new Pet(_player, HUNTER_PET); - if(!newpet->LoadPetFromDB(_player,petentry,petnumber)) - { - delete newpet; - newpet = NULL; - } - delete result; + delete newpet; + newpet = NULL; + WorldPacket data(SMSG_STABLE_RESULT, 1); + data << uint8(0x06); + SendPacket(&data); + return; } - if(newpet) - data << uint8(0x09); - else - data << uint8(0x06); + WorldPacket data(SMSG_STABLE_RESULT, 1); + data << uint8(0x09); SendPacket(&data); } @@ -778,16 +798,38 @@ void WorldSession::HandleStableSwapPet( WorldPacket & recv_data ) Field *fields = result->Fetch(); - uint32 slot = fields[0].GetUInt32(); - uint32 petentry = fields[1].GetUInt32(); + uint32 slot = fields[0].GetUInt32(); + uint32 creature_id = fields[1].GetUInt32(); delete result; + if(!creature_id) + { + WorldPacket data(SMSG_STABLE_RESULT, 1); + data << uint8(0x06); + SendPacket(&data); + return; + } + + CreatureInfo const* creatureInfo = objmgr.GetCreatureTemplate(creature_id); + if(!creatureInfo || !creatureInfo->isTameable(_player->CanTameExoticPets())) + { + WorldPacket data(SMSG_STABLE_RESULT, 1); + data << uint8(0x06); + SendPacket(&data); + return; + } + // move alive pet to slot or delete dead pet _player->RemovePet(pet,pet->isAlive() ? PetSaveMode(slot) : PET_SAVE_AS_DELETED); // summon unstabled pet +<<<<<<< HEAD:src/game/NPCHandler.cpp Pet *newpet = new Pet(_player); if(!newpet->LoadPetFromDB(_player,petentry,pet_number)) +======= + Pet *newpet = new Pet; + if(!newpet->LoadPetFromDB(_player,creature_id,pet_number)) +>>>>>>> b8ce292c7048fb8c4e4a06971c3859efe2421f28:src/game/NPCHandler.cpp { delete newpet; data << uint8(0x06); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index caf37a6a61f..51570e0750a 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -139,8 +139,19 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool return false; } - uint32 pet_number = fields[0].GetUInt32(); + PetType pet_type = PetType(fields[18].GetUInt8()); + if(pet_type==HUNTER_PET) + { + CreatureInfo const* creatureInfo = objmgr.GetCreatureTemplate(petentry); + if(!creatureInfo || !creatureInfo->isTameable(owner->CanTameExoticPets())) + { + delete result; + return false; + } + } + uint32 pet_number = fields[0].GetUInt32(); + if (current && owner->IsPetNeedBeTemporaryUnsummoned()) { owner->SetTemporaryUnsummonedPetNumber(pet_number); @@ -168,7 +179,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool return false; } - setPetType(PetType(fields[18].GetUInt8())); + setPetType(pet_type); setFaction(owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4f0bd135df3..8bbb27a61d9 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -3558,6 +3558,14 @@ bool Player::resetTalents(bool no_cost) //FIXME: remove pet before or after unlearn spells? for now after unlearn to allow removing of talent related, pet affecting auras RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true); + /* when prev line will dropped use next line + if(Pet* pet = GetPet()) + { + if(pet->getPetType()==HUNTER_PET && !pet->GetCreatureInfo()->isTameable(CanTameExoticPets())) + RemovePet(NULL,PET_SAVE_NOT_IN_SLOT, true); + } + */ + if(m_canTitanGrip) { diff --git a/src/game/Player.h b/src/game/Player.h index e9f520c0284..12d9c4c5efd 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1723,6 +1723,7 @@ class TRINITY_DLL_SPEC Player : public Unit void SetCanBlock(bool value); bool CanTitanGrip() const { return m_canTitanGrip ; } void SetCanTitanGrip(bool value) { m_canTitanGrip = value; } + bool CanTameExoticPets() const { return isGameMaster() || HasAuraType(SPELL_AURA_ALLOW_TAME_PET_TYPE); } void SetRegularAttackTime(); void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; } diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 44654fb1b0b..d2c9ba31564 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1877,10 +1877,11 @@ enum CreatureFamily enum CreatureTypeFlags { - CREATURE_TYPEFLAGS_TAMEABLE = 0x0001, - CREATURE_TYPEFLAGS_HERBLOOT = 0x0100, - CREATURE_TYPEFLAGS_MININGLOOT = 0x0200, - CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x8000 + CREATURE_TYPEFLAGS_TAMEABLE = 0x00001, + CREATURE_TYPEFLAGS_HERBLOOT = 0x00100, + CREATURE_TYPEFLAGS_MININGLOOT = 0x00200, + CREATURE_TYPEFLAGS_ENGINEERLOOT = 0x08000, + CREATURE_TYPEFLAGS_EXOTIC = 0x10000 }; enum CreatureEliteType diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index f7fb0137c78..a40f184cb61 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4672,14 +4672,19 @@ SpellCastResult Spell::CheckCast(bool strict) break; case 1515: { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_BAD_TARGETS; + if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel()) + Creature* target = (Creature*)m_targets.getUnitTarget(); + + if (target->getLevel() > m_caster->getLevel()) return SPELL_FAILED_HIGHLEVEL; // use SMSG_PET_TAME_FAILURE? - if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ()) + if (!target->GetCreatureInfo()->isTameable (((Player*)m_caster)->CanTameExoticPets())) return SPELL_FAILED_BAD_TARGETS; if(m_caster->GetPetGUID()) |