[8671] Correctly send SMSG_PET_TAME_FAILED with appropriate value when taming fail instead of spell fail.

I also removed conditions from Spell::EffectTameCreature which are checked in Spell::CheckCast.

Signed-off-by: ApoC <apoc@nymfe.net>
This commit is contained in:
XTZGZoReX 2009-10-18 18:25:46 +02:00 committed by ApoC
parent 906b2784a2
commit 0e1854a936
7 changed files with 80 additions and 37 deletions

View file

@ -238,13 +238,18 @@ struct CreatureInfo
return SKILL_SKINNING; // normal case
}
bool IsExotic() const
{
return (type_flags & CREATURE_TYPEFLAGS_EXOTIC);
}
bool isTameable(bool exotic) const
{
if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE)==0)
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;
return exotic || !IsExotic();
}
};

View file

@ -12572,6 +12572,13 @@ bool Player::CanRewardQuest( Quest const *pQuest, uint32 reward, bool msg )
return true;
}
void Player::SendPetTameFailure(PetTameFailureReason reason)
{
WorldPacket data(SMSG_PET_TAME_FAILURE, 1);
data << uint8(reason);
GetSession()->SendPacket(&data);
}
void Player::AddQuest( Quest const *pQuest, Object *questGiver )
{
uint16 log_slot = FindQuestSlot( 0 );

View file

@ -1418,6 +1418,8 @@ class MANGOS_DLL_SPEC Player : public Unit
bool m_mailsLoaded;
bool m_mailsUpdated;
void SendPetTameFailure(PetTameFailureReason reason);
void SetBindPoint(uint64 guid);
void SendTalentWipeConfirm(uint64 guid);
void RewardRage( uint32 damage, uint32 weaponSpeedHitFactor, bool attacker );

View file

@ -2640,4 +2640,23 @@ enum MailResponseResult
MAIL_ERR_ITEM_HAS_EXPIRED = 21,
};
// reasons for why pet tame may fail
// in fact, these are also used elsewhere
enum PetTameFailureReason
{
PETTAME_INVALIDCREATURE = 0,
PETTAME_TOOMANY = 1,
PETTAME_CREATUREALREADYOWNED = 2,
PETTAME_NOTTAMEABLE = 3,
PETTAME_ANOTHERSUMMONACTIVE = 4,
PETTAME_UNITSCANTTAME = 5,
PETTAME_NOPETAVAILABLE = 6, // not used in taming
PETTAME_INTERNALERROR = 7,
PETTAME_TOOHIGHLEVEL = 8,
PETTAME_DEAD = 9, // not used in taming
PETTAME_NOTDEAD = 10, // not used in taming
PETTAME_CANTCONTROLEXOTIC = 11, // 3.x
PETTAME_UNKNOWNERROR = 12
};
#endif

View file

@ -4313,26 +4313,51 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_EFFECT_TAMECREATURE:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
if (m_caster->GetTypeId() != TYPEID_PLAYER ||
!m_targets.getUnitTarget() ||
m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER ||
m_targets.getUnitTarget()->isPet())
return SPELL_FAILED_BAD_TARGETS;
if (!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
Player* plrCaster = (Player*)m_caster;
if(plrCaster->getClass() != CLASS_HUNTER)
{
plrCaster->SendPetTameFailure(PETTAME_UNITSCANTTAME);
return SPELL_FAILED_DONT_REPORT;
}
Creature* target = (Creature*)m_targets.getUnitTarget();
if (target->getLevel() > m_caster->getLevel())
return SPELL_FAILED_HIGHLEVEL;
if(target->isPet() || target->isCharmed())
{
plrCaster->SendPetTameFailure(PETTAME_CREATUREALREADYOWNED);
return SPELL_FAILED_DONT_REPORT;
}
// use SMSG_PET_TAME_FAILURE?
if (!target->GetCreatureInfo()->isTameable (((Player*)m_caster)->CanTameExoticPets()))
return SPELL_FAILED_BAD_TARGETS;
if (target->getLevel() > plrCaster->getLevel())
{
plrCaster->SendPetTameFailure(PETTAME_TOOHIGHLEVEL);
return SPELL_FAILED_DONT_REPORT;
}
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
if (target->GetCreatureInfo()->IsExotic() && !plrCaster->CanTameExoticPets())
{
plrCaster->SendPetTameFailure(PETTAME_CANTCONTROLEXOTIC);
return SPELL_FAILED_DONT_REPORT;
}
if(m_caster->GetCharmGUID())
return SPELL_FAILED_ALREADY_HAVE_CHARM;
if (!target->GetCreatureInfo()->isTameable(plrCaster->CanTameExoticPets()))
{
plrCaster->SendPetTameFailure(PETTAME_NOTTAMEABLE);
return SPELL_FAILED_DONT_REPORT;
}
if(plrCaster->GetPetGUID() || plrCaster->GetCharmGUID())
{
plrCaster->SendPetTameFailure(PETTAME_ANOTHERSUMMONACTIVE);
return SPELL_FAILED_DONT_REPORT;
}
break;
}

View file

@ -4097,35 +4097,23 @@ void Spell::EffectEnchantItemTmp(uint32 i)
void Spell::EffectTameCreature(uint32 /*i*/)
{
if(m_caster->GetPetGUID())
return;
if(!unitTarget)
return;
if(unitTarget->GetTypeId() == TYPEID_PLAYER)
return;
// Caster must be player, checked in Spell::CheckCast
Player* plr = (Player*)m_caster;
Creature* creatureTarget = (Creature*)unitTarget;
if(creatureTarget->isPet())
return;
if(m_caster->getClass() != CLASS_HUNTER)
return;
// cast finish successfully
//SendChannelUpdate(0);
finish();
Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget,m_spellInfo->Id);
Pet* pet = plr->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
if(!pet) // in versy specific state like near world end/etc.
return;
// "kill" original creature
creatureTarget->ForcedDespawn();
uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
uint32 level = (creatureTarget->getLevel() < (plr->getLevel() - 5)) ? (plr->getLevel() - 5) : creatureTarget->getLevel();
// prepare visual effect for levelup
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
@ -4137,13 +4125,10 @@ void Spell::EffectTameCreature(uint32 /*i*/)
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
// caster have pet now
m_caster->SetPet(pet);
plr->SetPet(pet);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
{
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
((Player*)m_caster)->PetSpellInitialize();
}
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
plr->PetSpellInitialize();
}
void Spell::EffectSummonPet(uint32 i)

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8670"
#define REVISION_NR "8671"
#endif // __REVISION_NR_H__