From c5d909693ba321fb6f54d6556f8a442e79f326ef Mon Sep 17 00:00:00 2001 From: ariel- Date: Mon, 18 Jan 2016 02:12:44 -0300 Subject: [PATCH] Implemented Unit Attack power mods handling Closes #17 --- src/server/game/DataStores/DBCStructure.h | 2 +- src/server/game/Entities/Player/Player.cpp | 4 +++ src/server/game/Entities/Unit/StatSystem.cpp | 35 +++++++++++++++----- src/server/game/Entities/Unit/Unit.cpp | 10 ++++-- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 1b0aaa7056..3cc660e017 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -731,7 +731,7 @@ struct ChrClassesEntry //uint32 flags2; // 8 m_flags (0x08 HasRelicSlot) uint32 CinematicSequence; // 9 m_cinematicSequenceID uint32 expansion; // 10 m_required_expansion - uint32 APPerStrenth; // 11 Attack Power bonus per point of strength + uint32 APPerStrength; // 11 Attack Power bonus per point of strength uint32 APPerAgility; // 12 Attack Power bonus per point of agility uint32 RAPPerAgility; // 13 Ranged Attack Power bonus per point of agility }; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e9a476d679..1590ef46ce 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2993,8 +2993,12 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS, 1.0f); SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0); + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS, 0); + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_NEG, 0); SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, 0.0f); SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0); + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS, 0); + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_NEG, 0); SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER, 0.0f); // Base crit values (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 1ea9177860..d62e1d3b5e 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -312,22 +312,22 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass()); UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; - uint16 index = UNIT_FIELD_ATTACK_POWER; + uint16 index = ranged ? UNIT_FIELD_RANGED_ATTACK_POWER : UNIT_FIELD_ATTACK_POWER; + uint16 index_mod_pos = ranged ? UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS : UNIT_FIELD_ATTACK_POWER_MOD_POS; + uint16 index_mod_neg = ranged ? UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG : UNIT_FIELD_ATTACK_POWER_MOD_NEG; + uint16 index_mult = ranged ? UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER : UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) - { - index = UNIT_FIELD_RANGED_ATTACK_POWER; val2 = (level + std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f)) * entry->RAPPerAgility; - } else { - float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrenth, 0.0f); + float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrength, 0.0f); float agilityValue = std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerAgility, 0.0f); SpellShapeshiftFormEntry const* form = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm()); // Directly taken from client, SHAPESHIFT_FLAG_AP_FROM_STRENGTH ? if (form && form->flags1 & 0x20) - agilityValue += std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerStrenth, 0.0f); + agilityValue += std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerStrength, 0.0f); val2 = strengthValue + agilityValue; } @@ -346,7 +346,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) attPowerMod += int32(GetArmor() / (*iter)->GetAmount()); } - SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field + float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; + + SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field + SetInt32Value(index_mod_pos, uint32(attPowerMod > 0.f ? attPowerMod : 0.f)); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS field + SetInt32Value(index_mod_neg, uint32(attPowerMod < 0.f ? -attPowerMod : 0.f)); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_NEG field + SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field Pet* pet = GetPet(); //update pet's AP Guardian* guardian = GetGuardianPet(); @@ -874,19 +879,26 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged) UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER; uint16 index = UNIT_FIELD_ATTACK_POWER; + uint16 indexModPos = UNIT_FIELD_ATTACK_POWER_MOD_POS; + uint16 indexModNeg = UNIT_FIELD_ATTACK_POWER_MOD_NEG; uint16 indexMulti = UNIT_FIELD_ATTACK_POWER_MULTIPLIER; if (ranged) { index = UNIT_FIELD_RANGED_ATTACK_POWER; + indexModPos = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS; + indexModNeg = UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG; indexMulti = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER; } float baseAttackPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); + float attackPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); float attackPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; - SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER - SetFloatValue(indexMulti, attackPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER + SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER + SetInt32Value(indexModPos, uint32(attackPowerMod > 0.f ? attackPowerMod : 0.f)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS + SetInt32Value(indexModNeg, uint32(attackPowerMod < 0.f ? -attackPowerMod : 0.f)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_NEG + SetFloatValue(indexMulti, attackPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER // automatically update weapon damage after attack power modification if (ranged) @@ -1198,10 +1210,15 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged) //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT); + float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE); float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; //UNIT_FIELD_(RANGED)_ATTACK_POWER field SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower); + //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_POS field + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS, int32(attPowerMod > 0.f ? attPowerMod : 0.f)); + //UNIT_FIELD_(RANGED)_ATTACK_POWER_MOD_NEG field + SetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_NEG, int32(attPowerMod < 0.f ? -attPowerMod : 0.f)); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4d9d526b41..eea85a442e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11738,14 +11738,20 @@ float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const { if (attType == RANGED_ATTACK) { - int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER); + int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS) + - GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG); + if (ap < 0) return 0.0f; return ap * (1.0f + GetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER)); } else { - int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER); + int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER) + + GetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_POS) + - GetInt32Value(UNIT_FIELD_ATTACK_POWER_MOD_NEG); + if (ap < 0) return 0.0f; return ap * (1.0f + GetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER));