Index: Spell.cpp =================================================================== --- Spell.cpp (revision 5507) +++ Spell.cpp (working copy) @@ -264,6 +264,22 @@ m_triggeringContainer = triggeringContainer; m_deletable = true; + // Get data for type of attack + switch (m_spellInfo->DmgClass) + { + case SPELL_DAMAGE_CLASS_MELEE: + if (m_spellInfo->AttributesEx3 & 0x1000000) m_attackType = OFF_ATTACK; + else m_attackType = BASE_ATTACK; + break; + case SPELL_DAMAGE_CLASS_RANGED: + m_attackType = RANGED_ATTACK; + break; + default: + if (m_spellInfo->Id == 5019) m_attackType = RANGED_ATTACK; // Wands + else m_attackType = BASE_ATTACK; + break; + } + m_spellSchool = SpellSchools(info->School); // Can be override for some spell (wand shoot for example) if(originalCasterGUID) m_originalCasterGUID = originalCasterGUID; else Index: Spell.h =================================================================== --- Spell.h (revision 5507) +++ Spell.h (working copy) @@ -406,6 +406,10 @@ Spell** m_selfContainer; // pointer to our spell container (if applicable) Spell** m_triggeringContainer; // pointer to container with spell that has triggered us + //Spell data + SpellSchools m_spellSchool; // Spell school (can be owerrided for some spells (wand shoot for example) + WeaponAttackType m_attackType; // For weapon based attack + bool m_canReflect; // can reflect this spell? bool m_autoRepeat; bool m_meleeSpell; bool m_rangedShoot; @@ -420,7 +424,6 @@ // These vars are used in both delayed spell system and modified immediate spell system bool m_deletable; // is the spell pending deletion or must be updated till permitted to delete? bool m_needSpellLog; // need to send spell log? - bool m_canReflect; // can reflect this spell? bool m_applyMultiplier[3]; // by effect: damage multiplier needed? float m_damageMultipliers[3]; // by effect: damage multiplier Index: SpellEffects.cpp =================================================================== --- SpellEffects.cpp (revision 5507) +++ SpellEffects.cpp (working copy) @@ -3366,7 +3366,6 @@ uint32 hitInfo = 0; uint32 nohitMask = HITINFO_ABSORB | HITINFO_RESIST | HITINFO_MISS; - SpellSchools damageSchool = SpellSchools(m_spellInfo->School); VictimState victimState = VICTIMSTATE_NORMAL; uint32 blocked_dmg = 0; uint32 absorbed_dmg = 0; @@ -3374,21 +3373,8 @@ CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL ); bool criticalhit = false; - // select weapon attack type... - WeaponAttackType attType; - - // offhand hand weapon required (not used with mainhand required (spellInfo->AttributesEx3 & 0x0000000000000400) in spell with damage effect - if(m_spellInfo->AttributesEx3 & 0x0000000001000000) - attType = OFF_ATTACK; - // some melee weapon spells have non-standard spell range - // FIXME: find better way to select melee/ranged weapon attack sorting - // FIXME: we also need select OFF_ATTACK if trigering some spell at offhand attack - else if(m_spellInfo->SpellVisual==3136 || m_spellInfo->SpellIconID==2293) - attType = BASE_ATTACK; - else if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 7) + if(m_attackType == RANGED_ATTACK) { - attType = RANGED_ATTACK; - // wand case if((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0) { @@ -3402,13 +3388,11 @@ if( unitTarget->IsImmunedToSpellDamage(m_spellInfo,false) ) return; - damageSchool = SpellSchools(pItem->GetProto()->Damage->DamageType); + m_spellSchool = SpellSchools(pItem->GetProto()->Damage->DamageType); } } - else - attType = BASE_ATTACK; - if(damageSchool==SPELL_SCHOOL_NORMAL && unitTarget->IsImmunedToPhysicalDamage() ) + if(m_spellSchool==SPELL_SCHOOL_NORMAL && unitTarget->IsImmunedToPhysicalDamage() ) { m_caster->SendAttackStateUpdate (HITINFO_MISS, unitTarget, 1, SPELL_SCHOOL_NORMAL, 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0); return; @@ -3424,7 +3408,7 @@ //if miss/parry, no eff=0 automatically by func DoAttackDamage //if crit eff = (bonus + weapon) * 2 //In a word, bonus + weapon will be calculated together in cases of miss, armor reduce, crit, etc. - bonus += m_caster->CalculateDamage (attType); + bonus += m_caster->CalculateDamage (m_attackType); switch(m_spellInfo->SpellFamilyName) { @@ -3474,15 +3458,15 @@ // prevent negative damage uint32 eff_damage = uint32(bonus > 0 ? bonus : 0); - m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, damageSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, attType, m_spellInfo, m_IsTriggeredSpell); + m_caster->DoAttackDamage(unitTarget, &eff_damage, &cleanDamage, &blocked_dmg, m_spellSchool, &hitInfo, &victimState, &absorbed_dmg, &resisted_dmg, m_attackType, m_spellInfo, m_IsTriggeredSpell); - if ((hitInfo & nohitMask) && attType != RANGED_ATTACK) // not send ranged miss/etc - m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, damageSchool, eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg); + if ((hitInfo & nohitMask) && m_attackType != RANGED_ATTACK) // not send ranged miss/etc + m_caster->SendAttackStateUpdate(hitInfo & nohitMask, unitTarget, 1, m_spellSchool, eff_damage, absorbed_dmg, resisted_dmg, VICTIMSTATE_NORMAL, blocked_dmg); if(hitInfo & HITINFO_CRITICALHIT) criticalhit = true; - m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, eff_damage, damageSchool, absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit); + m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, eff_damage, m_spellSchool, absorbed_dmg, resisted_dmg, false, blocked_dmg, criticalhit); if (eff_damage > (absorbed_dmg + resisted_dmg + blocked_dmg)) { @@ -3505,7 +3489,7 @@ } // take ammo - if(attType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) + if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) { Item *pItem = ((Player*)m_caster)->GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED ); if(!pItem || pItem->IsBroken())