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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
local REVISION = 3;if (type(ExScanner) == "table") and (ExScanner.vers and ExScanner.vers >= REVISION) thenreturn;end-- Examiner Scanner TableExScanner = ExScanner or {};ExScanner.vers = REVISION;ExScanner.ItemLinkPattern = "^.+|H(item:[^|]+)|h%[.+$";ExScanner.ItemUseToken = "^"..ITEM_SPELL_TRIGGER_ONUSE.." ";ExScanner.SetNamePattern = "^(.+) %((%d)/(%d)%)$";ExScanner.SetBonusTokenActive = "^"..ITEM_SET_BONUS:gsub("%%s","");ExScanner.MagicSchools = { "FIRE", "NATURE", "ARCANE", "FROST", "SHADOW", "HOLY" };ExScanner.Slots = {"HeadSlot", "NeckSlot", "ShoulderSlot", "BackSlot", "ChestSlot", "ShirtSlot", "TabardSlot", "WristSlot","HandsSlot", "WaistSlot", "LegsSlot", "FeetSlot", "Finger0Slot", "Finger1Slot", "Trinket0Slot", "Trinket1Slot","MainHandSlot", "SecondaryHandSlot", "RangedSlot",};ExScanner.SlotIDs = {};for _, slotName in ipairs(ExScanner.Slots) doExScanner.SlotIDs[slotName] = GetInventorySlotInfo(slotName);endExScanner.StatRatingBaseTable = {SPELLHASTE = 10,SPELLHIT = 8,SPELLCRIT = 14,HASTE = 10,HIT = 10,CRIT = 14,EXPERTISE = 2.5,DEFENSE = 1.5,DODGE = 13.8, -- Patch 3.2: Increased 15% from 12PARRY = 13.8, -- Patch 3.2: Reduced 8% from 15BLOCK = 5,RESILIENCE = 28.75, -- Patch 3.2: Increased 15% from 25ARMORPENETRATION = 4.69512176513672 / 1.25 * 1.12, -- Patch 3.1 Quote: "All classes now receive 25% more benefit from Armor Penetration Rating."-- Patch 3.2.2 Quote: "The amount of armor penetration gained per point of this rating has been reduced by 12%."};-- FAN EDIT: PvP Item Sets + their statsExScanner.PvPItemSets = {SPELLPOWER = {},AP = {}};ExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Refuge"] = true; -- Druid RestoExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Wildhide"] = true; -- Druid BalanceExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Regalia"] = true; -- MageExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Redemption"] = true; -- Paladin HolyExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Investiture"] = true; -- Priest HealExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Raiment"] = true; -- Priest ShadowExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Thunderfist"] = true; -- Shaman EleExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Wartide"] = true; -- Shaman RestoExScanner.PvPItemSets["SPELLPOWER"]["Gladiator's Felshroud"] = true; -- WarlockExScanner.PvPItemSets["AP"]["Gladiator's Desecration"] = true; -- Death KnightExScanner.PvPItemSets["AP"]["Gladiator's Sanctuary"] = true; -- Druid FeralExScanner.PvPItemSets["AP"]["Gladiator's Pursuit"] = true; -- HunterExScanner.PvPItemSets["AP"]["Gladiator's Vindication"] = true; -- Paladin RetriExScanner.PvPItemSets["AP"]["Gladiator's Vestments"] = true; -- RogueExScanner.PvPItemSets["AP"]["Gladiator's Earthshaker"] = true; -- Shaman EnhExScanner.PvPItemSets["AP"]["Gladiator's Battlegear"] = true; -- Warrior-- end FAN EDIT;-- ItemSlotValues Tables-- Legendary items uses the same values as epics.-- Heirloom items uses the same values as rares, although this is not entirely correct, and is messed up anyway, since their itemlevel is one.-- White and Grey items uses a factor of one, which is totally wrong, but I have no idea what a real number for those qualities would be.ExScanner.RarityFactor = { [0] = 1, [1] = 1, [2] = 2, [3] = 1.8, [4] = 1.2, [5] = 1.2, [6] = 1, [7] = 1.8 };ExScanner.RaritySubtract = { [0] = 0, [1] = 0, [2] = 8, [3] = 0.75, [4] = 26, [5] = 26, [6] = 0, [7] = 0.75 };ExScanner.Tip = ExScanner.Tip or CreateFrame("GameTooltip","ExScannerTip",nil,"GameTooltipTemplate");ExScanner.Tip:SetOwner(UIParent,"ANCHOR_NONE");-- Used in ScanUnitItemslocal scannedSetNames = {};---------------------------------------------------------------------------------------------------------- Scan all items and set bonuses on given 'unit' (Make sure the tables are reset) ----------------------------------------------------------------------------------------------------------function ExScanner:ScanUnitItems(unit,statTable,setTable)if (not unit) or (not UnitExists(unit)) thenreturn;end-- Check all item slotsfor _, slotName in ipairs(self.Slots) do-- Set New Item Tipself.Tip:ClearLines();self.Tip:SetInventoryItem(unit,GetInventorySlotInfo(slotName));local lastSetName;local lastBonusCount = 1;-- Check Linesfor i = 2, self.Tip:NumLines() doif (self:DoLineNeedScan(_G["ExScannerTipTextLeft"..i],true)) then-- We use "setMax" to check if the Line was a SetNamePattern (WTB continue statement in Lua)local setName, setCount, setMax;-- Set Header (Only run this if we haven't found a set on this item yet)if (not lastSetName) thensetName, setCount, setMax = self.text:match(self.SetNamePattern);if (setMax) and (not setTable[setName]) thensetTable[setName] = { count = tonumber(setCount), max = tonumber(setMax) };-- FAN EDIT: count PvP set stat bonusesif ((ExScanner.PvPItemSets["AP"][setName]) and (tonumber(setCount) >= 2)) thenstatTable["RESILIENCE"] = statTable["RESILIENCE"] + 100;statTable["AP"] = statTable["AP"] + 50;if (tonumber(setCount) >= 4) thenstatTable["AP"] = statTable["AP"] + 150;endendif ((ExScanner.PvPItemSets["SPELLPOWER"][setName]) and (tonumber(setCount) >= 2)) thenstatTable["RESILIENCE"] = statTable["RESILIENCE"] + 100;statTable["HEAL"] = statTable["HEAL"] + 29;statTable["SPELLDMG"] = statTable["SPELLDMG"] + 29;if (tonumber(setCount) >= 4) thenstatTable["HEAL"] = statTable["HEAL"] + 88;statTable["SPELLDMG"] = statTable["SPELLDMG"] + 88;endend-- end FAN EDIT;-- Mark this set as scanned, if any foundscannedSetNames[setName] = true;lastSetName = setName;--continue :(endend-- Check Line for Patterns if this Line was not a SetNamePatternif (not setMax) thenif (self.text:find(self.SetBonusTokenActive)) then-- Skip set bonues we have already includedif (lastSetName) and (not scannedSetNames[lastSetName]) thenself:ScanLineForPatterns(self.text,statTable);setTable[lastSetName]["setBonus"..lastBonusCount] = self.text;lastBonusCount = (lastBonusCount + 1);endelseself:ScanLineForPatterns(self.text,statTable);endendendendend-- Cleanupwipe(scannedSetNames);end---------------------------------------------------------------------------------------------------------- Scans a single item given by 'itemLink', stats are added to the 'statTable' variable ----------------------------------------------------------------------------------------------------------function ExScanner:ScanItemLink(itemLink,statTable)if (itemLink) then-- Set Linkself.Tip:ClearLines();self.Tip:SetHyperlink(itemLink);-- Check Linesfor i = 2, self.Tip:NumLines() doif (self:DoLineNeedScan(_G["ExScannerTipTextLeft"..i],false)) thenself:ScanLineForPatterns(self.text,statTable);endendendend---------------------------------------------------------------------------------------------------------- Checks if a Line Needs to be Scanned for Patterns ----------------------------------------------------------------------------------------------------------function ExScanner:DoLineNeedScan(tipLine,scanSetBonuses)-- Init Linelocal text = tipLine:GetText();local color = text:match("^(|c%x%x%x%x%x%x%x%x)");text = text:gsub("|c%x%x%x%x%x%x%x%x","");self.text = text;local r, g, b = tipLine:GetTextColor();r, g, b = ceil(r * 255), ceil(g * 255), ceil(b * 255);-- Always *Skip* Gray Linesif (r == 128 and g == 128 and b == 128) or (color == "|cff808080") thenreturn;-- Active Set Bonuses (Must be checked before green color check)elseif (not scanSetBonuses and text:find(self.SetBonusTokenActive)) thenreturn;-- Skip "Use:" lines, they are not a permanent stat, so don't include themelseif (text:find(self.ItemUseToken)) thenreturn;-- Always *Scan* Green Lineselseif (r == 0 and g == 255 and b == 0) or (color == "|cff00ff00") thenreturn 1;-- Should Match: Normal +Stat, Base Item Armor, Block Value on Shieldselseif (text:find("^[+-]?%d+ [^%d]")) thenreturn 1;-- Set Names (Needed to Check Sets)elseif (scanSetBonuses and text:find(self.SetNamePattern)) thenreturn 1;endreturn;end---------------------------------------------------------------------------------------------------------- Checks a Single Line for Patterns ----------------------------------------------------------------------------------------------------------function ExScanner:ScanLineForPatterns(text,statTable)for _, pattern in ipairs(self.Patterns) dolocal pos, _, value1, value2 = text:find(pattern.p);if (pos) and (value1 or pattern.v) thenif (type(pattern.s) == "string") thenstatTable[pattern.s] = (statTable[pattern.s] or 0) + (value1 or pattern.v);elseif (type(pattern.s) == "table") thenfor statIndex, statName in ipairs(pattern.s) doif (type(pattern.v) == "table") thenstatTable[statName] = (statTable[statName] or 0) + (pattern.v[statIndex]);-- Az: This is a bit messy, only supports 2 now, needs to make it dynamic and support as many extra values as possibleelseif (statIndex == 2) and (value2) thenstatTable[statName] = (statTable[statName] or 0) + (value2);elsestatTable[statName] = (statTable[statName] or 0) + (value1 or pattern.v);endendendendendend---------------------------------------------------------------------------------------------------------- Convert Rating to Percent http://www.wowwiki.com/Combat_Rating_System ----------------------------------------------------------------------------------------------------------function ExScanner:GetRatingInPercent(stat,rating,level,class)local base = self.StatRatingBaseTable[stat];-- Check Valid Inputif (not base or not rating or not level) thenreturn;end-- Patch 3.1 Quote: "shamans, paladins, druids, and death knights now receive 30% more melee haste from Haste Rating."if (class and stat == "HASTE") and (class == "PALADIN" or class == "SHAMAN" or class == "DEATHKNIGHT" or class == "DRUID") thenbase = (base / 1.3);end-- Calc Depending on Levelif (level >= 70) thenreturn rating / base / (82 / 52 * (131 / 63) ^ ((level - 70) / 10));elseif (level >= 60) thenreturn rating / base / (82 / (262 - 3 * level));elsereturn rating / base / ((level > 10 and level - 8 or 2) / 52);endend---------------------------------------------------------------------------------------------------------- Slot Value Calculation ----------------------------------------------------------------------------------------------------------function ExScanner:CalculateItemSlotValue(itemLink)local _, _, itemRarity, itemLevel = GetItemInfo(itemLink);return (itemLevel - self.RaritySubtract[itemRarity]) / self.RarityFactor[itemRarity];end
Enjoy the site? Donations are helpful - even just $1