140 lines
6.7 KiB
Lua
140 lines
6.7 KiB
Lua
-- DopingControl data/resist.lua
|
|
-- Resistance-reconstruction tables for the RESIST tab: what GEAR tooltips
|
|
-- and RACE grant, mirroring data/hit.lua's split for the HIT tab (patterns
|
|
-- + constants here, the pure parser in scan/resist.lua).
|
|
--
|
|
-- WHY RECONSTRUCTION (measured, not assumed -- see scan/hit.lua's header
|
|
-- for the full story): the server does not transmit
|
|
-- UNIT_FIELD_RESISTANCES for foreign players at all (Player::
|
|
-- InitVisibleBits() never sets the bit for anyone but the owning client),
|
|
-- so UnitResistance/GetUnitField can NEVER answer for a foreign unit --
|
|
-- this is not a corner case scan/engine.lua's three read paths occasionally
|
|
-- miss, it is the only path that can ever ANSWER for one. The equipped
|
|
-- items' tooltips are readable for foreign units in range
|
|
-- (GameTooltip:SetInventoryItem), exactly like the HIT tab's +hit lines,
|
|
-- so the total is rebuilt from the same source: item stat text, plus the
|
|
-- racial bonus below (which no tooltip ever states).
|
|
--
|
|
-- DC.RESIST_SCHOOLS -- the five schools that carry a resistance stat, in
|
|
-- TOOLTIP capitalization ("Fire Resistance"), paired with the
|
|
-- UnitResistance() school index used throughout the addon (core/const.lua
|
|
-- DC.SLOTS_RESIST: 2 fire / 3 nature / 4 frost / 5 shadow / 6 arcane; 0
|
|
-- physical and 1 holy are never queried -- there is no "Holy Resistance"
|
|
-- item stat in 1.12, which is also why this list has no sixth entry).
|
|
-- Kept in sync with DC.SLOTS_RESIST BY HAND (self-contained, like
|
|
-- DC.HIT_SCHOOLS/DC.SLOTS_HIT in data/hit.lua and core/const.lua) --
|
|
-- test_resist.lua pins the two against each other so they cannot drift
|
|
-- apart silently.
|
|
DopingControl = DopingControl or {}
|
|
local DC = DopingControl
|
|
|
|
DC.RESIST_SCHOOLS = {
|
|
{ name = "Fire", school = 2 },
|
|
{ name = "Nature", school = 3 },
|
|
{ name = "Frost", school = 4 },
|
|
{ name = "Shadow", school = 5 },
|
|
{ name = "Arcane", school = 6 },
|
|
}
|
|
|
|
-- DC.RESIST_SCHOOL_NUM -- tooltip school name -> UnitResistance() index,
|
|
-- GENERATED from DC.RESIST_SCHOOLS so the two tables cannot drift apart
|
|
-- (same idea as DC.HIT_SCHOOL_KEY in data/hit.lua).
|
|
DC.RESIST_SCHOOL_NUM = {}
|
|
for i = 1, table.getn(DC.RESIST_SCHOOLS) do
|
|
local e = DC.RESIST_SCHOOLS[i]
|
|
DC.RESIST_SCHOOL_NUM[e.name] = e.school
|
|
end
|
|
|
|
-- ------------------------------------------------------------------
|
|
-- DC.RESIST_PATTERNS -- ARRAY (order matters, FIRST MATCH WINS), each
|
|
-- entry { pattern = <Lua 5.0 string.find pattern with ONE numeric
|
|
-- capture>, kind = <school name> | "all" }.
|
|
--
|
|
-- Measured tooltip forms (2026-08-02, own-character tooltip, English
|
|
-- client):
|
|
-- "+10 Arcane Resistance" -- PLAIN stat line, no "Equip:"
|
|
-- "+10 Fire Resistance" -- (item base stats print this way,
|
|
-- "+10 Nature Resistance" -- unlike +hit which is always an
|
|
-- "+1 Fire Resistance" -- "Equip:" trigger line)
|
|
-- "Equip: +8 All Resistances." -- multi-school EQUIP trigger --
|
|
-- applies to ALL FIVE schools at
|
|
-- once; a parser keyed on the five
|
|
-- single-school patterns alone would
|
|
-- silently miss this line entirely
|
|
-- (the trap this table exists to
|
|
-- close, see scan/resist.lua
|
|
-- R.SumLines).
|
|
--
|
|
-- Both anchored at the LINE START (^): a stat line is the line's entire
|
|
-- content on this client, so anchoring guards against a flavor-text
|
|
-- sentence that happens to contain "Fire Resistance" mid-phrase. No
|
|
-- trailing anchor: the plain form has nothing after the number+word (WoW
|
|
-- classic tooltip text is fixed, so this cannot mismatch), and the Equip
|
|
-- form is allowed to keep trailing punctuation.
|
|
--
|
|
-- Extension point (mirrors DC.HIT_PATTERNS): a phrasing not listed here is
|
|
-- SILENTLY IGNORED, never guessed at. An "Equip: +N <School> Resistance."
|
|
-- single-school equip form is conceivable on this server but UNMEASURED --
|
|
-- it is deliberately absent until someone reads it off a real tooltip.
|
|
-- ------------------------------------------------------------------
|
|
DC.RESIST_PATTERNS = {}
|
|
for i = 1, table.getn(DC.RESIST_SCHOOLS) do
|
|
local e = DC.RESIST_SCHOOLS[i]
|
|
table.insert(DC.RESIST_PATTERNS, {
|
|
pattern = "^%+(%d+) " .. e.name .. " Resistance",
|
|
kind = e.name,
|
|
})
|
|
end
|
|
table.insert(DC.RESIST_PATTERNS, {
|
|
pattern = "^Equip: %+(%d+) All Resistances",
|
|
kind = "all",
|
|
})
|
|
|
|
-- ------------------------------------------------------------------
|
|
-- DC.RACE_RESIST -- race -> { [UnitResistance school index] = bonus }.
|
|
-- INNATE racial resistance, granted by the race itself rather than any
|
|
-- item -- invisible to a tooltip scan, so it has to be added on top of the
|
|
-- gear sum by hand (scan/engine.lua's E.AssembleResists gear-fallback
|
|
-- path) or the reconstructed total would silently understate every member
|
|
-- of these five races by exactly this amount.
|
|
--
|
|
-- Keys: BOTH spellings for every race that has a bonus (display name and
|
|
-- file token), same reasoning as DC.RACE_WEAPON_SKILL in data/hit.lua --
|
|
-- scan/hit.lua's H.ReadUnit stores `token or display` as the race passed
|
|
-- through the store, so either spelling must resolve. Aliases point at the
|
|
-- SAME table (never a separate copy), so a race can never end up counted
|
|
-- with two different bonus tables that could drift apart.
|
|
--
|
|
-- Verified racial resistances (task brief, 2026-08-02):
|
|
-- Dwarf +10 Frost
|
|
-- Gnome +10 Arcane
|
|
-- Night Elf +10 Nature
|
|
-- Tauren +10 Nature
|
|
-- Undead/Forsaken +10 Shadow
|
|
-- Human, Orc, Troll: none
|
|
--
|
|
-- WARNING -- NOT COVERED: TurtleWoW's two extra playable races, Goblin and
|
|
-- High Elf/Blood Elf. Their racial resistance (if they even have one) is
|
|
-- UNKNOWN -- it is not guessed here. Both are simply ABSENT from this
|
|
-- table, which is safe by construction: DC_Resist.RaceBonus (scan/
|
|
-- resist.lua) returns an empty bonus table for any race it does not
|
|
-- recognize, exactly the same degrade an unlisted/future race token gets.
|
|
-- Do not "fix" this by inventing a number -- add the real one once it is
|
|
-- measured, the same way the five below were.
|
|
-- ------------------------------------------------------------------
|
|
local DWARF_RESIST = { [4] = 10 } -- frost
|
|
local GNOME_RESIST = { [6] = 10 } -- arcane
|
|
local NIGHTELF_RESIST = { [3] = 10 } -- nature
|
|
local TAUREN_RESIST = { [3] = 10 } -- nature
|
|
local UNDEAD_RESIST = { [5] = 10 } -- shadow
|
|
|
|
DC.RACE_RESIST = {
|
|
["Dwarf"] = DWARF_RESIST,
|
|
["Gnome"] = GNOME_RESIST,
|
|
["Night Elf"] = NIGHTELF_RESIST,
|
|
["NightElf"] = NIGHTELF_RESIST,
|
|
["Tauren"] = TAUREN_RESIST,
|
|
["Undead"] = UNDEAD_RESIST,
|
|
["Scourge"] = UNDEAD_RESIST,
|
|
}
|