diff --git a/data/sql/updates/pending_db_world/rev_1674957729661075800.sql b/data/sql/updates/pending_db_world/rev_1674957729661075800.sql new file mode 100644 index 000000000..2a2b42c47 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1674957729661075800.sql @@ -0,0 +1,4 @@ +-- +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_rog_pickpocket'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(921,'spell_rog_pickpocket'); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 789cd1c43..01697f0ba 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -7878,7 +7878,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type) if (loot_type == LOOT_PICKPOCKETING) { - if (loot->loot_type != LOOT_PICKPOCKETING) + if (!loot || loot->loot_type != LOOT_PICKPOCKETING) { if (creature->CanGeneratePickPocketLoot()) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index da1ba7430..861679b7d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13778,9 +13778,9 @@ bool Unit::isTargetableForAttack(bool checkFakeDeath, Unit const* byWho) const return !HasUnitState(UNIT_STATE_UNATTACKABLE) && (!checkFakeDeath || !HasUnitState(UNIT_STATE_DIED)); } -bool Unit::IsValidAttackTarget(Unit const* target) const +bool Unit::IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) const { - return _IsValidAttackTarget(target, nullptr); + return _IsValidAttackTarget(target, bySpell); } // function based on function Unit::CanAttack from 13850 client diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index e0d02fd23..ba35c7c30 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1713,7 +1713,7 @@ public: bool isTargetableForAttack(bool checkFakeDeath = true, Unit const* byWho = nullptr) const; - bool IsValidAttackTarget(Unit const* target) const; + bool IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell = nullptr) const; bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj = nullptr) const; bool IsValidAssistTarget(Unit const* target) const; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 298f26e78..49f6cd7ca 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -2719,13 +2719,7 @@ void Spell::EffectPickPocket(SpellEffIndex /*effIndex*/) if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - // victim must be creature and attackable - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || m_caster->IsFriendlyTo(unitTarget)) - return; - - // victim have to be alive and humanoid or undead - if (unitTarget->IsAlive() && (unitTarget->GetCreatureTypeMask() &CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) != 0) - m_caster->ToPlayer()->SendLoot(unitTarget->GetGUID(), LOOT_PICKPOCKETING); + m_caster->ToPlayer()->SendLoot(unitTarget->GetGUID(), LOOT_PICKPOCKETING); } void Spell::EffectAddFarsight(SpellEffIndex effIndex) diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 84180db95..a6845e5f3 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -19,6 +19,7 @@ #include "Chat.h" #include "ConditionMgr.h" #include "DBCStores.h" +#include "LootMgr.h" #include "Player.h" #include "ScriptMgr.h" #include "Spell.h" @@ -1777,11 +1778,13 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(caster->ToPlayer())) return SPELL_FAILED_CANT_CAST_ON_TAPPED; - if (AttributesCu & SPELL_ATTR0_CU_PICKPOCKET) + if (HasAttribute(SPELL_ATTR0_CU_PICKPOCKET)) { - if (unitTarget->GetTypeId() == TYPEID_PLAYER) + Creature const* targetCreature = unitTarget->ToCreature(); + if (!targetCreature) return SPELL_FAILED_BAD_TARGETS; - else if ((unitTarget->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD) == 0) + + if (!LootTemplates_Pickpocketing.HaveLootFor(targetCreature->GetCreatureTemplate()->pickpocketLootId)) return SPELL_FAILED_TARGET_NO_POCKETS; } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index bb6b8b9e2..b5965edf3 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -675,6 +675,24 @@ class spell_rog_tricks_of_the_trade_proc : public AuraScript } }; +class spell_rog_pickpocket : public SpellScript +{ + PrepareSpellScript(spell_rog_pickpocket); + + SpellCastResult CheckCast() + { + if (!GetExplTargetUnit() || !GetCaster()->IsValidAttackTarget(GetExplTargetUnit(), GetSpellInfo())) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void Register() override + { + OnCheckCast += SpellCheckCastFn(spell_rog_pickpocket::CheckCast); + } +}; + void AddSC_rogue_spell_scripts() { RegisterSpellScript(spell_rog_savage_combat); @@ -690,4 +708,5 @@ void AddSC_rogue_spell_scripts() RegisterSpellScript(spell_rog_shiv); RegisterSpellScript(spell_rog_tricks_of_the_trade); RegisterSpellScript(spell_rog_tricks_of_the_trade_proc); + RegisterSpellScript(spell_rog_pickpocket); }