aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-06-06 20:31:23 -0500
committermegamage <none@none>2009-06-06 20:31:23 -0500
commitebfb4c05586498e9a2796bd64b923a82bbeb7004 (patch)
treee13aa0c3c6232b194f84e9aacf491b2d0ad5fb58
parent724e5fe5ce7c91f9f144602a94720a33da845777 (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
-rw-r--r--src/game/CharacterHandler.cpp4
-rw-r--r--src/game/Creature.h8
-rw-r--r--src/game/Level2.cpp2
-rw-r--r--src/game/NPCHandler.cpp90
-rw-r--r--src/game/Pet.cpp15
-rw-r--r--src/game/Player.cpp8
-rw-r--r--src/game/Player.h1
-rw-r--r--src/game/SharedDefines.h9
-rw-r--r--src/game/Spell.cpp9
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())