From dd52461d4049cafb3ae281743b0740feb251bc5b Mon Sep 17 00:00:00 2001 From: krz Date: Tue, 23 Jun 2009 04:47:46 +0200 Subject: * Allow spells to trigger ItemCombatSpells if spell is melee/ranged damage based. Original patch by freegajnja * Tabs to spaces. --HG-- branch : trunk --- src/game/MapManager.cpp | 17 +++++++------- src/game/Player.cpp | 60 +++++++++++++++++++++++++++++++++++++++---------- src/game/Player.h | 3 ++- src/game/Spell.cpp | 9 ++++++-- 4 files changed, 65 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 5a66ab6cea8..d1f3824fc9d 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -252,22 +252,21 @@ MapManager::Update(time_t diff) uint32 i=0; MapMapType::iterator iter; std::vector update_queue(i_maps.size()); - omp_set_num_threads(sWorld.getConfig(CONFIG_NUMTHREADS)); - for(iter = i_maps.begin(), i=0;iter != i_maps.end(); ++iter, i++) - update_queue[i]=iter->second; + omp_set_num_threads(sWorld.getConfig(CONFIG_NUMTHREADS)); + for(iter = i_maps.begin(), i=0;iter != i_maps.end(); ++iter, i++) + update_queue[i]=iter->second; /* - gomp in gcc <4.4 version cannot parallelise loops using random access iterators - so until gcc 4.4 isnt standard, we need the update_queue workaround + gomp in gcc <4.4 version cannot parallelise loops using random access iterators + so until gcc 4.4 isnt standard, we need the update_queue workaround */ #pragma omp parallel for schedule(dynamic) private(i) shared(update_queue) for(int32 i = 0; i < i_maps.size(); ++i) { checkAndCorrectGridStatesArray(); // debugging code, should be deleted some day - update_queue[i]->Update(i_timer.GetCurrent()); - sWorld.RecordTimeDiff("UpdateMap %u", update_queue[i]->GetId()); - // sLog.outError("This is thread %d out of %d threads,updating map %u",omp_get_thread_num(),omp_get_num_threads(),iter->second->GetId()); - + update_queue[i]->Update(i_timer.GetCurrent()); + sWorld.RecordTimeDiff("UpdateMap %u", update_queue[i]->GetId()); + // sLog.outError("This is thread %d out of %d threads,updating map %u",omp_get_thread_num(),omp_get_num_threads(),iter->second->GetId()); } ObjectAccessor::Instance().Update(i_timer.GetCurrent()); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c449c53b23b..b24b3da2ace 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -6990,17 +6990,53 @@ void Player::UpdateEquipSpellsAtFormChange() } } } - -void Player::CastItemCombatSpell(Item *item, CalcDamageInfo *damageInfo, ItemPrototype const * proto) +void Player::CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx) { - Unit * Target = damageInfo->target; - WeaponAttackType attType = damageInfo->attackType; - - if (!Target || Target == this ) + if(!target || !target->isAlive() || target == this) return; + for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) + { + // If usable, try to cast item spell + if (Item * item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i)) + if(!item->IsBroken()) + if (ItemPrototype const *proto = item->GetProto()) + { + // Additional check for weapons + if (proto->Class==ITEM_CLASS_WEAPON) + { + // offhand item cannot proc from main hand hit etc + EquipmentSlots slot; + switch (attType) + { + case BASE_ATTACK: slot = EQUIPMENT_SLOT_MAINHAND; break; + case OFF_ATTACK: slot = EQUIPMENT_SLOT_OFFHAND; break; + case RANGED_ATTACK: slot = EQUIPMENT_SLOT_RANGED; break; + default: slot = EQUIPMENT_SLOT_END; break; + } + if (slot != i) + continue; + // Check if item is useable (forms or disarm) + if (attType == BASE_ATTACK) + { + if (!((Player*)this)->IsUseEquipedWeapon(true)) + continue; + } + else + { + if (((Player*)this)->IsInFeralForm()) + continue; + } + } + ((Player*)this)->CastItemCombatSpell(target, attType, procVictim, procEx, item, proto); + } + } +} + +void Player::CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item *item, ItemPrototype const * proto) +{ // Can do effect if any damage done to target - if (damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE) + if (procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE) { for (int i = 0; i < 5; i++) { @@ -7022,7 +7058,7 @@ void Player::CastItemCombatSpell(Item *item, CalcDamageInfo *damageInfo, ItemPro } // not allow proc extra attack spell at extra attack - if( m_extraAttacks && IsSpellHaveEffect(spellInfo,SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) + if( m_extraAttacks && IsSpellHaveEffect(spellInfo, SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) return; float chance = spellInfo->procChance; @@ -7038,7 +7074,7 @@ void Player::CastItemCombatSpell(Item *item, CalcDamageInfo *damageInfo, ItemPro } if (roll_chance_f(chance)) - CastSpell(Target, spellInfo->Id, true, item); + CastSpell(target, spellInfo->Id, true, item); } } @@ -7058,13 +7094,13 @@ void Player::CastItemCombatSpell(Item *item, CalcDamageInfo *damageInfo, ItemPro if (entry && entry->procEx) { // Check hit/crit/dodge/parry requirement - if((entry->procEx & damageInfo->procEx) == 0) + if((entry->procEx & procEx) == 0) continue; } else { // Can do effect if any damage done to target - if (!(damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE)) + if (!(procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE)) continue; } @@ -7093,7 +7129,7 @@ void Player::CastItemCombatSpell(Item *item, CalcDamageInfo *damageInfo, ItemPro if(IsPositiveSpell(pEnchant->spellid[s])) CastSpell(this, pEnchant->spellid[s], true, item); else - CastSpell(Target, pEnchant->spellid[s], true, item); + CastSpell(target, pEnchant->spellid[s], true, item); } } } diff --git a/src/game/Player.h b/src/game/Player.h index 384acf7b760..dd211b6364e 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1798,7 +1798,8 @@ class TRINITY_DLL_SPEC Player : public Unit void ApplyItemEquipSpell(Item *item, bool apply, bool form_change = false); void ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply, bool form_change = false); void UpdateEquipSpellsAtFormChange(); - void CastItemCombatSpell(Item *item, CalcDamageInfo *damageInfo, ItemPrototype const * proto); + void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx); + void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item *item, ItemPrototype const * proto); void SendInitWorldStates(bool force = false, uint32 forceZoneId = 0); void SendUpdateWorldState(uint32 Field, uint32 Value); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 4a0e51e9372..a7fb8840158 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1043,11 +1043,16 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) procEx = createProcExtendMask(&damageInfo, missInfo); procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE; + + caster->DealSpellDamage(&damageInfo, true); // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge) if (missInfo != SPELL_MISS_REFLECT) + { caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_canTrigger); - - caster->DealSpellDamage(&damageInfo, true); + if(caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->Attributes & SPELL_ATTR_STOP_ATTACK_TARGET) == 0 && + (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) + ((Player *)caster)->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx); + } // Shadow Word: Death - deals damage equal to damage done to caster if victim is not killed if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags&0x0000000200000000LL && -- cgit v1.2.3 From 738f3567ca7b9f4aa736df9372877a61b34d4355 Mon Sep 17 00:00:00 2001 From: krz Date: Tue, 23 Jun 2009 04:52:39 +0200 Subject: * Missing part from previous commit. * First DealDamage then call ProcDamageAndspell. * Correctly trigger SPELL_EFFECT_ADD_EXTRA_ATTACKS from spells. * Some changes for SPELL_EFFECT_ADD_EXTRA_ATTACKS to allow proc self if there is no hidden cooldown (for example 12815) --HG-- branch : trunk --- src/game/SpellEffects.cpp | 4 ++-- src/game/Unit.cpp | 58 +++++++---------------------------------------- 2 files changed, 10 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 8169bc14886..885adeccf31 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5457,8 +5457,8 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/) if(!unitTarget || !unitTarget->isAlive()) return; - if( unitTarget->m_extraAttacks ) - return; + //if( unitTarget->m_extraAttacks ) + // return; Unit *victim = unitTarget->getVictim(); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 3031a89e0aa..69c458c4484 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1630,45 +1630,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss) } } - if(GetTypeId() == TYPEID_PLAYER && pVictim->isAlive()) - { - for(int i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++) - { - // If usable, try to cast item spell - if (Item * item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0,i)) - if(!item->IsBroken()) - if (ItemPrototype const *proto = item->GetProto()) - { - // Additional check for weapons - if (proto->Class==ITEM_CLASS_WEAPON) - { - // offhand item cannot proc from main hand hit etc - EquipmentSlots slot; - switch (damageInfo->attackType) - { - case BASE_ATTACK: slot = EQUIPMENT_SLOT_MAINHAND; break; - case OFF_ATTACK: slot = EQUIPMENT_SLOT_OFFHAND; break; - case RANGED_ATTACK: slot = EQUIPMENT_SLOT_RANGED; break; - default: slot = EQUIPMENT_SLOT_END; break; - } - if (slot != i) - continue; - // Check if item is useable (forms or disarm) - if (damageInfo->attackType == BASE_ATTACK) - { - if (!((Player*)this)->IsUseEquipedWeapon(true)) - continue; - } - else - { - if (((Player*)this)->IsInFeralForm()) - continue; - } - } - ((Player*)this)->CastItemCombatSpell(item, damageInfo, proto); - } - } - } + if(GetTypeId() == TYPEID_PLAYER) + ((Player *)this)->CastItemCombatSpell(pVictim, damageInfo->attackType, damageInfo->procVictim, damageInfo->procEx); // Do effect if any damage done to target if (damageInfo->procVictim & PROC_FLAG_TAKEN_ANY_DAMAGE) @@ -2373,7 +2336,7 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra ) { - if(hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) ) + if(!extra && hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) ) return; if (!pVictim->isAlive()) @@ -2401,8 +2364,8 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex CalculateMeleeDamage(pVictim, 0, &damageInfo, attType); // Send log damage message to client SendAttackStateUpdate(&damageInfo); - ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType); DealMeleeDamage(&damageInfo,true); + ProcDamageAndSpell(damageInfo.target, damageInfo.procAttacker, damageInfo.procVictim, damageInfo.procEx, damageInfo.damage, damageInfo.attackType); if (GetTypeId() == TYPEID_PLAYER) DEBUG_LOG("AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", @@ -7418,10 +7381,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB return false; } - // not allow proc extra attack spell at extra attack - if( m_extraAttacks && IsSpellHaveEffect(triggerEntry, SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) - return false; - // Costum requirements (not listed in procEx) Warning! damage dealing after this // Custom triggered spells switch (auraSpellInfo->Id) @@ -7536,16 +7495,15 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB if(!target || target!=this && !target->isAlive()) return false; + // apply spell cooldown before casting to prevent triggering spells with SPELL_EFFECT_ADD_EXTRA_ATTACKS if spell has hidden cooldown + if( cooldown && GetTypeId()==TYPEID_PLAYER ) + ((Player*)this)->AddSpellCooldown(trigger_spell_id,0,time(NULL) + cooldown); + if(basepoints0) CastCustomSpell(target,trigger_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); - //else if(spellmgr.GetSpellCustomAttr(trigger_spell_id) & SPELL_ATTR_CU_AURA_SPELL) - // AddAura(trigger_spell_id, target); else CastSpell(target,trigger_spell_id,true,castItem,triggeredByAura); - if( cooldown && GetTypeId()==TYPEID_PLAYER ) - ((Player*)this)->AddSpellCooldown(trigger_spell_id,0,time(NULL) + cooldown); - return true; } -- cgit v1.2.3 From 97e4a59a75f8f6918c548552b4f1b17c477c7762 Mon Sep 17 00:00:00 2001 From: krz Date: Tue, 23 Jun 2009 04:59:28 +0200 Subject: * Author of CastItemCombatSpell part was freeganja. Sorry for typo. * Some cleanup --HG-- branch : trunk --- src/game/Unit.cpp | 662 ------------------------------------------------------ 1 file changed, 662 deletions(-) (limited to 'src') diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 69c458c4484..28fb9e5eed8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -6186,668 +6186,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return true; } -/* -bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attackType, uint32 cooldown) -{ - SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto(); - - Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER - ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - - uint32 triggered_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; - Unit* target = !(procFlags & PROC_FLAG_HEAL) && IsPositiveSpell(triggered_spell_id) ? this : pVictim; - int32 basepoints0 = 0; - - switch(auraSpellInfo->SpellFamilyName) - { - case SPELLFAMILY_GENERIC: - { - switch(auraSpellInfo->Id) - { - // Aegis of Preservation - case 23780: - //Aegis Heal (instead non-existed triggered spell) - triggered_spell_id = 23781; - target = this; - break; - // Elune's Touch (moonkin mana restore) - case 24905: - { - // Elune's Touch (instead non-existed triggered spell) - triggered_spell_id = 33926; - basepoints0 = int32(0.3f * GetTotalAttackPowerValue(BASE_ATTACK)); - target = this; - break; - } - // Enlightenment - case 29601: - { - // only for cast with mana price - if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0) - return false; - break; // fall through to normal cast - } - // Health Restore - case 33510: - { - // at melee hit call std triggered spell - if(procFlags & PROC_FLAG_HIT_MELEE) - break; // fall through to normal cast - - // Mark of Conquest - else (at range hit) called custom case - triggered_spell_id = 39557; - target = this; - break; - } - // Shaleskin - case 36576: - return true; // nothing to do - // Forgotten Knowledge (Blade of Wizardry) - case 38319: - // only for harmful enemy targeted spell - if(!pVictim || pVictim==this || !procSpell || IsPositiveSpell(procSpell->Id)) - return false; - break; // fall through to normal cast - // Aura of Wrath (Darkmoon Card: Wrath trinket bonus) - case 39442: - { - // proc only at non-crit hits - if(procFlags & (PROC_FLAG_CRIT_MELEE|PROC_FLAG_CRIT_RANGED|PROC_FLAG_CRIT_SPELL)) - return false; - break; // fall through to normal cast - } - // Augment Pain (Timbal's Focusing Crystal trinket bonus) - case 45054: - { - if(!procSpell) - return false; - - //only periodic damage can trigger spell - bool found = false; - for(int j = 0; j < 3; ++j) - { - if( procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE || - procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE_PERCENT || - procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_LEECH ) - { - found = true; - break; - } - } - if(!found) - return false; - - break; // fall through to normal cast - } - // Evasive Maneuvers (Commendation of Kael'thas) - case 45057: - { - // damage taken that reduces below 35% health - // does NOT mean you must have been >= 35% before - if (int32(GetHealth())-int32(damage) >= int32(GetMaxHealth()*0.35f)) - return false; - break; // fall through to normal cast - } - } - - switch(triggered_spell_id) - { - // Setup - case 15250: - { - // applied only for main target - if(!pVictim || pVictim != getVictim()) - return false; - - // continue normal case - break; - } - // Shamanistic Rage triggered spell - case 30824: - basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK)*triggeredByAura->GetModifier()->m_amount/100); - break; - } - break; - } - case SPELLFAMILY_MAGE: - { - switch(auraSpellInfo->SpellIconID) - { - // Blazing Speed - case 2127: - //Blazing Speed (instead non-existed triggered spell) - triggered_spell_id = 31643; - target = this; - break; - } - switch(auraSpellInfo->Id) - { - // Persistent Shield (Scarab Brooch) - case 26467: - basepoints0 = int32(damage * 0.15f); - break; - } - break; - } - case SPELLFAMILY_WARRIOR: - { - //Rampage - if((auraSpellInfo->SpellFamilyFlags & 0x100000) && auraSpellInfo->SpellIconID==2006) - { - //all ranks have effect[0]==AURA (Proc Trigger Spell, non-existed) - //and effect[1]==TriggerSpell - if(auraSpellInfo->Effect[1]!=SPELL_EFFECT_TRIGGER_SPELL) - { - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have wrong effect in RM",triggeredByAura->GetSpellProto()->Id); - return false; - } - triggered_spell_id = auraSpellInfo->EffectTriggerSpell[1]; - break; // fall through to normal cast - } - break; - } - case SPELLFAMILY_WARLOCK: - { - // Pyroclasm - if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000 && auraSpellInfo->SpellIconID==1137) - { - // last case for Hellfire that damage caster also but don't must stun caster - if( pVictim == this ) - return false; - - // custom chance - float chance = 0; - switch (triggeredByAura->GetId()) - { - case 18096: chance = 13.0f; break; - case 18073: chance = 26.0f; break; - } - if (!roll_chance_f(chance)) - return false; - - // Pyroclasm (instead non-existed triggered spell) - triggered_spell_id = 18093; - target = pVictim; - break; - } - // Drain Soul - if(auraSpellInfo->SpellFamilyFlags & 0x0000000000004000) - { - bool found = false; - Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); - for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) - { - //Improved Drain Soul - if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113) - { - int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this); - basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100; - // Drain Soul - CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); - break; - } - } - // Not remove charge (aura removed on death in any cases) - // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura - return false; - } - break; - } - case SPELLFAMILY_PRIEST: - { - //Blessed Recovery - if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL && auraSpellInfo->SpellIconID==1875) - { - switch (triggeredByAura->GetSpellProto()->Id) - { - case 27811: triggered_spell_id = 27813; break; - case 27815: triggered_spell_id = 27817; break; - case 27816: triggered_spell_id = 27818; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR",triggeredByAura->GetSpellProto()->Id); - return false; - } - - int32 heal_amount = damage * triggeredByAura->GetModifier()->m_amount / 100; - basepoints0 = heal_amount/3; - target = this; - break; - } - // Shadowguard - if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958) - { - switch(triggeredByAura->GetSpellProto()->Id) - { - case 18137: - triggered_spell_id = 28377; break; // Rank 1 - case 19308: - triggered_spell_id = 28378; break; // Rank 2 - case 19309: - triggered_spell_id = 28379; break; // Rank 3 - case 19310: - triggered_spell_id = 28380; break; // Rank 4 - case 19311: - triggered_spell_id = 28381; break; // Rank 5 - case 19312: - triggered_spell_id = 28382; break; // Rank 6 - case 25477: - triggered_spell_id = 28385; break; // Rank 7 - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG",triggeredByAura->GetSpellProto()->Id); - return false; - } - target = pVictim; - break; - } - break; - } - case SPELLFAMILY_DRUID: - { - switch(auraSpellInfo->Id) - { - // Leader of the Pack (triggering Improved Leader of the Pack heal) - case 24932: - { - if (triggeredByAura->GetModifier()->m_amount == 0) - return false; - basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100; - triggered_spell_id = 34299; - break; - }; - // Druid Forms Trinket (Druid Tier5 Trinket, triggers different spells per Form) - case 37336: - { - switch(m_form) - { - case FORM_BEAR: - case FORM_DIREBEAR: - triggered_spell_id=37340; break;// Ursine Blessing - case FORM_CAT: - triggered_spell_id=37341; break;// Feline Blessing - case FORM_TREE: - triggered_spell_id=37342; break;// Slyvan Blessing - case FORM_MOONKIN: - triggered_spell_id=37343; break;// Lunar Blessing - case FORM_NONE: - triggered_spell_id=37344; break;// Cenarion Blessing (for caster form, except FORM_MOONKIN) - default: - return false; - } - - target = this; - break; - } - } - break; - } - case SPELLFAMILY_ROGUE: - { - if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000LL) - { - switch(auraSpellInfo->SpellIconID) - { - // Combat Potency - case 2260: - { - // skip non offhand attacks - if(attackType!=OFF_ATTACK) - return false; - break; // fall through to normal cast - } - } - } - break; - } - case SPELLFAMILY_PALADIN: - { - if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL) - { - switch(auraSpellInfo->Id) - { - // Lightning Capacitor - case 37657: - { - // trinket ProcTriggerSpell but for safe checks for player - if(!castItem || !pVictim || !pVictim->isAlive() || GetTypeId()!=TYPEID_PLAYER) - return false; - - if(((Player*)this)->HasSpellCooldown(37657)) - return false; - - // stacking - CastSpell(this, 37658, true, castItem, triggeredByAura); - // 2.5s cooldown before it can stack again, current system allow 1 sec step in cooldown - ((Player*)this)->AddSpellCooldown(37657,0,time(NULL)+(roll_chance_i(50) ? 2 : 3)); - - // counting - Aura * dummy = GetDummyAura(37658); - if (!dummy) - return false; - - // release at 3 aura in stack - if(dummy->GetStackAmount() <= 2) - return true; // main triggered spell casted anyway - - RemoveAurasDueToSpell(37658); - CastSpell(pVictim, 37661, true, castItem, triggeredByAura); - return true; - } - // Healing Discount - case 37705: - // Healing Trance (instead non-existed triggered spell) - triggered_spell_id = 37706; - target = this; - break; - // HoTs on Heals (Fel Reaver's Piston trinket) - case 38299: - { - // at direct heal effect - if(!procSpell || !IsSpellHaveEffect(procSpell,SPELL_EFFECT_HEAL)) - return false; - - // single proc at time - AuraList const& scAuras = GetSingleCastAuras(); - for(AuraList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr) - if((*itr)->GetId()==triggered_spell_id) - return false; - - // positive cast at victim instead self - target = pVictim; - break; - } - } - switch(auraSpellInfo->SpellIconID) - { - case 241: - { - switch(auraSpellInfo->EffectTriggerSpell[0]) - { - //Illumination - case 18350: - { - if(!procSpell) - return false; - - // procspell is triggered spell but we need mana cost of original casted spell - uint32 originalSpellId = procSpell->Id; - - // Holy Shock - if(procSpell->SpellFamilyName == SPELLFAMILY_PALADIN) - { - if(procSpell->SpellFamilyFlags & 0x0001000000000000LL) - { - switch(procSpell->Id) - { - case 25914: originalSpellId = 20473; break; - case 25913: originalSpellId = 20929; break; - case 25903: originalSpellId = 20930; break; - case 27175: originalSpellId = 27174; break; - case 33074: originalSpellId = 33072; break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id); - return false; - } - } - } - - SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); - if(!originalSpell) - { - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId); - return false; - } - - // percent stored in effect 1 (class scripts) base points - int32 percent = auraSpellInfo->EffectBasePoints[1]+1; - - basepoints0 = originalSpell->manaCost*percent/100; - triggered_spell_id = 20272; - target = this; - break; - } - } - break; - } - } - } - if(auraSpellInfo->SpellFamilyFlags & 0x00080000) - { - switch(auraSpellInfo->SpellIconID) - { - //Judgement of Wisdom (overwrite non existing triggered spell call in spell.dbc - case 206: - { - if(!pVictim || !pVictim->isAlive()) - return false; - - switch(triggeredByAura->GetSpellProto()->Id) - { - case 20186: - triggered_spell_id = 20268; // Rank 1 - break; - case 20354: - triggered_spell_id = 20352; // Rank 2 - break; - case 20355: - triggered_spell_id = 20353; // Rank 3 - break; - case 27164: - triggered_spell_id = 27165; // Rank 4 - break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoW",triggeredByAura->GetSpellProto()->Id); - return false; - } - - pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID()); - return true; // no hidden cooldown - } - //Judgement of Light - case 299: - { - if(!pVictim || !pVictim->isAlive()) - return false; - - // overwrite non existing triggered spell call in spell.dbc - switch(triggeredByAura->GetSpellProto()->Id) - { - case 20185: - triggered_spell_id = 20267; // Rank 1 - break; - case 20344: - triggered_spell_id = 20341; // Rank 2 - break; - case 20345: - triggered_spell_id = 20342; // Rank 3 - break; - case 20346: - triggered_spell_id = 20343; // Rank 4 - break; - case 27162: - triggered_spell_id = 27163; // Rank 5 - break; - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoL",triggeredByAura->GetSpellProto()->Id); - return false; - } - pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID()); - return true; // no hidden cooldown - } - } - } - // custom check for proc spell - switch(auraSpellInfo->Id) - { - // Bonus Healing (item spell) - case 40971: - { - if(!pVictim || !pVictim->isAlive()) - return false; - - // bonus if health < 50% - if(pVictim->GetHealth() >= pVictim->GetMaxHealth()*triggeredByAura->GetModifier()->m_amount/100) - return false; - - // cast at target positive spell - target = pVictim; - break; - } - } - switch(triggered_spell_id) - { - // Seal of Command - case 20424: - // prevent chain of triggered spell from same triggered spell - if(procSpell && procSpell->Id==20424) - return false; - break; - } - break; - } - case SPELLFAMILY_SHAMAN: - { - if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000) - { - switch(auraSpellInfo->SpellIconID) - { - case 19: - { - switch(auraSpellInfo->Id) - { - case 23551: // Lightning Shield - Tier2: 8 pieces proc shield - { - // Lightning Shield (overwrite non existing triggered spell call in spell.dbc) - triggered_spell_id = 23552; - target = pVictim; - break; - } - case 23552: // Lightning Shield - trigger shield damage - { - // Lightning Shield (overwrite non existing triggered spell call in spell.dbc) - triggered_spell_id = 27635; - target = pVictim; - break; - } - } - break; - } - // Mana Surge (Shaman T1 bonus) - case 87: - { - if(!procSpell) - return false; - - basepoints0 = procSpell->manaCost * 35/100; - triggered_spell_id = 23571; - target = this; - break; - } - //Nature's Guardian - case 2013: - { - if(GetTypeId()!=TYPEID_PLAYER) - return false; - - // damage taken that reduces below 30% health - // does NOT mean you must have been >= 30% before - if (10*(int32(GetHealth())-int32(damage)) >= 3*GetMaxHealth()) - return false; - - triggered_spell_id = 31616; - - // need check cooldown now - if( cooldown && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) - return false; - - basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100; - target = this; - if(pVictim && pVictim->isAlive()) - pVictim->getThreatManager().modifyThreatPercent(this,-10); - break; - } - } - } - - // Water Shield (we can't set cooldown for main spell - it's player casted spell - if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358) - { - target = this; - break; - } - - // Lightning Shield - if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37) - { - // overwrite non existing triggered spell call in spell.dbc - switch(triggeredByAura->GetSpellProto()->Id) - { - case 324: - triggered_spell_id = 26364; break; // Rank 1 - case 325: - triggered_spell_id = 26365; break; // Rank 2 - case 905: - triggered_spell_id = 26366; break; // Rank 3 - case 945: - triggered_spell_id = 26367; break; // Rank 4 - case 8134: - triggered_spell_id = 26369; break; // Rank 5 - case 10431: - triggered_spell_id = 26370; break; // Rank 6 - case 10432: - triggered_spell_id = 26363; break; // Rank 7 - case 25469: - triggered_spell_id = 26371; break; // Rank 8 - case 25472: - triggered_spell_id = 26372; break; // Rank 9 - default: - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield",triggeredByAura->GetSpellProto()->Id); - return false; - } - - target = pVictim; - break; - } - break; - } - } - - // standard non-dummy case - if(!triggered_spell_id) - { - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex()); - return false; - } - - SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); - - if(!triggerEntry) - { - sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have not existed EffectTriggered[%d]=%u, not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex(),triggered_spell_id); - return false; - } - - // not allow proc extra attack spell at extra attack - if( m_extraAttacks && IsSpellHaveEffect(triggerEntry,SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) - return false; - - if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) - return false; - - // default case - if(!target || target!=this && !target->isAlive()) - 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::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown) { -- cgit v1.2.3 From 51de1cd636959f0cd342359df94d70a279bd8ada Mon Sep 17 00:00:00 2001 From: BroodWyrm Date: Tue, 23 Jun 2009 20:12:30 +0200 Subject: *Fix Item 30639 --HG-- branch : trunk --- src/game/SpellAuras.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5e8241b486a..f8f7496737f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1904,6 +1904,22 @@ void Aura::HandleAuraDummy(bool apply, bool Real) if(caster) caster->CastSpell(caster,13138,true,NULL,this); return; + case 37096: // Blood Elf Disguise + if(caster) + { + switch(caster->getGender()) + { + case GENDER_FEMALE: + caster->CastSpell(m_target,37095,true,NULL,this); + break; + case GENDER_MALE: + caster->CastSpell(m_target,37093,true,NULL,this); + break; + default: + break; + } + } + return; case 39850: // Rocket Blast if(roll_chance_i(20)) // backfire stun m_target->CastSpell(m_target, 51581, true, NULL, this); -- cgit v1.2.3 From 0319f6a269b8b605604f53219f355dae27edf8f2 Mon Sep 17 00:00:00 2001 From: Rat Date: Wed, 24 Jun 2009 09:33:20 +0200 Subject: - properly reset Shada of Akama after wipe - despawn summons if Shade is killed, so Akama can complete the event --HG-- branch : trunk --- .../zone/black_temple/boss_shade_of_akama.cpp | 41 +++++++++++++++++----- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp index 5d82affcacf..d6378809f52 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_shade_of_akama.cpp @@ -107,11 +107,11 @@ const uint32 spawnEntries[4]= { 23523, 23318, 23524 }; struct TRINITY_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI { - mob_ashtongue_channelerAI(Creature* c) : ScriptedAI(c) {} + mob_ashtongue_channelerAI(Creature* c) : ScriptedAI(c) {ShadeGUID = 0;} uint64 ShadeGUID; - void Reset() { ShadeGUID = 0; } + void Reset() {} void JustDied(Unit* killer); void Aggro(Unit* who) {} void AttackStart(Unit* who) {} @@ -121,7 +121,7 @@ struct TRINITY_DLL_DECL mob_ashtongue_channelerAI : public ScriptedAI struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI { - mob_ashtongue_sorcererAI(Creature* c) : ScriptedAI(c) {} + mob_ashtongue_sorcererAI(Creature* c) : ScriptedAI(c) {ShadeGUID = 0;} uint64 ShadeGUID; uint32 CheckTimer; @@ -130,8 +130,7 @@ struct TRINITY_DLL_DECL mob_ashtongue_sorcererAI : public ScriptedAI void Reset() { StartBanishing = false; - CheckTimer = 5000; - ShadeGUID = 0; + CheckTimer = 5000; } void JustDied(Unit* killer); @@ -237,8 +236,20 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI reseting = false; } - void JustSummoned(Creature *summon) {summons.Summon(summon);} - void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);} + void JustDied(Unit* killer) + { + summons.DespawnAll(); + } + void JustSummoned(Creature *summon) + { + if(summon->GetEntry() == CREATURE_DEFENDER || summon->GetEntry() == 23523 || summon->GetEntry() == 23318 || summon->GetEntry() == 23524) + summons.Summon(summon); + } + void SummonedCreatureDespawn(Creature *summon) + { + if(summon->GetEntry() == CREATURE_DEFENDER || summon->GetEntry() == 23523 || summon->GetEntry() == 23318 || summon->GetEntry() == 23524) + summons.Despawn(summon); + } void MoveInLineOfSight(Unit *who) { @@ -505,7 +516,7 @@ void mob_ashtongue_sorcererAI::JustDied(Unit* killer) struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI { - npc_akamaAI(Creature* c) : ScriptedAI(c) + npc_akamaAI(Creature* c) : ScriptedAI(c), summons(m_creature) { ShadeHasDied = false; StartCombat = false; @@ -543,6 +554,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI bool ShadeHasDied; bool StartCombat; bool HasYelledOnce; + SummonList summons; void Reset() { @@ -555,6 +567,18 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has very very strange values m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } + summons.DespawnAll(); + } + + void JustSummoned(Creature *summon) + { + if(summon->GetEntry() == CREATURE_BROKEN) + summons.Summon(summon); + } + void SummonedCreatureDespawn(Creature *summon) + { + if(summon->GetEntry() == CREATURE_BROKEN) + summons.Despawn(summon); } void Aggro(Unit* who) {} @@ -624,6 +648,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI Creature* Shade = Unit::GetCreature((*m_creature), ShadeGUID); if(Shade && Shade->isAlive()) ((boss_shade_of_akamaAI*)Shade->AI())->HasKilledAkama = true; + summons.DespawnAll(); } void UpdateAI(const uint32 diff) -- cgit v1.2.3 From 13110a35c469d3a9087e604aaf336237c0573a3a Mon Sep 17 00:00:00 2001 From: krz Date: Wed, 24 Jun 2009 12:53:22 +0200 Subject: Do not check cooldown for triggered spells (triggered spells shouldn't trigger if they have cooldown) --HG-- branch : trunk --- src/game/Spell.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index a7fb8840158..d5156962f0c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3418,11 +3418,12 @@ void Spell::TriggerSpell() uint8 Spell::CanCast(bool strict) { // check cooldowns to prevent cheating - if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id)) + if(!m_IsTriggeredSpell && m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id)) { - if(m_triggeredByAuraSpell) - return SPELL_FAILED_DONT_REPORT; - else + //triggered spells shouldn't be casted (cooldown check in handleproctriggerspell) + // if(m_triggeredByAuraSpell) + // return SPELL_FAILED_DONT_REPORT; + // else return SPELL_FAILED_NOT_READY; } -- cgit v1.2.3 From 7fd26a5fee28cc875aff421ae38df61e259a5fc9 Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 24 Jun 2009 19:58:01 +0200 Subject: * Fix a crash in Player::BuyItemFromVendor caused by player spoofing packets (Backported from TC2) * Another crash exploit prevention using the same method in Bag::StoreItem, by Visagalis --HG-- branch : trunk --- src/game/Bag.cpp | 6 +++++- src/game/Player.cpp | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index 331b12acde5..a4b7bcb5c2d 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.cpp @@ -151,7 +151,11 @@ void Bag::RemoveItem( uint8 slot, bool /*update*/ ) void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ ) { - assert(slot < MAX_BAG_SIZE); + if(slot > MAX_BAG_SIZE) + { + sLog.outError("Player GUID" UI64FMTD "tried to manipulate packets and crash the server.", GetOwnerGUID()); + return; + } if( pItem ) { diff --git a/src/game/Player.cpp b/src/game/Player.cpp index b24b3da2ace..7e400be4cb0 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -17131,6 +17131,10 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint { // cheating attempt if(count < 1) count = 1; + + // cheating attempt + if(slot > MAX_BAG_SIZE) + return false; if(!isAlive()) return false; -- cgit v1.2.3 From c3c0ff3f3f21fb853c8aed3d6478a05ef06134ce Mon Sep 17 00:00:00 2001 From: Machiavelli Date: Wed, 24 Jun 2009 21:30:34 +0200 Subject: * Update log message, fix build --HG-- branch : trunk --- src/game/Bag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index a4b7bcb5c2d..783507c504a 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.cpp @@ -153,7 +153,7 @@ void Bag::StoreItem( uint8 slot, Item *pItem, bool /*update*/ ) { if(slot > MAX_BAG_SIZE) { - sLog.outError("Player GUID" UI64FMTD "tried to manipulate packets and crash the server.", GetOwnerGUID()); + sLog.outError("Player GUID " I64FMTD " tried to manipulate packets and crash the server.", GetOwnerGUID()); return; } -- cgit v1.2.3 From e92f3cf01fb618505f3600a9a291c33b12aa5e63 Mon Sep 17 00:00:00 2001 From: krz Date: Thu, 25 Jun 2009 03:11:10 +0200 Subject: Fix damage backlash from Shadow Word: Death and ranks --HG-- branch : trunk --- src/game/Spell.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index d5156962f0c..94065b8357f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1058,14 +1058,8 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target) if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags&0x0000000200000000LL && caster != unitTarget && unitTarget->isAlive()) { - // Redirect damage to caster if victim Alive - damageInfo.target = caster; - damageInfo.absorb = 0; - damageInfo.resist = 0; - damageInfo.blocked = 0; - // Send log damage message to client - caster->SendSpellNonMeleeDamageLog(&damageInfo); - caster->DealSpellDamage(&damageInfo, true); + // Redirect damage to caster if victim alive + m_caster->CastCustomSpell(m_caster, 32409, &m_damage, NULL, NULL, true); } // Judgement of Blood else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags & 0x0000000800000000LL && m_spellInfo->SpellIconID==153) -- cgit v1.2.3