From 2b11f791f223cec6d8ac165b1364961cb0289019 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Sat, 13 Apr 2024 14:42:07 +0800 Subject: [PATCH] Score calculation for item spell --- src/PlayerbotAI.cpp | 4 +- src/PlayerbotAI.h | 18 +- src/PlayerbotFactory.cpp | 492 ++++++++++++++++++--- src/PlayerbotFactory.h | 3 +- src/strategy/shaman/HealShamanStrategy.cpp | 2 +- 5 files changed, 449 insertions(+), 70 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 1fdd2089c..4ca16af76 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1604,7 +1604,7 @@ bool PlayerbotAI::IsTank(Player* player) } break; case CLASS_DRUID: - if (tab == DRUID_TAB_FERAL && HasAnyAuraOf(player, "bear form", "dire bear form", "thick hide", NULL)) { + if (tab == DRUID_TAB_FERAL && (player->GetShapeshiftForm() == FORM_BEAR || player->GetShapeshiftForm() == FORM_DIREBEAR || player->HasAura(16931))) { return true; } break; @@ -1695,7 +1695,7 @@ bool PlayerbotAI::IsDps(Player* player) bool PlayerbotAI::IsMainTank(Player* player) { - Group* group = bot->GetGroup(); + Group* group = player->GetGroup(); if (!group) { return false; } diff --git a/src/PlayerbotAI.h b/src/PlayerbotAI.h index d5fec1c92..79eea13eb 100644 --- a/src/PlayerbotAI.h +++ b/src/PlayerbotAI.h @@ -329,15 +329,15 @@ class PlayerbotAI : public PlayerbotAIBase void ResetStrategies(bool load = false); void ReInitCurrentEngine(); void Reset(bool full = false); - bool IsTank(Player* player); - bool IsHeal(Player* player); - bool IsDps(Player* player); - bool IsRanged(Player* player); - bool IsMelee(Player* player); - bool IsCaster(Player* player); - bool IsCombo(Player* player); - bool IsRangedDps(Player* player); - bool IsMainTank(Player* player); + static bool IsTank(Player* player); + static bool IsHeal(Player* player); + static bool IsDps(Player* player); + static bool IsRanged(Player* player); + static bool IsMelee(Player* player); + static bool IsCaster(Player* player); + static bool IsCombo(Player* player); + static bool IsRangedDps(Player* player); + static bool IsMainTank(Player* player); bool IsAssistTank(Player* player); bool IsAssistTankOfIndex(Player* player, int index); bool IsHealAssistantOfIndex(Player* player, int index); diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index ddcbef799..245df3bc7 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -28,6 +28,7 @@ #include "ItemVisitors.h" #include "InventoryAction.h" #include "SharedDefines.h" +#include "SpellAuraDefines.h" #include #include @@ -3590,6 +3591,7 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot) int itemLevel = proto->ItemLevel; int quality = proto->Quality; int meleeDps = 0, rangeDps = 0; + float score = 0; if (proto->IsRangedWeapon()) { rangeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * proto->Delay / 1000; } else if (proto->IsWeapon()) { @@ -3656,38 +3658,135 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot) } for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; j++) { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[j].SpellId); - if (!spellInfo) - continue; - // spell category check? - - for (uint8 i = 0 ; i < 3; i++) - { - if (spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) - { - switch (spellInfo->Effects[i].ApplyAuraName) - { - case SPELL_AURA_MOD_DAMAGE_DONE: - // case SPELL_AURA_MOD_HEALING_DONE: duplicated - spell_power += (spellInfo->Effects[i].BasePoints + 1) * 0.2; - break; - case SPELL_AURA_MOD_ATTACK_POWER: - attack_power += (spellInfo->Effects[i].BasePoints + 1) * 0.2; - case SPELL_AURA_MOD_SHIELD_BLOCKVALUE: - block += (spellInfo->Effects[i].BasePoints + 1) * 0.2; - default: - break; - } - } - } + score += CalculateSpellScore(proto->Spells[j].SpellId, bot, proto->Spells[j].SpellTrigger); + // SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[j].SpellId); + // if (!spellInfo) + // continue; + // // spell category check? + // for (uint8 i = 0; i < 3; i++) + // { + // float multiplier = proto->Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_ON_EQUIP ? 1.0f : 0.2f; + // if (spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) + // { + // switch (spellInfo->Effects[i].ApplyAuraName) + // { + // case SPELL_AURA_MOD_DAMAGE_DONE: + // // case SPELL_AURA_MOD_HEALING_DONE: duplicated + // spell_power += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case SPELL_AURA_MOD_ATTACK_POWER: + // attack_power += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case SPELL_AURA_MOD_SHIELD_BLOCKVALUE: + // block += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case SPELL_AURA_MOD_RATING: + // { + // for (uint32 rating = CR_WEAPON_SKILL; rating < MAX_COMBAT_RATING; ++rating) + // { + // if (spellInfo->Effects[j].MiscValue & (1 << rating)) + // { + // int32 val = spellInfo->Effects[j].BasePoints + 1; + // switch (rating) + // { + // case CR_DEFENSE_SKILL: + // defense += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case CR_DODGE: + // dodge += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case CR_PARRY: + // parry += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case CR_BLOCK: + // block += (spellInfo->Effects[i].BasePoints + 1) * multiplier; + // break; + // case CR_HIT_MELEE: + // // if () + // break; + // case CR_HIT_RANGED: + // break; + // case CR_HIT_SPELL: + // break; + // case CR_CRIT_MELEE: + // break; + // case CR_CRIT_RANGED: + // break; + // case CR_CRIT_SPELL: + // break; + // case CR_HIT_TAKEN_MELEE: + // break; + // case CR_HIT_TAKEN_RANGED: + // break; + // // CR_PARRY = 3, + // // CR_BLOCK = 4, + // // CR_HIT_MELEE = 5, + // // CR_HIT_RANGED = 6, + // // CR_HIT_SPELL = 7, + // // CR_CRIT_MELEE = 8, + // // CR_CRIT_RANGED = 9, + // // CR_CRIT_SPELL = 10, + // // CR_HIT_TAKEN_MELEE = 11, + // // CR_HIT_TAKEN_RANGED = 12, + // // CR_HIT_TAKEN_SPELL = 13, + // // CR_CRIT_TAKEN_MELEE = 14, + // // CR_CRIT_TAKEN_RANGED = 15, + // // CR_CRIT_TAKEN_SPELL = 16, + // // CR_HASTE_MELEE = 17, + // // CR_HASTE_RANGED = 18, + // // CR_HASTE_SPELL = 19, + // // CR_WEAPON_SKILL_MAINHAND = 20, + // // CR_WEAPON_SKILL_OFFHAND = 21, + // // CR_WEAPON_SKILL_RANGED = 22, + // // CR_EXPERTISE = 23, + // // CR_ARMOR_PENETRATION = 24 + // // } + // } + // } + // break; + // } + // } + // case SPELL_AURA_PROC_TRIGGER_SPELL: + // { + // multiplier = 0.2f; + // if (spellInfo->Effects[i].TriggerSpell) { + // SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell); + // if (!triggerSpellInfo) + // continue; + // for (uint8 k = 0; k < 3; i++) + // { + // if (triggerSpellInfo->Effects[k].Effect == SPELL_EFFECT_APPLY_AURA) + // { + // switch (triggerSpellInfo->Effects[k].ApplyAuraName) + // { + // case SPELL_AURA_MOD_DAMAGE_DONE: + // // case SPELL_AURA_MOD_HEALING_DONE: duplicated + // spell_power += (spellInfo->Effects[k].BasePoints + 1) * multiplier; + // break; + // case SPELL_AURA_MOD_ATTACK_POWER: + // attack_power += (spellInfo->Effects[k].BasePoints + 1) * multiplier; + // case SPELL_AURA_MOD_SHIELD_BLOCKVALUE: + // block += (spellInfo->Effects[k].BasePoints + 1) * multiplier; + // default: + // break; + // } + // } + // } + // } + // break; + // } + // default: + // break; + // } + // } } // Basic score - float score = (agility + strength + intellect + spirit + stamina + defense + dodge + parry + block + + score += (agility + strength + intellect + spirit + stamina + defense + dodge + parry + block + resilience + hit + crit + haste + expertise + attack_power + mana_regeneration + spell_power + armor_penetration + spell_penetration + armor + rangeDps + meleeDps) * 0.001; if (cls == CLASS_HUNTER) { // AGILITY only - score = agility * 2.5 + attack_power + armor_penetration * 2 + rangeDps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect; + score += agility * 2.5 + attack_power + armor_penetration * 2 + rangeDps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect; } else if (cls == CLASS_WARLOCK || cls == CLASS_MAGE || (cls == CLASS_PRIEST && tab == 2) || // shadow @@ -3695,7 +3794,7 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot) (cls == CLASS_DRUID && tab == 0) // balance ) { // SPELL DPS - score = intellect * 0.5 + spirit * 0.5 + spell_power + spell_penetration + score += intellect * 0.5 + spirit * 0.5 + spell_power + spell_penetration + hit * 1.2 + crit * 0.7 + haste * 1 + rangeDps; } else if ((cls == CLASS_PALADIN && tab == 0) || // holy (cls == CLASS_PRIEST && tab != 2) || // discipline / holy @@ -3703,34 +3802,34 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot) (cls == CLASS_DRUID && tab == 2) ) { // HEALER - score = intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1 + rangeDps; + score += intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1 + rangeDps; } else if (cls == CLASS_ROGUE) { // AGILITY mainly (STRENGTH also) - score = agility * 2 + strength + attack_power + armor_penetration * 1 + meleeDps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5; + score += agility * 2 + strength + attack_power + armor_penetration * 1 + meleeDps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5; } else if ((cls == CLASS_PALADIN && tab == 2) || // retribution (cls == CLASS_WARRIOR && tab != 2) || // arm / fury (cls == CLASS_DEATH_KNIGHT && tab != 0) // ice / unholy ) { // STRENGTH mainly (AGILITY also) - score = strength * 2 + agility + attack_power + armor_penetration + meleeDps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2; + score += strength * 2 + agility + attack_power + armor_penetration + meleeDps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2; } else if ((cls == CLASS_SHAMAN && tab == 1)) { // enhancement // STRENGTH mainly (AGILITY, INTELLECT also) - score = strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + meleeDps * 5 + score += strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + meleeDps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2; } else if ((cls == CLASS_WARRIOR && tab == 2) || (cls == CLASS_PALADIN && tab == 1)) { // TANK WITH SHIELD - score = strength * 1 + agility * 2 + attack_power * 0.2 + score += strength * 1 + agility * 2 + attack_power * 0.2 + defense * 2.5 + parry * 2 + dodge * 2 + resilience * 2 + block * 2 + armor * 0.3 + stamina * 3 + hit * 1 + crit * 0.2 + haste * 0.5 + expertise * 3; } else if (cls == CLASS_DEATH_KNIGHT && tab == 0){ // BLOOD DK TANK - score = strength * 1 + agility * 2 + attack_power * 0.2 + score += strength * 1 + agility * 2 + attack_power * 0.2 + defense * 3.5 + parry * 2 + dodge * 2 + resilience * 2 + armor * 0.3 + stamina * 2.5 + hit * 2 + crit * 0.5 + haste * 0.5 + expertise * 3.5; } else { // BEAR DRUID TANK (AND FERAL DRUID...?) - score = agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + meleeDps * 2 + score += agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + meleeDps * 2 + defense * 0.25 + dodge * 0.25 + armor * 0.3 + stamina * 1.5 + hit * 1 + crit * 1 + haste * 0.5 + expertise * 3; } @@ -3810,13 +3909,13 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) break; case ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL: { - if (botAI->IsMelee(bot) && enchant_spell_id == 28093) { // mongoose + if (PlayerbotAI::IsMelee(bot) && enchant_spell_id == 28093) { // mongoose agility += 40; - } else if (botAI->IsMelee(bot) && enchant_spell_id == 20007) { // crusader + } else if (PlayerbotAI::IsMelee(bot) && enchant_spell_id == 20007) { // crusader strength += 30; - } else if (botAI->IsMelee(bot) && enchant_spell_id == 59620) { // Berserk + } else if (PlayerbotAI::IsMelee(bot) && enchant_spell_id == 59620) { // Berserk attack_power += 120; - } else if (botAI->IsMelee(bot) && enchant_spell_id == 64440) { // Blade Warding + } else if (PlayerbotAI::IsMelee(bot) && enchant_spell_id == 64440) { // Blade Warding parry += 50; } break; @@ -3873,7 +3972,7 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) spirit += allStatsAmount; stamina += allStatsAmount; } - if (botAI->IsMelee(bot) && enchant_spell_id == 64571) { // Blood Draining + if (PlayerbotAI::IsMelee(bot) && enchant_spell_id == 64571) { // Blood Draining stamina += 80; } // if (enchant_spell_id) @@ -3980,42 +4079,42 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) block += float(enchant_amount); break; case ITEM_MOD_HIT_MELEE_RATING: - if (botAI->IsMelee(bot)) { + if (PlayerbotAI::IsMelee(bot)) { hit += float(enchant_amount); } break; case ITEM_MOD_HIT_RANGED_RATING: - if (botAI->IsRanged(bot) && !botAI->IsCaster(bot)) { + if (PlayerbotAI::IsRanged(bot) && !PlayerbotAI::IsCaster(bot)) { hit += float(enchant_amount); } break; case ITEM_MOD_HIT_SPELL_RATING: - if (botAI->IsCaster(bot)) { + if (PlayerbotAI::IsCaster(bot)) { hit += float(enchant_amount); } break; case ITEM_MOD_CRIT_MELEE_RATING: - if (botAI->IsMelee(bot)) { + if (PlayerbotAI::IsMelee(bot)) { crit += float(enchant_amount); } break; case ITEM_MOD_CRIT_RANGED_RATING: - if (botAI->IsRanged(bot) && !botAI->IsCaster(bot)) { + if (PlayerbotAI::IsRanged(bot) && !PlayerbotAI::IsCaster(bot)) { crit += float(enchant_amount); } break; case ITEM_MOD_CRIT_SPELL_RATING: - if (botAI->IsCaster(bot)) { + if (PlayerbotAI::IsCaster(bot)) { crit += float(enchant_amount); } break; case ITEM_MOD_HASTE_RANGED_RATING: - if (botAI->IsRanged(bot) && !botAI->IsCaster(bot)) { + if (PlayerbotAI::IsRanged(bot) && !PlayerbotAI::IsCaster(bot)) { crit += float(enchant_amount); } break; case ITEM_MOD_HASTE_SPELL_RATING: - if (botAI->IsCaster(bot)) { + if (PlayerbotAI::IsCaster(bot)) { haste += float(enchant_amount); } break; @@ -4038,7 +4137,7 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) attack_power += float(enchant_amount); break; case ITEM_MOD_RANGED_ATTACK_POWER: - if (botAI->IsRanged(bot) && !botAI->IsCaster(bot)) { + if (PlayerbotAI::IsRanged(bot) && !PlayerbotAI::IsCaster(bot)) { attack_power += float(enchant_amount); } break; @@ -4104,7 +4203,7 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) spell_penetration + armor + dps) * 0.001; if (cls == CLASS_HUNTER) { // AGILITY only - score = agility * 2.5 + attack_power + armor_penetration * 2 + dps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect; + score += agility * 2.5 + attack_power + armor_penetration * 2 + dps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect; } else if (cls == CLASS_WARLOCK || cls == CLASS_MAGE || (cls == CLASS_PRIEST && tab == 2) || // shadow @@ -4112,7 +4211,7 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) (cls == CLASS_DRUID && tab == 0) // balance ) { // SPELL DPS - score = intellect * 0.5 + spirit * 0.5 + spell_power + spell_penetration + score += intellect * 0.5 + spirit * 0.5 + spell_power + spell_penetration + hit * 1.2 + crit * 0.7 + haste * 1; } else if ((cls == CLASS_PALADIN && tab == 0) || // holy (cls == CLASS_PRIEST && tab != 2) || // discipline / holy @@ -4120,34 +4219,313 @@ float PlayerbotFactory::CalculateEnchantScore(uint32 enchant_id, Player* bot) (cls == CLASS_DRUID && tab == 2) ) { // HEALER - score = intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1; + score += intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1; + } else if (cls == CLASS_ROGUE) { + // AGILITY mainly (STRENGTH also) + score += agility * 2 + strength + attack_power + armor_penetration * 1 + dps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5; + } else if ((cls == CLASS_PALADIN && tab == 2) || // retribution + (cls == CLASS_WARRIOR && tab != 2) || // arm / fury + (cls == CLASS_DEATH_KNIGHT && tab != 0) // ice / unholy + ) { + // STRENGTH mainly (AGILITY also) + score += strength * 2 + agility + attack_power + armor_penetration + dps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2; + } else if ((cls == CLASS_SHAMAN && tab == 1)) { // enhancement + // STRENGTH mainly (AGILITY, INTELLECT also) + score += strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + dps * 5 + + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2; + } else if ((cls == CLASS_WARRIOR && tab == 2) || + (cls == CLASS_PALADIN && tab == 1)) { + // TANK WITH SHIELD + score += strength * 1 + agility * 2 + attack_power * 0.2 + + defense * 2.5 + parry * 2 + dodge * 2 + resilience * 2 + block * 2 + armor * 0.3 + stamina * 3 + + hit * 1 + crit * 0.2 + haste * 0.5 + expertise * 3; + } else if (cls == CLASS_DEATH_KNIGHT && tab == 0){ + // BLOOD DK TANK + score += strength * 1 + agility * 2 + attack_power * 0.2 + + defense * 3.5 + parry * 2 + dodge * 2 + resilience * 2 + armor * 0.3 + stamina * 2.5 + + hit * 2 + crit * 0.5 + haste * 0.5 + expertise * 3.5; + } else { + // BEAR DRUID TANK (AND FERAL DRUID...?) + score += agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + dps * 2 + + defense * 0.25 + dodge * 0.25 + armor * 0.3 + stamina * 1.5 + + hit * 1 + crit * 1 + haste * 0.5 + expertise * 3; + } + return score; +} + +float PlayerbotFactory::CalculateSpellScore(uint32 spell_id, Player* bot, uint32 trigger) +{ + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id); + if (!spellInfo) + return 0.0f; + int tab = AiFactory::GetPlayerSpecTab(bot); + uint8 cls = bot->getClass(); + int agility = 0, strength = 0, intellect = 0, spirit = 0; + int stamina = 0, defense = 0, dodge = 0, parry = 0, block = 0, resilience = 0; + int hit = 0, crit = 0, haste = 0, expertise = 0, attack_power = 0; + int mana_regeneration = 0, spell_power = 0, armor_penetration = 0, spell_penetration = 0; + int armor = 0; + int meleeDps = 0, rangeDps = 0; + bool isMelee = PlayerbotAI::IsMelee(bot); + bool isRanged = PlayerbotAI::IsRanged(bot); + bool isCaster = PlayerbotAI::IsCaster(bot); + for (int i = 0; i < MAX_SPELL_EFFECTS; i++) + { + float multiplier = trigger == ITEM_SPELLTRIGGER_ON_EQUIP ? 1.0f : 0.2f; + if (spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA) + { + int32 val = spellInfo->Effects[i].BasePoints + 1; + switch (spellInfo->Effects[i].ApplyAuraName) + { + case SPELL_AURA_MOD_DAMAGE_DONE: + // case SPELL_AURA_MOD_HEALING_DONE: duplicated + spell_power += val * multiplier; + break; + case SPELL_AURA_MOD_ATTACK_POWER: + attack_power += val * multiplier; + break; + case SPELL_AURA_MOD_SHIELD_BLOCKVALUE: + block += val * multiplier; + break; + case SPELL_AURA_MOD_RATING: + { + for (uint32 rating = CR_WEAPON_SKILL; rating < MAX_COMBAT_RATING; ++rating) + { + if (spellInfo->Effects[i].MiscValue & (1 << rating)) + { + switch (rating) + { + case CR_DEFENSE_SKILL: + defense += val * multiplier; + break; + case CR_DODGE: + dodge += val * multiplier; + break; + case CR_PARRY: + parry += val * multiplier; + break; + case CR_BLOCK: + block += val * multiplier; + break; + case CR_HIT_MELEE: + if (isMelee) { + hit += val * multiplier; + } + break; + case CR_HIT_RANGED: + if (isRanged && !isCaster) { + hit += val * multiplier; + } + break; + case CR_HIT_SPELL: + if (isCaster) { + hit += val * multiplier; + } + break; + case CR_CRIT_MELEE: + if (isMelee) { + crit += val * multiplier; + } + break; + case CR_CRIT_RANGED: + if (isRanged && !isCaster) { + crit += val * multiplier; + } + break; + case CR_CRIT_SPELL: + if (isCaster) { + crit += val * multiplier; + } + break; + case CR_HASTE_MELEE: + if (isMelee) { + haste += val * multiplier; + } + break; + case CR_HASTE_RANGED: + if (isRanged && !isCaster) { + haste += val * multiplier; + } + break; + case CR_HASTE_SPELL: + if (isCaster) { + haste += val * multiplier; + } + break; + case CR_EXPERTISE: + expertise += val * multiplier; + break; + case CR_ARMOR_PENETRATION: + armor_penetration += val * multiplier; + break; + default: + break; + } + } + break; + } + } + case SPELL_AURA_PROC_TRIGGER_SPELL: + { + multiplier = 0.2f; + if (spellInfo->Effects[i].TriggerSpell) { + SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell); + if (!triggerSpellInfo) + continue; + for (uint8 k = 0; k < MAX_SPELL_EFFECTS; k++) + { + if (triggerSpellInfo->Effects[k].Effect == SPELL_EFFECT_APPLY_AURA) + { + switch (triggerSpellInfo->Effects[k].ApplyAuraName) + { + case SPELL_AURA_MOD_DAMAGE_DONE: + // case SPELL_AURA_MOD_HEALING_DONE: duplicated + spell_power += val * multiplier; + break; + case SPELL_AURA_MOD_ATTACK_POWER: + attack_power += val * multiplier; + break; + case SPELL_AURA_MOD_SHIELD_BLOCKVALUE: + block += val * multiplier; + break; + case SPELL_AURA_MOD_RATING: + { + for (uint32 rating = CR_WEAPON_SKILL; rating < MAX_COMBAT_RATING; ++rating) + { + if (triggerSpellInfo->Effects[k].MiscValue & (1 << rating)) + { + switch (rating) + { + case CR_DEFENSE_SKILL: + defense += val * multiplier; + break; + case CR_DODGE: + dodge += val * multiplier; + break; + case CR_PARRY: + parry += val * multiplier; + break; + case CR_BLOCK: + block += val * multiplier; + break; + case CR_HIT_MELEE: + if (isMelee) { + hit += val * multiplier; + } + break; + case CR_HIT_RANGED: + if (isRanged && !isCaster) { + hit += val * multiplier; + } + break; + case CR_HIT_SPELL: + if (isCaster) { + hit += val * multiplier; + } + break; + case CR_CRIT_MELEE: + if (isMelee) { + crit += val * multiplier; + } + break; + case CR_CRIT_RANGED: + if (isRanged && !isCaster) { + crit += val * multiplier; + } + break; + case CR_CRIT_SPELL: + if (isCaster) { + crit += val * multiplier; + } + break; + case CR_HASTE_MELEE: + if (isMelee) { + haste += val * multiplier; + } + break; + case CR_HASTE_RANGED: + if (isRanged && !isCaster) { + haste += val * multiplier; + } + break; + case CR_HASTE_SPELL: + if (isCaster) { + haste += val * multiplier; + } + break; + case CR_EXPERTISE: + expertise += val * multiplier; + break; + case CR_ARMOR_PENETRATION: + armor_penetration += val * multiplier; + break; + default: + break; + } + } + break; + } + } + default: + break; + } + } + } + } + break; + } + default: + break; + } + } + } + float score = 0; + if (cls == CLASS_HUNTER) { + // AGILITY only + score += agility * 2.5 + attack_power + armor_penetration * 2 + rangeDps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect; + } else if (cls == CLASS_WARLOCK || + cls == CLASS_MAGE || + (cls == CLASS_PRIEST && tab == 2) || // shadow + (cls == CLASS_SHAMAN && tab == 0) || // element + (cls == CLASS_DRUID && tab == 0) // balance + ) { + // SPELL DPS + score += intellect * 0.5 + spirit * 0.5 + spell_power + spell_penetration + + hit * 1.2 + crit * 0.7 + haste * 1 + rangeDps; + } else if ((cls == CLASS_PALADIN && tab == 0) || // holy + (cls == CLASS_PRIEST && tab != 2) || // discipline / holy + (cls == CLASS_SHAMAN && tab == 2) || // heal + (cls == CLASS_DRUID && tab == 2) + ) { + // HEALER + score += intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1 + rangeDps; } else if (cls == CLASS_ROGUE) { // AGILITY mainly (STRENGTH also) - score = agility * 2 + strength + attack_power + armor_penetration * 1 + dps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5; + score += agility * 2 + strength + attack_power + armor_penetration * 1 + meleeDps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5; } else if ((cls == CLASS_PALADIN && tab == 2) || // retribution (cls == CLASS_WARRIOR && tab != 2) || // arm / fury (cls == CLASS_DEATH_KNIGHT && tab != 0) // ice / unholy ) { // STRENGTH mainly (AGILITY also) - score = strength * 2 + agility + attack_power + armor_penetration + dps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2; + score += strength * 2 + agility + attack_power + armor_penetration + meleeDps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2; } else if ((cls == CLASS_SHAMAN && tab == 1)) { // enhancement // STRENGTH mainly (AGILITY, INTELLECT also) - score = strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + dps * 5 + score += strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + meleeDps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2; } else if ((cls == CLASS_WARRIOR && tab == 2) || (cls == CLASS_PALADIN && tab == 1)) { // TANK WITH SHIELD - score = strength * 1 + agility * 2 + attack_power * 0.2 + score += strength * 1 + agility * 2 + attack_power * 0.2 + defense * 2.5 + parry * 2 + dodge * 2 + resilience * 2 + block * 2 + armor * 0.3 + stamina * 3 + hit * 1 + crit * 0.2 + haste * 0.5 + expertise * 3; } else if (cls == CLASS_DEATH_KNIGHT && tab == 0){ // BLOOD DK TANK - score = strength * 1 + agility * 2 + attack_power * 0.2 + score += strength * 1 + agility * 2 + attack_power * 0.2 + defense * 3.5 + parry * 2 + dodge * 2 + resilience * 2 + armor * 0.3 + stamina * 2.5 + hit * 2 + crit * 0.5 + haste * 0.5 + expertise * 3.5; } else { // BEAR DRUID TANK (AND FERAL DRUID...?) - score = agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + dps * 2 + score += agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + meleeDps * 2 + defense * 0.25 + dodge * 0.25 + armor * 0.3 + stamina * 1.5 + hit * 1 + crit * 1 + haste * 0.5 + expertise * 3; } diff --git a/src/PlayerbotFactory.h b/src/PlayerbotFactory.h index 2278fcbf2..5a1e583ee 100644 --- a/src/PlayerbotFactory.h +++ b/src/PlayerbotFactory.h @@ -116,7 +116,8 @@ class PlayerbotFactory static uint32 tradeSkills[]; static float CalculateItemScore(uint32 item_id, Player* bot); - float CalculateEnchantScore(uint32 enchant_id, Player* bot); + static float CalculateEnchantScore(uint32 enchant_id, Player* bot); + static float CalculateSpellScore(uint32 spell_id, Player* bot, uint32 trigger = ITEM_SPELLTRIGGER_ON_EQUIP); void InitTalentsTree(bool incremental = false, bool use_template = true, bool reset = false); static void InitTalentsBySpecNo(Player* bot, int specNo, bool reset); static void InitTalentsByParsedSpecLink(Player* bot, std::vector> parsedSpecLink, bool reset); diff --git a/src/strategy/shaman/HealShamanStrategy.cpp b/src/strategy/shaman/HealShamanStrategy.cpp index 97edd46b1..3fdc5bb38 100644 --- a/src/strategy/shaman/HealShamanStrategy.cpp +++ b/src/strategy/shaman/HealShamanStrategy.cpp @@ -45,7 +45,7 @@ void HealShamanStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr))); triggers.push_back(new TriggerNode( "group heal occasion", - NextAction::array(0, new NextAction("chain heal", 22.0f), NULL))); + NextAction::array(0, new NextAction("riptide on party", 23.0f), new NextAction("chain heal", 22.0f), NULL))); triggers.push_back(new TriggerNode( "party member critical health",