void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } float att_speed = GetAPMultiplier(attType, normalized); float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType)/ 14.0f * att_speed; float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); if (IsInFeralForm()) //check if player is druid and in cat or bear forms { uint8 lvl = getLevel(); if (lvl > 60) lvl = 60; weapon_mindamage = lvl*0.85f*att_speed; weapon_maxdamage = lvl*1.25f*att_speed; } else if (!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case) { //cannot use ranged/off attack, set values to 0 if (attType != BASE_ATTACK) { min_damage = 0; max_damage = 0; return; } weapon_mindamage = BASE_MINDAMAGE; weapon_maxdamage = BASE_MAXDAMAGE; } /* TODO: Is this still needed after ammo has been removed? else if (attType == RANGED_ATTACK) //add ammo DPS to ranged damage { weapon_mindamage += ammo * att_speed; weapon_maxdamage += ammo * att_speed; }*/ min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; }
void Creature::UpdateDamagePhysical(WeaponAttackType attType) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } //float att_speed = float(GetAttackTime(attType))/1000.0f; float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); /* difference in AP between current attack power and base value from DB */ // creature's damage in battleground is calculated in Creature::SelectLevel // so don't change it with ap and dmg multipliers float att_pwr_change = GetTotalAttackPowerValue(attType) - GetCreatureTemplate()->attackpower; float base_value = ((GetMap()->IsBattleground()) ? GetModifierValue(unitMod, BASE_VALUE) : (GetModifierValue(unitMod, BASE_VALUE) + (att_pwr_change * GetAPMultiplier(attType, false) / 14.0f))); float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = GetModifierValue(unitMod, TOTAL_PCT); float dmg_multiplier = ((GetMap()->IsBattleground()) ? 1.0f : GetCreatureTemplate()->dmg_multiplier); if (!CanUseAttackType(attType)) { weapon_mindamage = 0; weapon_maxdamage = 0; } float mindamage = ((base_value + weapon_mindamage) * dmg_multiplier * base_pct + total_value) * total_pct; float maxdamage = ((base_value + weapon_maxdamage) * dmg_multiplier * base_pct + total_value) * total_pct; switch (attType) { case BASE_ATTACK: default: SetStatFloatValue(UNIT_FIELD_MINDAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, maxdamage); break; case OFF_ATTACK: SetStatFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, maxdamage); break; case RANGED_ATTACK: SetStatFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, maxdamage); break; } }
void Creature::UpdateDamagePhysical(WeaponAttackType attType) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } //float att_speed = float(GetAttackTime(attType))/1000.0f; float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); /* difference in AP between current attack power and base value from DB */ float att_pwr_change = GetTotalAttackPowerValue(attType) - GetCreatureTemplate()->attackpower; float base_value = GetModifierValue(unitMod, BASE_VALUE) + (att_pwr_change * GetAPMultiplier(attType, false) / 14.0f); float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = GetModifierValue(unitMod, TOTAL_PCT); float dmg_multiplier = GetCreatureTemplate()->dmg_multiplier; if (!CanUseAttackType(attType)) { weapon_mindamage = 0; weapon_maxdamage = 0; } float mindamage = ((base_value + weapon_mindamage) * dmg_multiplier * base_pct + total_value) * total_pct; float maxdamage = ((base_value + weapon_maxdamage) * dmg_multiplier * base_pct + total_value) * total_pct; switch (attType) { case BASE_ATTACK: default: SetStatFloatValue(UNIT_FIELD_MIN_DAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAX_DAMAGE, maxdamage); break; case OFF_ATTACK: SetStatFloatValue(UNIT_FIELD_MIN_OFF_HAND_DAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAX_OFF_HAND_DAMAGE, maxdamage); break; case RANGED_ATTACK: SetStatFloatValue(UNIT_FIELD_MIN_RANGED_DAMAGE, mindamage); SetStatFloatValue(UNIT_FIELD_MAX_RANGED_DAMAGE, maxdamage); break; } }
void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } if (attType == OFF_ATTACK && !haveOffhandWeapon()) { minDamage = 0.0f; maxDamage = 0.0f; return; } float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE); float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE); if (!CanUseAttackType(attType)) // disarm case { weaponMinDamage = 0.0f; weaponMaxDamage = 0.0f; } // pussywizard: subtract value from database till its fixed (the way it worked before creature_levelstats damage implementation) float attackPower = GetTotalAttackPowerValue(attType) - (attType == RANGED_ATTACK ? GetCreatureTemplate()->rangedattackpower : GetCreatureTemplate()->attackpower); float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower * GetAPMultiplier(attType, normalized) / 14.0f); float basePct = GetModifierValue(unitMod, BASE_PCT); float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float dmgMultiplier = GetCreatureTemplate()->dmg_multiplier; // = dmg_multiplier * _GetDamageMod(rank); minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; // pussywizard: crashfix (casting negative to uint => min > max => assertion in urand) if (minDamage < 0.0f || minDamage > 1000000000.0f) minDamage = 0.0f; if (maxDamage < 0.0f || maxDamage > 1000000000.0f) maxDamage = 0.0f; if (minDamage > maxDamage) minDamage = maxDamage; }
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } float attackPowerMod = std::max(GetAPMultiplier(attType, normalized), 0.25f); float baseValue = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod; float basePct = GetModifierValue(unitMod, BASE_PCT); float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE); float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE); SpellShapeshiftFormEntry const* shapeshift = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm()); if (shapeshift && shapeshift->CombatRoundTime) { weaponMinDamage = weaponMinDamage * shapeshift->CombatRoundTime / 1000.0f / attackPowerMod; weaponMaxDamage = weaponMaxDamage * shapeshift->CombatRoundTime / 1000.0f / attackPowerMod; } else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case) { // cannot use ranged/off attack, set values to 0 if (attType != BASE_ATTACK) { minDamage = 0; maxDamage = 0; return; } weaponMinDamage = BASE_MINDAMAGE; weaponMaxDamage = BASE_MAXDAMAGE; } minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct; maxDamage = ((weaponMaxDamage + baseValue) * basePct + totalValue) * totalPct; }
void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { float variance = 1.0f; UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: variance = GetCreatureTemplate()->BaseVariance; unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: variance = GetCreatureTemplate()->BaseVariance; unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: variance = GetCreatureTemplate()->RangeVariance; unitMod = UNIT_MOD_DAMAGE_RANGED; break; } if (attType == OFF_ATTACK && !haveOffhandWeapon()) { minDamage = 0.0f; maxDamage = 0.0f; return; } float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE); float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE); if (!CanUseAttackType(attType)) // disarm case { weaponMinDamage = 0.0f; weaponMaxDamage = 0.0f; } float attackPower = GetTotalAttackPowerValue(attType); float attackSpeedMulti = GetAPMultiplier(attType, normalized); float baseValue = GetModifierValue(unitMod, BASE_VALUE) + (attackPower / 14.0f) * variance; float basePct = GetModifierValue(unitMod, BASE_PCT) * attackSpeedMulti; float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float dmgMultiplier = GetCreatureTemplate()->ModDamage; // = ModDamage * _GetDamageMod(rank); minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct; }
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } float att_speed = GetAPMultiplier(attType, normalized); float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * att_speed; float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); if (IsInFeralForm()) //check if player is druid and in cat or bear forms { float weaponSpeed = BASE_ATTACK_TIME / 1000.f; if (Item* weapon = GetWeaponForAttack(BASE_ATTACK, true)) weaponSpeed = weapon->GetTemplate()->Delay / 1000; if (GetShapeshiftForm() == FORM_CAT) { weapon_mindamage = weapon_mindamage / weaponSpeed; weapon_maxdamage = weapon_maxdamage / weaponSpeed; } else if (GetShapeshiftForm() == FORM_BEAR) { weapon_mindamage = weapon_mindamage / weaponSpeed + weapon_mindamage / 2.5; weapon_maxdamage = weapon_mindamage / weaponSpeed + weapon_maxdamage / 2.5; } } else if (!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case) { //cannot use ranged/off attack, set values to 0 if (attType != BASE_ATTACK) { min_damage = 0; max_damage = 0; return; } weapon_mindamage = BASE_MINDAMAGE; weapon_maxdamage = BASE_MAXDAMAGE; } /* TODO: Is this still needed after ammo has been removed? else if (attType == RANGED_ATTACK) //add ammo DPS to ranged damage { weapon_mindamage += ammo * att_speed; weapon_maxdamage += ammo * att_speed; }*/ min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; }
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } float attackSpeedMod = GetAPMultiplier(attType, normalized); float baseValue = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * attackSpeedMod; float basePct = GetModifierValue(unitMod, BASE_PCT); float totalValue = GetModifierValue(unitMod, TOTAL_VALUE); float totalPct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE); float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE); if (IsInFeralForm()) // check if player is druid and in cat or bear forms { uint8 lvl = getLevel(); if (lvl > 60) lvl = 60; weaponMinDamage = lvl * 0.85f * attackSpeedMod; weaponMaxDamage = lvl * 1.25f * attackSpeedMod; } else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case) { // cannot use ranged/off attack, set values to 0 if (attType != BASE_ATTACK) { minDamage = 0.0f; maxDamage = 0.0f; return; } weaponMinDamage = BASE_MINDAMAGE; weaponMaxDamage = BASE_MAXDAMAGE; } else if (attType == RANGED_ATTACK) // add ammo DPS to ranged damage { weaponMinDamage += GetAmmoDPS() * attackSpeedMod; weaponMaxDamage += GetAmmoDPS() * attackSpeedMod; } minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct; maxDamage = ((weaponMaxDamage + baseValue) * basePct + totalValue) * totalPct; // pussywizard: crashfix (casting negative to uint => min > max => assertion in urand) if (minDamage < 0.0f || minDamage > 1000000000.0f) minDamage = 0.0f; if (maxDamage < 0.0f || maxDamage > 1000000000.0f) maxDamage = 0.0f; if (minDamage > maxDamage) minDamage = maxDamage; }
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& min_damage, float& max_damage) { UnitMods unitMod; switch (attType) { case BASE_ATTACK: default: unitMod = UNIT_MOD_DAMAGE_MAINHAND; break; case OFF_ATTACK: unitMod = UNIT_MOD_DAMAGE_OFFHAND; break; case RANGED_ATTACK: unitMod = UNIT_MOD_DAMAGE_RANGED; break; } float att_speed = GetAPMultiplier(attType, normalized); float base_value = GetModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType) / 14.0f * att_speed; float base_pct = GetModifierValue(unitMod, BASE_PCT); float total_value = GetModifierValue(unitMod, TOTAL_VALUE); float total_pct = addTotalPct ? GetModifierValue(unitMod, TOTAL_PCT) : 1.0f; float weapon_mindamage = GetWeaponDamageRange(attType, MINDAMAGE); float weapon_maxdamage = GetWeaponDamageRange(attType, MAXDAMAGE); if (IsInFeralForm()) //check if player is druid and in cat or bear forms { float weaponSpeed = BASE_ATTACK_TIME / 1000.f; // Maybe fix that in GetWeaponForAttack ? if (Item* weapon = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) if (weapon->GetTemplate()->Class == ITEM_CLASS_WEAPON) weaponSpeed = float(0.001f * weapon->GetTemplate()->Delay); if (GetShapeshiftForm() == FORM_CAT) { weapon_mindamage = weapon_mindamage / weaponSpeed; weapon_maxdamage = weapon_maxdamage / weaponSpeed; } else if (GetShapeshiftForm() == FORM_BEAR) { weapon_mindamage = weapon_mindamage / weaponSpeed + weapon_mindamage / 2.5; weapon_maxdamage = weapon_maxdamage / weaponSpeed + weapon_maxdamage / 2.5; } } else if (!CanUseAttackType(attType)) //check if player not in form but still can't use (disarm case) { //cannot use ranged/off attack, set values to 0 if (attType != BASE_ATTACK) { min_damage = 0; max_damage = 0; return; } weapon_mindamage = BASE_MINDAMAGE; weapon_maxdamage = BASE_MAXDAMAGE; } min_damage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct; max_damage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct; }