-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClasses.lua
More file actions
199 lines (177 loc) · 8.72 KB
/
Copy pathClasses.lua
File metadata and controls
199 lines (177 loc) · 8.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
local addonName, ns = ...
-- Target total avoidance vs a +3 raid boss, compared against the sum of
-- character-sheet avoidance values (Miss + Dodge + Parry + Block). The
-- 2.4% above 100 already absorbs the four 0.04%-per-skill-deficit
-- penalties the server applies at combat-roll time (0.2% × 3 levels = 0.6%
-- per component × 4 components = 2.4%). In other words: sum the raw sheet
-- values, compare against 102.4, do not subtract anything beforehand.
-- See docs/adr/0003 postscript for the derivation and peer-addon
-- corroboration (AvoidanceRating, AvoidanceStatsTBC, Unbreakable Paladin,
-- CharacterStatsTBC, and the "Libram of Protection" top-ranker guide).
ns.TARGET_CAP = 102.4
-- Base chance to be missed by a same-level attacker. Used as-is in the
-- Miss component — the 102.4% target handles the +3 boss adjustment
-- implicitly, so we do NOT subtract per-level shift here.
ns.BASE_MISS = 5.0
-- Boss crit chance vs a +3 raid boss when the player is at the 350 defense
-- skill floor: 5% base + (15 weapon-skill diff × 0.04%) = 5.6%. The
-- anti-crit cap is reaching this number in total reduction via the three
-- additive sources tracked by ns.calc.computeAntiCrit:
-- 1. Defense skill above 350 → 0.04% per point
-- 2. Resilience rating (lvl 70) → ~1% per 39.4 rating
-- 3. Class talents → only Survival of the Fittest (druid) -3%
-- See docs/adr/0004 for the math and the TBC-vs-WotLK note on Resilience
-- applying vs PvE in 2.5.5.
ns.BOSS_CRIT_VS_PLUS3 = 5.6
-- Druid Survival of the Fittest: -3% melee crit chance taken. Passive,
-- always-on for any druid that has it talented. Assumed talented for any
-- druid that opens this addon — feral tanks without SotF maxed aren't
-- tanking raids, so the assumption holds in practice. Not gated via
-- GetTalentInfo to avoid unnecessary API chatter.
ns.SOTF_CRIT_REDUCTION = 3.0
-- WoW combat-rating index for Resilience (the stat that reduces crit
-- chance taken from any source in TBC). The named global has shifted
-- across clients:
-- - TBC 2.4 retail: CR_CRIT_TAKEN_MELEE (with _RANGED/_SPELL siblings
-- that all returned the same rating).
-- - TBC Anniversary 2.5.5: CR_RESILIENCE_PLAYER_DAMAGE_TAKEN — the
-- three sub-ratings collapsed into one named constant (index 16 in
-- this client; index 15 still works as an alias for backward compat,
-- but the old name `CR_CRIT_TAKEN_MELEE` is not exposed).
-- We chain the names so the addon stays portable across patches without
-- hardcoding a numeric index — those have drifted historically (14/15/16)
-- and even within a single client multiple indices can alias the same
-- rating. The global by name is the stable contract.
-- GetCombatRatingBonus(idx) returns the percentage already converted from
-- rating, so callers don't need to apply the ~39.4-rating-per-1% factor.
ns.CR_RESILIENCE = _G.CR_RESILIENCE_PLAYER_DAMAGE_TAKEN
or _G.CR_CRIT_TAKEN_MELEE
-- Defense Rating → Defense Skill conversion at level 70. Used to simulate
-- Flask of Fortification (which adds +10 Defense Rating, not raw skill).
-- 1 Defense Skill = 2.3654 Defense Rating → 1 Defense Rating = ~0.4228 skill
ns.DEFENSE_RATING_PER_SKILL = 2.3654
-- Libram of Repentance (paladin, ranged/libram slot). Grants +42 block
-- rating while Holy Shield is active — equivalent to ~5.326% block chance
-- at level 70 (42 / 7.8846 block-rating-per-1%-block). GetBlockChance
-- already includes this while HS is up, so we only need to add it to the
-- Holy Shield planned-delta when the libram is equipped and HS is being
-- simulated rather than actually active. Verified against wowhead TBC and
-- the Unbreakable Paladin addon's hardcoded 5.326455… constant.
ns.LIBRAM_OF_REPENTANCE_ITEM_ID = 29388
ns.LIBRAM_OF_REPENTANCE_BLOCK_DELTA = 5.326
-- Agility points required for 1% Dodge at level 70, per class. Cross-checked
-- against magey/tbc-warrior wiki, wowhead TBC tank guides, and
-- warcraft.wiki.gg on 2026-04-22. Druid in Bear form uses the base druid
-- agi→dodge value (Heart of the Wild does NOT modify this ratio; it scales
-- STR/STA in bear form but dodge-per-agi stays at the druid baseline).
ns.AGI_PER_DODGE_PCT = {
WARRIOR = 30.0,
PALADIN = 25.0,
DRUID = 14.7,
SHAMAN = 25.0,
HUNTER = 26.0,
ROGUE = 14.5,
PRIEST = 20.0,
MAGE = 20.0,
WARLOCK = 20.0,
}
ns.DEFAULT_AGI_PER_DODGE_PCT = 20.0
-- Class display labels. Every TBC-era class is listed so the snapshot
-- prints a clean name for any character — `mode` is NOT stored here
-- because it's determined at runtime from equipment (shield) and form.
ns.classInfo = {
WARRIOR = { label = "Warrior" },
PALADIN = { label = "Paladin" },
DRUID = { label = "Druid" },
HUNTER = { label = "Hunter" },
ROGUE = { label = "Rogue" },
PRIEST = { label = "Priest" },
SHAMAN = { label = "Shaman" },
MAGE = { label = "Mage" },
WARLOCK = { label = "Warlock" },
}
-- spellId → tracked aura key. Multiple spellIds map to the same key so the
-- aura survives rank changes (e.g. Blessing of Kings base vs the Greater
-- Blessing variant cast from a Symbol of Kings reagent).
--
-- Each entry carries `category` ("raid_buff" | "personal_cd") and an
-- optional `class` filter. Raid buffs come from external casters and apply
-- regardless of class; personal cooldowns are self-casts that only make
-- sense for the class that can use them (Holy Shield for paladins, Shield
-- Block for warriors).
--
-- Inclusion criterion for raid buffs is strict: every entry must have a
-- measurable effect on Miss / Dodge / Parry / Block % against a +3 boss.
-- Buffs that improve tank survival but don't touch the avoidance table
-- (Fortitude, Devotion Aura, Blessing of Sanctuary, armor-only consumables)
-- are intentionally out of scope — see docs/adr/0002.
ns.trackedAuras = {}
local function register(key, label, ids, opts)
opts = opts or {}
for _, id in ipairs(ids) do
ns.trackedAuras[id] = {
key = key,
label = label,
class = opts.class,
category = opts.category or "raid_buff",
}
end
end
-- +10% all stats → +Agi (dodge) and +Str (parry via class talents).
register("bok", "Blessing of Kings", { 20217, 25898 })
-- Flat +Stats → smaller version of BoK; affects the same avoidance paths.
register("motw", "Mark / Gift of the Wild",
{ 1126, 5232, 6756, 5234, 8907, 9884, 9885, 26990, 21849, 21850, 26991 })
-- +25 Agility → small but non-zero dodge bump. Competes with Elixir of
-- Major Agility for the "guardian" consumable slot; tanks sometimes pick
-- the scroll when cycling trash.
register("scrollAgility", "Scroll of Agility (V-VIII)",
{ 8115, 8116, 8117, 12174, 33077 })
-- +10 Defense Rating + 500 HP. The Defense is the standout: +0.4% to each
-- of miss, dodge, parry, block = +1.6% total avoidance. Single biggest
-- consumable impact on the uncrushable cap.
register("flaskFort", "Flask of Fortification", { 28518 })
-- +35 Agility + 20 Crit Rating. Agility path affects dodge; typically the
-- competitor to Flask of Fortification in the elixir/flask slot.
register("elixirMajorAgility", "Elixir of Major Agility", { 28497 })
-- Personal cooldowns — self-cast block-chance boosts. Class-gated by the
-- UI so the rows only appear for classes that can actually use them.
--
-- Holy Shield (paladin): +30% block chance for 10s, 4 charges, 10s CD —
-- the de-facto way paladins close the block gap to uncrush during combat.
-- TBC rank IDs 1-4 (rank 5 / 48952 is WotLK+).
register("holyShield", "Holy Shield", { 20925, 20927, 20928, 27179 },
{ class = "PALADIN", category = "personal_cd" })
-- Shield Block (warrior): +75% block chance for 5s, 5s CD. With Improved
-- Shield Block (Prot talent 4/4) uptime approaches 100% during tanking.
register("shieldBlock", "Shield Block", { 2565 },
{ class = "WARRIOR", category = "personal_cd" })
-- Display order — raid buffs (all classes see these).
ns.trackedAurasOrder = {
"bok",
"motw",
"flaskFort",
"elixirMajorAgility",
"scrollAgility",
}
-- Display order — personal cooldowns. The UI filters by class so each
-- player only sees the ones they can cast.
ns.personalCDsOrder = {
"holyShield",
"shieldBlock",
}
ns.trackedAurasLabels = {
bok = "Blessing of Kings",
motw = "Mark / Gift of the Wild",
flaskFort = "Flask of Fortification",
elixirMajorAgility = "Elixir of Major Agility",
scrollAgility = "Scroll of Agility",
holyShield = "Holy Shield",
shieldBlock = "Shield Block",
}
-- Class requirement for personal cooldowns. Keys not present here are
-- treated as "any class" (i.e. raid buffs).
ns.personalCDsClass = {
holyShield = "PALADIN",
shieldBlock = "WARRIOR",
}