diff options
author | megamage <none@none> | 2009-01-17 17:54:11 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-01-17 17:54:11 -0600 |
commit | 02c060be05b27dcd2d5d662027bae7fd91c3abfc (patch) | |
tree | 1e3bddc4c459f48445cf45ff7e5253bd08cbe450 /src | |
parent | 2cf1a3be1b310feafc43781ab9178f0c1f35d352 (diff) |
*Update to Mangos 7100.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Formulas.h | 13 | ||||
-rw-r--r-- | src/game/ItemPrototype.h | 6 | ||||
-rw-r--r-- | src/game/Level1.cpp | 2 | ||||
-rw-r--r-- | src/game/Player.cpp | 69 | ||||
-rw-r--r-- | src/game/Player.h | 10 | ||||
-rw-r--r-- | src/game/Spell.cpp | 36 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 86 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 8 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 5 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 3 | ||||
-rw-r--r-- | src/game/StatSystem.cpp | 35 | ||||
-rw-r--r-- | src/game/Unit.cpp | 246 | ||||
-rw-r--r-- | src/game/Unit.h | 3 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.cpp | 2 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
15 files changed, 423 insertions, 103 deletions
diff --git a/src/game/Formulas.h b/src/game/Formulas.h index a3af5adedbe..cdfe971eba6 100644 --- a/src/game/Formulas.h +++ b/src/game/Formulas.h @@ -80,8 +80,17 @@ namespace Trinity inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content) { - //TODO: need modifier for CONTENT_71_80 different from CONTENT_61_70? - const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235; + uint32 nBaseExp; + switch(content) + { + case CONTENT_1_60: nBaseExp = 45; break; + case CONTENT_61_70: nBaseExp = 235; break; + case CONTENT_71_80: nBaseExp = 580; break; + default: + sLog.outError("BaseGain: Unsupported content level %u",content); + nBaseExp = 45; break; + } + if( mob_level >= pl_level ) { uint32 nLevelDiff = mob_level - pl_level; diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index e4eb17c840f..b31cc819629 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -76,6 +76,12 @@ enum ItemSpelltriggerType ITEM_SPELLTRIGGER_ON_EQUIP = 1, ITEM_SPELLTRIGGER_CHANCE_ON_HIT = 2, ITEM_SPELLTRIGGER_SOULSTONE = 4, + /* + * ItemSpelltriggerType 5 might have changed on 2.4.3/3.0.3: Such auras + * will be applied on item pickup and removed on item loss - maybe on the + * other hand the item is destroyed if the aura is removed ("removed on + * death" of spell 57348 makes me think so) + */ ITEM_SPELLTRIGGER_ON_NO_DELAY_USE = 5, // no equip cooldown ITEM_SPELLTRIGGER_LEARN_SPELL_ID = 6 // used in item_template.spell_2 with spell_id with SPELL_GENERIC_LEARN in spell_1 }; diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 06032053490..e31d6fe6170 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -2085,7 +2085,7 @@ bool ChatHandler::HandleModifyBitCommand(const char* args) if( !*args ) return false; - Unit *unit = this->getSelectedUnit(); + Unit *unit = getSelectedUnit(); if (!unit) { SendSysMessage(LANG_NO_CHAR_SELECTED); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0f03e0791f4..758574de90b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -426,6 +426,11 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this) for (int i = 0; i < MAX_COMBAT_RATING; i++) m_baseRatingValue[i] = 0; + + m_baseSpellDamage = 0; + m_baseSpellHealing = 0; + m_baseFeralAP = 0; + m_baseManaRegen = 0; // Honor System m_lastHonorUpdateTime = time(NULL); @@ -2963,12 +2968,15 @@ void Player::learnSpell(uint32 spell_id) bool learning = addSpell(spell_id,active,true,false); // learn all disabled higher ranks (recursive) - SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id); - if (node) + if(disabled) { - PlayerSpellMap::iterator iter = m_spells.find(node->next); - if (disabled && iter != m_spells.end() && iter->second->disabled ) - learnSpell(node->next); + SpellChainNode const* node = spellmgr.GetSpellChainNode(spell_id); + if(node) + { + PlayerSpellMap::iterator iter = m_spells.find(node->next); + if (iter != m_spells.end() && iter->second->disabled ) + learnSpell(node->next); + } } // prevent duplicated entires in spell book, also not send if not in world (loading) @@ -6792,9 +6800,31 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl case ITEM_MOD_EXPERTISE_RATING: ApplyRatingMod(CR_EXPERTISE, int32(val), apply); break; + case ITEM_MOD_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(val), apply); + break; + case ITEM_MOD_RANGED_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply); + break; + case ITEM_MOD_FERAL_ATTACK_POWER: + ApplyFeralAPBonus(int32(val), apply); + break; + case ITEM_MOD_SPELL_HEALING_DONE: + ApplySpellHealingBonus(int32(val), apply); + break; + case ITEM_MOD_SPELL_DAMAGE_DONE: + ApplySpellDamageBonus(int32(val), apply); + break; + case ITEM_MOD_MANA_REGENERATION: + ApplyManaRegenBonus(int32(val), apply); + break; case ITEM_MOD_ARMOR_PENETRATION_RATING: ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply); break; + case ITEM_MOD_SPELL_POWER: + ApplySpellHealingBonus(int32(val), apply); + ApplySpellDamageBonus(int32(val), apply); + break; } } @@ -12267,10 +12297,39 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply); sLog.outDebug("+ %u EXPERTISE", enchant_amount); break; + case ITEM_MOD_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(enchant_amount), apply); + sLog.outDebug("+ %u ATTACK_POWER", enchant_amount); + break; + case ITEM_MOD_RANGED_ATTACK_POWER: + HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply); + sLog.outDebug("+ %u RANGED_ATTACK_POWER", enchant_amount); + break; + case ITEM_MOD_FERAL_ATTACK_POWER: + ((Player*)this)->ApplyFeralAPBonus(enchant_amount, apply); + sLog.outDebug("+ %u FERAL_ATTACK_POWER", enchant_amount); + break; + case ITEM_MOD_SPELL_HEALING_DONE: + ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply); + sLog.outDebug("+ %u SPELL_HEALING_DONE", enchant_amount); + break; + case ITEM_MOD_SPELL_DAMAGE_DONE: + ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply); + sLog.outDebug("+ %u SPELL_DAMAGE_DONE", enchant_amount); + break; + case ITEM_MOD_MANA_REGENERATION: + ((Player*)this)->ApplyManaRegenBonus(enchant_amount, apply); + sLog.outDebug("+ %u MANA_REGENERATION", enchant_amount); + break; case ITEM_MOD_ARMOR_PENETRATION_RATING: ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply); sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount); break; + case ITEM_MOD_SPELL_POWER: + ((Player*)this)->ApplySpellHealingBonus(enchant_amount, apply); + ((Player*)this)->ApplySpellDamageBonus(enchant_amount, apply); + sLog.outDebug("+ %u SPELL_POWER", enchant_amount); + break; default: break; } diff --git a/src/game/Player.h b/src/game/Player.h index 0917f0acf27..fb5bb036e4a 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1644,9 +1644,12 @@ class TRINITY_DLL_SPEC Player : public Unit void UpdateArmor(); void UpdateMaxHealth(); void UpdateMaxPower(Powers power); + void ApplyFeralAPBonus(int32 amount, bool apply); void UpdateAttackPowerAndDamage(bool ranged = false); void UpdateShieldBlockValue(); void UpdateDamagePhysical(WeaponAttackType attType); + void ApplySpellDamageBonus(int32 amount, bool apply); + void ApplySpellHealingBonus(int32 amount, bool apply); void UpdateSpellDamageAndHealingBonus(); void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage); @@ -1664,6 +1667,8 @@ class TRINITY_DLL_SPEC Player : public Unit uint32 GetRangedCritDamageReduction(uint32 damage) const; uint32 GetSpellCritDamageReduction(uint32 damage) const; uint32 GetDotDamageReduction(uint32 damage) const; + uint32 GetBaseSpellDamageBonus() { return m_baseSpellDamage;} + uint32 GetBaseSpellHealingBonus() { return m_baseSpellHealing;} float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const; void UpdateBlockPercentage(); @@ -1678,6 +1683,7 @@ class TRINITY_DLL_SPEC Player : public Unit void UpdateAllSpellCritChances(); void UpdateSpellCritChance(uint32 school); void UpdateExpertise(WeaponAttackType attType); + void ApplyManaRegenBonus(int32 amount, bool apply); void UpdateManaRegen(); const uint64& GetLootGUID() const { return m_lootGuid; } @@ -2344,6 +2350,10 @@ class TRINITY_DLL_SPEC Player : public Unit float m_auraBaseMod[BASEMOD_END][MOD_END]; int16 m_baseRatingValue[MAX_COMBAT_RATING]; + uint16 m_baseSpellDamage; + uint16 m_baseSpellHealing; + uint16 m_baseFeralAP; + uint16 m_baseManaRegen; SpellModList m_spellMods[MAX_SPELLMOD]; int32 m_SpellModRemoveCount; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 858b6038ba8..b57b2f3ff5f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -624,15 +624,19 @@ void Spell::prepareDataForTriggerSystem() // Ņan spell trigger another or not ( m_canTrigger ) // Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim) //========================================================================================== - // Fill flag can spell trigger or not - if (!m_IsTriggeredSpell) + // TODO: possible exist spell attribute for this + m_canTrigger = false; + + if (m_CastItem) + m_canTrigger = false; // Do not trigger from item cast spell + else if (!m_IsTriggeredSpell) m_canTrigger = true; // Normal cast - can trigger else if (!m_triggeredByAuraSpell) m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger - else // Exceptions (some periodic triggers) + + if (!m_canTrigger) // Exceptions (some periodic triggers) { - m_canTrigger = false; // Triggered spells can`t trigger another switch (m_spellInfo->SpellFamilyName) { case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard triggers need do it @@ -644,17 +648,17 @@ void Spell::prepareDataForTriggerSystem() case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it if (m_spellInfo->SpellFamilyFlags & 0x0001800000000000LL) m_canTrigger = true; break; - case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect - if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true; + case SPELLFAMILY_ROGUE: // For poisons need do it + if (m_spellInfo->SpellFamilyFlags & 0x000000101001E000LL) m_canTrigger = true; + break; + case SPELLFAMILY_HUNTER: // Hunter Rapid Killing/Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect + if (m_spellInfo->SpellFamilyFlags & 0x0100200000000014LL) m_canTrigger = true; break; case SPELLFAMILY_PALADIN: // For Holy Shock triggers need do it if (m_spellInfo->SpellFamilyFlags & 0x0001000000200000LL) m_canTrigger = true; break; } } - // Do not trigger from item cast spell - if (m_CastItem) - m_canTrigger = false; // Get data for type of attack and fill base info for trigger switch (m_spellInfo->DmgClass) @@ -3626,6 +3630,20 @@ uint8 Spell::CanCast(bool strict) } } } + else if (m_caster->GetTypeId()==TYPEID_PLAYER) // Target - is player caster + { + // 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->Effect[0] == 0 && m_spellInfo->EffectImplicitTargetA[1] != TARGET_SELF) + { + if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection())) + m_targets.setUnitTarget(target); + else + return SPELL_FAILED_BAD_TARGETS; + } + } // check pet presents for(int j=0;j<3;j++) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 182bacf8ee8..a7758846316 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -855,7 +855,7 @@ void Aura::_AddAura() if (!secondaura) { // Update Seals information - if( IsSealSpell(GetSpellProto()) ) + if (IsSealSpell(m_spellProto)) m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true); // Conflagrate aura state on Immolate @@ -863,15 +863,15 @@ void Aura::_AddAura() m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true); // Faerie Fire (druid versions) - if( m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true); // Victorious - if( m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true); // Swiftmend state on Regrowth & Rejuvenation - if(m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x50 ) + if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x50 ) m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true); // Deadly poison aura state @@ -945,59 +945,55 @@ void Aura::_RemoveAura() //***************************************************** // Update target aura state flag (at last aura remove) - // TODO: Make it easer //***************************************************** - // Update Seals information - if( IsSealSpell(GetSpellProto()) ) - m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false); - - // Conflagrate aura state - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4)) - m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false); - - // Faerie Fire (druid versions) - if( m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) - m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, false); - - // Victorious - if( m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) - m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false); - - // Swiftmend aura state - if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags & 0x50) + uint32 removeState = 0; + switch(m_spellProto->SpellFamilyName) { - bool found = false; - Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); - for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) - { - if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && (*i)->GetSpellProto()->SpellFamilyFlags & 0x50 ) - { - found = true; - break; - } - } - if(!found) - m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false); - } + case SPELLFAMILY_PALADIN: + if (IsSealSpell(m_spellProto)) + removeState = AURA_STATE_JUDGEMENT; // Update Seals information + break; + case SPELLFAMILY_WARLOCK: + if(m_spellProto->SpellFamilyFlags & 4) + removeState = AURA_STATE_IMMOLATE; // Conflagrate aura state + break; + case SPELLFAMILY_DRUID: + if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) + removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) + else if(m_spellProto->SpellFamilyFlags & 0x50) + removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state + break; + case SPELLFAMILY_WARRIOR: + if(m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) + removeState = AURA_STATE_WARRIOR_VICTORY_RUSH; // Victorious + break; + case SPELLFAMILY_ROGUE: + if(m_spellProto->SpellFamilyFlags & 0x10000) + removeState = AURA_STATE_DEADLY_POISON; // Deadly poison aura state + break; + case SPELLFAMILY_HUNTER: + if(m_spellProto->SpellFamilyFlags & 0x1000000000000000LL) + removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) - // Deadly poison aura state - if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags & 0x10000) + } + // Remove state (but need check other auras for it) + if (removeState) { - // current aura already removed, search present of another bool found = false; - Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + Unit::AuraMap& Auras = m_target->GetAuras(); + for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { - SpellEntry const* itr_spell = (*itr)->GetSpellProto(); - if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && itr_spell->SpellFamilyFlags & 0x10000) + SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); + if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && + auraSpellInfo->SpellFamilyFlags == m_spellProto->SpellFamilyFlags ) { found = true; break; } } - // this has been last deadly poison aura + // this has been last aura if(!found) - m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false); + m_target->ModifyAuraState(AuraState(removeState), false); } // reset cooldown state for spells diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 2c249afdd24..abf20cd9dc2 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1673,6 +1673,14 @@ void Spell::EffectDummy(uint32 i) switch(m_spellInfo->Id) { + // Judgement of Righteousness (0.2*$AP+0.32*$SPH) holy added in spellDamagBonus + case 20187: + { + if (!unitTarget) + return; + m_damage+=int32(0.2f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); + return; + } case 31789: // Righteous Defense (step 1) { // 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 79942a2d38e..2b5787bad90 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1273,6 +1273,11 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool if(spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) return false; + // TODO: Is this needed? + // Allow stack passive and not passive spells + if ((spellInfo_1->Attributes & SPELL_ATTR_PASSIVE)!=(spellInfo_2->Attributes & SPELL_ATTR_PASSIVE)) + return false; + // generic spells if(!spellInfo_1->SpellFamilyName) { diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 76bffbce1dd..8dc2d1af35c 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -285,6 +285,7 @@ enum SpellSelectTargetTypes #define SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR 0x000004000LL #define SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK 0x080000000LL +#define SPELLFAMILYFLAG_PALADIN_SEALS 0x26000C000A000000LL // Spell clasification enum SpellSpecific { @@ -338,7 +339,7 @@ inline bool IsSealSpell(SpellEntry const *spellInfo) { //Collection of all the seal family flags. No other paladin spell has any of those. return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && - ( spellInfo->SpellFamilyFlags & 0x26000C000A000000LL ); + ( spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_PALADIN_SEALS ); } inline bool IsElementalShield(SpellEntry const *spellInfo) diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 50f0ed66bd7..5473206e8bd 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -93,6 +93,21 @@ bool Player::UpdateStats(Stats stat) return true; } +void Player::ApplySpellDamageBonus(int32 amount, bool apply) +{ + m_baseSpellDamage+=apply?amount:-amount; + // For speed just update for client + ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply); +} + +void Player::ApplySpellHealingBonus(int32 amount, bool apply) +{ + m_baseSpellHealing+=apply?amount:-amount; + // For speed just update for client + for(int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++) + ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, amount, apply);; +} + void Player::UpdateSpellDamageAndHealingBonus() { // Magic damage modifiers implemented in Unit::SpellDamageBonus @@ -223,6 +238,12 @@ void Player::UpdateMaxPower(Powers power) SetMaxPower(power, uint32(value)); } +void Player::ApplyFeralAPBonus(int32 amount, bool apply) +{ + m_baseFeralAP+= apply ? amount:-amount; + UpdateAttackPowerAndDamage(); +} + void Player::UpdateAttackPowerAndDamage(bool ranged ) { float val2 = 0.0f; @@ -297,12 +318,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged ) switch(m_form) { case FORM_CAT: - val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f; break; + val2 = getLevel()*(mLevelMult+2.0f) + GetStat(STAT_STRENGTH)*2.0f + GetStat(STAT_AGILITY) - 20.0f + m_baseFeralAP; break; case FORM_BEAR: case FORM_DIREBEAR: - val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + val2 = getLevel()*(mLevelMult+3.0f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break; case FORM_MOONKIN: - val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; + val2 = getLevel()*(mLevelMult+1.5f) + GetStat(STAT_STRENGTH)*2.0f - 20.0f + m_baseFeralAP; break; default: val2 = GetStat(STAT_STRENGTH)*2.0f - 20.0f; break; } @@ -629,6 +650,12 @@ void Player::UpdateExpertise(WeaponAttackType attack) } } +void Player::ApplyManaRegenBonus(int32 amount, bool apply) +{ + m_baseManaRegen+= apply ? amount : -amount; + UpdateManaRegen(); +} + void Player::UpdateManaRegen() { float Intellect = GetStat(STAT_INTELLECT); @@ -638,7 +665,7 @@ void Player::UpdateManaRegen() power_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA); // Mana regen from SPELL_AURA_MOD_POWER_REGEN aura - float power_regen_mp5 = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f; + float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f; // Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura AuraList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index f50187efc64..d4c7b1de61f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -905,7 +905,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa if(spell->getState() == SPELL_STATE_PREPARING) { uint32 interruptFlags = spell->m_spellInfo->InterruptFlags; - if(interruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE) + if(interruptFlags & SPELL_INTERRUPT_FLAG_ABORT_ON_DMG) pVictim->InterruptNonMeleeSpells(false); else if(interruptFlags & SPELL_INTERRUPT_FLAG_PUSH_BACK) spell->Delayed(); @@ -5004,7 +5004,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 22858; break; } - else if (dummySpell->SpellIconID == 1697) // Second Wind + // Second Wind + if (dummySpell->SpellIconID == 1697) { // only for spells and hit/crit (trigger start always) and not start from self casted spells (5530 Mace Stun Effect for example) if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) @@ -5017,6 +5018,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { case 29838: triggered_spell_id=29842; break; case 29834: triggered_spell_id=29841; break; + case 42770: triggered_spell_id=42771; break; default: sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (SW)",dummySpell->Id); return false; @@ -5025,6 +5027,13 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu target = this; break; } + // Damage Shield + if (dummySpell->SpellIconID == 3214) + { + triggered_spell_id = 59653; + basepoints0 = GetShieldBlockValue() * triggeredByAura->GetModifier()->m_amount / 100; + break; + } break; } case SPELLFAMILY_WARLOCK: @@ -5074,6 +5083,16 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu mod->m_amount-=damage; return true; } + // Fel Synergy + if (dummySpell->SpellIconID == 3222) + { + target = GetPet(); + if (!target) + return false; + triggered_spell_id = 54181; + basepoints0 = damage * triggeredByAura->GetModifier()->m_amount / 100; + break; + } switch(dummySpell->Id) { // Nightfall @@ -5194,7 +5213,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return false; // heal amount - basepoints0 = int32(damage * 2 / 100); + basepoints0 = damage * triggeredByAura->GetModifier()->m_amount/100; target = this; triggered_spell_id = 39373; break; @@ -5326,6 +5345,31 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } } + // Cut to the Chase + if( dummySpell->SpellIconID == 2909 ) + { + // "refresh your Slice and Dice duration to its 5 combo point maximum" + // lookup Slice and Dice + AuraList const& sd = GetAurasByType(SPELL_AURA_MOD_HASTE); + for(AuraList::const_iterator itr = sd.begin(); itr != sd.end(); ++itr) + { + SpellEntry const *spellProto = (*itr)->GetSpellProto(); + if( spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && + spellProto->SpellFamilyFlags & 0x0000000000040000LL) + { + (*itr)->SetAuraMaxDuration(GetSpellMaxDuration(spellProto)); + (*itr)->RefreshAura(); + return true; + } + } + return false; + } + // Deadly Brew + if( dummySpell->SpellIconID == 2963 ) + { + triggered_spell_id = 25809; + break; + } // Quick Recovery if( dummySpell->SpellIconID == 2116 ) { @@ -5360,6 +5404,33 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 34720; break; } + // Hunting Party + if ( dummySpell->SpellIconID == 3406 ) + { + triggered_spell_id = 57669; + target = this; + return true; + } + // Lock and Load + if ( dummySpell->SpellIconID == 3579 ) + { + // Proc only from periodic (from trap activation proc another aura of this spell) + if (!(procFlag & PROC_FLAG_ON_DO_PERIODIC)) + return false; + if (!roll_chance_i(triggeredByAura->GetModifier()->m_amount)) + return false; + triggered_spell_id = 56453; + target = this; + break; + } + // Rapid Recuperation + if ( dummySpell->SpellIconID == 3560 ) + { + // mane regen from Rapid Killing + triggered_spell_id = 56654; + target = this; + break; + } break; } case SPELLFAMILY_PALADIN: @@ -5702,8 +5773,27 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 55533; break; } + // Spirit Hunt + case 58877: + { + // Cast on owner + target = GetOwner(); + if(!target) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + triggered_spell_id = 58879; + break; + } + } + // Ancestral Awakening + if (dummySpell->SpellIconID == 2018) + { + // TODO: frite dummy fot triggered spell + triggered_spell_id = 52759; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + target = this; + break; } - // Earth Shield if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL) { @@ -5712,6 +5802,26 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu triggered_spell_id = 379; break; } + // Improved Water Shield + if (dummySpell->SpellIconID == 2287) + { + // lookup water shield + AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); + for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) + { + if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000002000000000LL) + { + uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; + CastSpell(this, spell, true, castItem, triggeredByAura); + if ((*itr)->DropAuraCharge()) + RemoveAurasDueToSpell((*itr)->GetId()); + return true; + } + } + return false; + break; + } // Lightning Overload if (dummySpell->SpellIconID == 2018) // only this spell have SpellFamily Shaman SpellIconID == 2018 and dummy aura { @@ -5755,6 +5865,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return false; } // No thread generated mod + // TODO: exist special flag in spell attributes for this, need found and use! SpellModifier *mod = new SpellModifier; mod->op = SPELLMOD_THREAT; mod->value = -100; @@ -5777,10 +5888,78 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu return true; } + // Static Shock + if(dummySpell->SpellIconID == 3059) + { + // lookup Lightning Shield + AuraList const& vs = GetAurasByType(SPELL_AURA_PROC_TRIGGER_SPELL); + for(AuraList::const_iterator itr = vs.begin(); itr != vs.end(); ++itr) + { + if( (*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && + (*itr)->GetSpellProto()->SpellFamilyFlags & 0x0000000000000400LL) + { + uint32 spell = 0; + switch ((*itr)->GetId()) + { + case 324: spell = 26364; break; + case 325: spell = 26365; break; + case 905: spell = 26366; break; + case 945: spell = 26367; break; + case 8134: spell = 26369; break; + case 10431: spell = 26370; break; + case 10432: spell = 26363; break; + case 25469: spell = 26371; break; + case 25472: spell = 26372; break; + default: + return false; + } + CastSpell(this, spell, true, castItem, triggeredByAura); + if ((*itr)->DropAuraCharge()) + RemoveAurasDueToSpell((*itr)->GetId()); + return true; + } + } + return false; + break; + } break; } case SPELLFAMILY_DEATHKNIGHT: { + // Blood Aura + if (dummySpell->SpellIconID == 2636) + { + if (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->isHonorOrXPTarget(pVictim)) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + triggered_spell_id = 53168; + break; + } + // Butchery + if (dummySpell->SpellIconID == 2664) + { + basepoints0 = triggeredByAura->GetModifier()->m_amount; + triggered_spell_id = 50163; + target = this; + break; + } + // Dancing Rune Weapon + if (dummySpell->Id == 49028) + { + // 1 dummy aura for dismiss rune blade + if (triggeredByAura->GetEffIndex()!=2) + return false; + // TODO: wite script for this "fights on its own, doing the same attacks" + // NOTE: Trigger here on every attack and spell cast + return false; + } + // Mark of Blood + if (dummySpell->Id == 49005) + { + // TODO: need more info (cooldowns/PPM) + triggered_spell_id = 50424; + break; + } // Vendetta if (dummySpell->SpellFamilyFlags & 0x0000000000010000LL) { @@ -5790,20 +5969,34 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } // Necrosis - else if (dummySpell->SpellIconID == 2709) + if (dummySpell->SpellIconID == 2709) { basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; triggered_spell_id = 51460; break; } - // Butchery - else if (dummySpell->SpellIconID == 2664) + // Runic Power Back on Snare/Root + if (dummySpell->Id == 61257) { - basepoints0 = triggeredByAura->GetModifier()->m_amount; - triggered_spell_id = 50163; + // only for spells and hit/crit (trigger start always) and not start from self casted spells + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) + return false; + // Need snare or root mechanic + if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_SNARE)))) + return false; + triggered_spell_id = 61258; target = this; break; } + // Wandering Plague + if (dummySpell->SpellIconID == 1614) + { + if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, pVictim))) + return false; + basepoints0 = triggeredByAura->GetModifier()->m_amount * damage / 100; + triggered_spell_id = 50526; + break; + } break; } default: @@ -6272,10 +6465,6 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB trigger_spell_id = 26371; break; case 25472: // Rank 9 trigger_spell_id = 26372; break; - case 49280: // Rank 10 - trigger_spell_id = 49278; break; - case 49281: // Rank 11 - trigger_spell_id = 49279; break; default: sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id); return false; @@ -6494,8 +6683,9 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB // Astral Shift case 52179: { - if(!procSpell) + if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == pVictim) return false; + // Need stun, fear or silence mechanic if (!(GetAllSpellMechanicMask(procSpell) & ((1<<MECHANIC_SILENCE)|(1<<MECHANIC_STUN)|(1<<MECHANIC_FEAR)))) return false; @@ -7587,21 +7777,10 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 DotFactor = 0.95f; CastingTime = 3500; } - // Seal of Righteousness - 10.2%/9.8% ( based on weapon type ) of Holy Damage, multiplied by weapon speed - else if((spellProto->SpellFamilyFlags & 0x8000000LL) && spellProto->SpellIconID == 25) + // Judgement of Righteousness - 32% + else if (spellProto->SpellFamilyFlags & 0x0000000000000400LL) { - Item *item = ((Player*)this)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - float wspeed = GetAttackTime(BASE_ATTACK)/1000.0f; - - if( item && item->GetProto()->InventoryType == INVTYPE_2HWEAPON) - CastingTime = uint32(wspeed*3500*0.102f); - else - CastingTime = uint32(wspeed*3500*0.098f); - } - // Judgement of Righteousness - 73% - else if ((spellProto->SpellFamilyFlags & 1024) && spellProto->SpellIconID == 25) - { - CastingTime = 2555; + CastingTime = 1120; } // Seal of Vengeance - 17% per Fully Stacked Tick - 5 Applications else if ((spellProto->SpellFamilyFlags & 0x80000000000LL) && spellProto->SpellIconID == 2292) @@ -7619,11 +7798,6 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 { CastingTime = 0; } - // Seal of Righteousness trigger - already computed for parent spell - else if ( spellProto->SpellFamilyName==SPELLFAMILY_PALADIN && spellProto->SpellIconID==25 && spellProto->AttributesEx4 & 0x00800000LL ) - { - return pdamage; - } break; case SPELLFAMILY_SHAMAN: // totem attack @@ -7749,6 +7923,9 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask) if (GetTypeId() == TYPEID_PLAYER) { + // Base value + DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellDamageBonus(); + // Damage bonus from stats AuraList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT); for(AuraList::const_iterator i = mDamageDoneOfStatPercent.begin();i != mDamageDoneOfStatPercent.end(); ++i) @@ -8126,6 +8303,9 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) // Healing bonus of spirit, intellect and strength if (GetTypeId() == TYPEID_PLAYER) { + // Base value + AdvertisedBenefit +=((Player*)this)->GetBaseSpellHealingBonus(); + // Healing bonus from stats AuraList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT); for(AuraList::const_iterator i = mHealingDoneOfStatPercent.begin();i != mHealingDoneOfStatPercent.end(); ++i) diff --git a/src/game/Unit.h b/src/game/Unit.h index 5791c060289..4c3d6e48eee 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -45,7 +45,8 @@ enum SpellInterruptFlags SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back SPELL_INTERRUPT_FLAG_INTERRUPT = 0x04, // interrupt SPELL_INTERRUPT_FLAG_AUTOATTACK = 0x08, // no - SPELL_INTERRUPT_FLAG_DAMAGE = 0x10 // _complete_ interrupt on direct damage? + SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10, // _complete_ interrupt on direct damage + //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph" }; enum SpellChannelInterruptFlags diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index cd02ed42252..cd4a2e5faf0 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -568,7 +568,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid) uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) { - if(mapid != 530 || mapid != 571) // speed for most cases + if(mapid != 530 && mapid != 571) // speed for most cases return mapid; if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d159296e986..60f75e4853c 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 "7092" + #define REVISION_NR "7100" #endif // __REVISION_NR_H__ |