修改优化等
This commit is contained in:
549
GearScore.lua
549
GearScore.lua
@@ -24,6 +24,7 @@ local BUDGET_COST = {
|
||||
HEALTHREG = 2.0, MANAREG = 2.0,
|
||||
HEALTH = 0.07, MANA = 0.07,
|
||||
WEAPONDPS = 3.0,
|
||||
WEAPONSPEED = 1.5,
|
||||
}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -31,175 +32,204 @@ local BUDGET_COST = {
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local WEIGHTS = {
|
||||
-- ================================================================
|
||||
-- Pawn-style normalization: primary stat = 1.0
|
||||
-- TOHIT/CRIT per 1%; PDF: 1%hit≈18AP, 1%crit≈25AP, 1%spellhit≈14SP
|
||||
-- ================================================================
|
||||
WARRIOR = {
|
||||
specs = {
|
||||
{ name = "武器", tab = 1, color = "ffC79C6E",
|
||||
w = { STR=2.0, AGI=1.4, STA=0.1, TOHIT=18, CRIT=25, ATTACKPOWER=1.0,
|
||||
HEALTH=0.1, WEAPONDPS=14, BASEARMOR=0.01 } },
|
||||
w = { STR=1.0, AGI=0.7, STA=0.5, TOHIT=9, CRIT=12,
|
||||
ATTACKPOWER=0.5, HEALTH=0.05, WEAPONDPS=5, BASEARMOR=0.005 } },
|
||||
{ name = "狂怒", tab = 2, color = "ffC79C6E",
|
||||
w = { STR=2.2, AGI=1.6, STA=0.1, TOHIT=20, CRIT=22, ATTACKPOWER=1.0,
|
||||
HEALTH=0.1, WEAPONDPS=12, BASEARMOR=0.01 } },
|
||||
w = { STR=1.0, AGI=0.6, STA=0.5, TOHIT=10, CRIT=11,
|
||||
ATTACKPOWER=0.5, HEALTH=0.05, WEAPONDPS=5, BASEARMOR=0.005 } },
|
||||
{ name = "防护", tab = 3, color = "ff69CCF0",
|
||||
w = { STR=1.0, AGI=1.8, STA=2.5, TOHIT=10, CRIT=3, ATTACKPOWER=0.5,
|
||||
DEFENSE=1.5, DODGE=12, PARRY=12, BLOCK=8, BLOCKVALUE=0.5,
|
||||
ARMOR=0.12, HEALTH=0.25, HEALTHREG=0.5, WEAPONDPS=4, BASEARMOR=0.05 } },
|
||||
w = { STA=1.0, STR=0.5, AGI=0.7, TOHIT=5, CRIT=3, ATTACKPOWER=0.2,
|
||||
DEFENSE=0.8, DODGE=8, PARRY=7, BLOCK=6, BLOCKVALUE=0.35,
|
||||
ARMOR=0.02, HEALTH=0.1, HEALTHREG=1.0, WEAPONDPS=3, BASEARMOR=0.03 } },
|
||||
},
|
||||
-- 硬核物理(战士型): 耐 > 力 > 敏 > 攻强
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, STR=2.0, AGI=1.5, ATTACKPOWER=1.0,
|
||||
TOHIT=5, CRIT=5, DEFENSE=1.0, DODGE=8, PARRY=5, BLOCK=4, BLOCKVALUE=0.3,
|
||||
ARMOR=0.08, HEALTH=0.2, HEALTHREG=2.0, WEAPONDPS=5, BASEARMOR=0.03 } },
|
||||
w = { STA=1.5, STR=1.0, AGI=0.8, ATTACKPOWER=0.5,
|
||||
TOHIT=3, CRIT=3, DEFENSE=0.5, DODGE=5, PARRY=3, BLOCK=3, BLOCKVALUE=0.3,
|
||||
ARMOR=0.05, HEALTH=0.1, HEALTHREG=1.5, WEAPONDPS=3, BASEARMOR=0.02 } },
|
||||
},
|
||||
PALADIN = {
|
||||
specs = {
|
||||
{ name = "神圣", tab = 1, color = "ff00FF96",
|
||||
w = { INT=0.35, SPI=0.4, STA=0.05, HEAL=1.0, DMG=0.3, SPELLCRIT=6, MANAREG=3.0,
|
||||
MANA=0.02, BASEARMOR=0.005 } },
|
||||
w = { INT=1.0, SPI=0.3, STA=0.5, HEAL=0.55, DMG=0.1,
|
||||
SPELLCRIT=5, MANAREG=1.3, MANA=0.01, BASEARMOR=0.005 } },
|
||||
{ name = "防护", tab = 2, color = "ff69CCF0",
|
||||
w = { STR=1.2, AGI=1.0, STA=2.5, INT=0.3, TOHIT=10, CRIT=5, ATTACKPOWER=0.5, DMG=0.4,
|
||||
DEFENSE=1.5, DODGE=12, PARRY=12, BLOCK=10, BLOCKVALUE=0.5,
|
||||
ARMOR=0.12, HEALTH=0.25, MANAREG=1.5, WEAPONDPS=3, BASEARMOR=0.05 } },
|
||||
w = { STA=1.0, STR=0.5, AGI=0.5, INT=0.3, TOHIT=5, CRIT=3,
|
||||
ATTACKPOWER=0.2, DMG=0.4,
|
||||
DEFENSE=0.7, DODGE=7, PARRY=6, BLOCK=6, BLOCKVALUE=0.15,
|
||||
ARMOR=0.02, HEALTH=0.1, MANAREG=1.0, WEAPONDPS=2, BASEARMOR=0.03 } },
|
||||
{ name = "惩戒", tab = 3, color = "ffF58CBA",
|
||||
w = { STR=2.0, AGI=1.0, STA=0.1, INT=0.25, TOHIT=16, CRIT=20, SPELLCRIT=10,
|
||||
ATTACKPOWER=1.0, DMG=0.6, HEAL=0.05, WEAPONDPS=12, BASEARMOR=0.01 } },
|
||||
w = { STR=1.0, AGI=0.6, STA=0.5, INT=0.3,
|
||||
TOHIT=8, CRIT=10, SPELLCRIT=5,
|
||||
ATTACKPOWER=0.5, DMG=0.3, HEAL=0.05, WEAPONDPS=5, BASEARMOR=0.005 } },
|
||||
},
|
||||
-- 硬核圣骑士: 耐 > 力 > 智 = 敏 = 精
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, STR=2.0, INT=1.5, AGI=1.5, SPI=1.5,
|
||||
TOHIT=5, CRIT=5, ATTACKPOWER=0.5, HEAL=0.8, DMG=0.3,
|
||||
DEFENSE=0.8, DODGE=5, ARMOR=0.06, HEALTH=0.2,
|
||||
HEALTHREG=1.5, MANAREG=1.5, WEAPONDPS=4, BASEARMOR=0.03 } },
|
||||
w = { STA=1.5, STR=1.0, INT=0.8, AGI=0.8, SPI=0.8,
|
||||
TOHIT=3, CRIT=3, ATTACKPOWER=0.3, HEAL=0.4, DMG=0.2,
|
||||
DEFENSE=0.5, DODGE=3, ARMOR=0.04, HEALTH=0.1,
|
||||
HEALTHREG=1.0, MANAREG=1.0, WEAPONDPS=2, BASEARMOR=0.02 } },
|
||||
},
|
||||
HUNTER = {
|
||||
specs = {
|
||||
{ name = "野兽", tab = 1, color = "ffABD473",
|
||||
w = { AGI=2.4, STR=0.3, STA=0.1, INT=0.2, TOHIT=18, CRIT=22, RANGEDCRIT=22,
|
||||
ATTACKPOWER=0.8, RANGEDATTACKPOWER=1.0, MANAREG=1.5, WEAPONDPS=10, BASEARMOR=0.005 } },
|
||||
w = { AGI=1.0, STR=0.05, STA=0.5, INT=0.8,
|
||||
TOHIT=10, CRIT=10, RANGEDCRIT=10,
|
||||
ATTACKPOWER=0.4, RANGEDATTACKPOWER=0.5, MANAREG=2.0,
|
||||
WEAPONDPS=4, BASEARMOR=0.005 } },
|
||||
{ name = "射击", tab = 2, color = "ffABD473",
|
||||
w = { AGI=2.4, STR=0.3, STA=0.1, INT=0.2, TOHIT=18, CRIT=22, RANGEDCRIT=22,
|
||||
ATTACKPOWER=0.8, RANGEDATTACKPOWER=1.0, MANAREG=1.5, WEAPONDPS=10, BASEARMOR=0.005 } },
|
||||
w = { AGI=1.0, STR=0.05, STA=0.5, INT=0.9,
|
||||
TOHIT=10, CRIT=10, RANGEDCRIT=10,
|
||||
ATTACKPOWER=0.4, RANGEDATTACKPOWER=0.5, MANAREG=2.0,
|
||||
WEAPONDPS=4, BASEARMOR=0.005 } },
|
||||
{ name = "生存", tab = 3, color = "ffABD473",
|
||||
w = { AGI=2.0, STR=0.8, STA=0.3, INT=0.2, SPI=0.3, TOHIT=16, CRIT=18, RANGEDCRIT=18,
|
||||
ATTACKPOWER=1.0, RANGEDATTACKPOWER=1.0, MANAREG=1.0, WEAPONDPS=8, BASEARMOR=0.008 } },
|
||||
w = { AGI=1.0, STR=0.4, STA=0.5, INT=0.3, SPI=0.3,
|
||||
TOHIT=8, CRIT=8, RANGEDCRIT=8,
|
||||
ATTACKPOWER=0.5, RANGEDATTACKPOWER=0.5, MANAREG=1.0,
|
||||
WEAPONDPS=3, BASEARMOR=0.005 } },
|
||||
},
|
||||
-- 硬核猎人: 耐 > 敏 > 智 > 力
|
||||
-- 硬核猎人: 耐 > 敏 > 智 > 力 (精神配合灵魂链接有价值)
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, AGI=2.0, INT=1.0, STR=0.5, SPI=1.5,
|
||||
TOHIT=5, CRIT=5, RANGEDCRIT=5, ATTACKPOWER=0.4, RANGEDATTACKPOWER=0.5,
|
||||
ARMOR=0.06, HEALTH=0.2, HEALTHREG=2.5, WEAPONDPS=3, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, AGI=1.0, INT=0.5, STR=0.3, SPI=0.8,
|
||||
TOHIT=3, CRIT=3, RANGEDCRIT=3,
|
||||
ATTACKPOWER=0.2, RANGEDATTACKPOWER=0.3,
|
||||
ARMOR=0.04, HEALTH=0.1, HEALTHREG=1.5, WEAPONDPS=2, BASEARMOR=0.01 } },
|
||||
},
|
||||
ROGUE = {
|
||||
specs = {
|
||||
{ name = "刺杀", tab = 1, color = "ffFFF569",
|
||||
w = { AGI=2.0, STR=1.0, STA=0.1, TOHIT=18, CRIT=25, ATTACKPOWER=1.0,
|
||||
WEAPONDPS=10, BASEARMOR=0.008 } },
|
||||
w = { AGI=1.0, STR=0.5, STA=0.5, TOHIT=10, CRIT=12,
|
||||
ATTACKPOWER=0.45, WEAPONDPS=5, BASEARMOR=0.005 } },
|
||||
{ name = "战斗", tab = 2, color = "ffFFF569",
|
||||
w = { AGI=2.0, STR=1.0, STA=0.1, TOHIT=20, CRIT=22, ATTACKPOWER=1.0,
|
||||
WEAPONDPS=14, BASEARMOR=0.008 } },
|
||||
w = { AGI=1.0, STR=0.5, STA=0.5, TOHIT=10, CRIT=11,
|
||||
ATTACKPOWER=0.45, WEAPONDPS=6, BASEARMOR=0.005 } },
|
||||
{ name = "敏锐", tab = 3, color = "ffFFF569",
|
||||
w = { AGI=2.2, STR=1.0, STA=0.5, TOHIT=16, CRIT=20, ATTACKPOWER=1.0, DODGE=5,
|
||||
WEAPONDPS=8, BASEARMOR=0.01 } },
|
||||
w = { AGI=1.0, STR=0.5, STA=0.5, TOHIT=8, CRIT=10,
|
||||
ATTACKPOWER=0.45, DODGE=3, WEAPONDPS=4, BASEARMOR=0.005 } },
|
||||
},
|
||||
-- 硬核潜行者: 耐 > 敏 > 力 > 攻强
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, AGI=2.5, STR=1.5, ATTACKPOWER=1.0,
|
||||
TOHIT=5, CRIT=5, DODGE=5, ARMOR=0.06,
|
||||
HEALTH=0.2, HEALTHREG=2.0, WEAPONDPS=5, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, AGI=1.2, STR=0.8, ATTACKPOWER=0.5,
|
||||
TOHIT=3, CRIT=3, DODGE=3, ARMOR=0.04,
|
||||
HEALTH=0.1, HEALTHREG=1.5, WEAPONDPS=3, BASEARMOR=0.01 } },
|
||||
},
|
||||
PRIEST = {
|
||||
specs = {
|
||||
{ name = "戒律", tab = 1, color = "ff00FF96",
|
||||
w = { INT=0.35, SPI=0.55, STA=0.05, HEAL=1.0, DMG=0.3, SPELLCRIT=5, MANAREG=3.0,
|
||||
MANA=0.02, BASEARMOR=0.003 } },
|
||||
w = { INT=1.0, SPI=0.5, STA=0.5, HEAL=0.7, DMG=0.1,
|
||||
SPELLCRIT=4, MANAREG=1.2, MANA=0.01,
|
||||
WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
{ name = "神圣", tab = 2, color = "ff00FF96",
|
||||
w = { INT=0.35, SPI=0.55, STA=0.05, HEAL=1.0, DMG=0.3, SPELLCRIT=5, MANAREG=3.0,
|
||||
MANA=0.02, BASEARMOR=0.003 } },
|
||||
w = { INT=1.0, SPI=0.7, STA=0.5, HEAL=0.8, DMG=0.1,
|
||||
SPELLCRIT=3, MANAREG=1.35, MANA=0.01,
|
||||
WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
{ name = "暗影", tab = 3, color = "ff9482C9",
|
||||
w = { INT=0.15, SPI=0.35, STA=0.05, DMG=1.0, HEAL=0.05, SPELLCRIT=6, SPELLTOHIT=14,
|
||||
MANAREG=1.5, BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.2, SPI=0.2, STA=0.5,
|
||||
SPELLTOHIT=14, SPELLCRIT=8, MANAREG=1.0,
|
||||
WEAPONDPS=2.5, WEAPONSPEED=0.6, BASEARMOR=0.003 } },
|
||||
},
|
||||
-- 硬核法系(牧师): 耐 > 智 = 治疗 > 精
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, INT=2.0, HEAL=2.0, DMG=1.5, SPI=1.5,
|
||||
SPELLCRIT=3, SPELLTOHIT=5, MANAREG=2.5,
|
||||
ARMOR=0.06, HEALTH=0.15, HEALTHREG=1.0, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, INT=1.0, HEAL=1.0, DMG=0.8, SPI=0.8,
|
||||
SPELLCRIT=2, SPELLTOHIT=3, MANAREG=1.5,
|
||||
WEAPONDPS=1.5, WEAPONSPEED=0.3,
|
||||
ARMOR=0.04, HEALTH=0.08, HEALTHREG=0.8, BASEARMOR=0.01 } },
|
||||
},
|
||||
SHAMAN = {
|
||||
specs = {
|
||||
{ name = "元素", tab = 1, color = "ff0070DE",
|
||||
w = { INT=0.2, SPI=0.1, STA=0.05, DMG=1.0, SPELLCRIT=8, SPELLTOHIT=14,
|
||||
ATTACKPOWER=0.1, MANAREG=2.0, BASEARMOR=0.005 } },
|
||||
w = { DMG=1.0, INT=0.3, SPI=0.1, STA=0.5,
|
||||
SPELLTOHIT=10, SPELLCRIT=8, ATTACKPOWER=0.1,
|
||||
MANAREG=1.1, BASEARMOR=0.005 } },
|
||||
{ name = "增强", tab = 2, color = "ff0070DE",
|
||||
w = { STR=2.0, AGI=1.6, STA=0.1, INT=0.2, TOHIT=18, CRIT=22, ATTACKPOWER=1.0,
|
||||
DMG=0.3, SPELLCRIT=5, MANAREG=1.0, WEAPONDPS=14, BASEARMOR=0.01 } },
|
||||
w = { STR=1.0, AGI=0.9, STA=0.5, INT=0.3,
|
||||
TOHIT=10, CRIT=11, ATTACKPOWER=0.5,
|
||||
DMG=0.3, SPELLCRIT=3, MANAREG=1.0,
|
||||
WEAPONDPS=5, BASEARMOR=0.005 } },
|
||||
{ name = "恢复", tab = 3, color = "ff00FF96",
|
||||
w = { INT=0.35, SPI=0.3, STA=0.05, HEAL=1.0, DMG=0.2, SPELLCRIT=5, MANAREG=3.5,
|
||||
MANA=0.02, BASEARMOR=0.005 } },
|
||||
w = { INT=1.0, SPI=0.3, STA=0.5, HEAL=0.9, DMG=0.1,
|
||||
SPELLCRIT=5, MANAREG=1.7, MANA=0.01, BASEARMOR=0.005 } },
|
||||
},
|
||||
-- 硬核萨满(混合): 耐 > 力=敏 > 智=精
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, STR=1.5, AGI=1.5, INT=1.0, SPI=1.0,
|
||||
TOHIT=5, CRIT=5, ATTACKPOWER=0.5, HEAL=0.8, DMG=0.5,
|
||||
MANAREG=2.0, ARMOR=0.06, HEALTH=0.2, HEALTHREG=1.5,
|
||||
WEAPONDPS=4, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, STR=0.8, AGI=0.8, INT=0.5, SPI=0.5,
|
||||
TOHIT=3, CRIT=3, ATTACKPOWER=0.3, HEAL=0.4, DMG=0.3,
|
||||
MANAREG=1.0, ARMOR=0.04, HEALTH=0.1, HEALTHREG=1.0,
|
||||
WEAPONDPS=2, BASEARMOR=0.01 } },
|
||||
},
|
||||
MAGE = {
|
||||
specs = {
|
||||
{ name = "奥术", tab = 1, color = "ff69CCF0",
|
||||
w = { INT=0.2, SPI=0.15, STA=0.4, DMG=1.0, SPELLCRIT=7, SPELLTOHIT=14, MANAREG=2.0,
|
||||
MANA=0.01, BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.46, SPI=0.6, STA=0.3,
|
||||
SPELLTOHIT=10, SPELLCRIT=7, MANAREG=1.1,
|
||||
MANA=0.04, WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
{ name = "火焰", tab = 2, color = "ff69CCF0",
|
||||
w = { INT=0.15, SPI=0.1, STA=0.4, DMG=1.0, SPELLCRIT=9, SPELLTOHIT=14, MANAREG=2.0,
|
||||
MANA=0.01, BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.44, SPI=0.07, STA=0.3,
|
||||
SPELLTOHIT=12, SPELLCRIT=9, MANAREG=1.0,
|
||||
MANA=0.04, WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
{ name = "冰霜", tab = 3, color = "ff69CCF0",
|
||||
w = { INT=0.15, SPI=0.1, STA=0.4, DMG=1.0, SPELLCRIT=7, SPELLTOHIT=14, MANAREG=2.0,
|
||||
MANA=0.01, BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.37, SPI=0.06, STA=0.3,
|
||||
SPELLTOHIT=12, SPELLCRIT=7, MANAREG=0.8,
|
||||
MANA=0.03, WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
},
|
||||
-- 硬核法系(法师): 耐 > 智 = 法伤 > 精
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, INT=2.0, DMG=2.0, SPI=1.5,
|
||||
SPELLCRIT=3, SPELLTOHIT=5, MANAREG=2.5,
|
||||
ARMOR=0.08, HEALTH=0.15, HEALTHREG=1.0, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, INT=1.0, DMG=1.0, SPI=0.8,
|
||||
SPELLCRIT=2, SPELLTOHIT=3, MANAREG=1.5,
|
||||
WEAPONDPS=1.5, WEAPONSPEED=0.3,
|
||||
ARMOR=0.05, HEALTH=0.08, HEALTHREG=0.8, BASEARMOR=0.01 } },
|
||||
},
|
||||
WARLOCK = {
|
||||
specs = {
|
||||
{ name = "痛苦", tab = 1, color = "ff9482C9",
|
||||
w = { INT=0.15, SPI=0.1, STA=0.4, DMG=1.0, SPELLCRIT=4, SPELLTOHIT=14, MANAREG=1.0,
|
||||
HEALTH=0.08, BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.4, SPI=0.1, STA=0.5,
|
||||
SPELLTOHIT=12, SPELLCRIT=4, MANAREG=1.0,
|
||||
HEALTH=0.05, WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
{ name = "恶魔", tab = 2, color = "ff9482C9",
|
||||
w = { INT=0.15, SPI=0.1, STA=0.4, DMG=1.0, SPELLCRIT=6, SPELLTOHIT=14, MANAREG=1.5,
|
||||
BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.4, SPI=0.5, STA=0.5,
|
||||
SPELLTOHIT=12, SPELLCRIT=7, MANAREG=1.0,
|
||||
WEAPONDPS=2, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
{ name = "毁灭", tab = 3, color = "ff9482C9",
|
||||
w = { INT=0.15, SPI=0.1, STA=0.4, DMG=1.0, SPELLCRIT=8, SPELLTOHIT=14, MANAREG=1.5,
|
||||
BASEARMOR=0.003 } },
|
||||
w = { DMG=1.0, INT=0.34, SPI=0.25, STA=0.5,
|
||||
SPELLTOHIT=14, SPELLCRIT=9, MANAREG=0.65,
|
||||
WEAPONDPS=2.5, WEAPONSPEED=0.5, BASEARMOR=0.003 } },
|
||||
},
|
||||
-- 硬核法系(术士): 耐 > 智 = 法伤 > 精
|
||||
-- 硬核法系(术士): 耐 > 智 = 法伤 > 精 (精神低于法师因有生命分流)
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, INT=2.0, DMG=2.0, SPI=1.0,
|
||||
SPELLCRIT=3, SPELLTOHIT=5, MANAREG=2.0,
|
||||
ARMOR=0.06, HEALTH=0.15, HEALTHREG=1.0, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, INT=1.0, DMG=1.0, SPI=0.5,
|
||||
SPELLCRIT=2, SPELLTOHIT=3, MANAREG=1.0,
|
||||
WEAPONDPS=1.5, WEAPONSPEED=0.3,
|
||||
ARMOR=0.04, HEALTH=0.08, HEALTHREG=0.8, BASEARMOR=0.01 } },
|
||||
},
|
||||
DRUID = {
|
||||
specs = {
|
||||
{ name = "平衡", tab = 1, color = "ffFF7D0A",
|
||||
w = { INT=0.2, SPI=0.15, STA=0.05, DMG=1.0, HEAL=0.1, SPELLCRIT=7, SPELLTOHIT=14,
|
||||
MANAREG=2.0, MANA=0.01, BASEARMOR=0.005 } },
|
||||
w = { DMG=1.0, INT=0.38, SPI=0.34, STA=0.5,
|
||||
HEAL=0.1, SPELLTOHIT=12, SPELLCRIT=7,
|
||||
MANAREG=0.6, MANA=0.03, BASEARMOR=0.005 } },
|
||||
{ name = "野猫", tab = 2, color = "ffFF7D0A",
|
||||
w = { STR=2.4, AGI=1.4, STA=0.1, TOHIT=18, CRIT=22, ATTACKPOWER=1.0, DODGE=2,
|
||||
WEAPONDPS=2, BASEARMOR=0.008 } },
|
||||
w = { STR=1.2, AGI=1.0, STA=0.5, TOHIT=10, CRIT=11,
|
||||
ATTACKPOWER=0.5, DODGE=1, WEAPONDPS=0.5, BASEARMOR=0.005 } },
|
||||
{ name = "野熊", tab = 2, color = "ff69CCF0",
|
||||
w = { STR=1.5, AGI=2.0, STA=2.5, TOHIT=8, CRIT=5, ATTACKPOWER=0.5,
|
||||
DEFENSE=1.2, DODGE=12, ARMOR=0.12, HEALTH=0.25, BASEARMOR=0.05 } },
|
||||
w = { STA=1.0, AGI=0.5, STR=0.2, TOHIT=3, CRIT=3, ATTACKPOWER=0.35,
|
||||
DEFENSE=0.5, DODGE=6, ARMOR=0.1, HEALTH=0.08, BASEARMOR=0.04 } },
|
||||
{ name = "恢复", tab = 3, color = "ff00FF96",
|
||||
w = { INT=0.35, SPI=0.45, STA=0.05, HEAL=1.0, DMG=0.2, SPELLCRIT=5, MANAREG=3.0,
|
||||
MANA=0.02, BASEARMOR=0.005 } },
|
||||
w = { INT=1.0, SPI=0.87, STA=0.5, HEAL=1.2, DMG=0.1,
|
||||
SPELLCRIT=4, MANAREG=1.7, MANA=0.01, BASEARMOR=0.005 } },
|
||||
},
|
||||
-- 硬核德鲁伊(混合偏生存): 耐 > 敏 > 力 > 智 = 精
|
||||
hc = { name = "硬核", color = "ffFF4444",
|
||||
w = { STA=3.0, AGI=2.0, STR=1.5, INT=1.0, SPI=1.0,
|
||||
TOHIT=5, CRIT=5, ATTACKPOWER=0.5, HEAL=0.8, DMG=0.5,
|
||||
DODGE=5, ARMOR=0.06, HEALTH=0.2, HEALTHREG=2.0,
|
||||
WEAPONDPS=2, BASEARMOR=0.02 } },
|
||||
w = { STA=1.5, AGI=1.0, STR=0.8, INT=0.5, SPI=0.5,
|
||||
TOHIT=3, CRIT=3, ATTACKPOWER=0.3, HEAL=0.4, DMG=0.3,
|
||||
DODGE=3, ARMOR=0.04, HEALTH=0.1, HEALTHREG=1.0,
|
||||
WEAPONDPS=1, BASEARMOR=0.01 } },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -284,36 +314,46 @@ local function AdjustWeightsForLevel(baseWeights, level, isHC)
|
||||
for k, v in pairs(baseWeights) do adj[k] = v end
|
||||
|
||||
if isHC then
|
||||
-- HC: STA stays high at all levels (survival is the point)
|
||||
-- Only reduce hit/crit which are less useful at low levels
|
||||
-- HC: STA always stays high (survival is the whole point)
|
||||
if level <= 20 then
|
||||
adj.SPI = (adj.SPI or 0) * 1.3
|
||||
adj.SPI = math.max((adj.SPI or 0) * 1.3, 0.3)
|
||||
adj.TOHIT = (adj.TOHIT or 0) * 0.2
|
||||
adj.SPELLTOHIT = (adj.SPELLTOHIT or 0) * 0.2
|
||||
adj.HEALTHREG = (adj.HEALTHREG or 0) + 1.0
|
||||
adj.ARMOR = (adj.ARMOR or 0) + 0.03
|
||||
elseif level <= 40 then
|
||||
adj.SPI = (adj.SPI or 0) * 1.15
|
||||
adj.CRIT = (adj.CRIT or 0) * 0.3
|
||||
adj.SPELLCRIT = (adj.SPELLCRIT or 0) * 0.3
|
||||
adj.HEALTHREG = (adj.HEALTHREG or 0) + 0.8
|
||||
adj.ARMOR = (adj.ARMOR or 0) + 0.02
|
||||
elseif level <= 40 then
|
||||
adj.TOHIT = (adj.TOHIT or 0) * 0.5
|
||||
adj.SPELLTOHIT = (adj.SPELLTOHIT or 0) * 0.5
|
||||
adj.ARMOR = (adj.ARMOR or 0) + 0.01
|
||||
else
|
||||
adj.TOHIT = (adj.TOHIT or 0) * 0.8
|
||||
adj.SPELLTOHIT = (adj.SPELLTOHIT or 0) * 0.8
|
||||
end
|
||||
else
|
||||
if level <= 20 then
|
||||
adj.SPI = (adj.SPI or 0) * 2.5 + 0.5
|
||||
adj.STA = (adj.STA or 0) * 0.3
|
||||
-- PDF: 精神至上 at 1-20; SPI matters for all classes (regen)
|
||||
adj.SPI = math.max((adj.SPI or 0) * 1.5, 0.3)
|
||||
adj.STA = (adj.STA or 0) * 0.7
|
||||
-- SP/HEAL don't exist on items at this level
|
||||
adj.DMG = (adj.DMG or 0) * 0.15
|
||||
adj.HEAL = (adj.HEAL or 0) * 0.15
|
||||
adj.TOHIT = (adj.TOHIT or 0) * 0.2
|
||||
adj.SPELLTOHIT = (adj.SPELLTOHIT or 0) * 0.2
|
||||
adj.HEALTHREG = (adj.HEALTHREG or 0) + 1.5
|
||||
adj.ARMOR = (adj.ARMOR or 0) + 0.03
|
||||
elseif level <= 40 then
|
||||
adj.SPI = (adj.SPI or 0) * 1.5 + 0.2
|
||||
adj.CRIT = (adj.CRIT or 0) * 0.2
|
||||
adj.SPELLCRIT = (adj.SPELLCRIT or 0) * 0.2
|
||||
adj.RANGEDCRIT = (adj.RANGEDCRIT or 0) * 0.2
|
||||
adj.HEALTHREG = (adj.HEALTHREG or 0) + 0.8
|
||||
adj.ARMOR = (adj.ARMOR or 0) + 0.02
|
||||
elseif level <= 40 then
|
||||
-- PDF: 40级解锁板甲/锁甲, SP开始出现
|
||||
adj.SPI = math.max((adj.SPI or 0) * 1.2, 0.15)
|
||||
adj.DMG = (adj.DMG or 0) * 0.5
|
||||
adj.HEAL = (adj.HEAL or 0) * 0.5
|
||||
adj.TOHIT = (adj.TOHIT or 0) * 0.6
|
||||
adj.SPELLTOHIT = (adj.SPELLTOHIT or 0) * 0.6
|
||||
adj.ARMOR = (adj.ARMOR or 0) + 0.01
|
||||
else
|
||||
adj.TOHIT = (adj.TOHIT or 0) * 0.85
|
||||
adj.SPELLTOHIT = (adj.SPELLTOHIT or 0) * 0.85
|
||||
@@ -517,6 +557,10 @@ local STAT_PATTERNS = {
|
||||
{ p = "每秒伤害(%d+%.?%d*)", s = "WEAPONDPS" },
|
||||
{ p = "每秒(%d+%.?%d*)点伤害", s = "WEAPONDPS" },
|
||||
|
||||
-- Weapon attack speed ("速度 1.50" / "Speed 1.50") — stored as raw value
|
||||
{ p = "^速度 (%d+%.?%d*)", s = "WEAPONSPEED" },
|
||||
{ p = "^Speed (%d+%.?%d*)", s = "WEAPONSPEED" },
|
||||
|
||||
-- Base armor value ("63点护甲" / "123 护甲" / "500 Armor", no + prefix)
|
||||
{ p = "^(%d+)点护甲", s = "BASEARMOR" },
|
||||
{ p = "^(%d+) 点护甲", s = "BASEARMOR" },
|
||||
@@ -544,16 +588,25 @@ local STAT_PATTERNS = {
|
||||
{ p = "critical strike with spells by (%d+)%%", s = "SPELLCRIT" },
|
||||
{ p = "法术暴击.-(%d+)%%", s = "SPELLCRIT" },
|
||||
{ p = "法术.-致命一击.-(%d+)%%", s = "SPELLCRIT" },
|
||||
{ p = "法术.-爆击.-(%d+)%%", s = "SPELLCRIT" },
|
||||
{ p = "critical strike with ranged weapons by (%d+)%%", s = "RANGEDCRIT" },
|
||||
{ p = "远程暴击.-(%d+)%%", s = "RANGEDCRIT" },
|
||||
{ p = "远程.-致命一击.-(%d+)%%", s = "RANGEDCRIT" },
|
||||
{ p = "critical strike by (%d+)%%", s = "CRIT" },
|
||||
{ p = "致命一击几率.-(%d+)%%", s = "CRIT" },
|
||||
{ p = "致命一击.-提高(%d+)%%", s = "CRIT" },
|
||||
{ p = "致命一击.-(%d+)%%", s = "CRIT" },
|
||||
{ p = "暴击几率.-(%d+)%%", s = "CRIT" },
|
||||
{ p = "暴击.-(%d+)%%", s = "CRIT" },
|
||||
|
||||
-- Hit
|
||||
-- Hit (green equip effects: "使你击中目标的几率提高X%", "chance to hit by X%")
|
||||
{ p = "hit with spells by (%d+)%%", s = "SPELLTOHIT" },
|
||||
{ p = "法术击中.-(%d+)%%", s = "SPELLTOHIT" },
|
||||
{ p = "法术命中.-(%d+)%%", s = "SPELLTOHIT" },
|
||||
{ p = "用法术击中.-几率.-(%d+)%%", s = "SPELLTOHIT" },
|
||||
{ p = "chance to hit by (%d+)%%", s = "TOHIT" },
|
||||
{ p = "击中目标.-几率.-(%d+)%%", s = "TOHIT" },
|
||||
{ p = "击中.-提高(%d+)%%", s = "TOHIT" },
|
||||
{ p = "命中.-(%d+)%%", s = "TOHIT" },
|
||||
|
||||
-- Attack Power
|
||||
@@ -591,23 +644,30 @@ local STAT_PATTERNS = {
|
||||
{ p = "每5秒恢复(%d+)点生命", s = "HEALTHREG" },
|
||||
{ p = "每5秒回复(%d+)点生命", s = "HEALTHREG" },
|
||||
|
||||
-- Defense
|
||||
-- Defense (green equip: "提高你的防御技能X点", "+X Defense")
|
||||
{ p = "Increased Defense %+(%d+)", s = "DEFENSE" },
|
||||
{ p = "Defense %+(%d+)", s = "DEFENSE" },
|
||||
{ p = "%+(%d+) Defense", s = "DEFENSE" },
|
||||
{ p = "防御技能提高(%d+)", s = "DEFENSE" },
|
||||
{ p = "防御等级提高(%d+)", s = "DEFENSE" },
|
||||
{ p = "防御.-提高(%d+)", s = "DEFENSE" },
|
||||
|
||||
-- Avoidance
|
||||
-- Avoidance (green equip: "使你的躲闪几率提高X%")
|
||||
{ p = "dodge.-by (%d+)%%", s = "DODGE" },
|
||||
{ p = "躲闪几率.-(%d+)%%", s = "DODGE" },
|
||||
{ p = "躲闪.-提高(%d+)%%", s = "DODGE" },
|
||||
{ p = "躲闪.-(%d+)%%", s = "DODGE" },
|
||||
{ p = "parry.-by (%d+)%%", s = "PARRY" },
|
||||
{ p = "招架几率.-(%d+)%%", s = "PARRY" },
|
||||
{ p = "招架.-提高(%d+)%%", s = "PARRY" },
|
||||
{ p = "招架.-(%d+)%%", s = "PARRY" },
|
||||
{ p = "block attacks.-by (%d+)%%", s = "BLOCK" },
|
||||
{ p = "格挡几率.-(%d+)%%", s = "BLOCK" },
|
||||
{ p = "格挡.-提高(%d+)%%", s = "BLOCK" },
|
||||
{ p = "格挡率.-(%d+)%%", s = "BLOCK" },
|
||||
{ p = "block value.-by (%d+)", s = "BLOCKVALUE" },
|
||||
{ p = "格挡值.-(%d+)", s = "BLOCKVALUE" },
|
||||
{ p = "盾牌格挡值.-(%d+)", s = "BLOCKVALUE" },
|
||||
|
||||
-- HP/Mana
|
||||
{ p = "%+(%d+) Health", s = "HEALTH" },
|
||||
@@ -725,25 +785,65 @@ end
|
||||
-- ideal_EP = total_budget * best_efficiency_for_spec
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function GetBestEfficiency(weights)
|
||||
local best = 0
|
||||
-- Slot-specific and non-standard stats excluded from reference efficiency
|
||||
local EFF_EXCLUDE = { WEAPONDPS=true, WEAPONSPEED=true, BASEARMOR=true, HEALTH=true, MANA=true }
|
||||
-- Stats that only appear on higher-level items
|
||||
local EFF_LATE_GAME = { DMG=true, HEAL=true, SPELLTOHIT=true, SPELLCRIT=true,
|
||||
TOHIT=true, CRIT=true, RANGEDCRIT=true }
|
||||
local EFF_MID_GAME = { DMG=true, HEAL=true }
|
||||
|
||||
local function GetRefEfficiency(weights, level)
|
||||
local effs = {}
|
||||
for stat, w in pairs(weights) do
|
||||
local cost = BUDGET_COST[stat]
|
||||
if cost and cost > 0 and w > 0 then
|
||||
local eff = w / cost
|
||||
if eff > best then best = eff end
|
||||
if not EFF_EXCLUDE[stat] then
|
||||
local cost = BUDGET_COST[stat]
|
||||
if cost and cost > 0 and w > 0 then
|
||||
local skip = false
|
||||
if level and level < 25 and EFF_LATE_GAME[stat] then skip = true end
|
||||
if level and level >= 25 and level < 40 and EFF_MID_GAME[stat] then skip = true end
|
||||
if not skip then
|
||||
table.insert(effs, w / cost)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return best
|
||||
|
||||
table.sort(effs, function(a,b) return a > b end)
|
||||
|
||||
local n = table.getn(effs)
|
||||
local ref = 0
|
||||
if n >= 3 then
|
||||
ref = effs[1] * 0.45 + effs[2] * 0.30 + effs[3] * 0.25
|
||||
elseif n == 2 then
|
||||
ref = effs[1] * 0.55 + effs[2] * 0.45
|
||||
elseif n == 1 then
|
||||
ref = effs[1]
|
||||
end
|
||||
|
||||
if ref <= 0 then ref = 1.0 end
|
||||
return ref
|
||||
end
|
||||
|
||||
local function CalcRawEP(bonuses, weights)
|
||||
local DPS_DAMPEN_MELEE = 0.40
|
||||
local DPS_DAMPEN_RANGED = 0.70
|
||||
|
||||
local function CalcRawEP(bonuses, weights, dpsDampen)
|
||||
if not bonuses or not weights then return 0 end
|
||||
dpsDampen = dpsDampen or DPS_DAMPEN_MELEE
|
||||
local ep = 0
|
||||
for stat, value in pairs(bonuses) do
|
||||
local w = weights[stat]
|
||||
if w and w > 0 then
|
||||
ep = ep + value * w
|
||||
if stat == "WEAPONDPS" then
|
||||
ep = ep + value * w * dpsDampen
|
||||
elseif stat == "WEAPONSPEED" then
|
||||
local speedBonus = 3.0 - value
|
||||
if speedBonus > 0 then
|
||||
ep = ep + speedBonus * w
|
||||
end
|
||||
else
|
||||
ep = ep + value * w
|
||||
end
|
||||
end
|
||||
end
|
||||
return ep
|
||||
@@ -755,21 +855,106 @@ local function CalcTotalBudget(bonuses)
|
||||
for stat, value in pairs(bonuses) do
|
||||
local cost = BUDGET_COST[stat]
|
||||
if cost and cost > 0 then
|
||||
total = total + math.abs(value) * cost
|
||||
if stat == "WEAPONSPEED" then
|
||||
local speedBonus = 3.0 - value
|
||||
if speedBonus > 0 then
|
||||
total = total + speedBonus * cost
|
||||
end
|
||||
else
|
||||
total = total + math.abs(value) * cost
|
||||
end
|
||||
end
|
||||
end
|
||||
return total
|
||||
end
|
||||
|
||||
local function CalcNormalizedScore(bonuses, weights, armorCompat, slotCompat)
|
||||
local rawEP = CalcRawEP(bonuses, weights)
|
||||
local totalBudget = CalcTotalBudget(bonuses)
|
||||
local bestEff = GetBestEfficiency(weights)
|
||||
local GS_RANGED_LOCS = {
|
||||
INVTYPE_RANGED = true, INVTYPE_RANGEDRIGHT = true, INVTYPE_THROWN = true,
|
||||
}
|
||||
|
||||
if totalBudget <= 0 or bestEff <= 0 then return 0 end
|
||||
--------------------------------------------------------------------------------
|
||||
-- Horizontal comparison: reference EP for the best rare item at level/slot
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local idealEP = totalBudget * bestEff
|
||||
local rawScore = (rawEP / idealEP) * 10
|
||||
local SLOT_BUDGET_MOD = {
|
||||
INVTYPE_HEAD = 1.0, INVTYPE_CHEST = 1.0, INVTYPE_ROBE = 1.0, INVTYPE_LEGS = 1.0,
|
||||
INVTYPE_SHOULDER = 0.77, INVTYPE_HAND = 0.77, INVTYPE_WAIST = 0.77, INVTYPE_FEET = 0.77,
|
||||
INVTYPE_WRIST = 0.56, INVTYPE_CLOAK = 0.56,
|
||||
INVTYPE_NECK = 0.56, INVTYPE_FINGER = 0.56, INVTYPE_TRINKET = 0.56,
|
||||
INVTYPE_WEAPON = 0.42, INVTYPE_WEAPONMAINHAND = 0.42, INVTYPE_WEAPONOFFHAND = 0.36,
|
||||
INVTYPE_2HWEAPON = 1.0,
|
||||
INVTYPE_SHIELD = 0.56, INVTYPE_HOLDABLE = 0.42,
|
||||
INVTYPE_RANGED = 0.32, INVTYPE_RANGEDRIGHT = 0.32, INVTYPE_THROWN = 0.32,
|
||||
INVTYPE_RELIC = 0.32, INVTYPE_TABARD = 0, INVTYPE_BODY = 0,
|
||||
}
|
||||
|
||||
local WEAPON_EQUIP_LOCS = {
|
||||
INVTYPE_WEAPON = true, INVTYPE_WEAPONMAINHAND = true, INVTYPE_WEAPONOFFHAND = true,
|
||||
INVTYPE_2HWEAPON = true, INVTYPE_RANGED = true, INVTYPE_RANGEDRIGHT = true,
|
||||
INVTYPE_THROWN = true,
|
||||
}
|
||||
|
||||
local ARMOR_EQUIP_LOCS = {
|
||||
INVTYPE_HEAD = true, INVTYPE_CHEST = true, INVTYPE_ROBE = true, INVTYPE_LEGS = true,
|
||||
INVTYPE_SHOULDER = true, INVTYPE_HAND = true, INVTYPE_WAIST = true, INVTYPE_FEET = true,
|
||||
INVTYPE_WRIST = true, INVTYPE_SHIELD = true,
|
||||
}
|
||||
|
||||
local function GetRefWeaponDPS(equipLoc, level)
|
||||
local dps
|
||||
if level >= 58 then dps = 48
|
||||
elseif level >= 40 then dps = 28 + (level - 40) * 0.55
|
||||
elseif level >= 20 then dps = 13 + (level - 20) * 0.75
|
||||
elseif level >= 10 then dps = 6 + (level - 10) * 0.7
|
||||
else dps = 3 + level * 0.3
|
||||
end
|
||||
if equipLoc == "INVTYPE_2HWEAPON" then dps = dps * 1.3 end
|
||||
return dps
|
||||
end
|
||||
|
||||
local function GetReferenceEP(equipLoc, level, weights, refEff)
|
||||
local slotMod = SLOT_BUDGET_MOD[equipLoc] or 0.56
|
||||
|
||||
local refIlvl
|
||||
if level >= 58 then refIlvl = 63
|
||||
elseif level >= 40 then refIlvl = level + 7
|
||||
elseif level >= 20 then refIlvl = level + 5
|
||||
else refIlvl = level + 3
|
||||
end
|
||||
|
||||
local statBudget = refIlvl * 0.65 * slotMod
|
||||
local ep = statBudget * refEff
|
||||
|
||||
if WEAPON_EQUIP_LOCS[equipLoc] then
|
||||
local wDPS = weights.WEAPONDPS
|
||||
if wDPS and wDPS > 0 then
|
||||
local refDPS = GetRefWeaponDPS(equipLoc, level)
|
||||
local dampen = GS_RANGED_LOCS[equipLoc] and DPS_DAMPEN_RANGED or DPS_DAMPEN_MELEE
|
||||
ep = ep + refDPS * wDPS * dampen
|
||||
end
|
||||
end
|
||||
|
||||
if ARMOR_EQUIP_LOCS[equipLoc] then
|
||||
local wArmor = weights.BASEARMOR
|
||||
if wArmor and wArmor > 0 then
|
||||
local refArmor = level * 1.5 * slotMod
|
||||
ep = ep + refArmor * wArmor
|
||||
end
|
||||
end
|
||||
|
||||
return ep
|
||||
end
|
||||
|
||||
local function CalcNormalizedScore(bonuses, weights, armorCompat, slotCompat, level, equipLoc)
|
||||
local dpsDampen = DPS_DAMPEN_MELEE
|
||||
if equipLoc and GS_RANGED_LOCS[equipLoc] then dpsDampen = DPS_DAMPEN_RANGED end
|
||||
local rawEP = CalcRawEP(bonuses, weights, dpsDampen)
|
||||
local refEff = GetRefEfficiency(weights, level)
|
||||
local refEP = GetReferenceEP(equipLoc, level, weights, refEff)
|
||||
|
||||
if refEP <= 0 then return 0 end
|
||||
|
||||
local rawScore = (rawEP / refEP) * 10
|
||||
|
||||
local compat = (armorCompat or 1.0) * (slotCompat or 1.0)
|
||||
local finalScore = rawScore * compat
|
||||
@@ -800,10 +985,57 @@ local function ScoreLabel(score)
|
||||
return "不适"
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Score tooltip (uses GameTooltipTemplate — proven reliable in this addon)
|
||||
-- Created lazily on first use (nil parent like Trade.lua pattern)
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local GSTip
|
||||
|
||||
local function GS_ShowTip(parentTip, scoreLines)
|
||||
if not scoreLines or not parentTip then return end
|
||||
|
||||
if not GSTip then
|
||||
GSTip = CreateFrame("GameTooltip", "NanamiGSTooltip", nil, "GameTooltipTemplate")
|
||||
GSTip:SetFrameStrata("TOOLTIP")
|
||||
GSTip:SetClampedToScreen(true)
|
||||
end
|
||||
|
||||
GSTip:SetOwner(parentTip, "ANCHOR_NONE")
|
||||
GSTip:ClearAllPoints()
|
||||
|
||||
local bottom = parentTip:GetBottom()
|
||||
if bottom and bottom > 80 then
|
||||
GSTip:SetPoint("TOPLEFT", parentTip, "BOTTOMLEFT", 0, 2)
|
||||
else
|
||||
GSTip:SetPoint("BOTTOMLEFT", parentTip, "TOPLEFT", 0, -2)
|
||||
end
|
||||
|
||||
for _, entry in ipairs(scoreLines) do
|
||||
if entry.left and entry.right then
|
||||
GSTip:AddDoubleLine(entry.left, entry.right,
|
||||
entry.lr or 1, entry.lg or 1, entry.lb or 1,
|
||||
entry.rr or 1, entry.rg or 1, entry.rb or 1)
|
||||
else
|
||||
GSTip:AddLine(entry.text or "", entry.r or 1, entry.g or 0.84, entry.b or 0)
|
||||
end
|
||||
end
|
||||
|
||||
GSTip:Show()
|
||||
end
|
||||
|
||||
local function GS_HideFrame()
|
||||
if GSTip then GSTip:Hide() end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Main tooltip function
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local GS_SCORE_CACHE = {}
|
||||
local GS_CACHE_SIZE = 0
|
||||
local GS_CACHE_MAX = 200
|
||||
|
||||
function GS:AddScoreToTooltip(tooltip, link)
|
||||
if not tooltip or not link then return end
|
||||
if SFramesDB and SFramesDB.gearScore == false then return end
|
||||
@@ -814,9 +1046,20 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
local classData = WEIGHTS[classToken]
|
||||
if not classData then return end
|
||||
|
||||
local cacheKey = classToken .. "|" .. link
|
||||
local cached = GS_SCORE_CACHE[cacheKey]
|
||||
if cached then
|
||||
tooltip._gsScoreAdded = true
|
||||
if cached.scoreLines then
|
||||
GS_ShowTip(tooltip, cached.scoreLines)
|
||||
else
|
||||
GS_HideFrame()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
GSDebug("Processing: " .. tostring(link))
|
||||
|
||||
-- Step 0: Check item quality — skip gray, penalize white
|
||||
local quality = GetQualityFromLink(link)
|
||||
if quality < 0 then
|
||||
quality = GetQualityFromTooltip(tooltip)
|
||||
@@ -828,7 +1071,6 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
end
|
||||
GSDebug("Quality=" .. quality .. " mult=" .. qualityMult)
|
||||
|
||||
-- Step 1: Try GetItemInfo with extracted item string (more reliable than full link)
|
||||
local equipLoc, itemClass, itemSubClass
|
||||
pcall(function()
|
||||
local itemStr = ExtractItemString(link)
|
||||
@@ -850,7 +1092,6 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
.. " class=" .. tostring(itemClass) .. " sub=" .. tostring(itemSubClass))
|
||||
end)
|
||||
|
||||
-- Step 2: If GetItemInfo failed, parse equip slot from tooltip text
|
||||
if not equipLoc then
|
||||
local ttEquip, ttArmor, ttClass = ParseEquipLocFromTooltip(tooltip)
|
||||
if ttEquip then
|
||||
@@ -861,19 +1102,15 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
end
|
||||
end
|
||||
|
||||
-- Skip bags, ammo, tabards
|
||||
if equipLoc == "INVTYPE_BAG" or equipLoc == "INVTYPE_AMMO" or equipLoc == "INVTYPE_TABARD" then
|
||||
GSDebug("Skipped: bag/ammo/tabard")
|
||||
return
|
||||
end
|
||||
|
||||
-- Skip non-equippable items (only if we got valid info)
|
||||
if equipLoc and equipLoc ~= "" and not GS_EQUIP_LOCS[equipLoc] then
|
||||
GSDebug("Skipped: not equippable (" .. tostring(equipLoc) .. ")")
|
||||
return
|
||||
end
|
||||
|
||||
-- Step 3: Parse stats - try library first, then scan visible tooltip text
|
||||
local bonuses = ParseItemWithLib(link)
|
||||
if bonuses then
|
||||
GSDebug("Stats from ItemBonusLib")
|
||||
@@ -889,7 +1126,6 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
return
|
||||
end
|
||||
|
||||
-- Step 4: No equipLoc = not equipment (potion, food, etc.) → skip
|
||||
if not equipLoc or equipLoc == "" then
|
||||
GSDebug("No equipLoc, not equipment, skipping")
|
||||
return
|
||||
@@ -900,7 +1136,8 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
local isHC = IsPlayerHardcore()
|
||||
|
||||
local armorCompat = GetArmorCompat(classToken, itemClass, itemSubClass, level)
|
||||
GSDebug("ArmorCompat=" .. armorCompat .. " class=" .. classToken)
|
||||
GSDebug("ArmorCompat=" .. armorCompat .. " class=" .. classToken
|
||||
.. " slot=" .. tostring(equipLoc) .. " lv=" .. level)
|
||||
|
||||
local specs = classData.specs
|
||||
if not specs or table.getn(specs) == 0 then return end
|
||||
@@ -910,7 +1147,11 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
for i, spec in ipairs(specs) do
|
||||
local w = AdjustWeightsForLevel(spec.w, level, false)
|
||||
local slotCompat = GetSlotCompat(classToken, i, equipLoc)
|
||||
local s = CalcNormalizedScore(bonuses, w, armorCompat, slotCompat)
|
||||
local refEff = GetRefEfficiency(w, level)
|
||||
local refEP = GetReferenceEP(equipLoc, level, w, refEff)
|
||||
local s = CalcNormalizedScore(bonuses, w, armorCompat, slotCompat, level, equipLoc)
|
||||
GSDebug(" " .. spec.name .. ": rawScore=" .. string.format("%.2f", s)
|
||||
.. " refEP=" .. string.format("%.1f", refEP) .. " refEff=" .. string.format("%.3f", refEff))
|
||||
s = math.floor(s * qualityMult * 10 + 0.5) / 10
|
||||
if s < 1.0 and s > 0 then s = 1.0 end
|
||||
table.insert(scores, {
|
||||
@@ -926,38 +1167,55 @@ function GS:AddScoreToTooltip(tooltip, link)
|
||||
local hcScore = 0
|
||||
if classData.hc then
|
||||
local hw = AdjustWeightsForLevel(classData.hc.w, level, true)
|
||||
hcScore = CalcNormalizedScore(bonuses, hw, armorCompat, 1.0)
|
||||
hcScore = CalcNormalizedScore(bonuses, hw, armorCompat, 1.0, level, equipLoc)
|
||||
if not bonuses.STA or bonuses.STA <= 0 then
|
||||
hcScore = hcScore * 0.35
|
||||
end
|
||||
hcScore = math.floor(hcScore * qualityMult * 10 + 0.5) / 10
|
||||
if hcScore < 1.0 and hcScore > 0 then hcScore = 1.0 end
|
||||
if hcScore > 0 then anyShow = true end
|
||||
end
|
||||
|
||||
if not anyShow then return end
|
||||
if not anyShow then
|
||||
GS_SCORE_CACHE[cacheKey] = { scoreLines = nil }
|
||||
GS_CACHE_SIZE = GS_CACHE_SIZE + 1
|
||||
GS_HideFrame()
|
||||
return
|
||||
end
|
||||
|
||||
tooltip._gsScoreAdded = true
|
||||
|
||||
tooltip:AddLine(" ")
|
||||
tooltip:AddLine("|cffffd700── 装备评分 ──|r")
|
||||
local scoreLines = {}
|
||||
table.insert(scoreLines, { text = "── 装备评分 ──", r = 1, g = 0.84, b = 0 })
|
||||
|
||||
for _, sd in ipairs(scores) do
|
||||
local star = sd.isPrimary and "★ " or " "
|
||||
local sStr = string.format("%.1f", sd.score)
|
||||
local sColor = ScoreColorHex(sd.score)
|
||||
local left = star .. "|c" .. sd.color .. sd.name .. "|r"
|
||||
local right = "|c" .. sColor .. sStr .. " " .. sd.label .. "|r"
|
||||
tooltip:AddDoubleLine(left, right, 1,1,1, 1,1,1)
|
||||
table.insert(scoreLines, {
|
||||
left = star .. "|c" .. sd.color .. sd.name .. "|r",
|
||||
right = "|c" .. sColor .. sStr .. " " .. sd.label .. "|r",
|
||||
})
|
||||
end
|
||||
|
||||
if classData.hc and hcScore > 0 then
|
||||
local hcSColor = ScoreColorHex(hcScore)
|
||||
local hcStar = isHC and "★ " or " "
|
||||
local left = hcStar .. "|c" .. classData.hc.color .. "硬核|r"
|
||||
local right = "|c" .. hcSColor .. string.format("%.1f", hcScore)
|
||||
.. " " .. ScoreLabel(hcScore) .. "|r"
|
||||
tooltip:AddDoubleLine(left, right, 1,1,1, 1,1,1)
|
||||
table.insert(scoreLines, {
|
||||
left = hcStar .. "|c" .. classData.hc.color .. "硬核|r",
|
||||
right = "|c" .. hcSColor .. string.format("%.1f", hcScore)
|
||||
.. " " .. ScoreLabel(hcScore) .. "|r",
|
||||
})
|
||||
end
|
||||
|
||||
tooltip:Show()
|
||||
GS_ShowTip(tooltip, scoreLines)
|
||||
|
||||
if GS_CACHE_SIZE >= GS_CACHE_MAX then
|
||||
GS_SCORE_CACHE = {}
|
||||
GS_CACHE_SIZE = 0
|
||||
end
|
||||
GS_SCORE_CACHE[cacheKey] = { scoreLines = scoreLines }
|
||||
GS_CACHE_SIZE = GS_CACHE_SIZE + 1
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
@@ -976,6 +1234,7 @@ function GS:HookTooltips()
|
||||
local origHide = GameTooltip:GetScript("OnHide")
|
||||
GameTooltip:SetScript("OnHide", function()
|
||||
this._gsScoreAdded = nil
|
||||
GS_HideFrame()
|
||||
if origHide then origHide() end
|
||||
end)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user