mirror of
https://github.com/Sarjuuk/aowow.git
synced 2025-11-29 15:58:16 +08:00
Stats/CombatRatings
* define magic numbers from combat ratings * move forgotten rating base values from Util to Stats * fix localized rating strings for item and spell tooltips (expected float, got string) * some cleanup in item/spell types to make it more clear when an internal stat is being handled, not an itemMod or combatRating
This commit is contained in:
@@ -472,6 +472,34 @@ define('ITEM_MOD_HEALTH_REGEN', 46);
|
||||
define('ITEM_MOD_SPELL_PENETRATION', 47);
|
||||
define('ITEM_MOD_BLOCK_VALUE', 48);
|
||||
|
||||
// Combat Ratings
|
||||
define('CR_WEAPON_SKILL', 0);
|
||||
define('CR_DEFENSE_SKILL', 1);
|
||||
define('CR_DODGE', 2);
|
||||
define('CR_PARRY', 3);
|
||||
define('CR_BLOCK', 4);
|
||||
define('CR_HIT_MELEE', 5);
|
||||
define('CR_HIT_RANGED', 6);
|
||||
define('CR_HIT_SPELL', 7);
|
||||
define('CR_CRIT_MELEE', 8);
|
||||
define('CR_CRIT_RANGED', 9);
|
||||
define('CR_CRIT_SPELL', 10);
|
||||
define('CR_HIT_TAKEN_MELEE', 11);
|
||||
define('CR_HIT_TAKEN_RANGED', 12);
|
||||
define('CR_HIT_TAKEN_SPELL', 13);
|
||||
define('CR_CRIT_TAKEN_MELEE', 14);
|
||||
define('CR_CRIT_TAKEN_RANGED', 15);
|
||||
define('CR_CRIT_TAKEN_SPELL', 16);
|
||||
define('CR_HASTE_MELEE', 17);
|
||||
define('CR_HASTE_RANGED', 18);
|
||||
define('CR_HASTE_SPELL', 19);
|
||||
define('CR_WEAPON_SKILL_MAINHAND', 20);
|
||||
define('CR_WEAPON_SKILL_OFFHAND', 21);
|
||||
define('CR_WEAPON_SKILL_RANGED', 22);
|
||||
define('CR_EXPERTISE', 23);
|
||||
define('CR_ARMOR_PENETRATION', 24);
|
||||
// define('CR_MASTERY', 25); // not in 335a
|
||||
|
||||
// Powers
|
||||
define('POWER_MANA', 0);
|
||||
define('POWER_RAGE', 1);
|
||||
@@ -553,7 +581,7 @@ define('LOCK_PROPERTY_MINING', 3);
|
||||
define('NPC_TYPEFLAG_HERBLOOT', 0x0100);
|
||||
define('NPC_TYPEFLAG_MININGLOOT', 0x0200);
|
||||
define('NPC_TYPEFLAG_ENGINEERLOOT', 0x8000);
|
||||
define('NPC_TYPEFLAG_SPECIALLOOT', 0x8300);
|
||||
define('NPC_TYPEFLAG_SPECIALLOOT', NPC_TYPEFLAG_ENGINEERLOOT | NPC_TYPEFLAG_MININGLOOT | NPC_TYPEFLAG_HERBLOOT);
|
||||
|
||||
define('NPC_RANK_NORMAL', 0);
|
||||
define('NPC_RANK_ELITE', 1);
|
||||
|
||||
@@ -122,107 +122,120 @@ abstract class Stat // based on g_statTo
|
||||
public const IDX_FLAGS = 4;
|
||||
|
||||
private static /* array */ $data = array(
|
||||
self::HEALTH => ['health', ITEM_MOD_HEALTH, null, 115, self::FLAG_ITEM],
|
||||
self::MANA => ['mana', ITEM_MOD_MANA, null, 116, self::FLAG_ITEM],
|
||||
self::AGILITY => ['agi', ITEM_MOD_AGILITY, null, 21, self::FLAG_ITEM],
|
||||
self::STRENGTH => ['str', ITEM_MOD_STRENGTH, null, 20, self::FLAG_ITEM],
|
||||
self::INTELLECT => ['int', ITEM_MOD_INTELLECT, null, 23, self::FLAG_ITEM],
|
||||
self::SPIRIT => ['spi', ITEM_MOD_SPIRIT, null, 24, self::FLAG_ITEM],
|
||||
self::STAMINA => ['sta', ITEM_MOD_STAMINA, null, 22, self::FLAG_ITEM],
|
||||
self::ENERGY => ['energy', null, null, null, self::FLAG_ITEM],
|
||||
self::RAGE => ['rage', null, null, null, self::FLAG_ITEM],
|
||||
self::FOCUS => ['focus', null, null, null, self::FLAG_ITEM],
|
||||
self::RUNIC_POWER => ['runic', null, null, null, self::FLAG_ITEM | self::FLAG_SERVERSIDE],
|
||||
self::DEFENSE_RTG => ['defrtng', ITEM_MOD_DEFENSE_SKILL_RATING, 1, 42, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::DODGE_RTG => ['dodgertng', ITEM_MOD_DODGE_RATING, 2, 45, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::PARRY_RTG => ['parryrtng', ITEM_MOD_PARRY_RATING, 3, 46, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::BLOCK_RTG => ['blockrtng', ITEM_MOD_BLOCK_RATING, 4, 44, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_HIT_RTG => ['mlehitrtng', ITEM_MOD_HIT_MELEE_RATING, 5, 95, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_HIT_RTG => ['rgdhitrtng', ITEM_MOD_HIT_RANGED_RATING, 6, 39, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_HIT_RTG => ['splhitrtng', ITEM_MOD_HIT_SPELL_RATING, 7, 48, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_CRIT_RTG => ['mlecritstrkrtng', ITEM_MOD_CRIT_MELEE_RATING, 8, 84, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_CRIT_RTG => ['rgdcritstrkrtng', ITEM_MOD_CRIT_RANGED_RATING, 9, 40, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_CRIT_RTG => ['splcritstrkrtng', ITEM_MOD_CRIT_SPELL_RATING, 10, 49, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_HIT_TAKEN_RTG => ['_mlehitrtng', ITEM_MOD_HIT_TAKEN_MELEE_RATING, 11, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_HIT_TAKEN_RTG => ['_rgdhitrtng', ITEM_MOD_HIT_TAKEN_RANGED_RATING, 12, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_HIT_TAKEN_RTG => ['_splhitrtng', ITEM_MOD_HIT_TAKEN_SPELL_RATING, 13, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_CRIT_TAKEN_RTG => ['_mlecritstrkrtng', ITEM_MOD_CRIT_TAKEN_MELEE_RATING, 14, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_CRIT_TAKEN_RTG => ['_rgdcritstrkrtng', ITEM_MOD_CRIT_TAKEN_RANGED_RATING, 15, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_CRIT_TAKEN_RTG => ['_splcritstrkrtng', ITEM_MOD_CRIT_TAKEN_SPELL_RATING, 16, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_HASTE_RTG => ['mlehastertng', ITEM_MOD_HASTE_MELEE_RATING, 17, 78, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_HASTE_RTG => ['rgdhastertng', ITEM_MOD_HASTE_RANGED_RATING, 18, 101, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_HASTE_RTG => ['splhastertng', ITEM_MOD_HASTE_SPELL_RATING, 19, 102, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::HIT_RTG => ['hitrtng', ITEM_MOD_HIT_RATING, null, 119, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::CRIT_RTG => ['critstrkrtng', ITEM_MOD_CRIT_RATING, null, 96, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::HIT_TAKEN_RTG => ['_hitrtng', ITEM_MOD_HIT_TAKEN_RATING, null, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::CRIT_TAKEN_RTG => ['_critstrkrtng', ITEM_MOD_CRIT_TAKEN_RATING, null, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RESILIENCE_RTG => ['resirtng', ITEM_MOD_RESILIENCE_RATING, null, 79, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::HASTE_RTG => ['hastertng', ITEM_MOD_HASTE_RATING, null, 103, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::EXPERTISE_RTG => ['exprtng', ITEM_MOD_EXPERTISE_RATING, 23, 117, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::ATTACK_POWER => ['atkpwr', ITEM_MOD_ATTACK_POWER, null, 77, self::FLAG_ITEM],
|
||||
self::RANGED_ATTACK_POWER => ['rgdatkpwr', ITEM_MOD_RANGED_ATTACK_POWER, null, 38, self::FLAG_ITEM],
|
||||
self::FERAL_ATTACK_POWER => ['feratkpwr', ITEM_MOD_FERAL_ATTACK_POWER, null, 97, self::FLAG_ITEM],
|
||||
self::HEALING_SPELL_POWER => ['splheal', ITEM_MOD_SPELL_HEALING_DONE, null, 50, self::FLAG_ITEM],
|
||||
self::DAMAGE_SPELL_POWER => ['spldmg', ITEM_MOD_SPELL_DAMAGE_DONE, null, 51, self::FLAG_ITEM],
|
||||
self::MANA_REGENERATION => ['manargn', ITEM_MOD_MANA_REGENERATION, null, 61, self::FLAG_ITEM],
|
||||
self::ARMOR_PENETRATION_RTG => ['armorpenrtng', ITEM_MOD_ARMOR_PENETRATION_RATING, 24, 114, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_POWER => ['splpwr', ITEM_MOD_SPELL_POWER, null, 123, self::FLAG_ITEM],
|
||||
self::HEALTH_REGENERATION => ['healthrgn', ITEM_MOD_HEALTH_REGEN, null, 60, self::FLAG_ITEM],
|
||||
self::SPELL_PENETRATION => ['splpen', ITEM_MOD_SPELL_PENETRATION, null, 94, self::FLAG_ITEM],
|
||||
self::BLOCK => ['block', ITEM_MOD_BLOCK_VALUE, null, 43, self::FLAG_ITEM],
|
||||
// self::MASTERY_RTG => ['mastrtng', null, null, null, self::FLAG_NONE],
|
||||
self::ARMOR => ['armor', null, null, 41, self::FLAG_ITEM],
|
||||
self::FIRE_RESISTANCE => ['firres', null, null, 26, self::FLAG_ITEM],
|
||||
self::FROST_RESISTANCE => ['frores', null, null, 28, self::FLAG_ITEM],
|
||||
self::HOLY_RESISTANCE => ['holres', null, null, 30, self::FLAG_ITEM],
|
||||
self::SHADOW_RESISTANCE => ['shares', null, null, 29, self::FLAG_ITEM],
|
||||
self::NATURE_RESISTANCE => ['natres', null, null, 27, self::FLAG_ITEM],
|
||||
self::ARCANE_RESISTANCE => ['arcres', null, null, 25, self::FLAG_ITEM],
|
||||
self::FIRE_SPELL_POWER => ['firsplpwr', null, null, 53, self::FLAG_ITEM],
|
||||
self::FROST_SPELL_POWER => ['frosplpwr', null, null, 54, self::FLAG_ITEM],
|
||||
self::HOLY_SPELL_POWER => ['holsplpwr', null, null, 55, self::FLAG_ITEM],
|
||||
self::SHADOW_SPELL_POWER => ['shasplpwr', null, null, 57, self::FLAG_ITEM],
|
||||
self::NATURE_SPELL_POWER => ['natsplpwr', null, null, 56, self::FLAG_ITEM],
|
||||
self::ARCANE_SPELL_POWER => ['arcsplpwr', null, null, 52, self::FLAG_ITEM],
|
||||
self::HEALTH => ['health', ITEM_MOD_HEALTH, null, 115, self::FLAG_ITEM],
|
||||
self::MANA => ['mana', ITEM_MOD_MANA, null, 116, self::FLAG_ITEM],
|
||||
self::AGILITY => ['agi', ITEM_MOD_AGILITY, null, 21, self::FLAG_ITEM],
|
||||
self::STRENGTH => ['str', ITEM_MOD_STRENGTH, null, 20, self::FLAG_ITEM],
|
||||
self::INTELLECT => ['int', ITEM_MOD_INTELLECT, null, 23, self::FLAG_ITEM],
|
||||
self::SPIRIT => ['spi', ITEM_MOD_SPIRIT, null, 24, self::FLAG_ITEM],
|
||||
self::STAMINA => ['sta', ITEM_MOD_STAMINA, null, 22, self::FLAG_ITEM],
|
||||
self::ENERGY => ['energy', null, null, null, self::FLAG_ITEM],
|
||||
self::RAGE => ['rage', null, null, null, self::FLAG_ITEM],
|
||||
self::FOCUS => ['focus', null, null, null, self::FLAG_ITEM],
|
||||
self::RUNIC_POWER => ['runic', null, null, null, self::FLAG_ITEM | self::FLAG_SERVERSIDE],
|
||||
self::DEFENSE_RTG => ['defrtng', ITEM_MOD_DEFENSE_SKILL_RATING, CR_DEFENSE_SKILL, 42, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::DODGE_RTG => ['dodgertng', ITEM_MOD_DODGE_RATING, CR_DODGE, 45, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::PARRY_RTG => ['parryrtng', ITEM_MOD_PARRY_RATING, CR_PARRY, 46, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::BLOCK_RTG => ['blockrtng', ITEM_MOD_BLOCK_RATING, CR_BLOCK, 44, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_HIT_RTG => ['mlehitrtng', ITEM_MOD_HIT_MELEE_RATING, CR_HIT_MELEE, 95, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_HIT_RTG => ['rgdhitrtng', ITEM_MOD_HIT_RANGED_RATING, CR_HIT_RANGED, 39, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_HIT_RTG => ['splhitrtng', ITEM_MOD_HIT_SPELL_RATING, CR_HIT_SPELL, 48, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_CRIT_RTG => ['mlecritstrkrtng', ITEM_MOD_CRIT_MELEE_RATING, CR_CRIT_MELEE, 84, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_CRIT_RTG => ['rgdcritstrkrtng', ITEM_MOD_CRIT_RANGED_RATING, CR_CRIT_RANGED, 40, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_CRIT_RTG => ['splcritstrkrtng', ITEM_MOD_CRIT_SPELL_RATING, CR_CRIT_SPELL, 49, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_HIT_TAKEN_RTG => ['_mlehitrtng', ITEM_MOD_HIT_TAKEN_MELEE_RATING, CR_HIT_TAKEN_MELEE, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_HIT_TAKEN_RTG => ['_rgdhitrtng', ITEM_MOD_HIT_TAKEN_RANGED_RATING, CR_HIT_TAKEN_RANGED, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_HIT_TAKEN_RTG => ['_splhitrtng', ITEM_MOD_HIT_TAKEN_SPELL_RATING, CR_HIT_TAKEN_SPELL, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_CRIT_TAKEN_RTG => ['_mlecritstrkrtng', ITEM_MOD_CRIT_TAKEN_MELEE_RATING, CR_CRIT_TAKEN_MELEE, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_CRIT_TAKEN_RTG => ['_rgdcritstrkrtng', ITEM_MOD_CRIT_TAKEN_RANGED_RATING, CR_CRIT_TAKEN_RANGED, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_CRIT_TAKEN_RTG => ['_splcritstrkrtng', ITEM_MOD_CRIT_TAKEN_SPELL_RATING, CR_CRIT_TAKEN_SPELL, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::MELEE_HASTE_RTG => ['mlehastertng', ITEM_MOD_HASTE_MELEE_RATING, CR_HASTE_MELEE, 78, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RANGED_HASTE_RTG => ['rgdhastertng', ITEM_MOD_HASTE_RANGED_RATING, CR_HASTE_RANGED, 101, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_HASTE_RTG => ['splhastertng', ITEM_MOD_HASTE_SPELL_RATING, CR_HASTE_SPELL, 102, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::HIT_RTG => ['hitrtng', ITEM_MOD_HIT_RATING, -CR_HIT_MELEE, 119, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::CRIT_RTG => ['critstrkrtng', ITEM_MOD_CRIT_RATING, -CR_CRIT_MELEE, 96, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::HIT_TAKEN_RTG => ['_hitrtng', ITEM_MOD_HIT_TAKEN_RATING, -CR_HIT_TAKEN_MELEE, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::CRIT_TAKEN_RTG => ['_critstrkrtng', ITEM_MOD_CRIT_TAKEN_RATING, -CR_CRIT_TAKEN_MELEE, null, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::RESILIENCE_RTG => ['resirtng', ITEM_MOD_RESILIENCE_RATING, -CR_CRIT_TAKEN_MELEE, 79, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::HASTE_RTG => ['hastertng', ITEM_MOD_HASTE_RATING, -CR_HASTE_MELEE, 103, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::EXPERTISE_RTG => ['exprtng', ITEM_MOD_EXPERTISE_RATING, CR_EXPERTISE, 117, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::ATTACK_POWER => ['atkpwr', ITEM_MOD_ATTACK_POWER, null, 77, self::FLAG_ITEM],
|
||||
self::RANGED_ATTACK_POWER => ['rgdatkpwr', ITEM_MOD_RANGED_ATTACK_POWER, null, 38, self::FLAG_ITEM],
|
||||
self::FERAL_ATTACK_POWER => ['feratkpwr', ITEM_MOD_FERAL_ATTACK_POWER, null, 97, self::FLAG_ITEM],
|
||||
self::HEALING_SPELL_POWER => ['splheal', ITEM_MOD_SPELL_HEALING_DONE, null, 50, self::FLAG_ITEM],
|
||||
self::DAMAGE_SPELL_POWER => ['spldmg', ITEM_MOD_SPELL_DAMAGE_DONE, null, 51, self::FLAG_ITEM],
|
||||
self::MANA_REGENERATION => ['manargn', ITEM_MOD_MANA_REGENERATION, null, 61, self::FLAG_ITEM],
|
||||
self::ARMOR_PENETRATION_RTG => ['armorpenrtng', ITEM_MOD_ARMOR_PENETRATION_RATING, CR_ARMOR_PENETRATION, 114, self::FLAG_ITEM | self::FLAG_LVL_SCALING],
|
||||
self::SPELL_POWER => ['splpwr', ITEM_MOD_SPELL_POWER, null, 123, self::FLAG_ITEM],
|
||||
self::HEALTH_REGENERATION => ['healthrgn', ITEM_MOD_HEALTH_REGEN, null, 60, self::FLAG_ITEM],
|
||||
self::SPELL_PENETRATION => ['splpen', ITEM_MOD_SPELL_PENETRATION, null, 94, self::FLAG_ITEM],
|
||||
self::BLOCK => ['block', ITEM_MOD_BLOCK_VALUE, null, 43, self::FLAG_ITEM],
|
||||
// self::MASTERY_RTG => ['mastrtng', null, CR_MASTERY, null, self::FLAG_NONE],
|
||||
self::ARMOR => ['armor', null, null, 41, self::FLAG_ITEM],
|
||||
self::FIRE_RESISTANCE => ['firres', null, null, 26, self::FLAG_ITEM],
|
||||
self::FROST_RESISTANCE => ['frores', null, null, 28, self::FLAG_ITEM],
|
||||
self::HOLY_RESISTANCE => ['holres', null, null, 30, self::FLAG_ITEM],
|
||||
self::SHADOW_RESISTANCE => ['shares', null, null, 29, self::FLAG_ITEM],
|
||||
self::NATURE_RESISTANCE => ['natres', null, null, 27, self::FLAG_ITEM],
|
||||
self::ARCANE_RESISTANCE => ['arcres', null, null, 25, self::FLAG_ITEM],
|
||||
self::FIRE_SPELL_POWER => ['firsplpwr', null, null, 53, self::FLAG_ITEM],
|
||||
self::FROST_SPELL_POWER => ['frosplpwr', null, null, 54, self::FLAG_ITEM],
|
||||
self::HOLY_SPELL_POWER => ['holsplpwr', null, null, 55, self::FLAG_ITEM],
|
||||
self::SHADOW_SPELL_POWER => ['shasplpwr', null, null, 57, self::FLAG_ITEM],
|
||||
self::NATURE_SPELL_POWER => ['natsplpwr', null, null, 56, self::FLAG_ITEM],
|
||||
self::ARCANE_SPELL_POWER => ['arcsplpwr', null, null, 52, self::FLAG_ITEM],
|
||||
// v not part of g_statToJson v
|
||||
self::WEAPON_DAMAGE => ['dmg', null, null, null, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::WEAPON_DAMAGE_TYPE => ['damagetype', null, null, 35, self::FLAG_SERVERSIDE],
|
||||
self::WEAPON_DAMAGE_MIN => ['dmgmin1', null, null, 33, self::FLAG_SERVERSIDE],
|
||||
self::WEAPON_DAMAGE_MAX => ['dmgmax1', null, null, 34, self::FLAG_SERVERSIDE],
|
||||
self::WEAPON_SPEED => ['speed', null, null, 36, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::WEAPON_DPS => ['dps', null, null, 32, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::MELEE_DAMAGE_MIN => ['mledmgmin', null, null, 135, self::FLAG_SERVERSIDE],
|
||||
self::MELEE_DAMAGE_MAX => ['mledmgmax', null, null, 136, self::FLAG_SERVERSIDE],
|
||||
self::MELEE_SPEED => ['mlespeed', null, null, 137, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::MELEE_DPS => ['mledps', null, null, 134, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE | self::FLAG_PROFILER],
|
||||
self::RANGED_DAMAGE_MIN => ['rgddmgmin', null, null, 139, self::FLAG_SERVERSIDE],
|
||||
self::RANGED_DAMAGE_MAX => ['rgddmgmax', null, null, 140, self::FLAG_SERVERSIDE],
|
||||
self::RANGED_SPEED => ['rgdspeed', null, null, 141, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::RANGED_DPS => ['rgddps', null, null, 138, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE | self::FLAG_PROFILER],
|
||||
self::EXTRA_SOCKETS => ['nsockets', null, null, 100, self::FLAG_SERVERSIDE],
|
||||
self::ARMOR_BONUS => ['armorbonus', null, null, 109, self::FLAG_SERVERSIDE],
|
||||
self::MELEE_ATTACK_POWER => ['mleatkpwr', null, null, 37, self::FLAG_SERVERSIDE | self::FLAG_PROFILER],
|
||||
self::WEAPON_DAMAGE => ['dmg', null, null, null, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::WEAPON_DAMAGE_TYPE => ['damagetype', null, null, 35, self::FLAG_SERVERSIDE],
|
||||
self::WEAPON_DAMAGE_MIN => ['dmgmin1', null, null, 33, self::FLAG_SERVERSIDE],
|
||||
self::WEAPON_DAMAGE_MAX => ['dmgmax1', null, null, 34, self::FLAG_SERVERSIDE],
|
||||
self::WEAPON_SPEED => ['speed', null, null, 36, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::WEAPON_DPS => ['dps', null, null, 32, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::MELEE_DAMAGE_MIN => ['mledmgmin', null, null, 135, self::FLAG_SERVERSIDE],
|
||||
self::MELEE_DAMAGE_MAX => ['mledmgmax', null, null, 136, self::FLAG_SERVERSIDE],
|
||||
self::MELEE_SPEED => ['mlespeed', null, null, 137, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::MELEE_DPS => ['mledps', null, null, 134, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE | self::FLAG_PROFILER],
|
||||
self::RANGED_DAMAGE_MIN => ['rgddmgmin', null, null, 139, self::FLAG_SERVERSIDE],
|
||||
self::RANGED_DAMAGE_MAX => ['rgddmgmax', null, null, 140, self::FLAG_SERVERSIDE],
|
||||
self::RANGED_SPEED => ['rgdspeed', null, null, 141, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE],
|
||||
self::RANGED_DPS => ['rgddps', null, null, 138, self::FLAG_SERVERSIDE | self::FLAG_FLOAT_VALUE | self::FLAG_PROFILER],
|
||||
self::EXTRA_SOCKETS => ['nsockets', null, null, 100, self::FLAG_SERVERSIDE],
|
||||
self::ARMOR_BONUS => ['armorbonus', null, null, 109, self::FLAG_SERVERSIDE],
|
||||
self::MELEE_ATTACK_POWER => ['mleatkpwr', null, null, 37, self::FLAG_SERVERSIDE | self::FLAG_PROFILER],
|
||||
// v Profiler only v
|
||||
self::EXPERTISE => ['exp', null, null, null, self::FLAG_PROFILER],
|
||||
self::ARMOR_PENETRATION_PCT => ['armorpenpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MELEE_HIT_PCT => ['mlehitpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MELEE_CRIT_PCT => ['mlecritstrkpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MELEE_HASTE_PCT => ['mlehastepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RANGED_HIT_PCT => ['rgdhitpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RANGED_CRIT_PCT => ['rgdcritstrkpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RANGED_HASTE_PCT => ['rgdhastepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::SPELL_HIT_PCT => ['splhitpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::SPELL_CRIT_PCT => ['splcritstrkpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::SPELL_HASTE_PCT => ['splhastepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MANA_REGENERATION_SPI => ['spimanargn', null, null, null, self::FLAG_PROFILER],
|
||||
self::MANA_REGENERATION_OC => ['oocmanargn', null, null, null, self::FLAG_PROFILER],
|
||||
self::MANA_REGENERATION_IC => ['icmanargn', null, null, null, self::FLAG_PROFILER],
|
||||
self::ARMOR_TOTAL => ['fullarmor', null, null, null, self::FLAG_PROFILER],
|
||||
self::DEFENSE => ['def', null, null, null, self::FLAG_PROFILER],
|
||||
self::DODGE_PCT => ['dodgepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::PARRY_PCT => ['parrypct', null, null, null, self::FLAG_PROFILER],
|
||||
self::BLOCK_PCT => ['blockpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RESILIENCE_PCT => ['resipct', null, null, null, self::FLAG_PROFILER]
|
||||
self::EXPERTISE => ['exp', null, null, null, self::FLAG_PROFILER],
|
||||
self::ARMOR_PENETRATION_PCT => ['armorpenpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MELEE_HIT_PCT => ['mlehitpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MELEE_CRIT_PCT => ['mlecritstrkpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MELEE_HASTE_PCT => ['mlehastepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RANGED_HIT_PCT => ['rgdhitpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RANGED_CRIT_PCT => ['rgdcritstrkpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RANGED_HASTE_PCT => ['rgdhastepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::SPELL_HIT_PCT => ['splhitpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::SPELL_CRIT_PCT => ['splcritstrkpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::SPELL_HASTE_PCT => ['splhastepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::MANA_REGENERATION_SPI => ['spimanargn', null, null, null, self::FLAG_PROFILER],
|
||||
self::MANA_REGENERATION_OC => ['oocmanargn', null, null, null, self::FLAG_PROFILER],
|
||||
self::MANA_REGENERATION_IC => ['icmanargn', null, null, null, self::FLAG_PROFILER],
|
||||
self::ARMOR_TOTAL => ['fullarmor', null, null, null, self::FLAG_PROFILER],
|
||||
self::DEFENSE => ['def', null, null, null, self::FLAG_PROFILER],
|
||||
self::DODGE_PCT => ['dodgepct', null, null, null, self::FLAG_PROFILER],
|
||||
self::PARRY_PCT => ['parrypct', null, null, null, self::FLAG_PROFILER],
|
||||
self::BLOCK_PCT => ['blockpct', null, null, null, self::FLAG_PROFILER],
|
||||
self::RESILIENCE_PCT => ['resipct', null, null, null, self::FLAG_PROFILER]
|
||||
);
|
||||
|
||||
/* Combat Rating needed for 1% effect at level 60 (Note: Shaman, Druid, Paladin and Death Knight have a /1.3 modifier on HASTE not set here)
|
||||
* Data taken from gtcombatratings.dbc for level 60 [idx % 100 = 59]
|
||||
* Corrections from gtoctclasscombatratingscalar.dbc with Warrior as base [idx = ratingId + 1]
|
||||
* Maybe create this data during setup, but then again it will never change for 3.3.5a
|
||||
*/
|
||||
private static $crPerPctPoint = array(
|
||||
CR_WEAPON_SKILL => 2.50, CR_DEFENSE_SKILL => 1.50, CR_DODGE => 13.80, CR_PARRY => 13.80, CR_BLOCK => 5.00,
|
||||
CR_HIT_MELEE => 10.00, CR_HIT_RANGED => 10.00, CR_HIT_SPELL => 8.00, CR_CRIT_MELEE => 14.00, CR_CRIT_RANGED => 14.00,
|
||||
CR_CRIT_SPELL => 14.00, CR_HIT_TAKEN_MELEE => 10.00, CR_HIT_TAKEN_RANGED => 10.00, CR_HIT_TAKEN_SPELL => 8.00, CR_CRIT_TAKEN_MELEE => 28.75,
|
||||
CR_CRIT_TAKEN_RANGED => 28.75, CR_CRIT_TAKEN_SPELL => 28.75, CR_HASTE_MELEE => 10.00, CR_HASTE_RANGED => 10.00, CR_HASTE_SPELL => 10.00,
|
||||
CR_WEAPON_SKILL_MAINHAND => 2.50, CR_WEAPON_SKILL_OFFHAND => 2.50, CR_WEAPON_SKILL_RANGED => 2.50, CR_EXPERTISE => 2.50, CR_ARMOR_PENETRATION => 4.69512 / 1.1,
|
||||
);
|
||||
|
||||
public static function isLevelIndependent(int $stat) : bool
|
||||
@@ -233,6 +246,19 @@ abstract class Stat // based on g_statTo
|
||||
return !(self::$data[$stat][self::IDX_FLAGS] & self::FLAG_LVL_SCALING);
|
||||
}
|
||||
|
||||
public static function getRatingPctFactor(int $stat) : float
|
||||
{
|
||||
// Note: this makes the weapon skill related combat ratings inaccessible. Is this relevant..?
|
||||
if (!isset(self::$data[$stat]) || self::$data[$stat][self::IDX_COMBAT_RATING] === null)
|
||||
return 0.0;
|
||||
|
||||
// note: originally any CRIT_TAKEN_RTG stat was set to 0 in favor of RESILIENCE_RTG
|
||||
// we keep the dbc value and just link RESILIENCE_RTG to CRIT_TAKEN_RTG
|
||||
// note2: the js expects some stats to be directly mapped to a combat rating that doesn't exist
|
||||
// picked the next best one in this case and denoted it with a negative value in the $data dump
|
||||
return self::$crPerPctPoint[abs(self::$data[$stat][self::IDX_COMBAT_RATING])];
|
||||
}
|
||||
|
||||
public static function getJsonString(int $stat) : string
|
||||
{
|
||||
if (!isset(self::$data[$stat]))
|
||||
@@ -271,7 +297,7 @@ abstract class Stat // based on g_statTo
|
||||
{
|
||||
$x = [];
|
||||
foreach (self::$data as $k => [, , $c, , $f])
|
||||
if ($c && (!$flags || $flags & $f))
|
||||
if ($c > 0 && (!$flags || $flags & $f))
|
||||
$x[$k] = $c;
|
||||
|
||||
return $x;
|
||||
@@ -416,7 +442,7 @@ class StatsContainer
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fromDB(int $type, int $typeId, int $fieldFlags = 0x0) : self
|
||||
public function fromDB(int $type, int $typeId, int $fieldFlags = Stat::FLAG_NONE) : self
|
||||
{
|
||||
foreach (DB::Aowow()->selectRow('SELECT (?#) FROM ?_item_stats WHERE `type` = ?d AND `typeId` = ?d', Stat::getJsonStringsFor($fieldFlags ?: (Stat::FLAG_ITEM | Stat::FLAG_SERVERSIDE)), $type, $typeId) as $key => $amt)
|
||||
{
|
||||
@@ -446,7 +472,7 @@ class StatsContainer
|
||||
/* Output */
|
||||
/**********/
|
||||
|
||||
public function toJson(int $outFlags = 0x0) : array
|
||||
public function toJson(int $outFlags = Stat::FLAG_NONE) : array
|
||||
{
|
||||
$out = [];
|
||||
foreach ($this->store as $stat => $amt)
|
||||
@@ -523,13 +549,17 @@ class StatsContainer
|
||||
|
||||
public static function convertCombatRating(int $mask) : array
|
||||
{
|
||||
if (($mask & 0x00E0) == 0x00E0) // hit rating - all subcats (5:mle, 6:rgd, 7:spl)
|
||||
$hitMask = (1 << CR_HIT_MELEE) | (1 << CR_HIT_RANGED) | (1 << CR_HIT_SPELL);
|
||||
if (($mask & $hitMask) == $hitMask)
|
||||
return [Stat::HIT_RTG]; // generic hit rating
|
||||
|
||||
if (($mask & 0x0700) == 0x0700) // crit done rating - all subcats (8:mle, 9:rgd, 10:spl)
|
||||
$critMask = (1 << CR_CRIT_MELEE) | (1 << CR_CRIT_RANGED) | (1 << CR_CRIT_SPELL);
|
||||
if (($mask & $critMask) == $critMask)
|
||||
return [Stat::CRIT_RTG]; // generic crit rating
|
||||
|
||||
if (($mask & 0x1C000) == 0x1C000) // crit taken rating - all subcats (14:mle, 15:rgd, 16:spl)
|
||||
|
||||
$takentMask = (1 << CR_CRIT_TAKEN_MELEE) | (1 << CR_CRIT_TAKEN_RANGED) | (1 << CR_CRIT_TAKEN_SPELL);
|
||||
if (($mask & $takentMask) == $takentMask)
|
||||
return [Stat::RESILIENCE_RTG]; // resilience
|
||||
|
||||
$result = []; // there really shouldn't be multiple ratings in that mask besides the cases above, but who knows..
|
||||
|
||||
@@ -755,22 +755,22 @@ class ItemList extends BaseType
|
||||
if (!$qty || $type <= 0)
|
||||
continue;
|
||||
|
||||
$statId = Stat::getIndexFrom(Stat::IDX_ITEM_MOD, $type);
|
||||
|
||||
// base stat
|
||||
switch ($type)
|
||||
switch ($statId)
|
||||
{
|
||||
case ITEM_MOD_MANA:
|
||||
case ITEM_MOD_HEALTH:
|
||||
// $type += 1; // i think i fucked up somewhere mapping item_mods: offsets may be required somewhere
|
||||
case ITEM_MOD_AGILITY:
|
||||
case ITEM_MOD_STRENGTH:
|
||||
case ITEM_MOD_INTELLECT:
|
||||
case ITEM_MOD_SPIRIT:
|
||||
case ITEM_MOD_STAMINA:
|
||||
$x .= '<span><!--stat'.$type.'-->'.($qty > 0 ? '+' : '-').abs($qty).' '.Lang::item('statType', $type).'</span><br />';
|
||||
case Stat::MANA:
|
||||
case Stat::HEALTH:
|
||||
case Stat::AGILITY:
|
||||
case Stat::STRENGTH:
|
||||
case Stat::INTELLECT:
|
||||
case Stat::SPIRIT:
|
||||
case Stat::STAMINA:
|
||||
$x .= '<span><!--stat'.$statId.'-->'.Lang::item('statType', $type, [ord($qty > 0 ? '+' : '-'), abs($qty)]).'</span><br />';
|
||||
break;
|
||||
default: // rating with % for reqLevel
|
||||
$green[] = $this->parseRating($type, $qty, $interactive, $causesScaling);
|
||||
|
||||
$green[] = $this->formatRating($statId, $type, $qty, $interactive, $causesScaling);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1439,7 +1439,7 @@ class ItemList extends BaseType
|
||||
return round(($dps - 54.8) * 14);
|
||||
}
|
||||
|
||||
private function parseRating($type, $value, $interactive = false, &$scaling = false)
|
||||
private function formatRating(int $statId, int $itemMod, int $qty, bool $interactive = false, bool &$scaling = false) : string
|
||||
{
|
||||
// clamp level range
|
||||
$ssdLvl = isset($this->ssd[$this->id]) ? $this->ssd[$this->id]['maxLevel'] : 1;
|
||||
@@ -1447,27 +1447,27 @@ class ItemList extends BaseType
|
||||
$level = min(max($reqLvl, $ssdLvl), MAX_LEVEL);
|
||||
|
||||
// unknown rating
|
||||
if (!Stat::getIndexFrom(Stat::IDX_ITEM_MOD, $type))
|
||||
if (!$statId)
|
||||
{
|
||||
if (User::isInGroup(U_GROUP_EMPLOYEE))
|
||||
return sprintf(Lang::item('statType', count(Lang::item('statType')) - 1), $type, $value);
|
||||
return Lang::item('statType', count(Lang::item('statType')) - 1, [$itemMod, $qty]);
|
||||
else
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
|
||||
// level independent Bonus
|
||||
if (Stat::isLevelIndependent($type))
|
||||
return Lang::item('trigger', SPELL_TRIGGER_EQUIP).str_replace('%d', '<!--rtg'.$type.'-->'.$value, Lang::item('statType', $type));
|
||||
if (Stat::isLevelIndependent($statId))
|
||||
return Lang::item('trigger', SPELL_TRIGGER_EQUIP).str_replace('%d', '<!--rtg'.$statId.'-->'.$qty, Lang::item('statType', $itemMod));
|
||||
|
||||
// rating-Bonuses
|
||||
$scaling = true;
|
||||
|
||||
if ($interactive)
|
||||
$js = ' <small>('.sprintf(Util::$changeLevelString, Util::setRatingLevel($level, $type, $value)).')</small>';
|
||||
$js = ' <small>('.sprintf(Util::$changeLevelString, Util::setRatingLevel($level, $statId, $qty)).')</small>';
|
||||
else
|
||||
$js = ' <small>('.Util::setRatingLevel($level, $type, $value).')</small>';
|
||||
$js = ' <small>('.Util::setRatingLevel($level, $statId, $qty).')</small>';
|
||||
|
||||
return Lang::item('trigger', SPELL_TRIGGER_EQUIP).str_replace('%d', '<!--rtg'.$type.'-->'.$value.$js, Lang::item('statType', $type));
|
||||
return Lang::item('trigger', SPELL_TRIGGER_EQUIP).str_replace('%d', '<!--rtg'.$statId.'-->'.$qty.$js, Lang::item('statType', $itemMod));
|
||||
}
|
||||
|
||||
private function getSSDMod($type)
|
||||
|
||||
@@ -955,18 +955,22 @@ class SpellList extends BaseType
|
||||
}
|
||||
|
||||
// description-, buff-parsing component
|
||||
// returns [min, max, minFulltext, maxFulltext, ratingId]
|
||||
private function resolveVariableString($varParts)
|
||||
private function resolveVariableString(array $varParts) : array
|
||||
{
|
||||
$signs = ['+', '-', '/', '*', '%', '^'];
|
||||
|
||||
foreach ($varParts as $k => $v)
|
||||
$$k = $v;
|
||||
|
||||
$result = [null];
|
||||
// returns
|
||||
$minPoints = null;
|
||||
$maxPoints = null;
|
||||
$fmtStringMin = null;
|
||||
$fmtStringMax = null;
|
||||
$statId = null;
|
||||
|
||||
if (!$var)
|
||||
return $result;
|
||||
return [null, null, null, null, null];
|
||||
|
||||
if (!$effIdx) // if EffectIdx is omitted, assume EffectIdx: 1
|
||||
$effIdx = 1;
|
||||
@@ -977,7 +981,7 @@ class SpellList extends BaseType
|
||||
|
||||
$srcSpell = $lookup && $lookup != $this->id ? $this->refSpells[$lookup] : $this;
|
||||
if ($srcSpell->error)
|
||||
return $result;
|
||||
return [null, null, null, null, null];
|
||||
|
||||
switch ($var)
|
||||
{
|
||||
@@ -988,7 +992,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'b': // PointsPerComboPoint
|
||||
case 'B':
|
||||
@@ -997,18 +1001,18 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'd': // SpellDuration
|
||||
case 'D': // todo (med): min/max?; /w unit?
|
||||
$base = $srcSpell->getField('duration');
|
||||
|
||||
$result[2] = Lang::formatTime($srcSpell->getField('duration'), 'spell', 'duration');
|
||||
$fmtStringMin = Lang::formatTime($srcSpell->getField('duration'), 'spell', 'duration');
|
||||
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base < 0 ? 0 : $base;
|
||||
$minPoints = $base < 0 ? 0 : $base;
|
||||
break;
|
||||
case 'e': // EffectValueMultiplier
|
||||
case 'E':
|
||||
@@ -1017,7 +1021,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'f': // EffectDamageMultiplier
|
||||
case 'F':
|
||||
@@ -1026,11 +1030,11 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'g': // boolean choice with casters gender as condition $gX:Y;
|
||||
case 'G':
|
||||
$result[2] = '<'.$switch[0].'/'.$switch[1].'>';
|
||||
$fmtStringMin = '<'.$switch[0].'/'.$switch[1].'>';
|
||||
break;
|
||||
case 'h': // ProcChance
|
||||
case 'H':
|
||||
@@ -1039,7 +1043,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'i': // MaxAffectedTargets
|
||||
case 'I':
|
||||
@@ -1048,12 +1052,12 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'l': // boolean choice with last value as condition $lX:Y;
|
||||
case 'L':
|
||||
// resolve later by backtracking
|
||||
$result[2] = '$l'.$switch[0].':'.$switch[1].';';
|
||||
$fmtStringMin = '$l'.$switch[0].':'.$switch[1].';';
|
||||
break;
|
||||
case 'm': // BasePoints (minValue)
|
||||
case 'M': // BasePoints (maxValue)
|
||||
@@ -1069,25 +1073,25 @@ class SpellList extends BaseType
|
||||
}
|
||||
|
||||
// Aura giving combat ratings
|
||||
$rType = [];
|
||||
$stats = [];
|
||||
if ($aura == SPELL_AURA_MOD_RATING)
|
||||
if ($rType = StatsContainer::convertCombatRating($mv))
|
||||
if ($stats = StatsContainer::convertCombatRating($mv))
|
||||
$this->scaling[$this->id] = true;
|
||||
// Aura end
|
||||
|
||||
if ($rType)
|
||||
if ($stats)
|
||||
{
|
||||
$result[2] = '<!--rtg%s-->%s <small>(%s)</small>';
|
||||
$result[4] = $rType[0]; // could be multiple ratings in theory, but not expected to be
|
||||
$fmtStringMin = '<!--rtg%s-->%s <small>(%s)</small>';
|
||||
$statId = $stats[0]; // could be multiple ratings in theory, but not expected to be
|
||||
}
|
||||
/* todo: export to and solve formulas in javascript e.g.: spell 10187 - ${$42213m1*8*$<mult>} with $mult = ${${$?s31678[${1.05}][${${$?s31677[${1.04}][${${$?s31676[${1.03}][${${$?s31675[${1.02}][${${$?s31674[${1.01}][${1}]}}]}}]}}]}}]}*${$?s12953[${1.06}][${${$?s12952[${1.04}][${${$?s11151[${1.02}][${1}]}}]}}]}}
|
||||
else if ($this->interactive && ($modStrMin || $modStrMax))
|
||||
{
|
||||
$this->scaling[$this->id] = true;
|
||||
$result[2] = $modStrMin.'%s';
|
||||
$fmtStringMin = $modStrMin.'%s';
|
||||
}
|
||||
*/
|
||||
$result[0] = ctype_lower($var) ? $min : $max;
|
||||
$minPoints = ctype_lower($var) ? $min : $max;
|
||||
break;
|
||||
case 'n': // ProcCharges
|
||||
case 'N':
|
||||
@@ -1096,7 +1100,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'o': // TotalAmount for periodic auras (with variance)
|
||||
case 'O':
|
||||
@@ -1125,12 +1129,12 @@ class SpellList extends BaseType
|
||||
{
|
||||
$this->scaling[$this->id] = true;
|
||||
|
||||
$result[2] = $modStrMin.'%s';
|
||||
$result[3] = $modStrMax.'%s';
|
||||
$fmtStringMin = $modStrMin.'%s';
|
||||
$fmtStringMax = $modStrMax.'%s';
|
||||
}
|
||||
|
||||
$result[0] = $min;
|
||||
$result[1] = $max;
|
||||
$minPoints = $min;
|
||||
$maxPoints = $max;
|
||||
break;
|
||||
case 'q': // EffectMiscValue
|
||||
case 'Q':
|
||||
@@ -1139,7 +1143,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'r': // SpellRange
|
||||
case 'R':
|
||||
@@ -1148,7 +1152,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 's': // BasePoints (with variance)
|
||||
case 'S':
|
||||
@@ -1162,26 +1166,26 @@ class SpellList extends BaseType
|
||||
eval("\$max = $max $op $oparg;");
|
||||
}
|
||||
// Aura giving combat ratings
|
||||
$rType = [];
|
||||
$stats = [];
|
||||
if ($aura == SPELL_AURA_MOD_RATING)
|
||||
if ($rType = StatsContainer::convertCombatRating($mv))
|
||||
if ($stats = StatsContainer::convertCombatRating($mv))
|
||||
$this->scaling[$this->id] = true;
|
||||
// Aura end
|
||||
|
||||
if ($rType)
|
||||
if ($stats)
|
||||
{
|
||||
$result[2] = '<!--rtg%s-->%s <small>(%s)</small>';
|
||||
$result[4] = $rType[0]; // could be multiple ratings in theory, but not expected to be
|
||||
$fmtStringMin = '<!--rtg%s-->%s <small>(%s)</small>';
|
||||
$statId = $stats[0]; // could be multiple ratings in theory, but not expected to be
|
||||
}
|
||||
else if (($modStrMin || $modStrMax) && $this->interactive)
|
||||
{
|
||||
$this->scaling[$this->id] = true;
|
||||
$result[2] = $modStrMin.'%s';
|
||||
$result[3] = $modStrMax.'%s';
|
||||
$fmtStringMin = $modStrMin.'%s';
|
||||
$fmtStringMax = $modStrMax.'%s';
|
||||
}
|
||||
|
||||
$result[0] = $min;
|
||||
$result[1] = $max;
|
||||
$minPoints = $min;
|
||||
$maxPoints = $max;
|
||||
break;
|
||||
case 't': // Periode
|
||||
case 'T':
|
||||
@@ -1190,7 +1194,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'u': // StackCount
|
||||
case 'U':
|
||||
@@ -1199,7 +1203,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'v': // MaxTargetLevel
|
||||
case 'V':
|
||||
@@ -1208,7 +1212,7 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'x': // ChainTargetCount
|
||||
case 'X':
|
||||
@@ -1217,27 +1221,27 @@ class SpellList extends BaseType
|
||||
if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base))
|
||||
eval("\$base = $base $op $oparg;");
|
||||
|
||||
$result[0] = $base;
|
||||
$minPoints = $base;
|
||||
break;
|
||||
case 'z': // HomeZone
|
||||
$result[2] = Lang::spell('home');
|
||||
$fmtStringMin = Lang::spell('home');
|
||||
break;
|
||||
}
|
||||
|
||||
// handle excessively precise floats
|
||||
if (is_float($result[0]))
|
||||
$result[0] = round($result[0], 2);
|
||||
if (isset($result[1]) && is_float($result[1]))
|
||||
$result[1] = round($result[1], 2);
|
||||
if (is_float($minPoints))
|
||||
$minPoints = round($minPoints, 2);
|
||||
if (isset($maxPoints) && is_float($maxPoints))
|
||||
$maxPoints = round($maxPoints, 2);
|
||||
|
||||
return $result; // minPoints, maxPoints, fmtStringMin, fmtStringMax, combatRatingId
|
||||
return [$minPoints, $maxPoints, $fmtStringMin, $fmtStringMax, $statId];
|
||||
}
|
||||
|
||||
// description-, buff-parsing component
|
||||
private function resolveFormulaString($formula, $precision = 0)
|
||||
private function resolveFormulaString(string $formula, int $precision = 0)
|
||||
{
|
||||
$fSuffix = '%s';
|
||||
$fRating = 0;
|
||||
$fStat = 0;
|
||||
|
||||
// step 1: formula unpacking redux
|
||||
while (($formStartPos = strpos($formula, '${')) !== false)
|
||||
@@ -1273,7 +1277,7 @@ class SpellList extends BaseType
|
||||
++$formCurPos; // for some odd reason the precision decimal survives if we dont increment further..
|
||||
}
|
||||
|
||||
[$formOutStr, $fSuffix, $fRating] = $this->resolveFormulaString($formOutStr, $formPrecision);
|
||||
[$formOutStr, $fSuffix, $fStat] = $this->resolveFormulaString($formOutStr, $formPrecision);
|
||||
|
||||
$formula = substr_replace($formula, $formOutStr, $formStartPos, ($formCurPos - $formStartPos));
|
||||
}
|
||||
@@ -1307,34 +1311,34 @@ class SpellList extends BaseType
|
||||
$pos += $len;
|
||||
|
||||
// we are resolving a formula -> omit ranges
|
||||
$var = $this->resolveVariableString($varParts);
|
||||
[$minPoints, , $fmtStringMin, , $statId] = $this->resolveVariableString($varParts);
|
||||
|
||||
// time within formula -> rebase to seconds and omit timeUnit
|
||||
if (strtolower($varParts['var']) == 'd')
|
||||
{
|
||||
$var[0] /= 1000;
|
||||
unset($var[2]);
|
||||
$minPoints /= 1000;
|
||||
unset($fmtStringMin);
|
||||
}
|
||||
|
||||
$str .= $var[0];
|
||||
$str .= $minPoints;
|
||||
|
||||
// overwrite eventually inherited strings
|
||||
if (isset($var[2]))
|
||||
$fSuffix = $var[2];
|
||||
if (isset($fmtStringMin))
|
||||
$fSuffix = $fmtStringMin;
|
||||
|
||||
// overwrite eventually inherited ratings
|
||||
if (isset($var[4]))
|
||||
$fRating = $var[4];
|
||||
// overwrite eventually inherited stat
|
||||
if (isset($statId))
|
||||
$fStat = $statId;
|
||||
}
|
||||
$str .= substr($formula, $pos);
|
||||
$str = str_replace('#', '$', $str); // reset marks
|
||||
$str = str_replace('#', '$', $str); // reset markers
|
||||
|
||||
// step 3: try to evaluate result
|
||||
$evaled = $this->resolveEvaluation($str);
|
||||
|
||||
$return = is_numeric($evaled) ? round($evaled, $precision) : $evaled;
|
||||
|
||||
return [$return, $fSuffix, $fRating];
|
||||
return [$return, $fSuffix, $fStat];
|
||||
}
|
||||
|
||||
// should probably used only once to create ?_spell. come to think of it, it yields the same results every time.. it absolutely has to!
|
||||
@@ -1576,12 +1580,12 @@ class SpellList extends BaseType
|
||||
$formPrecision = $data[$formCurPos + 1];
|
||||
$formCurPos += 2;
|
||||
}
|
||||
[$formOutVal, $formOutStr, $ratingId] = $this->resolveFormulaString($formOutStr, $formPrecision ?: ($topLevel ? 0 : 10));
|
||||
[$formOutVal, $formOutStr, $statId] = $this->resolveFormulaString($formOutStr, $formPrecision ?: ($topLevel ? 0 : 10));
|
||||
|
||||
if ($ratingId && Util::checkNumeric($formOutVal) && $this->interactive)
|
||||
$resolved = sprintf($formOutStr, $ratingId, abs($formOutVal), sprintf(Util::$setRatingLevelString, $this->charLevel, $ratingId, abs($formOutVal), Util::setRatingLevel($this->charLevel, $ratingId, abs($formOutVal))));
|
||||
else if ($ratingId && Util::checkNumeric($formOutVal))
|
||||
$resolved = sprintf($formOutStr, $ratingId, abs($formOutVal), Util::setRatingLevel($this->charLevel, $ratingId, abs($formOutVal)));
|
||||
if ($statId && Util::checkNumeric($formOutVal) && $this->interactive)
|
||||
$resolved = sprintf($formOutStr, $statId, abs($formOutVal), sprintf(Util::$setRatingLevelString, $this->charLevel, $statId, abs($formOutVal), Util::setRatingLevel($this->charLevel, $statId, abs($formOutVal))));
|
||||
else if ($statId && Util::checkNumeric($formOutVal))
|
||||
$resolved = sprintf($formOutStr, $statId, abs($formOutVal), Util::setRatingLevel($this->charLevel, $statId, abs($formOutVal)));
|
||||
else
|
||||
$resolved = sprintf($formOutStr, Util::checkNumeric($formOutVal) ? abs($formOutVal) : $formOutVal);
|
||||
|
||||
@@ -1614,23 +1618,23 @@ class SpellList extends BaseType
|
||||
|
||||
$pos += $len;
|
||||
|
||||
$var = $this->resolveVariableString($varParts);
|
||||
$resolved = is_numeric($var[0]) ? abs($var[0]) : $var[0];
|
||||
if (isset($var[2]))
|
||||
[$minPoints, $maxPoints, $fmtStringMin, $fmtStringMax, $statId] = $this->resolveVariableString($varParts);
|
||||
$resolved = is_numeric($minPoints) ? abs($minPoints) : $minPoints;
|
||||
if (isset($fmtStringMin))
|
||||
{
|
||||
if (isset($var[4]) && $this->interactive)
|
||||
$resolved = sprintf($var[2], $var[4], abs($var[0]), sprintf(Util::$setRatingLevelString, $this->charLevel, $var[4], abs($var[0]), Util::setRatingLevel($this->charLevel, $var[4], abs($var[0]))));
|
||||
else if (isset($var[4]))
|
||||
$resolved = sprintf($var[2], $var[4], abs($var[0]), Util::setRatingLevel($this->charLevel, $var[4], abs($var[0])));
|
||||
if (isset($statId) && $this->interactive)
|
||||
$resolved = sprintf($fmtStringMin, $statId, abs($minPoints), sprintf(Util::$setRatingLevelString, $this->charLevel, $statId, abs($minPoints), Util::setRatingLevel($this->charLevel, $statId, abs($minPoints))));
|
||||
else if (isset($statId))
|
||||
$resolved = sprintf($fmtStringMin, $statId, abs($minPoints), Util::setRatingLevel($this->charLevel, $statId, abs($minPoints)));
|
||||
else
|
||||
$resolved = sprintf($var[2], $resolved);
|
||||
$resolved = sprintf($fmtStringMin, $resolved);
|
||||
}
|
||||
|
||||
if (isset($var[1]) && $var[0] != $var[1] && !isset($var[4]))
|
||||
if (isset($maxPoints) && $minPoints != $maxPoints && !isset($statId))
|
||||
{
|
||||
$_ = is_numeric($var[1]) ? abs($var[1]) : $var[1];
|
||||
$_ = is_numeric($maxPoints) ? abs($maxPoints) : $maxPoints;
|
||||
$resolved .= Lang::game('valueDelim');
|
||||
$resolved .= isset($var[3]) ? sprintf($var[3], $_) : $_;
|
||||
$resolved .= isset($fmtStringMax) ? sprintf($fmtStringMax, $_) : $_;
|
||||
}
|
||||
|
||||
$str .= $resolved;
|
||||
|
||||
@@ -520,13 +520,6 @@ abstract class Util
|
||||
'us', 'eu', 'kr', 'tw', 'cn', 'dev'
|
||||
);
|
||||
|
||||
# todo (high): find a sensible way to write data here on setup
|
||||
private static $gtCombatRatings = array(
|
||||
12 => 1.5, 13 => 13.8, 14 => 13.8, 15 => 5, 16 => 10, 17 => 10, 18 => 8, 19 => 14, 20 => 14,
|
||||
21 => 14, 22 => 10, 23 => 10, 24 => 8, 25 => 0, 26 => 0, 27 => 0, 28 => 10, 29 => 10,
|
||||
30 => 10, 31 => 10, 32 => 14, 33 => 0, 34 => 0, 35 => 28.75, 36 => 10, 37 => 2.5, 44 => 4.268292513760655
|
||||
);
|
||||
|
||||
public static $ssdMaskFields = array(
|
||||
'shoulderMultiplier', 'trinketMultiplier', 'weaponMultiplier', 'primBudged',
|
||||
'rangedMultiplier', 'clothShoulderArmor', 'leatherShoulderArmor', 'mailShoulderArmor',
|
||||
@@ -917,12 +910,13 @@ abstract class Util
|
||||
}
|
||||
|
||||
// for item and spells
|
||||
public static function setRatingLevel(int $level, int $type, int $val) : string
|
||||
public static function setRatingLevel(int $level, int $statId, int $val) : string
|
||||
{
|
||||
if (in_array($type, [ITEM_MOD_DEFENSE_SKILL_RATING, ITEM_MOD_DODGE_RATING, ITEM_MOD_PARRY_RATING, ITEM_MOD_BLOCK_RATING, ITEM_MOD_RESILIENCE_RATING]) && $level < 34)
|
||||
if (in_array($statId, [Stat::DEFENSE_RTG, Stat::DODGE_RTG, Stat::PARRY_RTG, Stat::BLOCK_RTG, Stat::RESILIENCE_RTG]) && $level < 34)
|
||||
$level = 34;
|
||||
|
||||
if (!isset(self::$gtCombatRatings[$type]))
|
||||
$factor = Stat::getRatingPctFactor($statId);
|
||||
if (!$factor)
|
||||
$result = 0;
|
||||
else
|
||||
{
|
||||
@@ -936,13 +930,13 @@ abstract class Util
|
||||
$c = 2 / 52;
|
||||
|
||||
// do not use localized number format here!
|
||||
$result = number_format($val / self::$gtCombatRatings[$type] / $c, 2);
|
||||
$result = number_format($val / $factor / $c, 2);
|
||||
}
|
||||
|
||||
if (!in_array($type, array(ITEM_MOD_DEFENSE_SKILL_RATING, ITEM_MOD_EXPERTISE_RATING)))
|
||||
if (!in_array($statId, [Stat::DEFENSE_RTG, Stat::EXPERTISE_RTG]))
|
||||
$result .= '%';
|
||||
|
||||
return Lang::item('ratingString', [$type, $result, $level]);
|
||||
return Lang::item('ratingString', [$statId, $result, $level]);
|
||||
}
|
||||
|
||||
public static function powerUseLocale($domain = 'www')
|
||||
|
||||
@@ -1801,7 +1801,7 @@ $lang = array(
|
||||
'block' => "%s Blocken",
|
||||
'charges' => "%d |4Aufladung:Aufladungen;",
|
||||
'locked' => "Verschlossen",
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$.2F%% @ Lvl<!--lvl-->%3$d',
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$s @ Lvl<!--lvl-->%3$d',
|
||||
'heroic' => "Heroisch",
|
||||
'startQuest' => "Dieser Gegenstand startet eine Quest",
|
||||
'bagSlotString' => '%1$d Platz %2$s',
|
||||
|
||||
@@ -1801,7 +1801,7 @@ $lang = array(
|
||||
'block' => "%s Block", // SHIELD_BLOCK_TEMPLATE
|
||||
'charges' => "%d |4Charge:Charges;", // ITEM_SPELL_CHARGES
|
||||
'locked' => "Locked", // LOCKED
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$.2F%% @ L<!--lvl-->%3$d',
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$s @ L<!--lvl-->%3$d',
|
||||
'heroic' => "Heroic", // ITEM_HEROIC
|
||||
'startQuest' => "This Item Begins a Quest", // ITEM_STARTS_QUEST
|
||||
'bagSlotString' => "%d Slot %s", // CONTAINER_SLOTS
|
||||
|
||||
@@ -1801,7 +1801,7 @@ $lang = array(
|
||||
'block' => "%s bloqueo",
|
||||
'charges' => "%d |4carga:cargas;",
|
||||
'locked' => "Cerrado",
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$.2F%% @ L<!--lvl-->%3$d',
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$s @ L<!--lvl-->%3$d',
|
||||
'heroic' => "Heroico",
|
||||
'startQuest' => "Este objeto inicia una misión",
|
||||
'bagSlotString' => '%2$s de %1$d casillas',
|
||||
|
||||
@@ -1801,7 +1801,7 @@ $lang = array(
|
||||
'block' => "Bloquer : %s",
|
||||
'charges' => "%d |4charge:charges;",
|
||||
'locked' => "Verrouillé",
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$.2F%% au niveau <!--lvl-->%3$d',
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$s au niveau <!--lvl-->%3$d',
|
||||
'heroic' => "Héroïque",
|
||||
'startQuest' => "Cet objet permet de lancer une quête",
|
||||
'bagSlotString' => '%2$s %1$d |4emplacement:emplacements;',
|
||||
|
||||
@@ -1801,7 +1801,7 @@ $lang = array(
|
||||
'block' => "Блок: %s",
|
||||
'charges' => "%d |4заряд:заряда:зарядов;",
|
||||
'locked' => "Заперто",
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$.2F%% на <!--lvl-->%3$d ур.',
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$s на <!--lvl-->%3$d ур.',
|
||||
'heroic' => "Героический",
|
||||
'startQuest' => "Этот предмет позволяет получить задание.",
|
||||
'bagSlotString' => '%2$s (%1$d |4ячейка:ячейки:ячеек;)',
|
||||
|
||||
@@ -1800,7 +1800,7 @@ $lang = array(
|
||||
'block' => "%d格挡",
|
||||
'charges' => "%d次",
|
||||
'locked' => "已锁",
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$.2F%% @ Lvl<!--lvl-->%3$d',
|
||||
'ratingString' => '<!--rtg%%%1$d-->%2$s @ Lvl<!--lvl-->%3$d',
|
||||
'heroic' => "英雄级别",
|
||||
'startQuest' => "该物品将触发一个任务",
|
||||
'bagSlotString' => "%d格%s",
|
||||
|
||||
Reference in New Issue
Block a user