diff --git a/src/game/Creature.h b/src/game/Creature.h index aca3bc6a4..ba89bc255 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -550,9 +550,9 @@ class MANGOS_DLL_SPEC Creature : public Unit void SetRoot(bool enable) override; void SetWaterWalk(bool enable) override; - uint32 GetShieldBlockValue() const override // dunno mob block value + uint32 GetShieldBlockDamageValue() const override // dunno mob block value { - return (getLevel() / 2 + uint32(GetStat(STAT_STRENGTH) / 20)); + return uint32(BASE_BLOCK_DAMAGE_PERCENT); } SpellSchoolMask GetMeleeDamageSchoolMask() const override { return m_meleeDamageSchoolMask; } diff --git a/src/game/Item.cpp b/src/game/Item.cpp index b5563a979..8c6cd58b0 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -740,46 +740,6 @@ uint32 Item::GetSkill() } } -uint32 Item::GetSpell() -{ - ItemPrototype const* proto = GetProto(); - - switch (proto->Class) - { - case ITEM_CLASS_WEAPON: - switch (proto->SubClass) - { - case ITEM_SUBCLASS_WEAPON_AXE: return 196; - case ITEM_SUBCLASS_WEAPON_AXE2: return 197; - case ITEM_SUBCLASS_WEAPON_BOW: return 264; - case ITEM_SUBCLASS_WEAPON_GUN: return 266; - case ITEM_SUBCLASS_WEAPON_MACE: return 198; - case ITEM_SUBCLASS_WEAPON_MACE2: return 199; - case ITEM_SUBCLASS_WEAPON_POLEARM: return 200; - case ITEM_SUBCLASS_WEAPON_SWORD: return 201; - case ITEM_SUBCLASS_WEAPON_SWORD2: return 202; - case ITEM_SUBCLASS_WEAPON_STAFF: return 227; - case ITEM_SUBCLASS_WEAPON_DAGGER: return 1180; - case ITEM_SUBCLASS_WEAPON_THROWN: return 2567; - case ITEM_SUBCLASS_WEAPON_SPEAR: return 3386; - case ITEM_SUBCLASS_WEAPON_CROSSBOW: return 5011; - case ITEM_SUBCLASS_WEAPON_WAND: return 5009; - default: return 0; - } - case ITEM_CLASS_ARMOR: - switch (proto->SubClass) - { - case ITEM_SUBCLASS_ARMOR_CLOTH: return 9078; - case ITEM_SUBCLASS_ARMOR_LEATHER: return 9077; - case ITEM_SUBCLASS_ARMOR_MAIL: return 8737; - case ITEM_SUBCLASS_ARMOR_PLATE: return 750; - case ITEM_SUBCLASS_ARMOR_SHIELD: return 9116; - default: return 0; - } - } - return 0; -} - int32 Item::GenerateItemRandomPropertyId(uint32 item_id) { ItemPrototype const* itemProto = sItemStorage.LookupEntry(item_id); diff --git a/src/game/Item.h b/src/game/Item.h index 7f7c984ac..e543e3730 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -329,7 +329,6 @@ class MANGOS_DLL_SPEC Item : public Object bool IsEquipped() const; uint32 GetSkill(); - uint32 GetSpell(); // RandomPropertyId (signed but stored as unsigned) int32 GetItemRandomPropertyId() const { return GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID); } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 0f71f82a4..b676a7033 100755 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -8338,12 +8338,10 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const* pSkill, bool racial) { switch (pSkill->categoryId) { - case SKILL_CATEGORY_LANGUAGES: return SKILL_RANGE_LANGUAGE; + case SKILL_CATEGORY_LANGUAGES: + return SKILL_RANGE_LANGUAGE; case SKILL_CATEGORY_WEAPON: - if (pSkill->id != SKILL_FIST_WEAPONS) - return SKILL_RANGE_LEVEL; - else - return SKILL_RANGE_MONO; + return SKILL_RANGE_LEVEL; case SKILL_CATEGORY_ARMOR: case SKILL_CATEGORY_CLASS: return SKILL_RANGE_MONO; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index b9f75c896..9222ee1b2 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2754,7 +2754,7 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(PLAYER_PARRY_PERCENTAGE, 0.0f); SetFloatValue(PLAYER_BLOCK_PERCENTAGE, 0.0f); - SetUInt32Value(PLAYER_SHIELD_BLOCK, 0); + SetUInt32Value(PLAYER_SHIELD_BLOCK, uint32(BASE_BLOCK_DAMAGE_PERCENT)); // Dodge percentage SetFloatValue(PLAYER_DODGE_PERCENTAGE, 0.0f); @@ -5037,17 +5037,6 @@ void Player::LeaveLFGChannel() } } -void Player::UpdateDefense() -{ - uint32 defense_skill_gain = sWorld.getConfig(CONFIG_UINT32_SKILL_GAIN_DEFENSE); - - if (UpdateSkill(SKILL_DEFENSE, defense_skill_gain)) - { - // update dependent from defense skill part - UpdateDefenseBonusesMod(); - } -} - void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply) { if (modGroup >= BASEMOD_END || modType >= MOD_END) @@ -5080,7 +5069,7 @@ void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, floa case CRIT_PERCENTAGE: UpdateCritPercentage(BASE_ATTACK); break; case RANGED_CRIT_PERCENTAGE: UpdateCritPercentage(RANGED_ATTACK); break; case OFFHAND_CRIT_PERCENTAGE: UpdateCritPercentage(OFF_ATTACK); break; - case SHIELD_BLOCK_VALUE: UpdateShieldBlockValue(); break; + case SHIELD_BLOCK_DAMAGE_VALUE: UpdateShieldBlockDamageValue(); break; default: break; } } @@ -5113,9 +5102,10 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const return m_auraBaseMod[modGroup][FLAT_MOD] * m_auraBaseMod[modGroup][PCT_MOD]; } -uint32 Player::GetShieldBlockValue() const +uint32 Player::GetShieldBlockDamageValue() const { - float value = (m_auraBaseMod[SHIELD_BLOCK_VALUE][FLAT_MOD] + GetStat(STAT_STRENGTH) * 0.5f - 10) * m_auraBaseMod[SHIELD_BLOCK_VALUE][PCT_MOD]; + float value = m_canBlock ? BASE_BLOCK_DAMAGE_PERCENT : 0; + value = (value + m_auraBaseMod[SHIELD_BLOCK_DAMAGE_VALUE][FLAT_MOD]) * m_auraBaseMod[SHIELD_BLOCK_DAMAGE_VALUE][PCT_MOD]; value = (value < 0) ? 0 : value; @@ -5140,6 +5130,14 @@ float Player::GetMeleeCritFromAgility() void Player::GetDodgeFromAgility(float& diminishing, float& nondiminishing) { + // 4.2.0: these classes no longer receive dodge from agility and have 5% base + if (getClass() == CLASS_WARRIOR || getClass() == CLASS_PALADIN || getClass() == CLASS_DEATH_KNIGHT) + { + diminishing = 0.0f; + nondiminishing = 5.0f; + return; + } + // Table for base dodge values const float dodge_base[MAX_CLASSES] = { @@ -5328,9 +5326,8 @@ void Player::UpdateRating(CombatRating cr) switch (cr) { - case CR_WEAPON_SKILL: // Implemented in Unit::RollMeleeOutcomeAgainst + case CR_WEAPON_SKILL: case CR_DEFENSE_SKILL: - UpdateDefenseBonusesMod(); break; case CR_DODGE: UpdateDodgePercentage(); @@ -5599,69 +5596,6 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step) return false; } -void Player::UpdateWeaponSkill(WeaponAttackType attType) -{ - // no skill gain in pvp - Unit* pVictim = getVictim(); - if (pVictim && pVictim->IsCharmerOrOwnerPlayerOrPlayerItself()) - return; - - if (IsInFeralForm()) - return; // always maximized SKILL_FERAL_COMBAT in fact - - if (GetShapeshiftForm() == FORM_TREE) - return; // use weapon but not skill up - - uint32 weaponSkillGain = sWorld.getConfig(CONFIG_UINT32_SKILL_GAIN_WEAPON); - - Item* pWeapon = GetWeaponForAttack(attType, true, true); - if (pWeapon && pWeapon->GetProto()->SubClass != ITEM_SUBCLASS_WEAPON_FISHING_POLE) - UpdateSkill(pWeapon->GetSkill(), weaponSkillGain); - else if (!pWeapon && attType == BASE_ATTACK) - UpdateSkill(SKILL_UNARMED, weaponSkillGain); - - UpdateAllCritPercentages(); -} - -void Player::UpdateCombatSkills(Unit* pVictim, WeaponAttackType attType, bool defence) -{ - uint32 plevel = getLevel(); // if defense than pVictim == attacker - uint32 greylevel = MaNGOS::XP::GetGrayLevel(plevel); - uint32 moblevel = pVictim->GetLevelForTarget(this); - if (moblevel < greylevel) - return; - - if (moblevel > plevel + 5) - moblevel = plevel + 5; - - uint32 lvldif = moblevel - greylevel; - if (lvldif < 3) - lvldif = 3; - - int32 skilldif = 5 * plevel - (defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType)); - - // Max skill reached for level. - // Can in some cases be less than 0: having max skill and then .level -1 as example. - if (skilldif <= 0) - return; - - float chance = float(3 * lvldif * skilldif) / plevel; - if (!defence) - chance *= 0.1f * GetStat(STAT_INTELLECT); - - chance = chance < 1.0f ? 1.0f : chance; // minimum chance to increase skill is 1% - - if (roll_chance_f(chance)) - { - if (defence) - UpdateDefense(); - else - UpdateWeaponSkill(attType); - } - else - return; -} - void Player::ModifySkillBonus(uint32 skillid, int32 val, bool talent) { SkillStatusMap::const_iterator itr = mSkillStatus.find(skillid); @@ -5678,11 +5612,8 @@ void Player::ModifySkillBonus(uint32 skillid, int32 val, bool talent) void Player::UpdateSkillsForLevel() { - uint16 maxconfskill = sWorld.GetConfigMaxSkillValue(); uint32 maxSkill = GetMaxSkillValueForLevel(); - bool alwaysMaxSkill = sWorld.getConfig(CONFIG_BOOL_ALWAYS_MAX_SKILL_FOR_LEVEL); - for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end(); ++itr) { if (itr->second.uState == SKILL_DELETED) @@ -5706,22 +5637,11 @@ void Player::UpdateSkillsForLevel() /// update only level dependent max skill values if (max != 1) { - /// maximize skill always - if (alwaysMaxSkill) - { - SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, maxSkill); - SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxSkill); - if (itr->second.uState != SKILL_NEW) - itr->second.uState = SKILL_CHANGED; - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, pskill); - } - else if (max != maxconfskill) /// update max skill value if current max skill not maximized - { - SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, val); - SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxSkill); - if (itr->second.uState != SKILL_NEW) - itr->second.uState = SKILL_CHANGED; - } + SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, maxSkill); + SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxSkill); + if (itr->second.uState != SKILL_NEW) + itr->second.uState = SKILL_CHANGED; + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, pskill); } } } @@ -5748,9 +5668,6 @@ void Player::UpdateSkillsToMaxSkillsForLevel() itr->second.uState = SKILL_CHANGED; GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, pskill); } - - if (pskill == SKILL_DEFENSE) - UpdateDefenseBonusesMod(); } } @@ -15627,6 +15544,22 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) SetGuidValue(PLAYER_DUEL_ARBITER, ObjectGuid()); SetUInt32Value(PLAYER_DUEL_TEAM, 0); + m_specsCount = fields[52].GetUInt8(); + m_activeSpec = fields[53].GetUInt8(); + + Tokens talentTrees = StrSplit(fields[26].GetString(), " "); + for (uint8 i = 0; i < MAX_TALENT_SPEC_COUNT; ++i) + { + if (i >= talentTrees.size()) + break; + + uint32 talentTree = atol(talentTrees[i].c_str()); + if (!talentTree || sTalentTabStore.LookupEntry(talentTree)) + m_talentsPrimaryTree[i] = talentTree; + else if (i == m_activeSpec) + SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents + } + // reset stats before loading any modifiers InitStatsForLevel(); InitGlyphsForLevel(); @@ -15659,9 +15592,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) _LoadMailedItems(holder->GetResult(PLAYER_LOGIN_QUERY_LOADMAILEDITEMS)); UpdateNextMailTimeAndUnreads(); - m_specsCount = fields[52].GetUInt8(); - m_activeSpec = fields[53].GetUInt8(); - _LoadGlyphs(holder->GetResult(PLAYER_LOGIN_QUERY_LOADGLYPHS)); _LoadAuras(holder->GetResult(PLAYER_LOGIN_QUERY_LOADAURAS), time_diff); @@ -15782,20 +15712,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) DEBUG_FILTER_LOG(LOG_FILTER_PLAYER_STATS, "The value of player %s after load item and aura is: ", m_name.c_str()); outDebugStatsValues(); - // must be after loading spells and talents - Tokens talentTrees = StrSplit(fields[26].GetString(), " "); - for (uint8 i = 0; i < MAX_TALENT_SPEC_COUNT; ++i) - { - if (i >= talentTrees.size()) - break; - - uint32 talentTree = atol(talentTrees[i].c_str()); - if (!talentTree || sTalentTabStore.LookupEntry(talentTree)) - m_talentsPrimaryTree[i] = talentTree; - else if (i == m_activeSpec) - SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents - } - // all fields read delete result; @@ -21069,19 +20985,6 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const return pRewardSource->IsWithinDistInMap(corpse, sWorld.getConfig(CONFIG_FLOAT_GROUP_XP_DISTANCE)); } -uint32 Player::GetBaseWeaponSkillValue(WeaponAttackType attType) const -{ - Item* item = GetWeaponForAttack(attType, true, true); - - // unarmed only with base attack - if (attType != BASE_ATTACK && !item) - return 0; - - // weapon skill or (unarmed for base attack) - uint32 skill = item ? item->GetSkill() : uint32(SKILL_UNARMED); - return GetBaseSkillValue(skill); -} - void Player::ResurectUsingRequestData() { /// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse @@ -21394,6 +21297,7 @@ void Player::SetCanBlock(bool value) m_canBlock = value; UpdateBlockPercentage(); + UpdateShieldBlockDamageValue(); } bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const diff --git a/src/game/Player.h b/src/game/Player.h index 5f4811128..0ab8e835f 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1797,11 +1797,6 @@ class MANGOS_DLL_SPEC Player : public Unit bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1); bool UpdateFishingSkill(); - uint32 GetBaseDefenseSkillValue() const { return GetBaseSkillValue(SKILL_DEFENSE); } - uint32 GetBaseWeaponSkillValue(WeaponAttackType attType) const; - - uint32 GetSpellByProto(ItemPrototype* proto); - float GetHealthBonusFromStamina(); float GetManaBonusFromIntellect(); @@ -1813,7 +1808,7 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateMaxPower(Powers power) override; void ApplyFeralAPBonus(int32 amount, bool apply); void UpdateAttackPowerAndDamage(bool ranged = false) override; - void UpdateShieldBlockValue(); + void UpdateShieldBlockDamageValue(); void UpdateDamagePhysical(WeaponAttackType attType) override; void ApplySpellPowerBonus(int32 amount, bool apply); void UpdateSpellDamageAndHealingBonus(); @@ -1823,7 +1818,6 @@ class MANGOS_DLL_SPEC Player : public Unit void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage); - void UpdateDefenseBonusesMod(); float GetMeleeCritFromAgility(); void GetDodgeFromAgility(float& diminishing, float& nondiminishing); float GetSpellCritFromIntellect(); @@ -1925,10 +1919,6 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateLocalChannels(uint32 newZone); void LeaveLFGChannel(); - void UpdateDefense(); - void UpdateWeaponSkill(WeaponAttackType attType); - void UpdateCombatSkills(Unit* pVictim, WeaponAttackType attType, bool defence); - void SetSkill(uint16 id, uint16 currVal, uint16 maxVal, uint16 step = 0); uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus uint16 GetPureMaxSkillValue(uint32 skill) const; // max @@ -2012,7 +2002,7 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateCorpseReclaimDelay(); void SendCorpseReclaimDelay(bool load = false); - uint32 GetShieldBlockValue() const override; // overwrite Unit version (virtual) + uint32 GetShieldBlockDamageValue() const override; // overwrite Unit version (virtual) bool CanParry() const { return m_canParry; } void SetCanParry(bool value); bool CanBlock() const { return m_canBlock; } diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 2fdf213dd..bbfeb086c 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -86,7 +86,7 @@ enum AuraType SPELL_AURA_48 = 48, // One periodic spell SPELL_AURA_MOD_DODGE_PERCENT = 49, SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT = 50, - SPELL_AURA_MOD_BLOCK_PERCENT = 51, + SPELL_AURA_MOD_BLOCK_CHANCE_PERCENT = 51, SPELL_AURA_MOD_CRIT_PERCENT = 52, SPELL_AURA_PERIODIC_LEECH = 53, SPELL_AURA_MOD_HIT_CHANCE = 54, @@ -185,7 +185,7 @@ enum AuraType SPELL_AURA_MECHANIC_IMMUNITY_MASK = 147, SPELL_AURA_RETAIN_COMBO_POINTS = 148, SPELL_AURA_REDUCE_PUSHBACK = 149, // Reduce Pushback - SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150, + SPELL_AURA_MOD_SHIELD_BLOCKDAMAGE = 150, SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index e3bc4ccca..16f32785c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -104,7 +104,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] = &Aura::HandleNULL, // 48 SPELL_AURA_48 4 spells in 4.3.4 Napalm (area damage spell with additional delayed damage effect) &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT &Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus - &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT + &Aura::HandleAuraModBlockChancePercent, // 51 SPELL_AURA_MOD_BLOCK_CHANCE_PERCENT &Aura::HandleAuraModCritPercent, // 52 SPELL_AURA_MOD_CRIT_PERCENT &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE @@ -203,7 +203,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] = &Aura::HandleModMechanicImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK implemented in Unit::IsImmuneToSpell and Unit::IsImmuneToSpellEffect (check part) &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK implemented in Spell::Delayed and Spell::DelayedChannel - &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT + &Aura::HandleModShieldBlockDamage, //150 SPELL_AURA_MOD_SHIELD_BLOCKDAMAGE &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT implemented in Unit::CalculateAbsorbAndResist @@ -211,7 +211,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] = &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING implemented in Player::getMaxTimer &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN implemented in Player::CalculateReputationGain &Aura::HandleUnused, //157 SPELL_AURA_PET_DAMAGE_MULTI (single test like spell 20782, also single for 214 aura) - &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE + &Aura::HandleNULL, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT implemented in Player::RewardHonor &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT implemented in Player::RegenerateAll and Player::RegenerateHealth @@ -306,7 +306,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS] = &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2 &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE &Aura::HandleModCombatSpeedPct, //252 SPELL_AURA_SLOW_ALL - &Aura::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::CalculateMeleeDamage + &Aura::HandleAuraModBlockCritChance, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE obsolete in 4.x, but spells exist &Aura::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND also disarm shield &Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonusTaken &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select @@ -3975,9 +3975,12 @@ void Aura::HandleAuraModSkill(bool apply, bool /*Real*/) uint32 prot = m_spellEffect->EffectMiscValue; int32 points = GetModifier()->m_amount; - ((Player*)GetTarget())->ModifySkillBonus(prot, (apply ? points : -points), m_modifier.m_auraname == SPELL_AURA_MOD_SKILL_TALENT); + // defense skill is removed in 4.x.x, spell tooltips updated, + // but auras still exist if (prot == SKILL_DEFENSE) - ((Player*)GetTarget())->UpdateDefenseBonusesMod(); + return; + + ((Player*)GetTarget())->ModifySkillBonus(prot, (apply ? points : -points), m_modifier.m_auraname == SPELL_AURA_MOD_SKILL_TALENT); } void Aura::HandleChannelDeathItem(bool apply, bool Real) @@ -6199,7 +6202,7 @@ void Aura::HandleAuraModDodgePercent(bool /*apply*/, bool /*Real*/) // sLog.outError("BONUS DODGE CHANCE: + %f", float(m_modifier.m_amount)); } -void Aura::HandleAuraModBlockPercent(bool /*apply*/, bool /*Real*/) +void Aura::HandleAuraModBlockChancePercent(bool /*apply*/, bool /*Real*/) { if (GetTarget()->GetTypeId() != TYPEID_PLAYER) return; @@ -7012,14 +7015,10 @@ void Aura::HandleModTargetResistance(bool apply, bool Real) target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, m_modifier.m_amount, apply); } -void Aura::HandleShieldBlockValue(bool apply, bool /*Real*/) +void Aura::HandleModShieldBlockDamage(bool apply, bool /*Real*/) { - BaseModType modType = FLAT_MOD; - if (m_modifier.m_auraname == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT) - modType = PCT_MOD; - if (GetTarget()->GetTypeId() == TYPEID_PLAYER) - ((Player*)GetTarget())->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_modifier.m_amount), apply); + ((Player*)GetTarget())->HandleBaseModValue(SHIELD_BLOCK_DAMAGE_VALUE, FLAT_MOD, float(m_modifier.m_amount), apply); } void Aura::HandleAuraRetainComboPoints(bool apply, bool Real) @@ -8746,9 +8745,6 @@ void Aura::HandleAuraStopNaturalManaRegen(bool apply, bool Real) void Aura::HandleAuraMastery(bool apply, bool Real) { - if (!Real) - return; - Unit* target = GetTarget(); if (target->GetTypeId() != TYPEID_PLAYER) return; @@ -8756,6 +8752,12 @@ void Aura::HandleAuraMastery(bool apply, bool Real) ((Player*)target)->UpdateMasteryAuras(); } +void Aura::HandleAuraModBlockCritChance(bool apply, bool Real) +{ + if (GetTarget()->GetTypeId() == TYPEID_PLAYER) + ((Player*)GetTarget())->ApplyModUInt32Value(PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE, m_modifier.m_amount, apply); +} + bool Aura::IsLastAuraOnHolder() { for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 51c179a99..3a13457e7 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -288,7 +288,7 @@ class MANGOS_DLL_SPEC Aura void HandleAuraTrackResources(bool Apply, bool Real); void HandleAuraModParryPercent(bool Apply, bool Real); void HandleAuraModDodgePercent(bool Apply, bool Real); - void HandleAuraModBlockPercent(bool Apply, bool Real); + void HandleAuraModBlockChancePercent(bool Apply, bool Real); void HandleAuraModCritPercent(bool Apply, bool Real); void HandlePeriodicLeech(bool Apply, bool Real); void HandleModHitChance(bool Apply, bool Real); @@ -321,9 +321,7 @@ class MANGOS_DLL_SPEC Aura void HandleModPercentStat(bool Apply, bool Real); void HandleModResistancePercent(bool Apply, bool Real); void HandleAuraModBaseResistancePCT(bool Apply, bool Real); - void HandleModShieldBlockPCT(bool Apply, bool Real); void HandleAuraTrackStealthed(bool Apply, bool Real); - void HandleModShieldBlock(bool Apply, bool Real); void HandleForceReaction(bool Apply, bool Real); void HandleAuraModRangedHaste(bool Apply, bool Real); void HandleRangedAmmoHaste(bool Apply, bool Real); @@ -345,7 +343,7 @@ class MANGOS_DLL_SPEC Aura void HandleSpiritOfRedemption(bool apply, bool Real); void HandleModManaRegen(bool apply, bool Real); void HandleComprehendLanguage(bool apply, bool Real); - void HandleShieldBlockValue(bool apply, bool Real); + void HandleModShieldBlockDamage(bool apply, bool Real); void HandleModSpellCritChanceShool(bool apply, bool Real); void HandleAuraRetainComboPoints(bool apply, bool Real); void HandleModSpellDamagePercentFromStat(bool apply, bool Real); @@ -375,6 +373,7 @@ class MANGOS_DLL_SPEC Aura void HandleAuraAddMechanicAbilities(bool apply, bool Real); void HandleAuraStopNaturalManaRegen(bool apply, bool Real); void HandleAuraMastery(bool apply, bool Real); + void HandleAuraModBlockCritChance(bool apply, bool Real); virtual ~Aura(); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 3365d5d26..5710d03b1 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -430,9 +430,6 @@ void Spell::EffectSchoolDMG(SpellEffectEntry const* effect) { damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100); } - // Shield Slam - else if ((classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0000020000000000)) && m_spellInfo->GetCategory()==1209) - damage += int32(m_caster->GetShieldBlockValue()); // Victory Rush else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x10000000000)) { @@ -765,11 +762,6 @@ void Spell::EffectSchoolDMG(SpellEffectEntry const* effect) int32 count = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_INDEX_2); damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); } - // Shield of Righteousness - else if (classOptions && classOptions->SpellFamilyFlags & UI64LIT(0x0010000000000000)) - { - damage += int32(m_caster->GetShieldBlockValue()); - } // Judgement else if (m_spellInfo->Id == 54158) { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index c0dfe9efa..0ac742eaa 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -4750,3 +4750,33 @@ SpellEntry const* GetSpellEntryByDifficulty(uint32 id, Difficulty difficulty, bo return NULL; } + +int32 GetMasteryCoefficient(SpellEntry const * spellProto) +{ + if (!spellProto || !spellProto->HasAttribute(SPELL_ATTR_EX8_MASTERY)) + return 0; + + // Find mastery scaling coef + int32 coef = 0; + for (uint32 j = 0; j < MAX_EFFECT_INDEX; ++j) + { + SpellEffectEntry const * effectEntry = spellProto->GetSpellEffect(SpellEffectIndex(j)); + if (!effectEntry) + continue; + + // mastery scaling coef is stored in dummy aura, except 77215 (Potent Afflictions, zero effect) + // and 76808 (Executioner, not stored at all) + int32 bp = effectEntry->CalculateSimpleValue(); + if (spellProto->Id == 76808) + bp = 250; + + if (!bp) + continue; + + coef = bp; + break; + } + + return coef; +} + diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 3f64b7f4a..a7f2599b7 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -607,6 +607,8 @@ int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellEntry cons SpellEntry const* GetSpellEntryByDifficulty(uint32 id, Difficulty difficulty, bool isRaid); +int32 GetMasteryCoefficient(SpellEntry const * spellProto); + // Spell proc event related declarations (accessed using SpellMgr functions) enum ProcFlags { diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 6bbccdd15..f8c592d76 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -16,12 +16,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "DBCStores.h" #include "Unit.h" #include "Player.h" #include "Pet.h" #include "Creature.h" #include "SharedDefines.h" #include "SpellAuras.h" +#include "SpellMgr.h" /*####################################### ######## ######## @@ -49,7 +51,6 @@ bool Player::UpdateStats(Stats stat) switch (stat) { case STAT_STRENGTH: - UpdateShieldBlockValue(); break; case STAT_AGILITY: UpdateArmor(); @@ -131,8 +132,10 @@ bool Player::UpdateAllStats() UpdateAllRatings(); UpdateAllCritPercentages(); UpdateAllSpellCritChances(); - UpdateDefenseBonusesMod(); - UpdateShieldBlockValue(); + UpdateBlockPercentage(); + UpdateParryPercentage(); + UpdateShieldBlockDamageValue(); + UpdateDodgePercentage(); UpdateArmorPenetration(); UpdateSpellDamageAndHealingBonus(); UpdateManaRegen(); @@ -393,9 +396,9 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) } } -void Player::UpdateShieldBlockValue() +void Player::UpdateShieldBlockDamageValue() { - SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue()); + SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockDamageValue()); } void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, float& min_damage, float& max_damage) @@ -479,13 +482,6 @@ void Player::UpdateDamagePhysical(WeaponAttackType attType) } } -void Player::UpdateDefenseBonusesMod() -{ - UpdateBlockPercentage(); - UpdateParryPercentage(); - UpdateDodgePercentage(); -} - void Player::UpdateBlockPercentage() { // No block @@ -494,11 +490,9 @@ void Player::UpdateBlockPercentage() { // Base value value = 5.0f; - // Modify value from defense skill - value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f; - // Increase from SPELL_AURA_MOD_BLOCK_PERCENT aura - value += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT); - // Increase from rating + // Increase from SPELL_AURA_MOD_BLOCK_CHANCE_PERCENT aura + value += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CHANCE_PERCENT); + // Increase from rating (exists only on auras) value += GetRatingBonusValue(CR_BLOCK); value = value < 0.0f ? 0.0f : value; } @@ -533,7 +527,7 @@ void Player::UpdateCritPercentage(WeaponAttackType attType) float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr); // Modify crit from weapon skill and maximized defense skill of same level victim difference - value += (int32(GetWeaponSkillValue(attType)) - int32(GetMaxSkillValueForLevel())) * 0.04f; + value += (int32(GetMaxSkillValueForLevel()) - int32(GetMaxSkillValueForLevel())) * 0.04f; value = value < 0.0f ? 0.0f : value; SetStatFloatValue(index, value); } @@ -570,17 +564,17 @@ void Player::UpdateParryPercentage() { const float parry_cap[MAX_CLASSES] = { - 47.003525f, // Warrior - 47.003525f, // Paladin - 145.560408f, // Hunter - 145.560408f, // Rogue - 0.0f, // Priest - 47.003525f, // DK - 145.560408f, // Shaman - 0.0f, // Mage - 0.0f, // Warlock - 0.0f, // ?? - 0.0f // Druid + 65.631440f, // Warrior + 65.631440f, // Paladin + 145.560408f, // Hunter + 145.560408f, // Rogue + 0.0f, // Priest + 65.631440f, // DK + 145.560408f, // Shaman + 0.0f, // Mage + 0.0f, // Warlock + 0.0f, // ?? + 0.0f // Druid }; // No parry @@ -592,9 +586,6 @@ void Player::UpdateParryPercentage() float nondiminishing = 5.0f; // Parry from rating float diminishing = GetRatingBonusValue(CR_PARRY); - // Modify value from defense skill (only bonus from defense rating diminishes) - nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f; - diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f; // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT); // apply diminishing formula to diminishing parry chance @@ -609,25 +600,22 @@ void Player::UpdateDodgePercentage() { const float dodge_cap[MAX_CLASSES] = { - 88.129021f, // Warrior - 88.129021f, // Paladin - 145.560408f, // Hunter - 145.560408f, // Rogue - 150.375940f, // Priest - 88.129021f, // DK - 145.560408f, // Shaman - 150.375940f, // Mage - 150.375940f, // Warlock - 0.0f, // ?? - 116.890707f // Druid + 65.631440f, // Warrior + 65.631440f, // Paladin + 145.560408f, // Hunter + 145.560408f, // Rogue + 150.375940f, // Priest + 65.631440f, // DK + 145.560408f, // Shaman + 150.375940f, // Mage + 150.375940f, // Warlock + 0.0f, // ?? + 116.890707f // Druid }; float diminishing = 0.0f, nondiminishing = 0.0f; // Dodge from agility GetDodgeFromAgility(diminishing, nondiminishing); - // Modify value from defense skill (only bonus from defense rating diminishes) - nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f; - diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f; // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT); // Dodge from rating @@ -804,28 +792,9 @@ void Player::UpdateMasteryAuras() SpellEntry const* spellEntry = holder->GetSpellProto(); - // Find mastery scaling coef - int32 masteryBonus = 0; - for (uint32 j = 0; j < MAX_EFFECT_INDEX; ++j) - { - SpellEffectEntry const * effectEntry = spellEntry->GetSpellEffect(SpellEffectIndex(j)); - if (!effectEntry) - continue; - - // mastery scaling coef is stored in dummy aura, except 77215 (Potent Afflictions, zero effect) - // and 76808 (Executioner, not stored at all) - uint32 bp = effectEntry->CalculateSimpleValue(); - if (holder->GetId() == 76808) - bp = 250; - - if (!bp) - continue; - - masteryBonus = bp; - break; - } - - if (!masteryBonus) + // calculate mastery scaling coef + int32 masteryCoef = GetMasteryCoefficient(spellEntry); + if (!masteryCoef) continue; // update aura modifiers @@ -835,11 +804,11 @@ void Player::UpdateMasteryAuras() if (!aura) continue; - if (aura->GetSpellProto()->CalculateSimpleValue(SpellEffectIndex(j))) + if (spellEntry->CalculateSimpleValue(SpellEffectIndex(j))) continue; aura->ApplyModifier(false, false); - aura->GetModifier()->m_amount = int32(masteryValue * masteryBonus / 100.0f); + aura->GetModifier()->m_amount = int32(masteryValue * masteryCoef / 100.0f); aura->ApplyModifier(true, false); } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index a9bb35c67..cb7fad5df 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1854,7 +1854,7 @@ void Unit::CalculateMeleeDamage(Unit* pVictim, uint32 damage, CalcDamageInfo* da damageInfo->TargetState = VICTIMSTATE_NORMAL; damageInfo->HitInfo |= HITINFO_BLOCK; damageInfo->procEx |= PROC_EX_BLOCK; - damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue(); + damageInfo->blocked_amount = damageInfo->target->GetShieldBlockDamageValue() * damageInfo->damage / 100.0f; // Target has a chance to double the blocked amount if it has SPELL_AURA_MOD_BLOCK_CRIT_CHANCE if (roll_chance_i(pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CRIT_CHANCE))) @@ -1903,7 +1903,7 @@ void Unit::CalculateMeleeDamage(Unit* pVictim, uint32 damage, CalcDamageInfo* da } // calculate values - int32 diff = damageInfo->target->GetDefenseSkillValue() - GetWeaponSkillValue(damageInfo->attackType); + int32 diff = damageInfo->target->GetMaxSkillValueForLevel() - GetMaxSkillValueForLevel(); float lowEnd = baseLowEnd - (0.05f * diff); float highEnd = baseHighEnd - (0.03f * diff); @@ -2046,8 +2046,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) if (pVictim->getLevel() < 30) Probability = 0.65f * pVictim->getLevel() + 0.5f; - uint32 VictimDefense = pVictim->GetDefenseSkillValue(); - uint32 AttackerMeleeSkill = GetUnitMeleeSkill(); + uint32 VictimDefense = pVictim->GetMaxSkillValueForLevel(this); + uint32 AttackerMeleeSkill = GetMaxSkillValueForLevel(); Probability *= AttackerMeleeSkill / (float)VictimDefense; @@ -2758,7 +2758,7 @@ void Unit::CalculateAbsorbResistBlock(Unit* pCaster, SpellNonMeleeDamage* damage if (blocked) { - damageInfo->blocked = GetShieldBlockValue(); + damageInfo->blocked = uint32(damageInfo->damage * GetShieldBlockDamageValue() / 100.0f); if (damageInfo->damage < damageInfo->blocked) damageInfo->blocked = damageInfo->damage; damageInfo->damage -= damageInfo->blocked; @@ -2930,11 +2930,8 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* pVictim, WeaponAttackT int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(pVictim); int32 victimMaxSkillValueForLevel = pVictim->GetMaxSkillValueForLevel(this); - int32 attackerWeaponSkill = GetWeaponSkillValue(attType, pVictim); - int32 victimDefenseSkill = pVictim->GetDefenseSkillValue(this); - // bonus from skills is 0.04% - int32 skillBonus = 4 * (attackerWeaponSkill - victimMaxSkillValueForLevel); + int32 skillBonus = 4 * (attackerMaxSkillValueForLevel - victimMaxSkillValueForLevel); int32 sum = 0, tmp = 0; int32 roll = urand(0, 10000); @@ -3019,11 +3016,9 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* pVictim, WeaponAttackT getLevel() < pVictim->GetLevelForTarget(this)) { // cap possible value (with bonuses > max skill) - int32 skill = attackerWeaponSkill; - int32 maxskill = attackerMaxSkillValueForLevel; - skill = (skill > maxskill) ? maxskill : skill; + int32 skill = attackerMaxSkillValueForLevel; - tmp = (10 + (victimDefenseSkill - skill)) * 100; + tmp = (10 + (victimMaxSkillValueForLevel - skill)) * 100; tmp = tmp > 4000 ? 4000 : tmp; if (roll < (sum += tmp)) { @@ -3066,10 +3061,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* pVictim, WeaponAttackT GetTypeId() == TYPEID_PLAYER && GetCharmerOrOwnerGuid())) { // when their weapon skill is 15 or more above victim's defense skill - tmp = victimDefenseSkill; - int32 tmpmax = victimMaxSkillValueForLevel; - // having defense above your maximum (from items, talents etc.) has no effect - tmp = tmp > tmpmax ? tmpmax : tmp; + tmp = victimMaxSkillValueForLevel; // tmp = mob's level * 5 - player's current defense skill tmp = attackerMaxSkillValueForLevel - tmp; if (tmp >= 15) @@ -3204,7 +3196,11 @@ bool Unit::IsSpellBlocked(Unit* pCaster, SpellEntry const* spellEntry, WeaponAtt } float blockChance = GetUnitBlockChance(); - blockChance += (int32(pCaster->GetWeaponSkillValue(attackType)) - int32(GetMaxSkillValueForLevel())) * 0.04f; + // For each point of difference between the attacker's level and the defender's level, + // the block chance is modified by 0.5% if the target is a mob and 0.2% if the target is a player. + blockChance += (getLevel() - pCaster->GetLevelForTarget(this)) * (pCaster->GetTypeId() == TYPEID_PLAYER ? 0.2f : 0.5f); + if (blockChance < 0.0f) + blockChance = 0.0f; return roll_chance_f(blockChance); } @@ -3262,13 +3258,12 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* pVictim, SpellEntry const* spell) attType = RANGED_ATTACK; // bonus from skills is 0.04% per skill Diff - int32 attackerWeaponSkill = (spell->GetEquippedItemClass() == ITEM_CLASS_WEAPON) ? int32(GetWeaponSkillValue(attType,pVictim)) : GetMaxSkillValueForLevel(); + int32 attackerWeaponSkill = GetMaxSkillValueForLevel(); int32 skillDiff = attackerWeaponSkill - int32(pVictim->GetMaxSkillValueForLevel(this)); - int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this)); uint32 roll = urand(0, 10000); - uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell) * 100.0f); + uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, skillDiff, spell) * 100.0f); // Roll miss uint32 tmp = spell->HasAttribute(SPELL_ATTR_EX3_CANT_MISS) ? 0 : missChance; if (roll < tmp) @@ -3559,7 +3554,7 @@ float Unit::MeleeMissChanceCalc(const Unit* pVictim, WeaponAttackType attType) c missChance += 19.0f; } - int32 skillDiff = int32(GetWeaponSkillValue(attType, pVictim)) - int32(pVictim->GetDefenseSkillValue(this)); + int32 skillDiff = int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetMaxSkillValueForLevel(this)); // PvP - PvE melee chances // TODO: implement diminishing returns for defense from player's defense rating @@ -3592,21 +3587,6 @@ float Unit::MeleeMissChanceCalc(const Unit* pVictim, WeaponAttackType attType) c return missChance; } -uint32 Unit::GetDefenseSkillValue(Unit const* target) const -{ - if (GetTypeId() == TYPEID_PLAYER) - { - // in PvP use full skill instead current skill value - uint32 value = (target && target->GetTypeId() == TYPEID_PLAYER) - ? ((Player*)this)->GetMaxSkillValue(SKILL_DEFENSE) - : ((Player*)this)->GetSkillValue(SKILL_DEFENSE); - value += uint32(((Player*)this)->GetRatingBonusValue(CR_DEFENSE_SKILL)); - return value; - } - else - return GetUnitMeleeSkill(target); -} - float Unit::GetUnitDodgeChance() const { if (hasUnitState(UNIT_STAT_STUNNED)) @@ -3682,7 +3662,7 @@ float Unit::GetUnitBlockChance() const else { float block = 5.0f; - block += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT); + block += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_CHANCE_PERCENT); return block > 0.0f ? block : 0.0f; } } @@ -3725,44 +3705,11 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit* pVict crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE); - - // Apply crit chance from defence skill - crit += (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f; - if (crit < 0.0f) crit = 0.0f; return crit; } -uint32 Unit::GetWeaponSkillValue(WeaponAttackType attType, Unit const* target) const -{ - uint32 value = 0; - if (GetTypeId() == TYPEID_PLAYER) - { - Item* item = ((Player*)this)->GetWeaponForAttack(attType, true, true); - - // feral or unarmed skill only for base attack - if (attType != BASE_ATTACK && !item) - return 0; - - if (IsInFeralForm()) - return GetMaxSkillValueForLevel(); // always maximized SKILL_FERAL_COMBAT in fact - - // weapon skill or (unarmed for base attack) - uint32 skill = item ? item->GetSkill() : uint32(SKILL_UNARMED); - - // in PvP use full skill instead current skill value - value = (target && target->GetTypeId() == TYPEID_PLAYER) - ? ((Player*)this)->GetMaxSkillValue(skill) - : ((Player*)this)->GetSkillValue(skill); - // Modify value from ratings - value += uint32(((Player*)this)->GetRatingBonusValue(CR_WEAPON_SKILL)); - } - else - value = GetUnitMeleeSkill(target); - return value; -} - void Unit::_UpdateSpells(uint32 time) { if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]) @@ -9257,6 +9204,13 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL; + // calculate basepoints dependent on mastery + if (unitPlayer && spellProto->HasAttribute(SPELL_ATTR_EX8_MASTERY) && !spellProto->CalculateSimpleValue(effect_index)) + { + if (int32 masteryCoef = GetMasteryCoefficient(spellProto)) + return int32(GetFloatValue(PLAYER_MASTERY) * masteryCoef / 100.0f); + } + uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0; int32 basePoints = 0; @@ -10373,19 +10327,6 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* pTarget, uint32 procFlag, // For melee/ranged based attack need update skills and set some Aura states if (!(procExtra & PROC_EX_CAST_END) && procFlag & MELEE_BASED_TRIGGER_MASK) { - // Update skills here for players - if (GetTypeId() == TYPEID_PLAYER) - { - // On melee based hit/miss/resist need update skill (for victim and attacker) - if (procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_MISS | PROC_EX_RESIST)) - { - if (pTarget->GetTypeId() != TYPEID_PLAYER && pTarget->GetCreatureType() != CREATURE_TYPE_CRITTER) - ((Player*)this)->UpdateCombatSkills(pTarget, attType, isVictim); - } - // Update defence if player is victim and parry/dodge/block - if (isVictim && procExtra & (PROC_EX_DODGE | PROC_EX_PARRY | PROC_EX_BLOCK)) - ((Player*)this)->UpdateDefense(); - } // If exist crit/parry/dodge/block need update aura state (for victim and attacker) if (procExtra & (PROC_EX_CRITICAL_HIT | PROC_EX_PARRY | PROC_EX_DODGE | PROC_EX_BLOCK)) { diff --git a/src/game/Unit.h b/src/game/Unit.h index cb484ffe0..586861227 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -136,6 +136,7 @@ enum SpellFacingFlags #define BASE_MINDAMAGE 1.0f #define BASE_MAXDAMAGE 2.0f #define BASE_ATTACK_TIME 2000 +#define BASE_BLOCK_DAMAGE_PERCENT 30 // byte value (UNIT_FIELD_BYTES_1,0) enum UnitStandStateType @@ -375,7 +376,7 @@ enum BaseModGroup CRIT_PERCENTAGE, RANGED_CRIT_PERCENTAGE, OFFHAND_CRIT_PERCENTAGE, - SHIELD_BLOCK_VALUE, + SHIELD_BLOCK_DAMAGE_VALUE, BASEMOD_END }; @@ -479,7 +480,7 @@ extern float baseMoveSpeed[MAX_MOVE_TYPE]; enum CombatRating { CR_WEAPON_SKILL = 0, - CR_DEFENSE_SKILL = 1, + CR_DEFENSE_SKILL = 1, // obsolete CR_DODGE = 2, CR_PARRY = 3, CR_BLOCK = 4, @@ -1356,10 +1357,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject float GetUnitBlockChance() const; float GetUnitCriticalChance(WeaponAttackType attackType, const Unit* pVictim) const; - virtual uint32 GetShieldBlockValue() const = 0; - uint32 GetUnitMeleeSkill(Unit const* target = NULL) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; } - uint32 GetDefenseSkillValue(Unit const* target = NULL) const; - uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const; + virtual uint32 GetShieldBlockDamageValue() const = 0; float GetWeaponProcChance() const; float GetPPMProcChance(uint32 WeaponSpeed, float PPM) const; diff --git a/src/game/UnitAuraProcHandler.cpp b/src/game/UnitAuraProcHandler.cpp index 30b9c4104..093066060 100644 --- a/src/game/UnitAuraProcHandler.cpp +++ b/src/game/UnitAuraProcHandler.cpp @@ -83,7 +83,7 @@ pAuraProcHandler AuraProcHandler[TOTAL_AURAS] = &Unit::HandleNULLProc, // 48 SPELL_AURA_48 4 spells in 4.3.4 Napalm (area damage spell with additional delayed damage effect) &Unit::HandleNULLProc, // 49 SPELL_AURA_MOD_DODGE_PERCENT &Unit::HandleNULLProc, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT - &Unit::HandleNULLProc, // 51 SPELL_AURA_MOD_BLOCK_PERCENT + &Unit::HandleNULLProc, // 51 SPELL_AURA_MOD_BLOCK_CHANCE_PERCENT &Unit::HandleNULLProc, // 52 SPELL_AURA_MOD_CRIT_PERCENT &Unit::HandleNULLProc, // 53 SPELL_AURA_PERIODIC_LEECH &Unit::HandleNULLProc, // 54 SPELL_AURA_MOD_HIT_CHANCE @@ -182,7 +182,7 @@ pAuraProcHandler AuraProcHandler[TOTAL_AURAS] = &Unit::HandleNULLProc, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK &Unit::HandleNULLProc, //148 SPELL_AURA_RETAIN_COMBO_POINTS &Unit::HandleCantTrigger, //149 SPELL_AURA_REDUCE_PUSHBACK - &Unit::HandleNULLProc, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT + &Unit::HandleNULLProc, //150 SPELL_AURA_MOD_SHIELD_BLOCKDAMAGE &Unit::HandleNULLProc, //151 SPELL_AURA_TRACK_STEALTHED &Unit::HandleNULLProc, //152 SPELL_AURA_MOD_DETECTED_RANGE &Unit::HandleNULLProc, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT @@ -1246,13 +1246,6 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit* pVictim, uint32 damage, Aura target = this; break; } - // Damage Shield - if (dummySpell->SpellIconID == 3214) - { - triggered_spell_id = 59653; - basepoints[0] = GetShieldBlockValue() * triggerAmount / 100; - break; - } // Sweeping Strikes if (dummySpell->Id == 12328) diff --git a/src/game/World.cpp b/src/game/World.cpp index 4eeb6ea74..2089e220a 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -666,9 +666,7 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_BOOL_SKILL_MILLING, "SkillChance.Milling", false); setConfig(CONFIG_UINT32_SKILL_GAIN_CRAFTING, "SkillGain.Crafting", 1); - setConfig(CONFIG_UINT32_SKILL_GAIN_DEFENSE, "SkillGain.Defense", 1); setConfig(CONFIG_UINT32_SKILL_GAIN_GATHERING, "SkillGain.Gathering", 1); - setConfig(CONFIG_UINT32_SKILL_GAIN_WEAPON, "SkillGain.Weapon", 1); setConfig(CONFIG_BOOL_SKILL_FAIL_LOOT_FISHING, "SkillFail.Loot.Fishing", true); setConfig(CONFIG_BOOL_SKILL_FAIL_GAIN_FISHING, "SkillFail.Gain.Fishing", true); @@ -684,8 +682,6 @@ void World::LoadConfigSettings(bool reload) setConfig(CONFIG_BOOL_SAVE_RESPAWN_TIME_IMMEDIATELY, "SaveRespawnTimeImmediately", true); setConfig(CONFIG_BOOL_WEATHER, "ActivateWeather", true); - setConfig(CONFIG_BOOL_ALWAYS_MAX_SKILL_FOR_LEVEL, "AlwaysMaxSkillForLevel", false); - if (configNoReload(reload, CONFIG_UINT32_EXPANSION, "Expansion", MAX_EXPANSION)) setConfigMinMax(CONFIG_UINT32_EXPANSION, "Expansion", MAX_EXPANSION, 0, MAX_EXPANSION); diff --git a/src/game/World.h b/src/game/World.h index 436b4530f..24db00f07 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -145,9 +145,7 @@ enum eConfigUInt32Values CONFIG_UINT32_SKILL_CHANCE_MINING_STEPS, CONFIG_UINT32_SKILL_CHANCE_SKINNING_STEPS, CONFIG_UINT32_SKILL_GAIN_CRAFTING, - CONFIG_UINT32_SKILL_GAIN_DEFENSE, CONFIG_UINT32_SKILL_GAIN_GATHERING, - CONFIG_UINT32_SKILL_GAIN_WEAPON, CONFIG_UINT32_MAX_OVERSPEED_PINGS, CONFIG_UINT32_EXPANSION, CONFIG_UINT32_CHATFLOOD_MESSAGE_COUNT, @@ -302,7 +300,6 @@ enum eConfigBoolValues CONFIG_BOOL_GM_LOWER_SECURITY, CONFIG_BOOL_GM_ALLOW_ACHIEVEMENT_GAINS, CONFIG_BOOL_SKILL_PROSPECTING, - CONFIG_BOOL_ALWAYS_MAX_SKILL_FOR_LEVEL, CONFIG_BOOL_WEATHER, CONFIG_BOOL_EVENT_ANNOUNCE, CONFIG_BOOL_QUEST_IGNORE_RAID, diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 8330bfb4f..b55c7d77f 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -548,11 +548,6 @@ LogColors = "" # Default: 0 (false) # 1 (true) # -# AlwaysMaxSkillForLevel -# Players will automatically gain max level dependent (weapon/defense) skill when logging in, leveling up etc. -# Default: 0 (false) -# 1 (true) -# # ActivateWeather # Activate weather system # Default: 1 (true) @@ -772,7 +767,6 @@ StartPlayerMoney = 0 InstantLogout = 1 DisableWaterBreath = 4 AllFlightPaths = 0 -AlwaysMaxSkillForLevel = 0 ActivateWeather = 1 CastUnstuck = 1 MaxSpellCastsInChain = 10 @@ -1276,10 +1270,8 @@ Visibility.AIRelocationNotifyDelay = 1000 # Default: 1 # # SkillGain.Crafting -# SkillGain.Defense # SkillGain.Gathering -# SkillGain.Weapon -# crafting/defense/gathering/weapon skills gain at skill grow (1,2,...) +# Crafting and gathering skill gains at skill grow (1,2,...) # Default: 1 # # SkillChance.Orange @@ -1389,9 +1381,7 @@ Rate.Reputation.LowLevel.Kill = 1 Rate.Reputation.LowLevel.Quest = 1 Rate.InstanceResetTime = 1 SkillGain.Crafting = 1 -SkillGain.Defense = 1 SkillGain.Gathering = 1 -SkillGain.Weapon = 1 SkillChance.Orange = 100 SkillChance.Yellow = 75 SkillChance.Green = 25 diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a85c70f69..5dc738a75 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 "12197" + #define REVISION_NR "12198" #endif // __REVISION_NR_H__