From 9eb5a3eea1606643fbe6044bd9d9349d7b43e370 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 20 Aug 2009 00:24:15 +0400 Subject: [PATCH] [8394] Fixes for some non-self only positive spells. * Propertly reject self targeting for pet spell 2947 and ranks, and spell 54646. * Some related fixes for pet spells with target mode TARGET_SINGLE_FRIEND_2 * Implement original caster bonus part of spell 54646. --- sql/mangos.sql | 3 +- .../8394_01_mangos_spell_proc_event.sql | 5 ++ sql/updates/Makefile.am | 2 + src/game/Spell.cpp | 42 +++++++++--- src/game/Unit.cpp | 68 +++++++++++++++++++ src/game/Unit.h | 1 + src/shared/revision_nr.h | 2 +- 7 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 sql/updates/8394_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 46631d957..415bef0d3 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_8392_02_mangos_spell_chain` bit(1) default NULL + `required_8394_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -17869,6 +17869,7 @@ INSERT INTO `spell_proc_event` VALUES (54488, 0x00000000, 0, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (54489, 0x00000000, 0, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (54490, 0x00000000, 0, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(54646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00015400, 0x00000002, 0.000000, 0.000000, 0), (54738, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (54747, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), (54749, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0), diff --git a/sql/updates/8394_01_mangos_spell_proc_event.sql b/sql/updates/8394_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..73afa3da5 --- /dev/null +++ b/sql/updates/8394_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8392_02_mangos_spell_chain required_8394_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (54646); +INSERT INTO `spell_proc_event` VALUES +(54646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00015400, 0x00000002, 0.000000, 0.000000, 0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 6931fbec0..71168d47d 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -85,6 +85,7 @@ pkgdata_DATA = \ 8377_01_mangos_spell_area.sql \ 8392_01_mangos_spell_proc_event.sql \ 8392_02_mangos_spell_chain.sql \ + 8394_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -150,4 +151,5 @@ EXTRA_DIST = \ 8377_01_mangos_spell_area.sql \ 8392_01_mangos_spell_proc_event.sql \ 8392_02_mangos_spell_chain.sql \ + 8394_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 19362bcef..1c745f496 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3859,19 +3859,34 @@ SpellCastResult Spell::CheckCast(bool strict) } } } - else if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster + else if (m_caster == target) { - // Additional check for some spells - // If 0 spell effect empty - client not send target data (need use selection) - // TODO: check it on next client version - if (m_targets.m_targetMask == TARGET_FLAG_SELF && - m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE) + + if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster { - if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection())) - m_targets.setUnitTarget(target); - else - return SPELL_FAILED_BAD_TARGETS; + // Additional check for some spells + // If 0 spell effect empty - client not send target data (need use selection) + // TODO: check it on next client version + if (m_targets.m_targetMask == TARGET_FLAG_SELF && + m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE) + { + if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection())) + m_targets.setUnitTarget(target); + else + return SPELL_FAILED_BAD_TARGETS; + } } + + // Some special spells with non-caster only mode + + // Fire Shield + if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && + m_spellInfo->SpellIconID == 16) + return SPELL_FAILED_BAD_TARGETS; + + // Focus Magic (main spell) + if (m_spellInfo->Id == 54646) + return SPELL_FAILED_BAD_TARGETS; } // check pet presents @@ -4679,7 +4694,12 @@ SpellCastResult Spell::CheckPetCast(Unit* target) bool need = false; for(uint32 i = 0; i < 3; ++i) { - if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES) + if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND_2 || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || + m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES) { need = true; if(!target) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f3d4aa9a2..dabb9ae62 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4524,6 +4524,68 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return true; } +bool Unit::HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown) +{ + SpellEntry const *triggeredByAuraSpell = triggeredByAura->GetSpellProto(); + + Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER + ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; + + uint32 triggered_spell_id = 0; + Unit* target = pVictim; + int32 basepoints0 = 0; + + switch(triggeredByAuraSpell->SpellFamilyName) + { + case SPELLFAMILY_MAGE: + { + switch(triggeredByAuraSpell->Id) + { + // Focus Magic + case 54646: + { + Unit* caster = triggeredByAura->GetCaster(); + if(!caster) + return false; + + triggered_spell_id = 54648; + target = caster; + break; + } + } + } + } + + // processed charge only counting case + if(!triggered_spell_id) + return true; + + SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); + + if(!triggerEntry) + { + sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",triggeredByAuraSpell->Id,triggered_spell_id); + return false; + } + + // default case + if(!target || target!=this && !target->isAlive()) + return false; + + if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) + return false; + + if(basepoints0) + CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); + else + CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); + + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); + + return true; +} + bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown) { SpellEntry const *dummySpell = triggeredByAura->GetSpellProto (); @@ -11142,6 +11204,12 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag triggeredByAura->SetInUse(false); continue; } + sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); + if (!HandleSpellCritChanceAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown)) + { + triggeredByAura->SetInUse(false); + continue; + } break; default: // nothing do, just charges counter diff --git a/src/game/Unit.h b/src/game/Unit.h index 6312968b0..9fc9d5160 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1551,6 +1551,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent ); bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); + bool HandleSpellCritChanceAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown); bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown); bool HandleMendingAuraProc(Aura* triggeredByAura); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 75b0b94c6..37059f288 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8393" + #define REVISION_NR "8394" #endif // __REVISION_NR_H__