Skip to content

Commit d598919

Browse files
committed
Implement SPELL_FAILED_ALREADY_BEING_TAMED.
1 parent 9bdbd33 commit d598919

3 files changed

Lines changed: 56 additions & 38 deletions

File tree

src/game/SharedDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1714,6 +1714,7 @@ enum MailResponseResult
17141714
// in fact, these are also used elsewhere
17151715
enum PetTameFailureReason
17161716
{
1717+
PETTAME_NONE = 0, // no error, don't send to client
17171718
PETTAME_INVALIDCREATURE = 1,
17181719
PETTAME_TOOMANY = 2,
17191720
PETTAME_CREATUREALREADYOWNED = 3,

src/game/Spells/Spell.cpp

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6209,6 +6209,30 @@ SpellCastResult Spell::CheckCast(bool strict)
62096209
return SPELL_FAILED_BAD_TARGETS;
62106210
}
62116211

6212+
if (m_spellInfo->HasAttribute(SPELL_ATTR_EX2_SPECIAL_TAMING_FLAG))
6213+
{
6214+
Player* pPlayer = m_caster->ToPlayer();
6215+
if (!pPlayer)
6216+
return SPELL_FAILED_BAD_TARGETS;
6217+
6218+
PetTameFailureReason result = CheckTamingSpell(pPlayer, false);
6219+
if (result != PETTAME_NONE)
6220+
{
6221+
pPlayer->SendPetTameFailure(result);
6222+
return SPELL_FAILED_DONT_REPORT;
6223+
}
6224+
6225+
auto const& auras = m_targets.getUnitTarget()->GetSpellAuraHolderMap();
6226+
for (auto const& itr : auras)
6227+
{
6228+
if (itr.second->IsDeleted())
6229+
continue;
6230+
6231+
if (itr.second->GetSpellProto()->HasAttribute(SPELL_ATTR_EX2_SPECIAL_TAMING_FLAG))
6232+
return SPELL_FAILED_ALREADY_BEING_TAMED;
6233+
}
6234+
}
6235+
62126236
for (uint8 i = 0; i < MAX_EFFECT_INDEX; ++i)
62136237
{
62146238
// for effects of spells that have only one target
@@ -6307,47 +6331,14 @@ SpellCastResult Spell::CheckCast(bool strict)
63076331
case SPELL_EFFECT_TAMECREATURE:
63086332
{
63096333
// Spell can be triggered, we need to check original caster prior to caster
6310-
Unit* caster = GetAffectiveCaster();
6311-
if (!caster || caster->GetTypeId() != TYPEID_PLAYER ||
6312-
!m_targets.getUnitTarget() ||
6313-
m_targets.getUnitTarget()->IsPlayer())
6334+
Player* pPlayer = ToPlayer(GetAffectiveCaster());
6335+
if (!pPlayer)
63146336
return SPELL_FAILED_BAD_TARGETS;
63156337

6316-
Player* plrCaster = (Player*)caster;
6317-
6318-
bool gmmode = m_triggeredBySpellInfo == nullptr;
6319-
6320-
if (plrCaster->GetClass() != CLASS_HUNTER && !gmmode)
6338+
PetTameFailureReason result = CheckTamingSpell(pPlayer, m_triggeredBySpellInfo == nullptr);
6339+
if (result != PETTAME_NONE)
63216340
{
6322-
plrCaster->SendPetTameFailure(PETTAME_UNITSCANTTAME);
6323-
return SPELL_FAILED_DONT_REPORT;
6324-
}
6325-
6326-
Creature* target = (Creature*)m_targets.getUnitTarget();
6327-
6328-
if (target->IsPet() || target->IsCharmed())
6329-
{
6330-
plrCaster->SendPetTameFailure(PETTAME_CREATUREALREADYOWNED);
6331-
return SPELL_FAILED_DONT_REPORT;
6332-
}
6333-
6334-
if (target->GetLevel() > plrCaster->GetLevel() && !gmmode)
6335-
{
6336-
plrCaster->SendPetTameFailure(PETTAME_TOOHIGHLEVEL);
6337-
return SPELL_FAILED_DONT_REPORT;
6338-
}
6339-
6340-
if (!target->GetCreatureInfo()->IsTameable())
6341-
{
6342-
plrCaster->SendPetTameFailure(PETTAME_NOTTAMEABLE);
6343-
return SPELL_FAILED_DONT_REPORT;
6344-
}
6345-
6346-
if (plrCaster->GetPetGuid() || plrCaster->GetCharmGuid() ||
6347-
(!plrCaster->IsSavingDisabled() &&
6348-
sCharacterDatabaseCache.GetCharacterPetByOwner(plrCaster->GetGUIDLow())))
6349-
{
6350-
plrCaster->SendPetTameFailure(PETTAME_ANOTHERSUMMONACTIVE);
6341+
pPlayer->SendPetTameFailure(result);
63516342
return SPELL_FAILED_DONT_REPORT;
63526343
}
63536344

@@ -7365,6 +7356,31 @@ bool Spell::CanAutoCast(Unit* target)
73657356
return false; //target invalid
73667357
}
73677358

7359+
PetTameFailureReason Spell::CheckTamingSpell(Player* caster, bool gm)
7360+
{
7361+
if (caster->GetClass() != CLASS_HUNTER && !gm)
7362+
return PETTAME_UNITSCANTTAME;
7363+
7364+
if (caster->GetPetGuid() || caster->GetCharmGuid() || (!caster->IsSavingDisabled() && sCharacterDatabaseCache.GetCharacterPetByOwner(caster->GetGUIDLow())))
7365+
return PETTAME_ANOTHERSUMMONACTIVE;
7366+
7367+
Creature* target = ToCreature(m_targets.getUnitTarget());
7368+
7369+
if (!target)
7370+
return PETTAME_INVALIDCREATURE;
7371+
7372+
if (target->IsPet() || target->IsCharmed())
7373+
return PETTAME_CREATUREALREADYOWNED;
7374+
7375+
if (target->GetLevel() > caster->GetLevel() && !gm)
7376+
return PETTAME_TOOHIGHLEVEL;
7377+
7378+
if (!target->GetCreatureInfo()->IsTameable())
7379+
return PETTAME_NOTTAMEABLE;
7380+
7381+
return PETTAME_NONE;
7382+
}
7383+
73687384
SpellCastResult Spell::CheckRange(bool strict)
73697385
{
73707386
Unit* target = m_targets.getUnitTarget();

src/game/Spells/Spell.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ class Spell
385385

386386
bool CheckTarget(Unit* target, SpellEffectIndex eff);
387387
bool CanAutoCast(Unit* target);
388+
PetTameFailureReason CheckTamingSpell(Player* caster, bool gm);
388389

389390
static void SendCastResult(Player* caster, SpellEntry const* spellInfo, SpellCastResult result);
390391
void SendCastResult(SpellCastResult result);

0 commit comments

Comments
 (0)