vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[ |
2 | |||
3 | LootLink 3.5: An in-game item database |
||
4 | copyright 2004 by Telo |
||
5 | |||
6 | - Watches all chat links you see to cache link color and link data |
||
7 | - Automatically extracts data from items already in or added to your inventory |
||
8 | - Automatically caches link data from items already in or added to your bank |
||
9 | - Automatically inspects your target and extracts data for each of their equipped items |
||
10 | - Automatically gets link data from your auction queries |
||
11 | - Can perform a fully automatic scan of the entire auction house inventory |
||
12 | - Stores sell prices for items that you've had in inventory when you've talked to a merchant |
||
13 | and displays them in the tooltips for stacks of items that you are looting, stacks of items |
||
14 | in your inventory and entries in the LootLink browse window |
||
15 | - Converts green loot messages into correctly colored item messages if the item is cached |
||
16 | - Provides a browsable, searchable window that allows you to find any item in the cache |
||
17 | - Allows you to shift-click items in the browse window to insert links in the chat edit box |
||
18 | |||
19 | ]] |
||
20 | |||
21 | -------------------------------------------------------------------------------------------------- |
||
22 | -- Local LootLink variables |
||
23 | -------------------------------------------------------------------------------------------------- |
||
24 | |||
25 | -- Function hooks |
||
26 | local lOriginal_CanSendAuctionQuery; |
||
27 | local lOriginal_AuctionFrameBrowse_OnEvent; |
||
28 | local lOriginal_ContainerFrameItemButton_OnEnter; |
||
29 | local lOriginal_ContainerFrame_Update; |
||
30 | local lOriginal_GameTooltip_SetLootItem; |
||
31 | local lOriginal_GameTooltip_SetOwner; |
||
32 | local lOriginal_GameTooltip_OnHide; |
||
33 | local lOriginal_GameTooltip_ClearMoney; |
||
34 | local lOriginal_GameTooltip_ClearMoney_Temp; |
||
35 | local lOriginal_ShoppingTooltip1_SetMerchantCompareItem; |
||
36 | local lOriginal_ShoppingTooltip2_SetMerchantCompareItem; |
||
37 | local lOriginal_ShoppingTooltip1_SetAuctionCompareItem; |
||
38 | local lOriginal_ShoppingTooltip2_SetAuctionCompareItem; |
||
39 | local lOriginal_SetItemRef; |
||
40 | local lOriginal_OnTooltipAddMoney; |
||
41 | |||
42 | --local ll = {}; |
||
43 | |||
44 | -- If non-nil, kick off a full auction scan next time auctioneer is used |
||
45 | local lScanAuction; |
||
46 | |||
47 | -- Used for scanning inventory items for their sell prices at a merchant |
||
48 | local lBagID; |
||
49 | local lSlotID; |
||
50 | |||
51 | -- If non-nil, don't add extra information to the tooltip on GameTooltip_ClearMoney |
||
52 | local lSuppressInfoAdd; |
||
53 | |||
54 | -- If non-nil, check for appearance of GameTooltip for adding information |
||
55 | local lCheckTooltip; |
||
56 | |||
57 | -- Timer for frequency of tooltip checks |
||
58 | local lCheckTimer = 0; |
||
59 | |||
60 | -- The current owner of the GameTooltip |
||
61 | local lGameToolTipOwner; |
||
62 | |||
63 | -- Cache of auction item information |
||
64 | local lAuctionItemInfo; |
||
65 | |||
66 | -- Used to remember that confirmation is needed of irreversible commands |
||
67 | local lResetNeedsConfirm; |
||
68 | local lMakeHomeNeedsConfirm; |
||
69 | local lLightModeNeedsConfirm; |
||
70 | |||
71 | -- If non-nil, the data version upgrade reminder is not displayed on every /lootlink or /ll command |
||
72 | local lDisableVersionReminder; |
||
73 | |||
74 | -- The current server name and index |
||
75 | local lServer; |
||
76 | local lServerIndex; |
||
77 | |||
78 | -- The number of items in the database, total and for this server |
||
79 | local lItemLinksSizeTotal; |
||
80 | local lItemLinksSizeServer; |
||
81 | |||
82 | local STATE_NAME = 0; |
||
83 | local STATE_BOUND = 1; |
||
84 | local STATE_UNIQUE = 2; |
||
85 | local STATE_LOCATION = 3; |
||
86 | local STATE_TYPE = 4; |
||
87 | local STATE_DAMAGE = 5; |
||
88 | local STATE_DPS = 6; |
||
89 | local STATE_ARMOR = 7; |
||
90 | local STATE_BLOCK = 8; |
||
91 | local STATE_CONTAINER = 9; |
||
92 | local STATE_REQUIRES = 10; |
||
93 | local STATE_FINISH = 11; |
||
94 | local STATE_SPACE = 12 |
||
95 | local STATE_SET = 13; |
||
96 | |||
97 | local tooltipSpace = " "..string.char(10); |
||
98 | |||
99 | local BINDS_DOES_NOT_BIND = 0; |
||
100 | local BINDS_EQUIP = 1; |
||
101 | local BINDS_PICKUP = 2; |
||
102 | local BINDS_USED = 3; |
||
103 | |||
104 | local TYPE_ARMOR = 0; |
||
105 | local TYPE_WEAPON = 1; |
||
106 | local TYPE_SHIELD = 2; |
||
107 | local TYPE_RECIPE = 3; |
||
108 | local TYPE_CONTAINER = 4; |
||
109 | local TYPE_MISC = 5; |
||
110 | |||
111 | local SUBTYPE_ARMOR_CLOTH = 0; |
||
112 | local SUBTYPE_ARMOR_LEATHER = 1; |
||
113 | local SUBTYPE_ARMOR_MAIL = 2; |
||
114 | local SUBTYPE_ARMOR_PLATE = 3; |
||
115 | local SUBTYPE_ARMOR_RELIC = 4; |
||
116 | |||
117 | local lColorSortTable = { }; |
||
118 | lColorSortTable["ffff8000"] = 1; -- legendary, orange |
||
119 | lColorSortTable["ffa335ee"] = 2; -- epic, purple |
||
120 | lColorSortTable["ff0070dd"] = 3; -- rare, blue |
||
121 | lColorSortTable["ff1eff00"] = 4; -- uncommon, green |
||
122 | lColorSortTable["ffffffff"] = 5; -- common, white |
||
123 | lColorSortTable["ff9d9d9d"] = 6; -- poor, gray |
||
124 | lColorSortTable["ff40ffc0"] = 100; -- unknown, teal |
||
125 | |||
126 | local ArmorSubtypes = { }; |
||
127 | ArmorSubtypes[CLOTH] = SUBTYPE_ARMOR_CLOTH; |
||
128 | ArmorSubtypes[LEATHER] = SUBTYPE_ARMOR_LEATHER; |
||
129 | ArmorSubtypes[MAIL] = SUBTYPE_ARMOR_MAIL; |
||
130 | ArmorSubtypes[PLATE] = SUBTYPE_ARMOR_PLATE; |
||
131 | ArmorSubtypes[INVTYPE_RELIC] = SUBTYPE_ARMOR_RELIC; |
||
132 | |||
133 | local SUBTYPE_WEAPON_AXE = 0; |
||
134 | local SUBTYPE_WEAPON_BOW = 1; |
||
135 | local SUBTYPE_WEAPON_DAGGER = 2; |
||
136 | local SUBTYPE_WEAPON_MACE = 3; |
||
137 | local SUBTYPE_WEAPON_FISHING_POLE = 4; |
||
138 | local SUBTYPE_WEAPON_STAFF = 5; |
||
139 | local SUBTYPE_WEAPON_SWORD = 6; |
||
140 | local SUBTYPE_WEAPON_GUN = 7; |
||
141 | local SUBTYPE_WEAPON_WAND = 8; |
||
142 | local SUBTYPE_WEAPON_THROWN = 9; |
||
143 | local SUBTYPE_WEAPON_POLEARM = 10; |
||
144 | local SUBTYPE_WEAPON_FIST_WEAPON = 11; |
||
145 | local SUBTYPE_WEAPON_CROSSBOW = 12; |
||
146 | |||
147 | local WeaponSubtypes = { }; |
||
148 | WeaponSubtypes[AXE] = SUBTYPE_WEAPON_AXE; |
||
149 | WeaponSubtypes[BOW] = SUBTYPE_WEAPON_BOW; |
||
150 | WeaponSubtypes[DAGGER] = SUBTYPE_WEAPON_DAGGER; |
||
151 | WeaponSubtypes[MACE] = SUBTYPE_WEAPON_MACE; |
||
152 | WeaponSubtypes[FISHING_POLE] = SUBTYPE_WEAPON_FISHING_POLE; |
||
153 | WeaponSubtypes[STAFF] = SUBTYPE_WEAPON_STAFF; |
||
154 | WeaponSubtypes[SWORD] = SUBTYPE_WEAPON_SWORD; |
||
155 | WeaponSubtypes[GUN] = SUBTYPE_WEAPON_GUN; |
||
156 | WeaponSubtypes[WAND] = SUBTYPE_WEAPON_WAND; |
||
157 | WeaponSubtypes[THROWN] = SUBTYPE_WEAPON_THROWN; |
||
158 | WeaponSubtypes[POLEARM] = SUBTYPE_WEAPON_POLEARM; |
||
159 | WeaponSubtypes[FIST_WEAPON] = SUBTYPE_WEAPON_FIST_WEAPON; |
||
160 | WeaponSubtypes[CROSSBOW] = SUBTYPE_WEAPON_CROSSBOW; |
||
161 | |||
162 | local SUBTYPE_SHIELD_BUCKLER = 0; |
||
163 | local SUBTYPE_SHIELD_SHIELD = 1; |
||
164 | |||
165 | local ShieldSubtypes = { }; |
||
166 | ShieldSubtypes["Buckler"] = SUBTYPE_SHIELD_BUCKLER; |
||
167 | ShieldSubtypes[SHIELD] = SUBTYPE_SHIELD_SHIELD; |
||
168 | |||
169 | local SUBTYPE_RECIPE_ALCHEMY = 0; |
||
170 | local SUBTYPE_RECIPE_BLACKSMITHING = 1; |
||
171 | local SUBTYPE_RECIPE_COOKING = 2; |
||
172 | local SUBTYPE_RECIPE_ENCHANTING = 3; |
||
173 | local SUBTYPE_RECIPE_ENGINEERING = 4; |
||
174 | local SUBTYPE_RECIPE_LEATHERWORKING = 5; |
||
175 | local SUBTYPE_RECIPE_TAILORING = 6; |
||
176 | local SUBTYPE_RECIPE_FIRST_AID = 7; |
||
177 | local SUBTYPE_RECIPE_FISHING = 8; |
||
178 | |||
179 | local RecipeSubtypes = { }; |
||
180 | RecipeSubtypes[ALCHEMY] = SUBTYPE_RECIPE_ALCHEMY; |
||
181 | RecipeSubtypes[BLACKSMITHING] = SUBTYPE_RECIPE_BLACKSMITHING; |
||
182 | RecipeSubtypes[COOKING] = SUBTYPE_RECIPE_COOKING; |
||
183 | RecipeSubtypes[ENCHANTING] = SUBTYPE_RECIPE_ENCHANTING; |
||
184 | RecipeSubtypes[ENGINEERING] = SUBTYPE_RECIPE_ENGINEERING; |
||
185 | RecipeSubtypes[LEATHERWORKING] = SUBTYPE_RECIPE_LEATHERWORKING; |
||
186 | RecipeSubtypes[TAILORING] = SUBTYPE_RECIPE_TAILORING; |
||
187 | RecipeSubtypes[FIRST_AID] = SUBTYPE_RECIPE_FIRST_AID; |
||
188 | RecipeSubtypes[FISHING] = SUBTYPE_RECIPE_FISHING; |
||
189 | |||
190 | local SUBTYPE_CONTAINER_BAG = 0; |
||
191 | local SUBTYPE_CONTAINER_AMMO_POUCH = 1; |
||
192 | local SUBTYPE_CONTAINER_QUIVER = 2; |
||
193 | local SUBTYPE_CONTAINER_SOUL_BAG = 3; |
||
194 | local SUBTYPE_CONTAINER_HERB_BAG = 4; |
||
195 | local SUBTYPE_CONTAINER_ENCHANTING_BAG = 5; |
||
196 | local SUBTYPE_CONTAINER_ENGINEERING_BAG = 6; |
||
197 | |||
198 | local ContainerSubtypes = { }; |
||
199 | ContainerSubtypes[BAG] = SUBTYPE_CONTAINER_BAG; |
||
200 | ContainerSubtypes[AMMO_POUCH] = SUBTYPE_CONTAINER_AMMO_POUCH; |
||
201 | ContainerSubtypes[QUIVER] = SUBTYPE_CONTAINER_QUIVER; |
||
202 | ContainerSubtypes[SOUL_BAG] = SUBTYPE_CONTAINER_SOUL_BAG; |
||
203 | ContainerSubtypes[HERB_BAG] = SUBTYPE_CONTAINER_HERB_BAG; |
||
204 | ContainerSubtypes[ENCHANTING_BAG] = SUBTYPE_CONTAINER_ENCHANTING_BAG; |
||
205 | ContainerSubtypes[ENGINEERING_BAG] = SUBTYPE_CONTAINER_ENGINEERING_BAG; |
||
206 | |||
207 | local lTypeAndSubtypeToSkill = { }; |
||
208 | lTypeAndSubtypeToSkill[TYPE_ARMOR] = { }; |
||
209 | lTypeAndSubtypeToSkill[TYPE_ARMOR][SUBTYPE_ARMOR_CLOTH] = CLOTH; |
||
210 | lTypeAndSubtypeToSkill[TYPE_ARMOR][SUBTYPE_ARMOR_LEATHER] = LEATHER; |
||
211 | lTypeAndSubtypeToSkill[TYPE_ARMOR][SUBTYPE_ARMOR_MAIL] = MAIL; |
||
212 | lTypeAndSubtypeToSkill[TYPE_ARMOR][SUBTYPE_ARMOR_PLATE] = PLATE_MAIL; |
||
213 | lTypeAndSubtypeToSkill[TYPE_ARMOR][SUBTYPE_ARMOR_RELIC] = INVTYPE_RELIC; |
||
214 | lTypeAndSubtypeToSkill[TYPE_WEAPON] = { }; |
||
215 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_AXE] = { } |
||
216 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_AXE][0] = AXES; |
||
217 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_AXE][1] = TWO_HANDED_AXES; |
||
218 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_BOW] = BOWS; |
||
219 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_DAGGER] = DAGGERS; |
||
220 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_MACE] = { } |
||
221 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_MACE][0] = MACES; |
||
222 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_MACE][1] = TWO_HANDED_MACES; |
||
223 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_FISHING_POLE] = FISHING_POLE; |
||
224 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_STAFF] = STAVES; |
||
225 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_SWORD] = { }; |
||
226 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_SWORD][0] = SWORDS; |
||
227 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_SWORD][1] = TWO_HANDED_SWORDS; |
||
228 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_GUN] = GUNS; |
||
229 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_WAND] = WANDS; |
||
230 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_THROWN] = THROWN; |
||
231 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_POLEARM] = POLEARMS; --@todo Telo: unconfirmed |
||
232 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_FIST_WEAPON] = UNARMED; |
||
233 | lTypeAndSubtypeToSkill[TYPE_WEAPON][SUBTYPE_WEAPON_CROSSBOW] = CROSSBOWS; |
||
234 | lTypeAndSubtypeToSkill[TYPE_SHIELD] = { }; |
||
235 | lTypeAndSubtypeToSkill[TYPE_SHIELD][SUBTYPE_SHIELD_BUCKLER] = SHIELD; --@todo Telo: deprecated subtype, should remove |
||
236 | lTypeAndSubtypeToSkill[TYPE_SHIELD][SUBTYPE_SHIELD_SHIELD] = SHIELD; |
||
237 | lTypeAndSubtypeToSkill[TYPE_RECIPE] = { }; |
||
238 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_ALCHEMY] = ALCHEMY; |
||
239 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_BLACKSMITHING] = BLACKSMITHING; |
||
240 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_COOKING] = COOKING; |
||
241 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_ENCHANTING] = ENCHANTING; |
||
242 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_ENGINEERING] = ENGINEERING; |
||
243 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_LEATHERWORKING] = LEATHERWORKING; |
||
244 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_TAILORING] = TAILORING; |
||
245 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_FIRST_AID] = FIRST_AID; |
||
246 | lTypeAndSubtypeToSkill[TYPE_RECIPE][SUBTYPE_RECIPE_FISHING] = FISHING; |
||
247 | lTypeAndSubtypeToSkill[TYPE_CONTAINER] = { }; |
||
248 | lTypeAndSubtypeToSkill[TYPE_CONTAINER][SUBTYPE_CONTAINER_BAG] = BAG; |
||
249 | lTypeAndSubtypeToSkill[TYPE_CONTAINER][SUBTYPE_CONTAINER_AMMO_POUCH] = AMMO_POUCH; |
||
250 | lTypeAndSubtypeToSkill[TYPE_CONTAINER][SUBTYPE_CONTAINER_QUIVER] = QUIVER; |
||
251 | lTypeAndSubtypeToSkill[TYPE_CONTAINER][SUBTYPE_CONTAINER_SOUL_BAG] = SOUL_BAG; |
||
252 | lTypeAndSubtypeToSkill[TYPE_CONTAINER][SUBTYPE_CONTAINER_ENCHANTING_BAG] = ENCHANTING_BAG; |
||
253 | |||
254 | local LocationTypes = { }; |
||
255 | LocationTypes[INVTYPE_HOLDABLE] = { i = 0, type = TYPE_MISC }; |
||
256 | LocationTypes[INVTYPE_CLOAK] = { i = 1, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
257 | LocationTypes[INVTYPE_WEAPON] = { i = 2, type = TYPE_WEAPON, subtypes = WeaponSubtypes }; |
||
258 | LocationTypes[INVTYPE_2HWEAPON] = { i = 3, type = TYPE_WEAPON, subtypes = WeaponSubtypes }; |
||
259 | LocationTypes[INVTYPE_WEAPONOFFHAND] = { i = 4, type = TYPE_SHIELD, subtypes = ShieldSubtypes }; |
||
260 | LocationTypes[INVTYPE_WRIST] = { i = 5, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
261 | LocationTypes[INVTYPE_CHEST] = { i = 6, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
262 | LocationTypes[INVTYPE_LEGS] = { i = 7, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
263 | LocationTypes[INVTYPE_FEET] = { i = 8, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
264 | LocationTypes[INVTYPE_BODY] = { i = 9, type = TYPE_MISC }; |
||
265 | LocationTypes[INVTYPE_RANGED] = { i = 10, type = TYPE_WEAPON, subtypes = WeaponSubtypes }; |
||
266 | LocationTypes[INVTYPE_WEAPONMAINHAND] = { i = 11, type = TYPE_WEAPON, subtypes = WeaponSubtypes }; |
||
267 | LocationTypes[INVTYPE_WAIST] = { i = 12, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
268 | LocationTypes[INVTYPE_HEAD] = { i = 13, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
269 | LocationTypes[GUN] = { i = 14, type = TYPE_WEAPON, subtype = SUBTYPE_WEAPON_GUN }; |
||
270 | LocationTypes[INVTYPE_FINGER] = { i = 15, type = TYPE_MISC }; |
||
271 | LocationTypes[INVTYPE_HAND] = { i = 16, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
272 | LocationTypes[INVTYPE_SHOULDER] = { i = 17, type = TYPE_ARMOR, subtypes = ArmorSubtypes }; |
||
273 | LocationTypes[WAND] = { i = 18, type = TYPE_WEAPON, subtype = SUBTYPE_WEAPON_WAND }; |
||
274 | LocationTypes[INVTYPE_TRINKET] = { i = 19, type = TYPE_MISC }; |
||
275 | LocationTypes[INVTYPE_TABARD] = { i = 20, type = TYPE_MISC }; |
||
276 | LocationTypes[INVTYPE_NECK] = { i = 21, type = TYPE_MISC }; |
||
277 | LocationTypes[THROWN] = { i = 22, type = TYPE_WEAPON, subtype = SUBTYPE_WEAPON_THROWN }; |
||
278 | LocationTypes[CROSSBOW] = { i = 23, type = TYPE_WEAPON, subtype = SUBTYPE_WEAPON_CROSSBOW }; |
||
279 | LocationTypes[INVTYPE_RELIC] = { i = 24, type = TYPE_ARMOR, subtype = SUBTYPE_ARMOR_RELIC }; |
||
280 | |||
281 | local INVENTORY_SLOT_LIST = { |
||
282 | { name = "HeadSlot" }, |
||
283 | { name = "NeckSlot" }, |
||
284 | { name = "ShoulderSlot" }, |
||
285 | { name = "BackSlot" }, |
||
286 | { name = "ChestSlot" }, |
||
287 | { name = "ShirtSlot" }, |
||
288 | { name = "TabardSlot" }, |
||
289 | { name = "WristSlot" }, |
||
290 | { name = "HandsSlot" }, |
||
291 | { name = "WaistSlot" }, |
||
292 | { name = "LegsSlot" }, |
||
293 | { name = "FeetSlot" }, |
||
294 | { name = "Finger0Slot" }, |
||
295 | { name = "Finger1Slot" }, |
||
296 | { name = "Trinket0Slot" }, |
||
297 | { name = "Trinket1Slot" }, |
||
298 | { name = "MainHandSlot" }, |
||
299 | { name = "SecondaryHandSlot" }, |
||
300 | { name = "RangedSlot" }, |
||
301 | }; |
||
302 | |||
303 | local ChatMessageTypes = { |
||
304 | "CHAT_MSG_SYSTEM", |
||
305 | "CHAT_MSG_SAY", |
||
306 | "CHAT_MSG_TEXT_EMOTE", |
||
307 | "CHAT_MSG_YELL", |
||
308 | "CHAT_MSG_WHISPER", |
||
309 | "CHAT_MSG_PARTY", |
||
310 | "CHAT_MSG_GUILD", |
||
311 | "CHAT_MSG_OFFICER", |
||
312 | "CHAT_MSG_CHANNEL", |
||
313 | "CHAT_MSG_RAID", |
||
314 | "CHAT_MSG_LOOT", |
||
315 | }; |
||
316 | |||
317 | local LOOTLINK_DROPDOWN_LIST = { |
||
318 | { name = SORT_NAME, sortType = "name" }, |
||
319 | { name = SORT_RARITY, sortType = "rarity" }, |
||
320 | { name = SORT_LOCATION, sortType = "location" }, |
||
321 | { name = SORT_TYPE, sortType = "type" }, |
||
322 | { name = SORT_SUBTYPE, sortType = "subtype" }, |
||
323 | { name = SORT_LEVEL, sortType = "level" }, |
||
324 | { name = SORT_BINDS, sortType = "binds" }, |
||
325 | { name = SORT_UNIQUE, sortType = "unique" }, |
||
326 | { name = SORT_ARMOR, sortType = "armor" }, |
||
327 | { name = SORT_BLOCK, sortType = "block" }, |
||
328 | { name = SORT_MINDAMAGE, sortType = "minDamage" }, |
||
329 | { name = SORT_MAXDAMAGE, sortType = "maxDamage" }, |
||
330 | { name = SORT_DPS, sortType = "DPS" }, |
||
331 | { name = SORT_SPEED, sortType = "speed" }, |
||
332 | { name = SORT_SLOTS, sortType = "slots" }, |
||
333 | { name = SORT_SKILL, sortType = "skill" }, |
||
334 | { name = SORT_SET, sortType = "set" }, |
||
335 | }; |
||
336 | |||
337 | local LLS_RARITY_LIST = { |
||
338 | { name = ANY, value = nil }, |
||
339 | { name = UNKNOWN, value = "ff40ffc0", r = 64 / 255, g = 255 / 255, b = 192 / 255 }, |
||
340 | { name = POOR, value = "ff9d9d9d", r = 157 / 255, g = 157 / 255, b = 157 / 255 }, |
||
341 | { name = COMMON, value = "ffffffff", r = 1, g = 1, b = 1 }, |
||
342 | { name = UNCOMMON, value = "ff1eff00", r = 30 / 255, g = 1, b = 0 }, |
||
343 | { name = RARE, value = "ff0070dd", r = 0, g = 70 / 255, b = 221 / 255 }, |
||
344 | { name = EPIC, value = "ffa335ee", r = 163 / 255, g = 53 / 255, b = 238 / 255 }, |
||
345 | { name = LEGENDARY, value = "ffff8000", r = 1, g = 128 / 255, b = 0 }, |
||
346 | }; |
||
347 | |||
348 | local LLS_BINDS_LIST = { |
||
349 | { name = ANY, value = nil }, |
||
350 | { name = DOES_NOT, value = BINDS_DOES_NOT_BIND }, |
||
351 | { name = ON_EQUIP, value = BINDS_EQUIP }, |
||
352 | { name = ON_PICKUP, value = BINDS_PICKUP }, |
||
353 | { name = ON_USE, value = BINDS_USE }, |
||
354 | }; |
||
355 | |||
356 | local LLS_TYPE_LIST = { |
||
357 | { name = ANY, value = nil }, |
||
358 | { name = ARMOR, value = TYPE_ARMOR }, |
||
359 | { name = CONTAINER, value = TYPE_CONTAINER }, |
||
360 | { name = OTHER, value = TYPE_MISC }, |
||
361 | { name = RECIPE, value = TYPE_RECIPE }, |
||
362 | { name = SHIELD, value = TYPE_SHIELD }, |
||
363 | { name = WEAPON, value = TYPE_WEAPON }, |
||
364 | }; |
||
365 | |||
366 | local LLS_SUBTYPE_ARMOR_LIST = { |
||
367 | { name = ANY, value = nil }, |
||
368 | { name = CLOTH, value = SUBTYPE_ARMOR_CLOTH }, |
||
369 | { name = LEATHER, value = SUBTYPE_ARMOR_LEATHER }, |
||
370 | { name = MAIL, value = SUBTYPE_ARMOR_MAIL }, |
||
371 | { name = PLATE, value = SUBTYPE_ARMOR_PLATE }, |
||
372 | { name = INVTYPE_RELIC, value = SUBTYPE_ARMOR_RELIC }, |
||
373 | }; |
||
374 | |||
375 | local LLS_SUBTYPE_WEAPON_LIST = { |
||
376 | { name = ANY, value = nil }, |
||
377 | { name = AXE, value = SUBTYPE_WEAPON_AXE }, |
||
378 | { name = BOW, value = SUBTYPE_WEAPON_BOW }, |
||
379 | { name = CROSSBOW, value = SUBTYPE_WEAPON_CROSSBOW }, |
||
380 | { name = DAGGER, value = SUBTYPE_WEAPON_DAGGER }, |
||
381 | { name = FISHING_POLE, value = SUBTYPE_WEAPON_FISHING_POLE }, |
||
382 | { name = FIST_WEAPON, value = SUBTYPE_WEAPON_FIST_WEAPON }, |
||
383 | { name = GUN, value = SUBTYPE_WEAPON_GUN }, |
||
384 | { name = MACE, value = SUBTYPE_WEAPON_MACE }, |
||
385 | { name = POLEARM, value = SUBTYPE_WEAPON_POLEARM }, |
||
386 | { name = STAFF, value = SUBTYPE_WEAPON_STAFF }, |
||
387 | { name = SWORD, value = SUBTYPE_WEAPON_SWORD }, |
||
388 | { name = THROWN, value = SUBTYPE_WEAPON_THROWN }, |
||
389 | { name = WAND, value = SUBTYPE_WEAPON_WAND }, |
||
390 | }; |
||
391 | |||
392 | local LLS_SUBTYPE_SHIELD_LIST = { |
||
393 | { name = ANY, value = nil }, |
||
394 | { name = BUCKLER, value = SUBTYPE_SHIELD_BUCKLER }, |
||
395 | { name = SHIELD, value = SUBTYPE_SHIELD_SHIELD }, |
||
396 | }; |
||
397 | |||
398 | local LLS_SUBTYPE_RECIPE_LIST = { |
||
399 | { name = ANY, value = nil }, |
||
400 | { name = ALCHEMY, value = SUBTYPE_RECIPE_ALCHEMY }, |
||
401 | { name = BLACKSMITHING, value = SUBTYPE_RECIPE_BLACKSMITHING }, |
||
402 | { name = COOKING, value = SUBTYPE_RECIPE_COOKING }, |
||
403 | { name = ENCHANTING, value = SUBTYPE_RECIPE_ENCHANTING }, |
||
404 | { name = ENGINEERING, value = SUBTYPE_RECIPE_ENGINEERING }, |
||
405 | { name = LEATHERWORKING, value = SUBTYPE_RECIPE_LEATHERWORKING }, |
||
406 | { name = TAILORING, value = SUBTYPE_RECIPE_TAILORING }, |
||
407 | }; |
||
408 | |||
409 | local LLS_SUBTYPE_CONTAINER_LIST = { |
||
410 | { name = ANY, value = nil }, |
||
411 | { name = BAG, value = SUBTYPE_CONTAINER_BAG }, |
||
412 | { name = AMMO_POUCH, value = SUBTYPE_CONTAINER_AMMO_POUCH }, |
||
413 | { name = QUIVER, value = SUBTYPE_CONTAINER_QUIVER }, |
||
414 | { name = ENCHANTING_BAG, value = SUBTYPE_CONTAINER_ENCHANTING_BAG }, |
||
415 | { name = ENGINEERING_BAG, value = SUBTYPE_CONTAINER_ENGINEERING_BAG }, |
||
416 | { name = HERB_BAG, value = SUBTYPE_CONTAINER_HERB_BAG }, |
||
417 | { name = SOUL_BAG, value = SUBTYPE_CONTAINER_SOUL_BAG }, |
||
418 | }; |
||
419 | |||
420 | local LLS_LOCATION_LIST = { |
||
421 | { name = ANY, }, |
||
422 | { name = NONE, }, |
||
423 | { name = INVTYPE_CLOAK, }, |
||
424 | { name = INVTYPE_CHEST, }, |
||
425 | { name = CROSSBOW, }, |
||
426 | { name = INVTYPE_FEET, }, |
||
427 | { name = INVTYPE_FINGER, }, |
||
428 | { name = INVTYPE_HAND, }, |
||
429 | { name = INVTYPE_HEAD, }, |
||
430 | { name = INVTYPE_HOLDABLE, }, |
||
431 | { name = GUN, }, |
||
432 | { name = INVTYPE_LEGS, }, |
||
433 | { name = INVTYPE_WEAPONMAINHAND, }, |
||
434 | { name = INVTYPE_NECK, }, |
||
435 | { name = INVTYPE_WEAPONOFFHAND, }, |
||
436 | { name = INVTYPE_WEAPON, }, |
||
437 | { name = INVTYPE_RANGED, }, |
||
438 | { name = INVTYPE_BODY, }, |
||
439 | { name = INVTYPE_SHOULDER, }, |
||
440 | { name = INVTYPE_TABARD, }, |
||
441 | { name = THROWN, }, |
||
442 | { name = INVTYPE_TRINKET, }, |
||
443 | { name = INVTYPE_2HWEAPON, }, |
||
444 | { name = INVTYPE_WAIST, }, |
||
445 | { name = WAND, }, |
||
446 | { name = INVTYPE_WRIST, }, |
||
447 | }; |
||
448 | |||
449 | local LLS_EXTRA_LIST = { |
||
450 | { name = ALL, }, |
||
451 | { name = ONLY, }, |
||
452 | { name = NONE, }, |
||
453 | }; |
||
454 | |||
455 | local LLO_RARITY_LIST = { |
||
456 | { name = NONE }, |
||
457 | { name = "|cff9d9d9d"..POOR }, |
||
458 | { name = "|cffffffff"..COMMON }, |
||
459 | { name = "|cff1eff00"..UNCOMMON }, |
||
460 | { name = "|cff0070dd"..RARE }, |
||
461 | { name = "|cffa335ee"..EPIC }, |
||
462 | { name = "|cffff8000"..LEGENDARY }, |
||
463 | }; |
||
464 | |||
465 | local lMagicCharacters = { }; |
||
466 | lMagicCharacters["^"] = 1; |
||
467 | lMagicCharacters["$"] = 1; |
||
468 | lMagicCharacters["("] = 1; |
||
469 | lMagicCharacters[")"] = 1; |
||
470 | lMagicCharacters["%"] = 1; |
||
471 | lMagicCharacters["."] = 1; |
||
472 | lMagicCharacters["["] = 1; |
||
473 | lMagicCharacters["]"] = 1; |
||
474 | lMagicCharacters["*"] = 1; |
||
475 | lMagicCharacters["+"] = 1; |
||
476 | lMagicCharacters["-"] = 1; |
||
477 | lMagicCharacters["?"] = 1; |
||
478 | |||
479 | local lBankBagIDs = { BANK_CONTAINER, 5, 6, 7, 8, 9, 10, }; |
||
480 | |||
481 | -- Item types that can't have enchants or "of" stat bonuses |
||
482 | local lNoBonuses = { |
||
483 | [""] = 2, |
||
484 | ["INVTYPE_TRINKET"] = 2, |
||
485 | ["INVTYPE_AMMO"] = 2, |
||
486 | ["INVTYPE_THROWN"] = 2, |
||
487 | ["INVTYPE_BAG"] = 2, |
||
488 | ["INVTYPE_TABARD"] = 2, |
||
489 | ["INVTYPE_BODY"] = 2, |
||
490 | ["INVTYPE_HOLDABLE"] = 1, |
||
491 | ["INVTYPE_FINGER"] = 1, |
||
492 | ["INVTYPE_WAIST"] = 1, |
||
493 | } |
||
494 | |||
495 | local lRarityFilter = { |
||
496 | ff40ffc0 = -1, |
||
497 | ff9d9d9d = 0, |
||
498 | ffffffff = 1, |
||
499 | ff1eff00 = 2, |
||
500 | ff0070dd = 3, |
||
501 | ffa335ee = 4, |
||
502 | ffff8000 = 5, |
||
503 | }; |
||
504 | |||
505 | -------------------------------------------------------------------------------------------------- |
||
506 | -- Global LootLink variables |
||
507 | -------------------------------------------------------------------------------------------------- |
||
508 | |||
509 | LOOTLINK_VERSION = 350; -- version 3.50 |
||
510 | |||
511 | LOOTLINK_ITEM_HEIGHT = 16; |
||
512 | LOOTLINK_ITEMS_SHOWN = 22; |
||
513 | |||
514 | UIPanelWindows["LootLinkFrame"] = { area = "left", pushable = 11, whileDead = 1 }; |
||
515 | UIPanelWindows["LootLinkSearchFrame"] = { area = "center", pushable = 0, whileDead = 1 }; |
||
516 | UIPanelWindows["LootLinkOptionsFrame"] = { area = "center", pushable = 0, whileDead = 1 }; |
||
517 | |||
518 | -------------------------------------------------------------------------------------------------- |
||
519 | -- Internal functions |
||
520 | -------------------------------------------------------------------------------------------------- |
||
521 | |||
522 | -- |
||
523 | -- Functions with no other functional dependencies |
||
524 | -- |
||
525 | |||
526 | local function LootLink_MakeIntFromHexString(str) |
||
527 | local remain = str; |
||
528 | local amount = 0; |
||
529 | while( remain ~= "" ) do |
||
530 | amount = amount * 16; |
||
531 | local byteVal = string.byte(strupper(strsub(remain, 1, 1))); |
||
532 | if( byteVal >= string.byte("0") and byteVal <= string.byte("9") ) then |
||
533 | amount = amount + (byteVal - string.byte("0")); |
||
534 | elseif( byteVal >= string.byte("A") and byteVal <= string.byte("F") ) then |
||
535 | amount = amount + 10 + (byteVal - string.byte("A")); |
||
536 | end |
||
537 | remain = strsub(remain, 2); |
||
538 | end |
||
539 | return amount; |
||
540 | end |
||
541 | |||
542 | local function LootLink_GetRGBFromHexColor(hexColor) |
||
543 | local red = LootLink_MakeIntFromHexString(strsub(hexColor, 3, 4)) / 255; |
||
544 | local green = LootLink_MakeIntFromHexString(strsub(hexColor, 5, 6)) / 255; |
||
545 | local blue = LootLink_MakeIntFromHexString(strsub(hexColor, 7, 8)) / 255; |
||
546 | return red, green, blue; |
||
547 | end |
||
548 | |||
549 | local function LootLink_MouseIsOver(frame) |
||
550 | local x, y = GetCursorPosition(); |
||
551 | |||
552 | if( not frame ) then |
||
553 | return nil; |
||
554 | end |
||
555 | |||
556 | x = x / frame:GetEffectiveScale(); |
||
557 | y = y / frame:GetEffectiveScale(); |
||
558 | |||
559 | local left = frame:GetLeft(); |
||
560 | local right = frame:GetRight(); |
||
561 | local top = frame:GetTop(); |
||
562 | local bottom = frame:GetBottom(); |
||
563 | |||
564 | if( not left or not right or not top or not bottom ) then |
||
565 | return nil; |
||
566 | end |
||
567 | |||
568 | if( (x > left and x < right) and (y > bottom and y < top) ) then |
||
569 | return 1; |
||
570 | else |
||
571 | return nil; |
||
572 | end |
||
573 | end |
||
574 | |||
575 | local function LootLink_GetDataVersion() |
||
576 | if( not LootLinkState or not LootLinkState.DataVersion ) then |
||
577 | return 0; |
||
578 | end |
||
579 | return LootLinkState.DataVersion; |
||
580 | end |
||
581 | |||
582 | local function LootLink_SetDataVersion(version) |
||
583 | if( not LootLinkState ) then |
||
584 | LootLinkState = { }; |
||
585 | end |
||
586 | if( not LootLinkState.DataVersion or LootLinkState.DataVersion < version ) then |
||
587 | LootLinkState.DataVersion = version; |
||
588 | end |
||
589 | end |
||
590 | |||
591 | local function LootLink_AddServer(name) |
||
592 | if( not LootLinkState ) then |
||
593 | LootLinkState = { }; |
||
594 | end |
||
595 | |||
596 | if( not LootLinkState.Servers ) then |
||
597 | LootLinkState.Servers = 0; |
||
598 | LootLinkState.ServerNamesToIndices = { }; |
||
599 | end |
||
600 | |||
601 | if( not LootLinkState.ServerNamesToIndices[name] ) then |
||
602 | LootLinkState.ServerNamesToIndices[name] = LootLinkState.Servers; |
||
603 | LootLinkState.Servers = LootLinkState.Servers + 1; |
||
604 | end |
||
605 | |||
606 | return LootLinkState.ServerNamesToIndices[name]; |
||
607 | end |
||
608 | |||
609 | local function LootLink_ConvertServerFormat(item) |
||
610 | if( item.servers ) then |
||
611 | local i, v; |
||
612 | local list; |
||
613 | for i, v in item.servers do |
||
614 | if( not list ) then |
||
615 | list = TEXT(i); |
||
616 | else |
||
617 | list = list.." "..i; |
||
618 | end |
||
619 | end |
||
620 | item.s = list; |
||
621 | item.servers = nil; |
||
622 | end |
||
623 | end |
||
624 | |||
625 | local function LootLink_CheckItemServerRaw(item, serverIndex) |
||
626 | if( not item.s ) then |
||
627 | return nil; |
||
628 | end |
||
629 | |||
630 | local server; |
||
631 | for server in string.gfind(item.s, "(%d+)") do |
||
632 | if( tonumber(server) == serverIndex ) then |
||
633 | return 1; |
||
634 | end |
||
635 | end |
||
636 | |||
637 | return nil; |
||
638 | end |
||
639 | |||
640 | local function LootLink_AddItemServer(item, serverIndex) |
||
641 | if( not item.s ) then |
||
642 | item.s = TEXT(serverIndex); |
||
643 | elseif( not LootLink_CheckItemServerRaw(item, serverIndex) ) then |
||
644 | item.s = item.s.." "..serverIndex; |
||
645 | end |
||
646 | end |
||
647 | |||
648 | local function LootLink_EscapeString(string) |
||
649 | return string.gsub(string, "\"", "\\\""); |
||
650 | end |
||
651 | |||
652 | local function LootLink_UnescapeString(string) |
||
653 | return string.gsub(string, "\\\"", "\""); |
||
654 | end |
||
655 | |||
656 | local function LootLink_EscapePattern(string) |
||
657 | local result = ""; |
||
658 | local remain = string; |
||
659 | local char; |
||
660 | |||
661 | while( remain ~= "" ) do |
||
662 | char = strsub(remain, 1, 1); |
||
663 | if( lMagicCharacters[char] ) then |
||
664 | result = result.."%"..char; |
||
665 | else |
||
666 | result = result..char; |
||
667 | end |
||
668 | remain = strsub(remain, 2); |
||
669 | end |
||
670 | |||
671 | return result; |
||
672 | end |
||
673 | |||
674 | local function LootLink_CheckNumeric(string) |
||
675 | local remain = string; |
||
676 | local hasNumber; |
||
677 | local hasPeriod; |
||
678 | local char; |
||
679 | |||
680 | while( remain ~= "" ) do |
||
681 | char = strsub(remain, 1, 1); |
||
682 | if( char >= "0" and char <= "9" ) then |
||
683 | hasNumber = 1; |
||
684 | elseif( char == "." and not hasPeriod ) then |
||
685 | hasPeriod = 1; |
||
686 | else |
||
687 | return nil; |
||
688 | end |
||
689 | remain = strsub(remain, 2); |
||
690 | end |
||
691 | |||
692 | return hasNumber; |
||
693 | end |
||
694 | |||
695 | local function LootLink_NameFromLink(link) |
||
696 | local name; |
||
697 | if( not link ) then |
||
698 | return nil; |
||
699 | end |
||
700 | for name in string.gfind(link, "|c%x+|Hitem:%d+:%d+:%d+:%d+|h%[(.-)%]|h|r") do |
||
701 | return name; |
||
702 | end |
||
703 | return nil; |
||
704 | end |
||
705 | |||
706 | function LootLink_MoneyToggle(force) |
||
707 | if( lOriginal_GameTooltip_ClearMoney_Temp ) then |
||
708 | GameTooltip_ClearMoney = lOriginal_GameTooltip_ClearMoney_Temp; |
||
709 | lOriginal_GameTooltip_ClearMoney_Temp = nil; |
||
710 | elseif ( not force ) then |
||
711 | lOriginal_GameTooltip_ClearMoney_Temp = GameTooltip_ClearMoney; |
||
712 | GameTooltip_ClearMoney = LootLink_GameTooltip_ClearMoney_Temp; |
||
713 | else |
||
714 | DEFAULT_CHAT_FRAME:AddMessage( "LootLink_MoneyToggle just tried to break?" ); |
||
715 | end |
||
716 | end |
||
717 | |||
718 | local function LootLink_MatchType(left, right) |
||
719 | local lt = LocationTypes[left]; |
||
720 | local _type; |
||
721 | local subtype; |
||
722 | |||
723 | if( lt ) then |
||
724 | local subtypes; |
||
725 | |||
726 | -- Check for weapon override of base type |
||
727 | if( WeaponSubtypes[right] ) then |
||
728 | _type = TYPE_WEAPON; |
||
729 | subtypes = WeaponSubtypes; |
||
730 | else |
||
731 | _type = lt.type; |
||
732 | subtypes = lt.subtypes; |
||
733 | end |
||
734 | |||
735 | if( subtypes ) then |
||
736 | subtype = subtypes[right]; |
||
737 | else |
||
738 | subtype = lt.subtype; |
||
739 | end |
||
740 | return nil, lt.i, _type, subtype; |
||
741 | end |
||
742 | |||
743 | return 1, nil, TYPE_MISC, nil; |
||
744 | end |
||
745 | |||
746 | local function LootLink_HideTooltipMoney() |
||
747 | LootLinkTooltipMoneyFrame:SetPoint("LEFT", "LootLinkTooltipTextLeft1", "LEFT", 0, 0); |
||
748 | LootLinkTooltipMoneyFrame:Hide(); |
||
749 | end |
||
750 | |||
751 | local function LootLink_SetTooltipMoney(frame, count, money, stack) |
||
752 | if( count and count > 1 ) then |
||
753 | money = money * count; |
||
754 | frame:AddLine(format(LOOTLINK_SELL_PRICE_N, count), 1.0, 1.0, 1.0); |
||
755 | elseif( stack ) then |
||
756 | frame:AddLine(LOOTLINK_SELL_PRICE_EACH, 1.0, 1.0, 1.0); |
||
757 | else |
||
758 | frame:AddLine(LOOTLINK_SELL_PRICE, 1.0, 1.0, 1.0); |
||
759 | end |
||
760 | |||
761 | local numLines = frame:NumLines(); |
||
762 | local moneyFrame = getglobal(frame:GetName().."MoneyFrame"); |
||
763 | local newLine = frame:GetName().."TextLeft"..numLines; |
||
764 | |||
765 | moneyFrame:SetPoint("LEFT", newLine, "RIGHT", 4, 0); |
||
766 | moneyFrame:Show(); |
||
767 | MoneyFrame_Update(moneyFrame:GetName(), money); |
||
768 | frame:SetMinimumWidth(moneyFrame:GetWidth() + getglobal(newLine):GetWidth() - 10); |
||
769 | end |
||
770 | |||
771 | local function LL_SearchData(item, tag) |
||
772 | if( item.d ) then |
||
773 | local s, e; |
||
774 | local value; |
||
775 | |||
776 | s, e, value = string.find(item.d, tag.."(.-)·") |
||
777 | if( value ) then |
||
778 | return tonumber(value); |
||
779 | end |
||
780 | end |
||
781 | return nil; |
||
782 | end |
||
783 | |||
784 | -- |
||
785 | -- Functions that are dependent on preceding local functions, ordered appropriately |
||
786 | -- |
||
787 | |||
788 | local function LootLink_GetName( elem ) |
||
789 | if ( type(elem) == "table" ) then |
||
790 | return elem[1], elem[2]; |
||
791 | else |
||
792 | return elem; |
||
793 | end |
||
794 | end |
||
795 | |||
796 | local function LootLink_GetValue( elem, index, link ) |
||
797 | local name; |
||
798 | if ( type(elem) == "table" ) then |
||
799 | index = elem[2]; |
||
800 | elem = elem[1]; |
||
801 | end |
||
802 | if ( link and ItemLinks[elem] and ItemLinks[elem].i ~= link ) then |
||
803 | if ( ItemLinks[elem].m ) then |
||
804 | for k, v in ItemLinks[elem].m do |
||
805 | if v.i == link then |
||
806 | index = k; |
||
807 | break; |
||
808 | end |
||
809 | end |
||
810 | if ( not index ) then |
||
811 | --DEFAULT_CHAT_FRAME:AddMessage( elem.." "..link.." doesn't appear to exist yet?" ); |
||
812 | return nil; |
||
813 | end |
||
814 | end |
||
815 | end |
||
816 | if ( index and ItemLinks[elem] and ItemLinks[elem].m ) then |
||
817 | return ItemLinks[elem].m[index], index; |
||
818 | elseif ( ItemLinks[elem] ) then |
||
819 | return ItemLinks[elem]; |
||
820 | else |
||
821 | return nil; |
||
822 | end |
||
823 | end |
||
824 | |||
825 | local function LootLink_InitSizes(serverIndex) |
||
826 | local index; |
||
827 | local value; |
||
828 | |||
829 | lItemLinksSizeTotal = 0; |
||
830 | lItemLinksSizeServer = 0; |
||
831 | |||
832 | for index, value in ItemLinks do |
||
833 | lItemLinksSizeTotal = lItemLinksSizeTotal + 1; |
||
834 | if( LootLink_CheckItemServer(value, serverIndex) ) then |
||
835 | lItemLinksSizeServer = lItemLinksSizeServer + 1; |
||
836 | end |
||
837 | end |
||
838 | end |
||
839 | |||
840 | local function LootLink_GetSize(serverIndex) |
||
841 | if( not serverIndex ) then |
||
842 | return lItemLinksSizeTotal; |
||
843 | end |
||
844 | return lItemLinksSizeServer; |
||
845 | end |
||
846 | |||
847 | local function LootLink_Status() |
||
848 | DEFAULT_CHAT_FRAME:AddMessage(format(LOOTLINK_STATUS_HEADER, LOOTLINK_VERSION / 100)); |
||
849 | if( LootLinkState ) then |
||
850 | DEFAULT_CHAT_FRAME:AddMessage(format(LOOTLINK_DATA_VERSION, LootLink_GetSize(), LootLink_GetSize(lServerIndex), lServer, LootLink_GetDataVersion() / 100)); |
||
851 | if( LootLinkState.HideInfo ) then |
||
852 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_INFO_HIDDEN); |
||
853 | else |
||
854 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_INFO_SHOWN); |
||
855 | end |
||
856 | if( LootLinkState.LightMode ) then |
||
857 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_LIGHT_MODE); |
||
858 | else |
||
859 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_FULL_MODE); |
||
860 | end |
||
861 | else |
||
862 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_INFO_SHOWN); |
||
863 | end |
||
864 | if( lScanAuction ) then |
||
865 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_SCHEDULED_AUCTION_SCAN); |
||
866 | end |
||
867 | end |
||
868 | |||
869 | local function LootLink_GetHyperlink(name, index) |
||
870 | local itemLink = LootLink_GetValue( name, index ); |
||
871 | if( itemLink and itemLink.i --[[and LootLink_CheckItemServer(itemLink, lServerIndex)]] ) then |
||
872 | -- Remove instance-specific data that we captured from the link we return |
||
873 | local item = string.gsub(itemLink.i, "(%d+):(%d+):(%d+):(%d+)", "%1:%2:%3:0"); |
||
874 | return "item:"..item; |
||
875 | end |
||
876 | return nil; |
||
877 | end |
||
878 | |||
879 | local function LootLink_GetLink(name, index) |
||
880 | local itemLink = LootLink_GetValue(name, index); |
||
881 | if( itemLink and itemLink.c and itemLink.i --[[and (IsAltKeyDown() or LootLink_CheckItemServer(itemLink, lServerIndex))]] ) then |
||
882 | local link = "|c"..itemLink.c.."|H"..LootLink_GetHyperlink(name, index).."|h["..name.."]|h|r"; |
||
883 | return link; |
||
884 | end |
||
885 | return nil; |
||
886 | end |
||
887 | |||
888 | local function LootLink_GetSet(set) |
||
889 | if ( not LootLinkState.sets ) then |
||
890 | LootLinkState.sets = {} |
||
891 | end |
||
892 | local sets = LootLinkState.sets; |
||
893 | for k, v in sets do |
||
894 | if ( v == set ) then |
||
895 | return k; |
||
896 | end |
||
897 | end |
||
898 | tinsert(sets, set); |
||
899 | return getn(sets); |
||
900 | end |
||
901 | |||
902 | function LootLink_BuildSearchData(name, value, alternate) |
||
903 | local state, itemLink, loop, index, field, left, right, iStart, iEnd, val1, val2, val3, foundRequires, _type, subtype = STATE_NAME, LootLink_GetHyperlink(name, alternate); |
||
904 | |||
905 | if( not itemLink ) then |
||
906 | return nil; |
||
907 | end |
||
908 | |||
909 | -- This is the only place the tooltip hyperlink is set directly, therefore |
||
910 | -- this should only be called when we know that the tooltip will be valid |
||
911 | |||
912 | -- Protect money frame while we set hidden tooltip |
||
913 | LootLink_MoneyToggle(); |
||
914 | LLHiddenTooltip:SetOwner(WorldFrame,"ANCHOR_NONE"); |
||
915 | LLHiddenTooltip:SetHyperlink(itemLink); |
||
916 | LootLink_MoneyToggle(1); |
||
917 | |||
918 | -- Double check that the data is good |
||
919 | local realname, link, quality, level, _, _, _, count = GetItemInfo(itemLink); |
||
920 | if ( not realname ) then |
||
921 | LootLink_ScheduleItem(name,LootLink_GetValue(name,alternate).i); |
||
922 | return nil; |
||
923 | else |
||
924 | local tooltipname = LLHiddenTooltipTextLeft1:GetText(); |
||
925 | if ( realname ~= tooltipname ) then |
||
926 | -- if this returns, we're in trouble. |
||
927 | return nil; |
||
928 | end |
||
929 | end |
||
930 | |||
931 | local savedD = value.d; |
||
932 | local savedT = value.t; |
||
933 | |||
934 | value.d = ""; |
||
935 | if( not LootLinkState.LightMode ) then |
||
936 | value.t = ""; |
||
937 | end |
||
938 | |||
939 | value.c = string.gsub( ITEM_QUALITY_COLORS[quality].hex, "|c(.+)", "%1" ); |
||
940 | |||
941 | for index = 1, 30, 1 do |
||
942 | field = getglobal("LLHiddenTooltipTextLeft"..index); |
||
943 | if( field and field:IsShown() ) then |
||
944 | left = field:GetText(); |
||
945 | else |
||
946 | left = nil; |
||
947 | end |
||
948 | |||
949 | field = getglobal("LLHiddenTooltipTextRight"..index); |
||
950 | if( field and field:IsShown() ) then |
||
951 | right = field:GetText(); |
||
952 | else |
||
953 | right = nil; |
||
954 | end |
||
955 | |||
956 | if( left ) then |
||
957 | if( not LootLinkState.LightMode ) then |
||
958 | -- cull set data to show 0/# and don't save durability |
||
959 | left = string.gsub( left, "(.+ %()%d+(%/%d%))", "%10%2" ); |
||
960 | if ( string.sub( left, 1, 10 ) ~= "Durability" ) then |
||
961 | value.t = value.t..left.."·"; |
||
962 | end |
||
963 | end |
||
964 | else |
||
965 | left = ""; |
||
966 | end |
||
967 | if( right ) then |
||
968 | if( not LootLinkState.LightMode ) then |
||
969 | value.t = value.t..right.."·"; |
||
970 | end |
||
971 | else |
||
972 | right = ""; |
||
973 | end |
||
974 | |||
975 | loop = 1; |
||
976 | while( loop ) do |
||
977 | if( state == STATE_NAME ) then |
||
978 | state = STATE_BOUND; |
||
979 | loop = nil; |
||
980 | elseif( state == STATE_BOUND ) then |
||
981 | iStart, iEnd, val1 = string.find(left, "Binds when (.+)"); |
||
982 | if( val1 ) then |
||
983 | if( val1 == "equipped" ) then |
||
984 | value.d = value.d.."bi"..BINDS_EQUIP.."·"; |
||
985 | elseif( val1 == "picked up" ) then |
||
986 | value.d = value.d.."bi"..BINDS_PICKUP.."·"; |
||
987 | elseif( val1 == "used" ) then |
||
988 | value.d = value.d.."bi"..BINDS_USED.."·"; |
||
989 | end |
||
990 | loop = nil; |
||
991 | else |
||
992 | value.d = value.d.."bi"..BINDS_DOES_NOT_BIND.."·"; |
||
993 | end |
||
994 | state = STATE_UNIQUE; |
||
995 | elseif( state == STATE_UNIQUE ) then |
||
996 | if( string.find(left, "Unique") ) then |
||
997 | value.d = value.d.."un1·"; |
||
998 | loop = nil; |
||
999 | end |
||
1000 | state = STATE_LOCATION; |
||
1001 | elseif( state == STATE_LOCATION ) then |
||
1002 | local location; |
||
1003 | loop, location, _type, subtype = LootLink_MatchType(left, right); |
||
1004 | if( location ) then |
||
1005 | value.d = value.d.."lo"..location.."·"; |
||
1006 | end |
||
1007 | if( _type == TYPE_WEAPON ) then |
||
1008 | state = STATE_DAMAGE; |
||
1009 | elseif( _type == TYPE_ARMOR or _type == TYPE_SHIELD ) then |
||
1010 | state = STATE_ARMOR; |
||
1011 | else |
||
1012 | state = STATE_CONTAINER; |
||
1013 | end |
||
1014 | elseif( state == STATE_DAMAGE ) then |
||
1015 | iStart, iEnd, val1, val2 = string.find(left, "(%d+) %- (%d+) Damage"); |
||
1016 | if( val1 and val2 ) then |
||
1017 | value.d = value.d.."mi"..val1.."·ma"..val2.."·"; |
||
1018 | end |
||
1019 | iStart, iEnd, val1 = string.find(right, "Speed (.+)"); |
||
1020 | if( val1 ) then |
||
1021 | value.d = value.d.."sp"..val1.."·"; |
||
1022 | end |
||
1023 | state = STATE_DPS; |
||
1024 | loop = nil; |
||
1025 | elseif( state == STATE_DPS ) then |
||
1026 | iStart, iEnd, val1 = string.find(left, "%((.+) damage per second%)"); |
||
1027 | if( val1 ) then |
||
1028 | value.d = value.d.."dp"..val1.."·"; |
||
1029 | end |
||
1030 | state = STATE_REQUIRES; |
||
1031 | loop = nil; |
||
1032 | elseif( state == STATE_ARMOR ) then |
||
1033 | iStart, iEnd, val1 = string.find(left, "(%d+) Armor"); |
||
1034 | if( val1 ) then |
||
1035 | value.d = value.d.."ar"..val1.."·"; |
||
1036 | end |
||
1037 | if( _type == TYPE_SHIELD ) then |
||
1038 | state = STATE_BLOCK; |
||
1039 | else |
||
1040 | state = STATE_REQUIRES; |
||
1041 | end |
||
1042 | loop = nil; |
||
1043 | elseif( state == STATE_BLOCK ) then |
||
1044 | iStart, iEnd, val1 = string.find(left, "(%d+) Block"); |
||
1045 | if( val1 ) then |
||
1046 | value.d = value.d.."bl"..val1.."·"; |
||
1047 | end |
||
1048 | state = STATE_REQUIRES; |
||
1049 | loop = nil; |
||
1050 | elseif( state == STATE_CONTAINER ) then |
||
1051 | iStart, iEnd, val1, val2 = string.find(left, "(%d+) Slot (.+)"); |
||
1052 | if( val1 ) then |
||
1053 | _type = TYPE_CONTAINER; |
||
1054 | subtype = ContainerSubtypes[val2]; |
||
1055 | value.d = value.d.."sl"..val1.."·"; |
||
1056 | loop = nil; |
||
1057 | end |
||
1058 | state = STATE_REQUIRES; |
||
1059 | elseif( state == STATE_REQUIRES ) then |
||
1060 | iStart, iEnd, val1 = string.find(left, "Requires (.+)"); |
||
1061 | if( val1 ) then |
||
1062 | iStart, iEnd, val2 = string.find(val1, "Level (%d+)"); |
||
1063 | if( val2 ) then |
||
1064 | value.d = value.d.."le"..val2.."·"; |
||
1065 | else |
||
1066 | iStart, iEnd, val2, val3 = string.find(val1, "(.+) %((%d+)%)"); |
||
1067 | if( val2 and val3 ) then |
||
1068 | val1 = RecipeSubtypes[val2]; |
||
1069 | if( val1 and _type == TYPE_MISC ) then |
||
1070 | _type = TYPE_RECIPE; |
||
1071 | subtype = val1; |
||
1072 | value.d = value.d.."sk"..val3.."·"; |
||
1073 | end |
||
1074 | end |
||
1075 | end |
||
1076 | else |
||
1077 | state = STATE_SPACE; |
||
1078 | end |
||
1079 | loop = nil; |
||
1080 | elseif( state == STATE_SPACE ) then |
||
1081 | if ( left == tooltipSpace ) then |
||
1082 | state = STATE_SET; |
||
1083 | end |
||
1084 | loop = nil; |
||
1085 | elseif( state == STATE_SET ) then |
||
1086 | if ( left ~= "" ) then |
||
1087 | iStart, iEnd, val1, val2 = string.find(left, "(.+) %(%d+%/(%d+)%)"); |
||
1088 | if( val2 ) then |
||
1089 | local set = LootLink_GetSet(val1); |
||
1090 | value.d = value.d.."se"..set.."·"; |
||
1091 | state = STATE_FINISH; |
||
1092 | end |
||
1093 | end |
||
1094 | loop = nil; |
||
1095 | elseif( state == STATE_FINISH ) then |
||
1096 | loop = nil; |
||
1097 | end |
||
1098 | end |
||
1099 | end |
||
1100 | if( _type ) then |
||
1101 | value.d = value.d.."ty".._type.."·"; |
||
1102 | end |
||
1103 | if( subtype ) then |
||
1104 | value.d = value.d.."su"..subtype.."·"; |
||
1105 | end |
||
1106 | |||
1107 | if ( realname and name ~= realname ) then |
||
1108 | if ( not ItemLinks[realname] ) then |
||
1109 | ItemLinks[realname] = {}; |
||
1110 | ItemLinks[realname] = value; |
||
1111 | else |
||
1112 | if ( ItemLinks[realname].i ~= value.i and ItemLinks[realname].m ) then |
||
1113 | local found; |
||
1114 | for k, v in ItemLinks[realname].m do |
||
1115 | if v.i == value.i then |
||
1116 | found = 1; |
||
1117 | break; |
||
1118 | end |
||
1119 | end |
||
1120 | if ( not found ) then |
||
1121 | tinsert( ItemLinks[realname].m, value ); |
||
1122 | end |
||
1123 | end |
||
1124 | end |
||
1125 | end |
||
1126 | |||
1127 | if ( savedD ~= value.d or savedT ~= value.t ) then |
||
1128 | return 2; |
||
1129 | end |
||
1130 | return 1; |
||
1131 | end |
||
1132 | |||
1133 | local function BuildUsabilityData(data) |
||
1134 | local nSkills; |
||
1135 | local iSkill; |
||
1136 | local HeaderData = { }; |
||
1137 | local name, header, isExpanded, rank; |
||
1138 | local Collapse = { }; |
||
1139 | local nToCollapse = 0; |
||
1140 | local iCollapse; |
||
1141 | |||
1142 | data.class = UnitClass("player"); |
||
1143 | data.race = UnitRace("player"); |
||
1144 | data.level = UnitLevel("player"); |
||
1145 | data.skills = { }; |
||
1146 | |||
1147 | -- We need to expand all of the skills, but first want to save off their state |
||
1148 | nSkills = GetNumSkillLines(); |
||
1149 | for iSkill = 1, nSkills do |
||
1150 | local name, header, isExpanded, rank = GetSkillLineInfo(iSkill); |
||
1151 | if( header and not isExpanded ) then |
||
1152 | -- Since we don't know the final index for this item yet, we'll store it by name |
||
1153 | HeaderData[name] = 0; |
||
1154 | end |
||
1155 | end |
||
1156 | |||
1157 | -- Now expand everything and save off our known skills |
||
1158 | ExpandSkillHeader(0); |
||
1159 | nSkills = GetNumSkillLines() |
||
1160 | for iSkill = 1, nSkills do |
||
1161 | local name, header, isExpanded, rank = GetSkillLineInfo(iSkill); |
||
1162 | if( not header ) then |
||
1163 | data.skills[name] = rank; |
||
1164 | elseif( HeaderData[name] ) then |
||
1165 | -- We now know the final index for this header item |
||
1166 | HeaderData[name] = iSkill; |
||
1167 | end |
||
1168 | end |
||
1169 | |||
1170 | -- Finally, return the skills page to its original state |
||
1171 | for name, iSkill in HeaderData do |
||
1172 | Collapse[nToCollapse + 1] = iSkill; |
||
1173 | nToCollapse = nToCollapse + 1; |
||
1174 | end |
||
1175 | if( nToCollapse > 0 ) then |
||
1176 | table.sort(Collapse); |
||
1177 | for iCollapse = nToCollapse, 1, -1 do |
||
1178 | CollapseSkillHeader(Collapse[iCollapse]); |
||
1179 | end |
||
1180 | end |
||
1181 | end |
||
1182 | |||
1183 | local function LootLink_GetSkillRank(ud, _type, subtype, location) |
||
1184 | local entry = lTypeAndSubtypeToSkill[_type][subtype]; |
||
1185 | |||
1186 | if( type(entry) == "table" ) then |
||
1187 | -- Two-handed vs. One-handed weapon |
||
1188 | if( location ) then |
||
1189 | if( location == 3 ) then |
||
1190 | return ud.skills[entry[1]]; |
||
1191 | else |
||
1192 | return ud.skills[entry[0]]; |
||
1193 | end |
||
1194 | else |
||
1195 | return nil; |
||
1196 | end |
||
1197 | else |
||
1198 | -- Everything else |
||
1199 | return ud.skills[entry]; |
||
1200 | end |
||
1201 | end |
||
1202 | |||
1203 | local function LootLink_SetHyperlink(tooltip, name, link, index) |
||
1204 | -- If the link isn't in the local cache, it may not be valid |
||
1205 | if ( not link ) then |
||
1206 | return nil; |
||
1207 | end |
||
1208 | local value = ItemLinks[name]; |
||
1209 | if ( index and value.m ) then |
||
1210 | value = value.m[index]; |
||
1211 | end |
||
1212 | if( not GetItemInfo(link) ) then |
||
1213 | -- To avoid disconnects, we'll create our own lame tooltip for these |
||
1214 | if( value ) then |
||
1215 | local extraSkip = 0; |
||
1216 | local lines = 1; |
||
1217 | local usabilityData; |
||
1218 | |||
1219 | -- Name, in rarity color |
||
1220 | tooltip:SetText("|c"..value.c..name.."|r"); |
||
1221 | |||
1222 | -- Binds on equip, binds on pickup |
||
1223 | local binds = LL_SearchData(value, "bi"); |
||
1224 | if( binds == BINDS_EQUIP ) then |
||
1225 | tooltip:AddLine(ITEM_BIND_ON_EQUIP, 1, 1, 1); |
||
1226 | lines = lines + 1; |
||
1227 | elseif( binds == BINDS_PICKUP ) then |
||
1228 | tooltip:AddLine(ITEM_BIND_ON_PICKUP, 1, 1, 1); |
||
1229 | lines = lines + 1; |
||
1230 | elseif( binds == BINDS_USED ) then |
||
1231 | tooltip:AddLine(ITEM_BIND_ON_USE, 1, 1, 1); |
||
1232 | lines = lines + 1; |
||
1233 | end |
||
1234 | |||
1235 | -- Unique? |
||
1236 | local unique = LL_SearchData(value, "un"); |
||
1237 | if( unique ) then |
||
1238 | tooltip:AddLine("Unique", 1, 1, 1); |
||
1239 | lines = lines + 1; |
||
1240 | end |
||
1241 | |||
1242 | local _type = LL_SearchData(value, "ty"); |
||
1243 | local subtype = LL_SearchData(value, "su"); |
||
1244 | |||
1245 | -- Equip location and type/subtype |
||
1246 | local location = LL_SearchData(value, "lo"); |
||
1247 | if( location ) then |
||
1248 | local subtypes; |
||
1249 | local name; |
||
1250 | for i, v in LocationTypes do |
||
1251 | if( v.i == location ) then |
||
1252 | name = i; |
||
1253 | subtypes = v.subtypes; |
||
1254 | break; |
||
1255 | end |
||
1256 | end |
||
1257 | if( name ) then |
||
1258 | tooltip:AddLine(name, 1, 1, 1); |
||
1259 | lines = lines + 1; |
||
1260 | if( subtype ) then |
||
1261 | if( _type == TYPE_WEAPON ) then |
||
1262 | subtypes = WeaponSubtypes; |
||
1263 | end |
||
1264 | if( subtypes ) then |
||
1265 | for i, v in subtypes do |
||
1266 | if( v == subtype ) then |
||
1267 | if( i == name ) then |
||
1268 | local line = getglobal(tooltip:GetName().."TextLeft"..lines); |
||
1269 | |||
1270 | if( not usabilityData ) then |
||
1271 | usabilityData = { }; |
||
1272 | BuildUsabilityData(usabilityData); |
||
1273 | end |
||
1274 | if( not LootLink_GetSkillRank(usabilityData, _type, subtype, location) ) then |
||
1275 | line:SetTextColor(1, 0, 0); |
||
1276 | end |
||
1277 | else |
||
1278 | local line = getglobal(tooltip:GetName().."TextRight"..lines); |
||
1279 | line:SetText(i); |
||
1280 | |||
1281 | if( not usabilityData ) then |
||
1282 | usabilityData = { }; |
||
1283 | BuildUsabilityData(usabilityData); |
||
1284 | end |
||
1285 | if( LootLink_GetSkillRank(usabilityData, _type, subtype, location) ) then |
||
1286 | line:SetTextColor(1, 1, 1); |
||
1287 | else |
||
1288 | line:SetTextColor(1, 0, 0); |
||
1289 | end |
||
1290 | |||
1291 | line:Show(); |
||
1292 | extraSkip = extraSkip + 1; |
||
1293 | break; |
||
1294 | end |
||
1295 | end |
||
1296 | end |
||
1297 | end |
||
1298 | end |
||
1299 | end |
||
1300 | end |
||
1301 | |||
1302 | -- Now do type specific data |
||
1303 | if( _type == TYPE_ARMOR ) then |
||
1304 | local armor = LL_SearchData(value, "ar"); |
||
1305 | if( armor ) then |
||
1306 | tooltip:AddLine(armor.." Armor", 1, 1, 1); |
||
1307 | lines = lines + 1; |
||
1308 | end |
||
1309 | elseif( _type == TYPE_WEAPON ) then |
||
1310 | local min = LL_SearchData(value, "mi"); |
||
1311 | local max = LL_SearchData(value, "ma"); |
||
1312 | local speed = LL_SearchData(value, "sp"); |
||
1313 | local dps = LL_SearchData(value, "dp"); |
||
1314 | |||
1315 | if( min and max ) then |
||
1316 | tooltip:AddLine(min.." - "..max.." Damage", 1, 1, 1); |
||
1317 | lines = lines + 1; |
||
1318 | if( speed ) then |
||
1319 | local line = getglobal(tooltip:GetName().."TextRight"..lines); |
||
1320 | line:SetText(format("Speed %.2f", tonumber(speed))); |
||
1321 | line:SetTextColor(1, 1, 1); |
||
1322 | line:Show(); |
||
1323 | extraSkip = extraSkip + 1; |
||
1324 | end |
||
1325 | end |
||
1326 | if( dps ) then |
||
1327 | tooltip:AddLine("("..dps.." damage per second)", 1, 1, 1); |
||
1328 | lines = lines + 1; |
||
1329 | end |
||
1330 | elseif( _type == TYPE_SHIELD ) then |
||
1331 | local armor = LL_SearchData(value, "ar"); |
||
1332 | local block = LL_SearchData(value, "bl"); |
||
1333 | if( armor ) then |
||
1334 | tooltip:AddLine(armor.." Armor", 1, 1, 1); |
||
1335 | lines = lines + 1; |
||
1336 | end |
||
1337 | if( block ) then |
||
1338 | tooltip:AddLine(block.." Block", 1, 1, 1); |
||
1339 | lines = lines + 1; |
||
1340 | end |
||
1341 | elseif( _type == TYPE_RECIPE ) then |
||
1342 | local skill = LL_SearchData(value, "sk"); |
||
1343 | if( skill and subtype ) then |
||
1344 | for i, v in RecipeSubtypes do |
||
1345 | if( v == subtype ) then |
||
1346 | if( not usabilityData ) then |
||
1347 | usabilityData = { }; |
||
1348 | BuildUsabilityData(usabilityData); |
||
1349 | end |
||
1350 | local rank = LootLink_GetSkillRank(usabilityData, _type, subtype, location); |
||
1351 | if( not rank or rank < skill ) then |
||
1352 | tooltip:AddLine("Requires "..i.." ("..skill..")", 1, 0, 0); |
||
1353 | else |
||
1354 | tooltip:AddLine("Requires "..i.." ("..skill..")", 1, 1, 1); |
||
1355 | end |
||
1356 | lines = lines + 1; |
||
1357 | break; |
||
1358 | end |
||
1359 | end |
||
1360 | end |
||
1361 | elseif( _type == TYPE_CONTAINER ) then |
||
1362 | local slots = LL_SearchData(value, "sl"); |
||
1363 | if( slots ) then |
||
1364 | local subtype = LL_SearchData(value, "su") or 0; |
||
1365 | local bag = lTypeAndSubtypeToSkill[_type][subtype]; -- repurposed skill table, fix later? |
||
1366 | tooltip:AddLine(slots.." Slot "..bag, 1, 1, 1); |
||
1367 | lines = lines + 1; |
||
1368 | end |
||
1369 | end |
||
1370 | |||
1371 | local level = LL_SearchData(value, "le"); |
||
1372 | |||
1373 | -- Now add any extra text data that we have |
||
1374 | if( value.t ) then |
||
1375 | local skip = lines + extraSkip; |
||
1376 | local piece; |
||
1377 | for piece in string.gfind(value.t, "(.-)·") do |
||
1378 | if( lines < 29 ) then |
||
1379 | if( skip == 0 ) then |
||
1380 | if( string.find(piece, "Requires Level .*") ) then |
||
1381 | if( level and tonumber(level) > UnitLevel("player") ) then |
||
1382 | tooltip:AddLine(piece, 1, 0, 0, 1, 1); |
||
1383 | else |
||
1384 | tooltip:AddLine(piece, 1, 1, 1, 1, 1); |
||
1385 | end |
||
1386 | elseif( string.find(piece, ":") ) then |
||
1387 | if( string.find(piece, "^Class") ) then |
||
1388 | if( string.find(piece, "^Class.*"..UnitClass("player")) ) then |
||
1389 | tooltip:AddLine(piece, 1, 1, 1, 1, 1); |
||
1390 | else |
||
1391 | tooltip:AddLine(piece, 1, 0, 0, 1, 1); |
||
1392 | end |
||
1393 | else |
||
1394 | tooltip:AddLine(piece, 0, 1, 0, 1, 1); |
||
1395 | end |
||
1396 | elseif( string.find(piece, "\"") or string.find(piece, "%(%d+/%d+%)") ) then |
||
1397 | tooltip:AddLine(piece, 1, 0.8235, 0, 1, 1); |
||
1398 | elseif( string.find(piece, "^ ") ) then |
||
1399 | tooltip:AddLine(piece, 0.5, 0.5, 0.5, 1, 1); |
||
1400 | else |
||
1401 | tooltip:AddLine(piece, 1, 1, 1, 1, 1); |
||
1402 | end |
||
1403 | lines = lines + 1; |
||
1404 | else |
||
1405 | skip = skip - 1; |
||
1406 | end |
||
1407 | end |
||
1408 | end |
||
1409 | end |
||
1410 | |||
1411 | -- And, after all that, let the user know that we faked this tooltip |
||
1412 | if( lines < 30 ) then |
||
1413 | tooltip:AddLine("|cff40ffc0<"..LOOTLINK_TOOLTIP_GENERATED..">|r"); |
||
1414 | lines = lines + 1; |
||
1415 | end |
||
1416 | |||
1417 | if( lines < 30 and not LootLink_CheckItemServer(value, lServerIndex) ) then |
||
1418 | tooltip:AddLine("|cff40ffc0<"..LOOTLINK_TOOLTIP_SERVER..">|r"); |
||
1419 | lines = lines + 1; |
||
1420 | end |
||
1421 | |||
1422 | -- Finally, show the tooltip, which adjusts its size |
||
1423 | tooltip:Show(); |
||
1424 | end |
||
1425 | else |
||
1426 | -- Get the actual tooltip from the cache |
||
1427 | tooltip:SetHyperlink(link); |
||
1428 | |||
1429 | -- After setting the tooltip, parse its data |
||
1430 | LootLink_ScheduleItem(name, value.i); |
||
1431 | --LootLink_BuildSearchData(name, value, index); |
||
1432 | |||
1433 | if( not LootLink_ValidateItem(name, link) ) then |
||
1434 | tooltip:AddLine("|cff40ffc0<"..LOOTLINK_TOOLTIP_BAD_ITEM..">|r"); |
||
1435 | elseif( not LootLink_CheckItemServerRaw(value, lServerIndex) ) then |
||
1436 | tooltip:AddLine("|cff40ffc0<"..LOOTLINK_TOOLTIP_SERVER..">|r"); |
||
1437 | --LootLink_AddItemServer(value, lServerIndex); |
||
1438 | --lItemLinksSizeServer = lItemLinksSizeServer + 1; |
||
1439 | --return 1; |
||
1440 | end |
||
1441 | end |
||
1442 | end |
||
1443 | |||
1444 | local function LootLink_SetTitle() |
||
1445 | local lootLinkTitle = getglobal("LootLinkTitleText"); |
||
1446 | local total = LootLink_GetSize(lServerIndex); |
||
1447 | local size; |
||
1448 | |||
1449 | if( not DisplayIndices ) then |
||
1450 | size = total; |
||
1451 | else |
||
1452 | size = DisplayIndices.onePastEnd - 1; |
||
1453 | end |
||
1454 | if( size < total ) then |
||
1455 | if( size == 1 ) then |
||
1456 | lootLinkTitle:SetText(TEXT(LOOTLINK_TITLE_FORMAT_PARTIAL_SINGULAR)); |
||
1457 | else |
||
1458 | lootLinkTitle:SetText(format(TEXT(LOOTLINK_TITLE_FORMAT_PARTIAL_PLURAL), size)); |
||
1459 | end |
||
1460 | else |
||
1461 | if( size == 1 ) then |
||
1462 | lootLinkTitle:SetText(TEXT(LOOTLINK_TITLE_FORMAT_SINGULAR)); |
||
1463 | else |
||
1464 | lootLinkTitle:SetText(format(TEXT(LOOTLINK_TITLE_FORMAT_PLURAL), size)); |
||
1465 | end |
||
1466 | end |
||
1467 | end |
||
1468 | |||
1469 | local function LootLink_MatchesSearch(name, value, ud) |
||
1470 | if( not value ) then |
||
1471 | return nil; |
||
1472 | end |
||
1473 | if( LootLinkState ) then |
||
1474 | if ( LootLinkState.spoof and name ) then |
||
1475 | if ( not LootLink_ValidateItem( name, value.i ) ) then |
||
1476 | return nil; |
||
1477 | end |
||
1478 | end |
||
1479 | if ( LootLinkState.server ) then |
||
1480 | if ( not LootLink_CheckItemServer(value, lServerIndex) ) then |
||
1481 | return nil; |
||
1482 | end |
||
1483 | end |
||
1484 | if ( LootLinkState.rarityfilter ) then |
||
1485 | if ( value.c and lRarityFilter[value.c] < LootLinkState.rarityfilter ) then |
||
1486 | return nil; |
||
1487 | end |
||
1488 | end |
||
1489 | if ( LootLinkState.noname ) then |
||
1490 | if ( ItemLinks[name] and ItemLinks[name].i and ItemLinks[name].i ~= value.i ) then |
||
1491 | return nil; |
||
1492 | end |
||
1493 | else |
||
1494 | if ( LootLinkState.novariants ) then |
||
1495 | if ( string.gsub(value.i, "%d+:%d+:(%d+):%d+", "%1") ~="0" and ItemLinks[name] and ItemLinks[name].i and ItemLinks[name].i ~= value.i ) then |
||
1496 | return nil; |
||
1497 | end |
||
1498 | end |
||
1499 | if ( LootLinkState.enchants ) then |
||
1500 | if ( string.gsub(value.i, "%d+:(%d+):%d+:%d+", "%1") ~= "0" ) then |
||
1501 | return nil; |
||
1502 | end |
||
1503 | end |
||
1504 | end |
||
1505 | end |
||
1506 | if( not LootLinkFrame.SearchParams or not name ) then |
||
1507 | return 1; |
||
1508 | end |
||
1509 | |||
1510 | if( value.d ) then |
||
1511 | local sp = LootLinkFrame.SearchParams; |
||
1512 | |||
1513 | if( sp.server ) then |
||
1514 | if ( not LootLink_CheckItemServer(value, lServerIndex) ) then |
||
1515 | return nil; |
||
1516 | end |
||
1517 | end |
||
1518 | |||
1519 | if( sp.spoof ) then |
||
1520 | if ( LootLink_ValidateItem( name, value.i ) ) then |
||
1521 | return nil; |
||
1522 | end |
||
1523 | end |
||
1524 | |||
1525 | if( sp.text ) then |
||
1526 | if( not value.t ) then |
||
1527 | return nil; |
||
1528 | end |
||
1529 | if( not string.find(string.lower(value.t), string.lower(sp.text), 1, sp.plain) ) then |
||
1530 | return nil; |
||
1531 | end |
||
1532 | end |
||
1533 | |||
1534 | if( sp.name ) then |
||
1535 | if( not string.find(string.lower(name), string.lower(sp.name), 1, sp.plain) ) then |
||
1536 | return nil; |
||
1537 | end |
||
1538 | end |
||
1539 | |||
1540 | if( sp.rarity ) then |
||
1541 | if( LLS_RARITY_LIST[sp.rarity].value ~= value.c ) then |
||
1542 | return nil; |
||
1543 | end |
||
1544 | end |
||
1545 | |||
1546 | if( sp.binds ) then |
||
1547 | if( LLS_BINDS_LIST[sp.binds].value ~= LL_SearchData(value, "bi") ) then |
||
1548 | return nil; |
||
1549 | end |
||
1550 | end |
||
1551 | |||
1552 | if( sp.unique ) then |
||
1553 | if( sp.unique ~= LL_SearchData(value, "un") ) then |
||
1554 | return nil; |
||
1555 | end |
||
1556 | end |
||
1557 | |||
1558 | if( sp.usable ) then |
||
1559 | local _type = LL_SearchData(value, "ty"); |
||
1560 | local subtype = LL_SearchData(value, "su"); |
||
1561 | local level = LL_SearchData(value, "le"); |
||
1562 | local skill = LL_SearchData(value, "sk"); |
||
1563 | |||
1564 | -- Check for the required skill |
||
1565 | if( _type ) then |
||
1566 | if( subtype ) then |
||
1567 | local rank = LootLink_GetSkillRank(ud, _type, subtype, LL_SearchData(value, "lo")); |
||
1568 | if( not rank or (skill and skill > rank) ) then |
||
1569 | return nil; |
||
1570 | end |
||
1571 | end |
||
1572 | end |
||
1573 | |||
1574 | -- Check for the required class |
||
1575 | if( value.t and string.find(value.t, "·Class") and not string.find(value.t, "·Class.*"..UnitClass("player")) ) then |
||
1576 | return nil; |
||
1577 | end |
||
1578 | |||
1579 | -- Check level requirement |
||
1580 | if( level and level > ud.level ) then |
||
1581 | return nil; |
||
1582 | end |
||
1583 | end |
||
1584 | |||
1585 | if( sp.location ) then |
||
1586 | local location = LL_SearchData(value, "lo"); |
||
1587 | |||
1588 | if( sp.location == 2 ) then |
||
1589 | if( location ) then |
||
1590 | return nil; |
||
1591 | end |
||
1592 | elseif( sp.location ~= 1 ) then |
||
1593 | if( LocationTypes[LLS_LOCATION_LIST[sp.location].name].i ~= location ) then |
||
1594 | return nil; |
||
1595 | end |
||
1596 | end |
||
1597 | end |
||
1598 | |||
1599 | if( sp.minLevel ) then |
||
1600 | local level = LL_SearchData(value, "le"); |
||
1601 | if( not level or level < sp.minLevel ) then |
||
1602 | return nil; |
||
1603 | end |
||
1604 | end |
||
1605 | |||
1606 | if( sp.maxLevel ) then |
||
1607 | local level = LL_SearchData(value, "le"); |
||
1608 | if( level and level > sp.maxLevel ) then |
||
1609 | return nil; |
||
1610 | end |
||
1611 | end |
||
1612 | |||
1613 | if( sp.set ) then |
||
1614 | local set = LL_SearchData(value, "se"); |
||
1615 | if( not set ) then |
||
1616 | return nil; |
||
1617 | end |
||
1618 | end |
||
1619 | |||
1620 | if( sp.type ) then |
||
1621 | local _type = LLS_TYPE_LIST[sp.type].value; |
||
1622 | if( _type ~= LL_SearchData(value, "ty") ) then |
||
1623 | return nil; |
||
1624 | end |
||
1625 | if( sp.subtype ) then |
||
1626 | local subtype; |
||
1627 | if( _type == TYPE_ARMOR ) then |
||
1628 | subtype = LLS_SUBTYPE_ARMOR_LIST[sp.subtype].value; |
||
1629 | elseif( _type == TYPE_SHIELD ) then |
||
1630 | subtype = LLS_SUBTYPE_SHIELD_LIST[sp.subtype].value; |
||
1631 | elseif( _type == TYPE_WEAPON ) then |
||
1632 | subtype = LLS_SUBTYPE_WEAPON_LIST[sp.subtype].value; |
||
1633 | elseif( _type == TYPE_RECIPE ) then |
||
1634 | subtype = LLS_SUBTYPE_RECIPE_LIST[sp.subtype].value; |
||
1635 | elseif( _type == TYPE_CONTAINER ) then |
||
1636 | subtype = LLS_SUBTYPE_CONTAINER_LIST[sp.subtype].value; |
||
1637 | end |
||
1638 | if( subtype and subtype ~= LL_SearchData(value, "su") ) then |
||
1639 | return nil; |
||
1640 | end |
||
1641 | end |
||
1642 | |||
1643 | if( _type == TYPE_WEAPON ) then |
||
1644 | if( sp.minMinDamage ) then |
||
1645 | local damage = LL_SearchData(value, "mi"); |
||
1646 | if( not damage or damage < sp.minMinDamage ) then |
||
1647 | return nil; |
||
1648 | end |
||
1649 | end |
||
1650 | |||
1651 | if( sp.minMaxDamage ) then |
||
1652 | local damage = LL_SearchData(value, "ma"); |
||
1653 | if( not damage or damage < sp.minMaxDamage ) then |
||
1654 | return nil; |
||
1655 | end |
||
1656 | end |
||
1657 | |||
1658 | if( sp.maxSpeed ) then |
||
1659 | local speed = LL_SearchData(value, "sp"); |
||
1660 | if( not speed or speed > sp.maxSpeed ) then |
||
1661 | return nil; |
||
1662 | end |
||
1663 | end |
||
1664 | |||
1665 | if( sp.minDPS ) then |
||
1666 | local DPS = LL_SearchData(value, "dp"); |
||
1667 | if( not DPS or DPS < sp.minDPS ) then |
||
1668 | return nil; |
||
1669 | end |
||
1670 | end |
||
1671 | elseif( _type == TYPE_ARMOR or _type == TYPE_SHIELD ) then |
||
1672 | if( sp.minArmor ) then |
||
1673 | local armor = LL_SearchData(value, "ar"); |
||
1674 | if( not armor or armor < sp.minArmor ) then |
||
1675 | return nil; |
||
1676 | end |
||
1677 | end |
||
1678 | |||
1679 | if( _type == TYPE_SHIELD ) then |
||
1680 | if( sp.minBlock ) then |
||
1681 | local block = LL_SearchData(value, "bl"); |
||
1682 | if( not block or block < sp.minBlock ) then |
||
1683 | return nil; |
||
1684 | end |
||
1685 | end |
||
1686 | end |
||
1687 | elseif( _type == TYPE_CONTAINER ) then |
||
1688 | if( sp.minSlots ) then |
||
1689 | local slots = LL_SearchData(value, "sl"); |
||
1690 | if( not slots or slots < sp.minSlots ) then |
||
1691 | return nil; |
||
1692 | end |
||
1693 | end |
||
1694 | elseif( _type == TYPE_RECIPE ) then |
||
1695 | if( sp.minSkill ) then |
||
1696 | local skill = LL_SearchData(value, "sk"); |
||
1697 | if( not skill or skill < sp.minSkill ) then |
||
1698 | return nil; |
||
1699 | end |
||
1700 | end |
||
1701 | |||
1702 | if( sp.maxSkill ) then |
||
1703 | local skill = LL_SearchData(value, "sk"); |
||
1704 | if( not skill or skill > sp.maxSkill ) then |
||
1705 | return nil; |
||
1706 | end |
||
1707 | end |
||
1708 | end |
||
1709 | end |
||
1710 | else |
||
1711 | return nil; |
||
1712 | end |
||
1713 | |||
1714 | return 1; |
||
1715 | end |
||
1716 | |||
1717 | local function LootLink_NameComparison(elem1, elem2) |
||
1718 | local v1, i1 = elem1[1], elem1[3]; |
||
1719 | local v2, i2 = elem2[1], elem2[3]; |
||
1720 | |||
1721 | if ( v1 == v2 ) then |
||
1722 | if ( i1 and i2 ) then |
||
1723 | return i1 < i2; |
||
1724 | elseif ( i1 ) then |
||
1725 | return false; |
||
1726 | elseif ( i2 ) then |
||
1727 | return true; |
||
1728 | end |
||
1729 | end |
||
1730 | return v1 < v2; |
||
1731 | end |
||
1732 | |||
1733 | local function LootLink_ColorComparison(elem1, elem2) |
||
1734 | local color1; |
||
1735 | local color2; |
||
1736 | local v1 = elem1[2]; |
||
1737 | local v2 = elem2[2]; |
||
1738 | |||
1739 | if( v1 and v1.c ) then |
||
1740 | color1 = v1.c; |
||
1741 | else |
||
1742 | color1 = "ffffffff"; |
||
1743 | end |
||
1744 | if( v2 and v2.c ) then |
||
1745 | color2 = v2.c; |
||
1746 | else |
||
1747 | color2 = "ffffffff"; |
||
1748 | end |
||
1749 | |||
1750 | if( color1 == color2 ) then |
||
1751 | return LootLink_NameComparison( elem1, elem2 ); |
||
1752 | end |
||
1753 | |||
1754 | if( not lColorSortTable[color1] and not lColorSortTable[color2] ) then |
||
1755 | return color1 < color2; |
||
1756 | end |
||
1757 | |||
1758 | if( lColorSortTable[color1] ) then |
||
1759 | if( lColorSortTable[color2] ) then |
||
1760 | return lColorSortTable[color1] < lColorSortTable[color2]; |
||
1761 | end |
||
1762 | return nil; |
||
1763 | end |
||
1764 | return 1; |
||
1765 | end |
||
1766 | |||
1767 | local function LootLink_GenericComparison(elem1, elem2, v1, v2) |
||
1768 | if( v1 == v2 ) then |
||
1769 | return LootLink_NameComparison( elem1, elem2 ); |
||
1770 | end |
||
1771 | if( not v1 ) then |
||
1772 | return 1; |
||
1773 | end |
||
1774 | if( not v2 ) then |
||
1775 | return nil; |
||
1776 | end |
||
1777 | if( tonumber(v1) and tonumber(v2) ) then |
||
1778 | return tonumber(v1) < tonumber(v2); |
||
1779 | end |
||
1780 | return v1 < v2; |
||
1781 | end |
||
1782 | |||
1783 | local function LootLink_BindsComparison(elem1, elem2) |
||
1784 | local v1, v2; |
||
1785 | |||
1786 | local value1 = elem1[2]; |
||
1787 | local value2 = elem2[2]; |
||
1788 | |||
1789 | if( value1 and value1.d ) then |
||
1790 | v1 = LL_SearchData(ItemLinks[elem1], "bi"); |
||
1791 | end |
||
1792 | if( value2 and value2.d ) then |
||
1793 | v2 = LL_SearchData(ItemLinks[elem2], "bi"); |
||
1794 | end |
||
1795 | |||
1796 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1797 | end |
||
1798 | |||
1799 | local function LootLink_UniqueComparison(elem1, elem2) |
||
1800 | local v1, v2; |
||
1801 | |||
1802 | local value1 = elem1[2]; |
||
1803 | local value2 = elem2[2]; |
||
1804 | |||
1805 | if( value1 and value1.d ) then |
||
1806 | v1 = LL_SearchData(value1, "un"); |
||
1807 | end |
||
1808 | if( value2 and value2.d ) then |
||
1809 | v2 = LL_SearchData(value2, "un"); |
||
1810 | end |
||
1811 | |||
1812 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1813 | end |
||
1814 | |||
1815 | local function LootLink_LocationComparison(elem1, elem2) |
||
1816 | local v1, v2; |
||
1817 | |||
1818 | local value1 = elem1[2]; |
||
1819 | local value2 = elem2[2]; |
||
1820 | |||
1821 | if( value1 and value1.d ) then |
||
1822 | v1 = LL_SearchData(value1, "lo"); |
||
1823 | end |
||
1824 | if( value2 and value2.d ) then |
||
1825 | v2 = LL_SearchData(value2, "lo"); |
||
1826 | end |
||
1827 | |||
1828 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1829 | end |
||
1830 | |||
1831 | local function LootLink_TypeComparison(elem1, elem2) |
||
1832 | local v1, v2; |
||
1833 | |||
1834 | local value1 = elem1[2]; |
||
1835 | local value2 = elem2[2]; |
||
1836 | |||
1837 | if( value1 and value1.d ) then |
||
1838 | v1 = LL_SearchData(value1, "ty"); |
||
1839 | end |
||
1840 | if( value2 and value2.d ) then |
||
1841 | v2 = LL_SearchData(value2, "ty"); |
||
1842 | end |
||
1843 | |||
1844 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1845 | end |
||
1846 | |||
1847 | local function LootLink_SubtypeComparison(elem1, elem2) |
||
1848 | local v1, v2; |
||
1849 | |||
1850 | local value1 = elem1[2]; |
||
1851 | local value2 = elem2[2]; |
||
1852 | |||
1853 | if( value1 and value1.d ) then |
||
1854 | v1 = LL_SearchData(value1, "su"); |
||
1855 | end |
||
1856 | if( value2 and value2.d ) then |
||
1857 | v2 = LL_SearchData(value2, "su"); |
||
1858 | end |
||
1859 | |||
1860 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1861 | end |
||
1862 | |||
1863 | local function LootLink_MinDamageComparison(elem1, elem2) |
||
1864 | local v1, v2; |
||
1865 | |||
1866 | local value1 = elem1[2]; |
||
1867 | local value2 = elem2[2]; |
||
1868 | |||
1869 | if( value1 and value1.d ) then |
||
1870 | v1 = LL_SearchData(value1, "mi"); |
||
1871 | end |
||
1872 | if( value2 and value2.d ) then |
||
1873 | v2 = LL_SearchData(value2, "mi"); |
||
1874 | end |
||
1875 | |||
1876 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1877 | end |
||
1878 | |||
1879 | local function LootLink_MaxDamageComparison(elem1, elem2) |
||
1880 | local v1, v2; |
||
1881 | |||
1882 | local value1 = elem1[2]; |
||
1883 | local value2 = elem2[2]; |
||
1884 | |||
1885 | if( value1 and value1.d ) then |
||
1886 | v1 = LL_SearchData(value1, "ma"); |
||
1887 | end |
||
1888 | if( value2 and value2.d ) then |
||
1889 | v2 = LL_SearchData(value2, "ma"); |
||
1890 | end |
||
1891 | |||
1892 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1893 | end |
||
1894 | |||
1895 | local function LootLink_SpeedComparison(elem1, elem2) |
||
1896 | local v1, v2; |
||
1897 | |||
1898 | local value1 = elem1[2]; |
||
1899 | local value2 = elem2[2]; |
||
1900 | |||
1901 | if( value1 and value1.d ) then |
||
1902 | v1 = LL_SearchData(value1, "sp"); |
||
1903 | end |
||
1904 | if( value2 and value2.d ) then |
||
1905 | v2 = LL_SearchData(value2, "sp"); |
||
1906 | end |
||
1907 | |||
1908 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1909 | end |
||
1910 | |||
1911 | local function LootLink_DPSComparison(elem1, elem2) |
||
1912 | local v1, v2; |
||
1913 | |||
1914 | local value1 = elem1[2]; |
||
1915 | local value2 = elem2[2]; |
||
1916 | |||
1917 | if( value1 and value1.d ) then |
||
1918 | v1 = LL_SearchData(value1, "dp"); |
||
1919 | end |
||
1920 | if( value2 and value2.d ) then |
||
1921 | v2 = LL_SearchData(value2, "dp"); |
||
1922 | end |
||
1923 | |||
1924 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1925 | end |
||
1926 | |||
1927 | local function LootLink_ArmorComparison(elem1, elem2) |
||
1928 | local v1, v2; |
||
1929 | |||
1930 | local value1 = elem1[2]; |
||
1931 | local value2 = elem2[2]; |
||
1932 | |||
1933 | if( value1 and value1.d ) then |
||
1934 | v1 = LL_SearchData(value1, "ar"); |
||
1935 | end |
||
1936 | if( value2 and value2.d ) then |
||
1937 | v2 = LL_SearchData(value2, "ar"); |
||
1938 | end |
||
1939 | |||
1940 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1941 | end |
||
1942 | |||
1943 | local function LootLink_BlockComparison(elem1, elem2) |
||
1944 | local v1, v2; |
||
1945 | |||
1946 | local value1 = elem1[2]; |
||
1947 | local value2 = elem2[2]; |
||
1948 | |||
1949 | if( value1 and value1.d ) then |
||
1950 | v1 = LL_SearchData(value1, "bl"); |
||
1951 | end |
||
1952 | if( value2 and value2.d ) then |
||
1953 | v2 = LL_SearchData(value2, "bl"); |
||
1954 | end |
||
1955 | |||
1956 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1957 | end |
||
1958 | |||
1959 | local function LootLink_SlotsComparison(elem1, elem2) |
||
1960 | local v1, v2; |
||
1961 | |||
1962 | local value1 = elem1[2]; |
||
1963 | local value2 = elem2[2]; |
||
1964 | |||
1965 | if( value1 and value1.d ) then |
||
1966 | v1 = LL_SearchData(value1, "sl"); |
||
1967 | end |
||
1968 | if( value2 and value2.d ) then |
||
1969 | v2 = LL_SearchData(value2, "sl"); |
||
1970 | end |
||
1971 | |||
1972 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1973 | end |
||
1974 | |||
1975 | local function LootLink_SkillComparison(elem1, elem2) |
||
1976 | local v1, v2; |
||
1977 | |||
1978 | local value1 = elem1[2]; |
||
1979 | local value2 = elem2[2]; |
||
1980 | |||
1981 | if( value1 and value1.d ) then |
||
1982 | v1 = LL_SearchData(value1, "sk"); |
||
1983 | end |
||
1984 | if( value2 and value2.d ) then |
||
1985 | v2 = LL_SearchData(value2, "sk"); |
||
1986 | end |
||
1987 | |||
1988 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
1989 | end |
||
1990 | |||
1991 | local function LootLink_LevelComparison(elem1, elem2) |
||
1992 | local v1, v2; |
||
1993 | |||
1994 | local value1 = elem1[2]; |
||
1995 | local value2 = elem2[2]; |
||
1996 | |||
1997 | if( value1 and value1.d ) then |
||
1998 | v1 = LL_SearchData(value1, "le"); |
||
1999 | end |
||
2000 | if( value2 and value2.d ) then |
||
2001 | v2 = LL_SearchData(value2, "le"); |
||
2002 | end |
||
2003 | |||
2004 | return LootLink_GenericComparison(elem1, elem2, v1, v2); |
||
2005 | end |
||
2006 | |||
2007 | -- Ugly, but functional |
||
2008 | local function LootLink_SetComparison(elem1, elem2) |
||
2009 | local v1, v2; |
||
2010 | |||
2011 | local value1 = elem1[2]; |
||
2012 | local value2 = elem2[2]; |
||
2013 | |||
2014 | local sets = LootLinkState.sets; |
||
2015 | |||
2016 | if ( not sets ) then |
||
2017 | return LootLink_NameComparison(elem1, elem2); |
||
2018 | end |
||
2019 | |||
2020 | if( value1 and value1.d ) then |
||
2021 | v1 = LL_SearchData(value1, "se"); |
||
2022 | v1 = sets[v1]; |
||
2023 | end |
||
2024 | if( value2 and value2.d ) then |
||
2025 | v2 = LL_SearchData(value2, "se"); |
||
2026 | v2 = sets[v2]; |
||
2027 | end |
||
2028 | |||
2029 | if ( not v1 and not v2 ) then |
||
2030 | return LootLink_NameComparison(elem1, elem2); |
||
2031 | elseif ( not v1 ) then |
||
2032 | return nil; |
||
2033 | elseif ( not v2 ) then |
||
2034 | return 1; |
||
2035 | else |
||
2036 | if ( v1 == v2 ) then |
||
2037 | return LootLink_NameComparison(elem1, elem2); |
||
2038 | else |
||
2039 | return v1 < v2; |
||
2040 | end |
||
2041 | end |
||
2042 | end |
||
2043 | |||
2044 | local function LootLink_Sort() |
||
2045 | if( LOOTLINK_DROPDOWN_LIST[UIDropDownMenu_GetSelectedID(LootLinkFrameDropDown)].sortType ) then |
||
2046 | local sortType = LOOTLINK_DROPDOWN_LIST[UIDropDownMenu_GetSelectedID(LootLinkFrameDropDown)].sortType; |
||
2047 | if( sortType == "name" ) then |
||
2048 | table.sort(DisplayIndices, LootLink_NameComparison); |
||
2049 | elseif( sortType == "rarity" ) then |
||
2050 | table.sort(DisplayIndices, LootLink_ColorComparison); |
||
2051 | elseif( sortType == "binds" ) then |
||
2052 | table.sort(DisplayIndices, LootLink_BindsComparison); |
||
2053 | elseif( sortType == "unique" ) then |
||
2054 | table.sort(DisplayIndices, LootLink_UniqueComparison); |
||
2055 | elseif( sortType == "location" ) then |
||
2056 | table.sort(DisplayIndices, LootLink_LocationComparison); |
||
2057 | elseif( sortType == "type" ) then |
||
2058 | table.sort(DisplayIndices, LootLink_TypeComparison); |
||
2059 | elseif( sortType == "subtype" ) then |
||
2060 | table.sort(DisplayIndices, LootLink_SubtypeComparison); |
||
2061 | elseif( sortType == "minDamage" ) then |
||
2062 | table.sort(DisplayIndices, LootLink_MinDamageComparison); |
||
2063 | elseif( sortType == "maxDamage" ) then |
||
2064 | table.sort(DisplayIndices, LootLink_MaxDamageComparison); |
||
2065 | elseif( sortType == "speed" ) then |
||
2066 | table.sort(DisplayIndices, LootLink_SpeedComparison); |
||
2067 | elseif( sortType == "DPS" ) then |
||
2068 | table.sort(DisplayIndices, LootLink_DPSComparison); |
||
2069 | elseif( sortType == "armor" ) then |
||
2070 | table.sort(DisplayIndices, LootLink_ArmorComparison); |
||
2071 | elseif( sortType == "block" ) then |
||
2072 | table.sort(DisplayIndices, LootLink_BlockComparison); |
||
2073 | elseif( sortType == "slots" ) then |
||
2074 | table.sort(DisplayIndices, LootLink_SlotsComparison); |
||
2075 | elseif( sortType == "skill" ) then |
||
2076 | table.sort(DisplayIndices, LootLink_SkillComparison); |
||
2077 | elseif( sortType == "level" ) then |
||
2078 | table.sort(DisplayIndices, LootLink_LevelComparison); |
||
2079 | elseif( sortType == "set" ) then |
||
2080 | table.sort(DisplayIndices, LootLink_SetComparison); |
||
2081 | end |
||
2082 | end |
||
2083 | end |
||
2084 | |||
2085 | local function LootLink_BuildDisplayIndices() |
||
2086 | local iNew = 1; |
||
2087 | local index; |
||
2088 | local value; |
||
2089 | local UsabilityData; |
||
2090 | |||
2091 | if( LootLinkFrame.SearchParams and LootLinkFrame.SearchParams.usable ) then |
||
2092 | UsabilityData = { }; |
||
2093 | BuildUsabilityData(UsabilityData); |
||
2094 | end |
||
2095 | |||
2096 | DisplayIndices = { }; |
||
2097 | for index, value in ItemLinks do |
||
2098 | if( LootLink_MatchesSearch(index, value, UsabilityData) ) then |
||
2099 | DisplayIndices[iNew] = { index, value, nil }; |
||
2100 | iNew = iNew + 1; |
||
2101 | end |
||
2102 | if( value.m ) then |
||
2103 | for i, altvalue in value.m do |
||
2104 | if( LootLink_MatchesSearch(index, altvalue, UsabilityData) ) then |
||
2105 | DisplayIndices[iNew] = { index, altvalue, i }; |
||
2106 | iNew = iNew + 1; |
||
2107 | end |
||
2108 | end |
||
2109 | end |
||
2110 | end |
||
2111 | DisplayIndices.onePastEnd = iNew; |
||
2112 | LootLink_SetDataVersion(100); -- version 1.00 |
||
2113 | LootLink_Sort(); |
||
2114 | LootLink_SetTitle(); |
||
2115 | LootLinkQuickSearch_Clear(); |
||
2116 | end |
||
2117 | |||
2118 | local function LootLink_Reset() |
||
2119 | ItemLinks = { }; |
||
2120 | |||
2121 | LootLink_SetDataVersion(110); -- version 1.10 |
||
2122 | |||
2123 | LootLink_InitSizes(lServerIndex); |
||
2124 | |||
2125 | if( DisplayIndices ) then |
||
2126 | LootLink_BuildDisplayIndices(); |
||
2127 | LootLink_Update(); |
||
2128 | end |
||
2129 | end |
||
2130 | |||
2131 | local function LootLink_MakeHome() |
||
2132 | local index; |
||
2133 | local value; |
||
2134 | |||
2135 | LootLink_SetDataVersion(110); -- version 1.10 |
||
2136 | |||
2137 | for index, value in ItemLinks do |
||
2138 | if( not value._ ) then |
||
2139 | -- If this item predates multiple server support, mark is as seen on this server |
||
2140 | LootLink_AddItemServer(value, lServerIndex); |
||
2141 | else |
||
2142 | -- Otherwise just wipe the flag since it only applies to pre-1.10 data |
||
2143 | value._ = nil; |
||
2144 | end |
||
2145 | end |
||
2146 | |||
2147 | LootLink_InitSizes(lServerIndex); |
||
2148 | end |
||
2149 | |||
2150 | local function LootLink_LightMode() |
||
2151 | local index; |
||
2152 | local value; |
||
2153 | |||
2154 | for index, value in ItemLinks do |
||
2155 | value.t = nil; |
||
2156 | end |
||
2157 | LootLinkState.LightMode = 1; |
||
2158 | end |
||
2159 | |||
2160 | -- |
||
2161 | -- Uncategorized functions; will sort later |
||
2162 | -- |
||
2163 | |||
2164 | local function LootLinkFrameDropDown_Initialize() |
||
2165 | local info; |
||
2166 | for i = 1, getn(LOOTLINK_DROPDOWN_LIST), 1 do |
||
2167 | info = { }; |
||
2168 | info.text = LOOTLINK_DROPDOWN_LIST[i].name; |
||
2169 | info.func = LootLinkFrameDropDownButton_OnClick; |
||
2170 | UIDropDownMenu_AddButton(info); |
||
2171 | end |
||
2172 | end |
||
2173 | |||
2174 | local function LLS_RarityDropDown_Initialize() |
||
2175 | local info; |
||
2176 | for i = 1, getn(LLS_RARITY_LIST), 1 do |
||
2177 | info = { }; |
||
2178 | info.text = LLS_RARITY_LIST[i].name; |
||
2179 | info.func = LLS_RarityDropDown_OnClick; |
||
2180 | if( LLS_RARITY_LIST[i].value ) then |
||
2181 | info.textR = LLS_RARITY_LIST[i].r; |
||
2182 | info.textG = LLS_RARITY_LIST[i].g; |
||
2183 | info.textB = LLS_RARITY_LIST[i].b; |
||
2184 | end |
||
2185 | UIDropDownMenu_AddButton(info); |
||
2186 | end |
||
2187 | end |
||
2188 | |||
2189 | local function LLO_RarityDropDown_Initialize() |
||
2190 | local info; |
||
2191 | for i = 1, getn(LLO_RARITY_LIST), 1 do |
||
2192 | info = { }; |
||
2193 | info.text = LLO_RARITY_LIST[i].name; |
||
2194 | info.func = LLO_RarityDropDown_OnClick; |
||
2195 | UIDropDownMenu_AddButton(info); |
||
2196 | end |
||
2197 | end |
||
2198 | |||
2199 | local function LLS_BindsDropDown_Initialize() |
||
2200 | local info; |
||
2201 | for i = 1, getn(LLS_BINDS_LIST), 1 do |
||
2202 | info = { }; |
||
2203 | info.text = LLS_BINDS_LIST[i].name; |
||
2204 | info.func = LLS_BindsDropDown_OnClick; |
||
2205 | UIDropDownMenu_AddButton(info); |
||
2206 | end |
||
2207 | end |
||
2208 | |||
2209 | local function LLS_LocationDropDown_Initialize() |
||
2210 | local info; |
||
2211 | for i = 1, getn(LLS_LOCATION_LIST), 1 do |
||
2212 | info = { }; |
||
2213 | info.text = LLS_LOCATION_LIST[i].name; |
||
2214 | info.func = LLS_LocationDropDown_OnClick; |
||
2215 | UIDropDownMenu_AddButton(info); |
||
2216 | end |
||
2217 | end |
||
2218 | |||
2219 | local function LLS_TypeDropDown_Initialize() |
||
2220 | local info; |
||
2221 | for i = 1, getn(LLS_TYPE_LIST), 1 do |
||
2222 | info = { }; |
||
2223 | info.text = LLS_TYPE_LIST[i].name; |
||
2224 | info.func = LLS_TypeDropDown_OnClick; |
||
2225 | UIDropDownMenu_AddButton(info); |
||
2226 | end |
||
2227 | end |
||
2228 | |||
2229 | local function LLS_SubtypeDropDownArmor_Initialize() |
||
2230 | local info; |
||
2231 | for i = 1, getn(LLS_SUBTYPE_ARMOR_LIST), 1 do |
||
2232 | info = { }; |
||
2233 | info.text = LLS_SUBTYPE_ARMOR_LIST[i].name; |
||
2234 | info.func = LLS_SubtypeDropDown_OnClick; |
||
2235 | UIDropDownMenu_AddButton(info); |
||
2236 | end |
||
2237 | end |
||
2238 | |||
2239 | local function LLS_SubtypeDropDownShield_Initialize() |
||
2240 | local info; |
||
2241 | for i = 1, getn(LLS_SUBTYPE_SHIELD_LIST), 1 do |
||
2242 | info = { }; |
||
2243 | info.text = LLS_SUBTYPE_SHIELD_LIST[i].name; |
||
2244 | info.func = LLS_SubtypeDropDown_OnClick; |
||
2245 | UIDropDownMenu_AddButton(info); |
||
2246 | end |
||
2247 | end |
||
2248 | |||
2249 | local function LLS_SubtypeDropDownWeapon_Initialize() |
||
2250 | local info; |
||
2251 | for i = 1, getn(LLS_SUBTYPE_WEAPON_LIST), 1 do |
||
2252 | info = { }; |
||
2253 | info.text = LLS_SUBTYPE_WEAPON_LIST[i].name; |
||
2254 | info.func = LLS_SubtypeDropDown_OnClick; |
||
2255 | UIDropDownMenu_AddButton(info); |
||
2256 | end |
||
2257 | end |
||
2258 | |||
2259 | local function LLS_SubtypeDropDownRecipe_Initialize() |
||
2260 | local info; |
||
2261 | for i = 1, getn(LLS_SUBTYPE_RECIPE_LIST), 1 do |
||
2262 | info = { }; |
||
2263 | info.text = LLS_SUBTYPE_RECIPE_LIST[i].name; |
||
2264 | info.func = LLS_SubtypeDropDown_OnClick; |
||
2265 | UIDropDownMenu_AddButton(info); |
||
2266 | end |
||
2267 | end |
||
2268 | |||
2269 | local function LLS_SubtypeDropDownContainer_Initialize() |
||
2270 | local info; |
||
2271 | for i = 1, getn(LLS_SUBTYPE_CONTAINER_LIST), 1 do |
||
2272 | info = { }; |
||
2273 | info.text = LLS_SUBTYPE_CONTAINER_LIST[i].name; |
||
2274 | info.func = LLS_SubtypeDropDown_OnClick; |
||
2275 | UIDropDownMenu_AddButton(info); |
||
2276 | end |
||
2277 | end |
||
2278 | |||
2279 | local function LootLink_UIDropDownMenu_SetSelectedID(frame, id, names) |
||
2280 | UIDropDownMenu_SetSelectedID(frame, id); |
||
2281 | if( not frame ) then |
||
2282 | frame = this; |
||
2283 | end |
||
2284 | UIDropDownMenu_SetText(names[id].name, frame); |
||
2285 | end |
||
2286 | |||
2287 | local function LootLink_SetupTypeUI(iType, iSubtype) |
||
2288 | local _type = LLS_TYPE_LIST[iType].value; |
||
2289 | |||
2290 | if( not iSubtype ) then |
||
2291 | iSubtype = 1; |
||
2292 | end |
||
2293 | |||
2294 | -- Hide all of the variable labels and fields to start |
||
2295 | getglobal("LLS_SubtypeLabel"):Hide(); |
||
2296 | getglobal("LLS_SubtypeDropDown"):Hide(); |
||
2297 | getglobal("LLS_MinimumArmorLabel"):Hide(); |
||
2298 | getglobal("LLS_MinimumBlockLabel"):Hide(); |
||
2299 | getglobal("LLS_MinimumDamageLabel"):Hide(); |
||
2300 | getglobal("LLS_MaximumDamageLabel"):Hide(); |
||
2301 | getglobal("LLS_MaximumSpeedLabel"):Hide(); |
||
2302 | getglobal("LLS_MinimumDPSLabel"):Hide(); |
||
2303 | getglobal("LLS_MinimumSlotsLabel"):Hide(); |
||
2304 | getglobal("LLS_MinimumSkillLabel"):Hide(); |
||
2305 | getglobal("LLS_MaximumSkillLabel"):Hide(); |
||
2306 | getglobal("LLS_MinimumArmorEditBox"):Hide(); |
||
2307 | getglobal("LLS_MinimumBlockEditBox"):Hide(); |
||
2308 | getglobal("LLS_MinimumDamageEditBox"):Hide(); |
||
2309 | getglobal("LLS_MaximumDamageEditBox"):Hide(); |
||
2310 | getglobal("LLS_MaximumSpeedEditBox"):Hide(); |
||
2311 | getglobal("LLS_MinimumDPSEditBox"):Hide(); |
||
2312 | getglobal("LLS_MinimumSlotsEditBox"):Hide(); |
||
2313 | getglobal("LLS_MinimumSkillEditBox"):Hide(); |
||
2314 | getglobal("LLS_MaximumSkillEditBox"):Hide(); |
||
2315 | |||
2316 | if( _type ~= TYPE_OTHER ) then |
||
2317 | local label = getglobal("LLS_SubtypeLabel"); |
||
2318 | local dropdown = getglobal("LLS_SubtypeDropDown"); |
||
2319 | local initfunc; |
||
2320 | |||
2321 | -- Show the dropdown and its label |
||
2322 | label:Show(); |
||
2323 | dropdown:Show(); |
||
2324 | |||
2325 | if( _type == TYPE_ARMOR ) then |
||
2326 | label:SetText(LLS_SUBTYPE_ARMOR); |
||
2327 | initfunc = LLS_SubtypeDropDownArmor_Initialize; |
||
2328 | |||
2329 | getglobal("LLS_MinimumArmorLabel"):Show(); |
||
2330 | getglobal("LLS_MinimumArmorEditBox"):Show(); |
||
2331 | elseif( _type == TYPE_SHIELD ) then |
||
2332 | label:SetText(LLS_SUBTYPE_SHIELD); |
||
2333 | initfunc = LLS_SubtypeDropDownShield_Initialize; |
||
2334 | |||
2335 | getglobal("LLS_MinimumArmorLabel"):Show(); |
||
2336 | getglobal("LLS_MinimumBlockLabel"):Show(); |
||
2337 | getglobal("LLS_MinimumArmorEditBox"):Show(); |
||
2338 | getglobal("LLS_MinimumBlockEditBox"):Show(); |
||
2339 | elseif( _type == TYPE_WEAPON ) then |
||
2340 | label:SetText(LLS_SUBTYPE_WEAPON); |
||
2341 | initfunc = LLS_SubtypeDropDownWeapon_Initialize; |
||
2342 | |||
2343 | getglobal("LLS_MinimumDamageLabel"):Show(); |
||
2344 | getglobal("LLS_MaximumDamageLabel"):Show(); |
||
2345 | getglobal("LLS_MaximumSpeedLabel"):Show(); |
||
2346 | getglobal("LLS_MinimumDPSLabel"):Show(); |
||
2347 | getglobal("LLS_MinimumDamageEditBox"):Show(); |
||
2348 | getglobal("LLS_MaximumDamageEditBox"):Show(); |
||
2349 | getglobal("LLS_MaximumSpeedEditBox"):Show(); |
||
2350 | getglobal("LLS_MinimumDPSEditBox"):Show(); |
||
2351 | elseif( _type == TYPE_CONTAINER ) then |
||
2352 | label:SetText(LLS_SUBTYPE_CONTAINER); |
||
2353 | initfunc = LLS_SubtypeDropDownContainer_Initialize; |
||
2354 | |||
2355 | getglobal("LLS_MinimumSlotsLabel"):Show(); |
||
2356 | getglobal("LLS_MinimumSlotsEditBox"):Show(); |
||
2357 | else |
||
2358 | label:SetText(LLS_SUBTYPE_RECIPE); |
||
2359 | initfunc = LLS_SubtypeDropDownRecipe_Initialize; |
||
2360 | |||
2361 | getglobal("LLS_MinimumSkillLabel"):Show(); |
||
2362 | getglobal("LLS_MaximumSkillLabel"):Show(); |
||
2363 | getglobal("LLS_MinimumSkillEditBox"):Show(); |
||
2364 | getglobal("LLS_MaximumSkillEditBox"):Show(); |
||
2365 | end |
||
2366 | |||
2367 | UIDropDownMenu_Initialize(dropdown, initfunc); |
||
2368 | UIDropDownMenu_SetSelectedID(LLS_SubtypeDropDown, iSubtype); |
||
2369 | end |
||
2370 | |||
2371 | LLS_TextEditBox:SetFocus(); |
||
2372 | end |
||
2373 | |||
2374 | local function LootLink_InspectSlot(unit, id) |
||
2375 | local link = GetInventoryItemLink(unit, id); |
||
2376 | if( link ) then |
||
2377 | local name = LootLink_ProcessLinks(link, 1); |
||
2378 | if( name and ItemLinks[name] ) then |
||
2379 | local count = GetInventoryItemCount(unit, id); |
||
2380 | if( count > 1 ) then |
||
2381 | ItemLinks[name].x = 1; |
||
2382 | end |
||
2383 | LootLink_Event_InspectSlot(name, count, ItemLinks[name], unit, id); |
||
2384 | end |
||
2385 | end |
||
2386 | end |
||
2387 | |||
2388 | function LootLink_Inspect(who) |
||
2389 | if ( not UnitIsPlayer(who) ) then return; end |
||
2390 | if ( who == "mouseover" ) then |
||
2391 | if ( not LLInspect_List ) then |
||
2392 | LLInspect_List = {}; |
||
2393 | end |
||
2394 | local name = UnitName(who); |
||
2395 | local time = GetTime(); |
||
2396 | local lasttime = LLInspect_List[name]; |
||
2397 | if ( lasttime and time - lasttime < 120 ) then |
||
2398 | return nil; |
||
2399 | end |
||
2400 | if ( not lasttime ) then |
||
2401 | LLInspect_List.total = (LLInspect_List.total or 0) + 1; |
||
2402 | end |
||
2403 | if ( LLInspect_List.total and LLInspect_List.total > 250 ) then |
||
2404 | local list = 0; |
||
2405 | for k, v in LLInspect_List do |
||
2406 | list = list + 1; |
||
2407 | v = nil; |
||
2408 | if ( list == 100 ) then |
||
2409 | break; |
||
2410 | end |
||
2411 | end |
||
2412 | end |
||
2413 | |||
2414 | LLInspect_List[name] = time; |
||
2415 | end |
||
2416 | |||
2417 | local index; |
||
2418 | |||
2419 | for index = 1, getn(INVENTORY_SLOT_LIST), 1 do |
||
2420 | LootLink_InspectSlot(who, INVENTORY_SLOT_LIST[index].id) |
||
2421 | end |
||
2422 | end |
||
2423 | |||
2424 | local function LootLink_ScanInventory() |
||
2425 | local bagid; |
||
2426 | local size; |
||
2427 | local slotid; |
||
2428 | local link; |
||
2429 | |||
2430 | for bagid = 0, 4, 1 do |
||
2431 | size = GetContainerNumSlots(bagid); |
||
2432 | if( size ) then |
||
2433 | for slotid = size, 1, -1 do |
||
2434 | link = GetContainerItemLink(bagid, slotid); |
||
2435 | if( link ) then |
||
2436 | local name = LootLink_ProcessLinks(link, 1); |
||
2437 | if( name and ItemLinks[name] ) then |
||
2438 | local texture, count, locked, quality, readable = GetContainerItemInfo(bagid, slotid); |
||
2439 | if( count > 1 ) then |
||
2440 | ItemLinks[name].x = 1; |
||
2441 | end |
||
2442 | LootLink_Event_ScanInventory(name, count, ItemLinks[name], bagid, slotid); |
||
2443 | end |
||
2444 | end |
||
2445 | end |
||
2446 | end |
||
2447 | end |
||
2448 | end |
||
2449 | |||
2450 | local function LootLink_ScanSellPrices() |
||
2451 | local bagid; |
||
2452 | local size; |
||
2453 | local slotid; |
||
2454 | local link; |
||
2455 | |||
2456 | LootLink_MoneyToggle(); |
||
2457 | for bagid = 0, 4, 1 do |
||
2458 | lBagID = bagid; |
||
2459 | size = GetContainerNumSlots(bagid); |
||
2460 | if( size ) then |
||
2461 | for slotid = size, 1, -1 do |
||
2462 | lSlotID = slotid; |
||
2463 | LLHiddenTooltip:SetBagItem(bagid, slotid); |
||
2464 | end |
||
2465 | end |
||
2466 | end |
||
2467 | |||
2468 | lBagID = nil; |
||
2469 | lSlotID = nil; |
||
2470 | |||
2471 | LootLink_MoneyToggle(1); |
||
2472 | end |
||
2473 | |||
2474 | local function LootLink_StartAuctionScan() |
||
2475 | -- Start with the first page |
||
2476 | lCurrentAuctionPage = nil; |
||
2477 | |||
2478 | -- Hook the functions that we need for the scan |
||
2479 | if( not lOriginal_CanSendAuctionQuery ) then |
||
2480 | lOriginal_CanSendAuctionQuery = CanSendAuctionQuery; |
||
2481 | CanSendAuctionQuery = LootLink_CanSendAuctionQuery; |
||
2482 | end |
||
2483 | if( not lOriginal_AuctionFrameBrowse_OnEvent ) then |
||
2484 | lOriginal_AuctionFrameBrowse_OnEvent = AuctionFrameBrowse_OnEvent; |
||
2485 | AuctionFrameBrowse_OnEvent = LootLink_AuctionFrameBrowse_OnEvent; |
||
2486 | end |
||
2487 | |||
2488 | LootLink_Event_StartAuctionScan(); |
||
2489 | end |
||
2490 | |||
2491 | local function LootLink_StopAuctionScan() |
||
2492 | LootLink_Event_StopAuctionScan(); |
||
2493 | |||
2494 | -- Unhook the scanning functions |
||
2495 | if( lOriginal_CanSendAuctionQuery ) then |
||
2496 | CanSendAuctionQuery = lOriginal_CanSendAuctionQuery; |
||
2497 | lOriginal_CanSendAuctionQuery = nil; |
||
2498 | end |
||
2499 | if( lOriginal_AuctionFrameBrowse_OnEvent ) then |
||
2500 | AuctionFrameBrowse_OnEvent = lOriginal_AuctionFrameBrowse_OnEvent; |
||
2501 | lOriginal_AuctionFrameBrowse_OnEvent = nil; |
||
2502 | end |
||
2503 | end |
||
2504 | |||
2505 | local function LootLink_AuctionNextQuery() |
||
2506 | if( lCurrentAuctionPage ) then |
||
2507 | local numBatchAuctions, totalAuctions = GetNumAuctionItems("list"); |
||
2508 | local maxPages = floor(totalAuctions / NUM_AUCTION_ITEMS_PER_PAGE); |
||
2509 | |||
2510 | if( lCurrentAuctionPage < maxPages ) then |
||
2511 | lCurrentAuctionPage = lCurrentAuctionPage + 1; |
||
2512 | BrowseNoResultsText:SetText(format(LOOTLINK_AUCTION_PAGE_N, lCurrentAuctionPage + 1, maxPages + 1)); |
||
2513 | else |
||
2514 | lScanAuction = nil; |
||
2515 | LootLink_StopAuctionScan(); |
||
2516 | if( totalAuctions > 0 ) then |
||
2517 | BrowseNoResultsText:SetText(LOOTLINK_AUCTION_SCAN_DONE); |
||
2518 | LootLink_Event_FinishedAuctionScan(); |
||
2519 | end |
||
2520 | return; |
||
2521 | end |
||
2522 | else |
||
2523 | lCurrentAuctionPage = 0; |
||
2524 | BrowseNoResultsText:SetText(LOOTLINK_AUCTION_SCAN_START); |
||
2525 | end |
||
2526 | QueryAuctionItems("", "", "", nil, nil, nil, lCurrentAuctionPage, nil, nil); |
||
2527 | LootLink_Event_AuctionQuery(lCurrentAuctionPage); |
||
2528 | end |
||
2529 | |||
2530 | local function LootLink_ScanAuction() |
||
2531 | local numBatchAuctions, totalAuctions = GetNumAuctionItems("list"); |
||
2532 | local auctionid; |
||
2533 | local link; |
||
2534 | |||
2535 | if( numBatchAuctions > 0 ) then |
||
2536 | for auctionid = 1, numBatchAuctions do |
||
2537 | link = GetAuctionItemLink("list", auctionid); |
||
2538 | if( link ) then |
||
2539 | local name = LootLink_ProcessLinks(link, 1); |
||
2540 | if( name and ItemLinks[name] ) then |
||
2541 | local name_, texture, count, quality, canUse, level, minBid, minIncrement, buyoutPrice, bidAmount, highBidder, owner = GetAuctionItemInfo("list", auctionid); |
||
2542 | if( count > 1 ) then |
||
2543 | ItemLinks[name].x = 1; |
||
2544 | end |
||
2545 | LootLink_Event_ScanAuction(name, count, ItemLinks[name], lCurrentAuctionPage, auctionid); |
||
2546 | end |
||
2547 | end |
||
2548 | end |
||
2549 | end |
||
2550 | end |
||
2551 | |||
2552 | local function LootLink_ScanBank() |
||
2553 | local index; |
||
2554 | local bagid; |
||
2555 | local size; |
||
2556 | local slotid; |
||
2557 | local link; |
||
2558 | |||
2559 | for index, bagid in lBankBagIDs do |
||
2560 | size = GetContainerNumSlots(bagid); |
||
2561 | if( size ) then |
||
2562 | for slotid = size, 1, -1 do |
||
2563 | link = GetContainerItemLink(bagid, slotid); |
||
2564 | if( link ) then |
||
2565 | local name = LootLink_ProcessLinks(link, 1); |
||
2566 | if( name and ItemLinks[name] ) then |
||
2567 | local texture, count, locked, quality, readable = GetContainerItemInfo(bagid, slotid); |
||
2568 | if( count > 1 ) then |
||
2569 | ItemLinks[name].x = 1; |
||
2570 | end |
||
2571 | LootLink_Event_ScanBank(name, count, ItemLinks[name], bagid, slotid); |
||
2572 | end |
||
2573 | end |
||
2574 | end |
||
2575 | end |
||
2576 | end |
||
2577 | end |
||
2578 | |||
2579 | local function LootLink_ScanSellPrice(price) |
||
2580 | local link = GetContainerItemLink(lBagID, lSlotID); |
||
2581 | local texture, itemCount, locked, quality, readable = GetContainerItemInfo(lBagID, lSlotID); |
||
2582 | local name; |
||
2583 | |||
2584 | if( itemCount and itemCount > 1 ) then |
||
2585 | price = price / itemCount; |
||
2586 | end |
||
2587 | |||
2588 | name = LootLink_NameFromLink(link); |
||
2589 | if( name and ItemLinks[name] ) then |
||
2590 | ItemLinks[name].p = price; |
||
2591 | if( itemCount and itemCount > 1 ) then |
||
2592 | ItemLinks[name].x = 1; |
||
2593 | end |
||
2594 | end |
||
2595 | end |
||
2596 | |||
2597 | local function LootLink_CheckTooltipInfo() |
||
2598 | if( GameTooltip:IsVisible() ) then |
||
2599 | -- If we've already added our information or money is already showing, no need to do it again |
||
2600 | if( GameTooltip.llDone or GameTooltipMoneyFrame:IsVisible() ) then |
||
2601 | return nil; |
||
2602 | end |
||
2603 | |||
2604 | -- Don't add information to tooltips generated while the mouse is over the minimap |
||
2605 | if( LootLink_MouseIsOver(MinimapCluster) ) then |
||
2606 | return nil; |
||
2607 | end |
||
2608 | |||
2609 | local field = getglobal("GameTooltipTextLeft1"); |
||
2610 | if( field and field:IsShown() ) then |
||
2611 | local name = field:GetText(); |
||
2612 | if( name ) then |
||
2613 | if( ItemLinks[name] ) then |
||
2614 | LootLink_AddTooltipInfo(name, GameTooltip); |
||
2615 | end |
||
2616 | -- Whether or not we had information for this item, there's no need to check it again |
||
2617 | return nil; |
||
2618 | end |
||
2619 | end |
||
2620 | end |
||
2621 | |||
2622 | return 1; |
||
2623 | end |
||
2624 | |||
2625 | local function LootLink_CheckVersionReminder() |
||
2626 | local index; |
||
2627 | local value; |
||
2628 | local version; |
||
2629 | |||
2630 | version = LootLink_GetDataVersion(); |
||
2631 | for index, value in LOOTLINK_DATA_UPGRADE_HELP do |
||
2632 | if( version < value.version ) then |
||
2633 | DEFAULT_CHAT_FRAME:AddMessage(value.text); |
||
2634 | end |
||
2635 | end |
||
2636 | end |
||
2637 | |||
2638 | local function LootLink_UpgradeData() |
||
2639 | local index; |
||
2640 | local item; |
||
2641 | |||
2642 | for index, item in ItemLinks do |
||
2643 | LootLink_ConvertServerFormat(item); |
||
2644 | if( item.item ) then |
||
2645 | item.i = item.item; |
||
2646 | item.item = nil; |
||
2647 | end |
||
2648 | if( item.color ) then |
||
2649 | item.c = item.color; |
||
2650 | item.color = nil; |
||
2651 | end |
||
2652 | if( item.price ) then |
||
2653 | item.p = item.price; |
||
2654 | item.price = nil; |
||
2655 | end |
||
2656 | if( item.stack ) then |
||
2657 | item.x = item.stack; |
||
2658 | item.stack = nil; |
||
2659 | end |
||
2660 | |||
2661 | if( item.SearchData ) then |
||
2662 | local data = ""; |
||
2663 | |||
2664 | if( item.SearchData.type ) then |
||
2665 | data = data.."ty"..item.SearchData.type.."·"; |
||
2666 | end |
||
2667 | if( item.SearchData.location ) then |
||
2668 | data = data.."lo"..LocationTypes[item.SearchData.location].i.."·"; |
||
2669 | end |
||
2670 | if( item.SearchData.subtype ) then |
||
2671 | data = data.."su"..item.SearchData.subtype.."·"; |
||
2672 | end |
||
2673 | if( item.SearchData.binds ) then |
||
2674 | data = data.."bi"..item.SearchData.binds.."·"; |
||
2675 | end |
||
2676 | if( item.SearchData.level ) then |
||
2677 | data = data.."le"..item.SearchData.level.."·"; |
||
2678 | end |
||
2679 | if( item.SearchData.armor ) then |
||
2680 | data = data.."ar"..item.SearchData.armor.."·"; |
||
2681 | end |
||
2682 | if( item.SearchData.minDamage ) then |
||
2683 | data = data.."mi"..item.SearchData.minDamage.."·"; |
||
2684 | end |
||
2685 | if( item.SearchData.maxDamage ) then |
||
2686 | data = data.."ma"..item.SearchData.maxDamage.."·"; |
||
2687 | end |
||
2688 | if( item.SearchData.speed ) then |
||
2689 | data = data.."sp"..item.SearchData.speed.."·"; |
||
2690 | end |
||
2691 | if( item.SearchData.DPS ) then |
||
2692 | data = data.."dp"..item.SearchData.DPS.."·"; |
||
2693 | end |
||
2694 | if( item.SearchData.unique ) then |
||
2695 | data = data.."un"..item.SearchData.unique.."·"; |
||
2696 | end |
||
2697 | if( item.SearchData.block ) then |
||
2698 | data = data.."bl"..item.SearchData.block.."·"; |
||
2699 | end |
||
2700 | if( item.SearchData.slots ) then |
||
2701 | data = data.."sl"..item.SearchData.slots.."·"; |
||
2702 | end |
||
2703 | if( item.SearchData.skill ) then |
||
2704 | data = data.."sk"..item.SearchData.skill.."·"; |
||
2705 | end |
||
2706 | |||
2707 | if( item.SearchData.text ) then |
||
2708 | item.t = item.SearchData.text; |
||
2709 | end |
||
2710 | |||
2711 | item.d = data; |
||
2712 | item.SearchData = nil; |
||
2713 | end |
||
2714 | end |
||
2715 | end |
||
2716 | |||
2717 | local function LootLink_VariablesLoaded() |
||
2718 | local index; |
||
2719 | local value; |
||
2720 | |||
2721 | if( not LootLinkState ) then |
||
2722 | LootLinkState = { }; |
||
2723 | elseif ( LootLinkState.options ) then |
||
2724 | for k, v in LootLinkState.options do |
||
2725 | LootLinkState[k] = v; |
||
2726 | end |
||
2727 | LootLinkState.options = nil; |
||
2728 | end |
||
2729 | |||
2730 | if( not ItemLinks ) then |
||
2731 | LootLink_Reset(); |
||
2732 | end |
||
2733 | |||
2734 | lServer = GetCVar("realmName"); |
||
2735 | lServerIndex = LootLink_AddServer(lServer); |
||
2736 | |||
2737 | LootLink_UpgradeData(); |
||
2738 | |||
2739 | LootLink_InitSizes(lServerIndex); |
||
2740 | |||
2741 | -- Display and move minimap button -- |
||
2742 | if ( not LootLinkState.hideminimap ) then |
||
2743 | LootLinkMinimapButton:Show(); |
||
2744 | LootLink_Minimap_Position(); |
||
2745 | end |
||
2746 | |||
2747 | if ( LootLinkState.mouseover ) then |
||
2748 | this:RegisterEvent("UPDATE_MOUSEOVER_UNIT"); |
||
2749 | end |
||
2750 | if ( LootLinkState.sortType ) then |
||
2751 | LootLink_UIDropDownMenu_SetSelectedID(LootLinkFrameDropDown, LootLinkState.sortType, LOOTLINK_DROPDOWN_LIST); |
||
2752 | end |
||
2753 | end |
||
2754 | |||
2755 | -------------------------------------------------------------------------------------------------- |
||
2756 | -- OnFoo functions |
||
2757 | -------------------------------------------------------------------------------------------------- |
||
2758 | function LootLink_OnLoad() |
||
2759 | local index; |
||
2760 | local value; |
||
2761 | |||
2762 | for index, value in ChatMessageTypes do |
||
2763 | this:RegisterEvent(value); |
||
2764 | end |
||
2765 | |||
2766 | for index = 1, getn(INVENTORY_SLOT_LIST), 1 do |
||
2767 | INVENTORY_SLOT_LIST[index].id = GetInventorySlotInfo(INVENTORY_SLOT_LIST[index].name); |
||
2768 | end |
||
2769 | |||
2770 | this:RegisterEvent("PLAYER_TARGET_CHANGED"); |
||
2771 | this:RegisterEvent("PLAYER_ENTERING_WORLD"); |
||
2772 | this:RegisterEvent("PLAYER_LEAVING_WORLD"); |
||
2773 | this:RegisterEvent("BANKFRAME_OPENED"); |
||
2774 | this:RegisterEvent("VARIABLES_LOADED"); |
||
2775 | this:RegisterEvent("AUCTION_HOUSE_SHOW"); |
||
2776 | this:RegisterEvent("AUCTION_HOUSE_CLOSE"); |
||
2777 | this:RegisterEvent("AUCTION_ITEM_LIST_UPDATE"); |
||
2778 | this:RegisterEvent("MERCHANT_SHOW"); |
||
2779 | --this:RegisterEvent("PLAYER_LOGOUT"); |
||
2780 | this:RegisterEvent("MEMORY_EXHAUSTED"); |
||
2781 | this:RegisterEvent("MEMORY_RECOVERED"); |
||
2782 | |||
2783 | -- Register our slash command |
||
2784 | SLASH_LOOTLINK1 = "/lootlink"; |
||
2785 | SLASH_LOOTLINK2 = "/ll"; |
||
2786 | SlashCmdList["LOOTLINK"] = function(msg) |
||
2787 | LootLink_SlashCommandHandler(msg); |
||
2788 | end |
||
2789 | |||
2790 | -- Hook the GameTooltip:SetOwner function |
||
2791 | lOriginal_GameTooltip_SetOwner = GameTooltip.SetOwner; |
||
2792 | GameTooltip.SetOwner = LootLink_GameTooltip_SetOwner; |
||
2793 | |||
2794 | -- Hook the ContainerFrameItemButton_OnEnter, ContainerFrame_Update and GameTooltip:SetLootItem functions |
||
2795 | lOriginal_ContainerFrameItemButton_OnEnter = ContainerFrameItemButton_OnEnter; |
||
2796 | ContainerFrameItemButton_OnEnter = LootLink_ContainerFrameItemButton_OnEnter; |
||
2797 | lOriginal_ContainerFrame_Update = ContainerFrame_Update; |
||
2798 | ContainerFrame_Update = LootLink_ContainerFrame_Update; |
||
2799 | lOriginal_GameTooltip_SetLootItem = GameTooltip.SetLootItem; |
||
2800 | GameTooltip.SetLootItem = LootLink_GameTooltip_SetLootItem; |
||
2801 | |||
2802 | -- Hook GameTooltip_OnHide and GameTooltip_ClearMoney |
||
2803 | lOriginal_GameTooltip_OnHide = GameTooltip_OnHide; |
||
2804 | GameTooltip_OnHide = LootLink_GameTooltip_OnHide; |
||
2805 | lOriginal_GameTooltip_ClearMoney = GameTooltip_ClearMoney; |
||
2806 | GameTooltip_ClearMoney = LootLink_GameTooltip_ClearMoney; |
||
2807 | |||
2808 | -- Hook the shopping tooltip functions |
||
2809 | lOriginal_ShoppingTooltip1_SetMerchantCompareItem = ShoppingTooltip1.SetMerchantCompareItem; |
||
2810 | ShoppingTooltip1.SetMerchantCompareItem = LootLink_ShoppingTooltip1_SetMerchantCompareItem; |
||
2811 | lOriginal_ShoppingTooltip2_SetMerchantCompareItem = ShoppingTooltip2.SetMerchantCompareItem; |
||
2812 | ShoppingTooltip2.SetMerchantCompareItem = LootLink_ShoppingTooltip2_SetMerchantCompareItem; |
||
2813 | |||
2814 | lOriginal_ShoppingTooltip1_SetAuctionCompareItem = ShoppingTooltip1.SetAuctionCompareItem; |
||
2815 | ShoppingTooltip1.SetAuctionCompareItem = LootLink_ShoppingTooltip1_SetAuctionCompareItem; |
||
2816 | lOriginal_ShoppingTooltip2_SetAuctionCompareItem = ShoppingTooltip2.SetAuctionCompareItem; |
||
2817 | ShoppingTooltip2.SetAuctionCompareItem = LootLink_ShoppingTooltip2_SetAuctionCompareItem; |
||
2818 | |||
2819 | -- Hook SetItemRef |
||
2820 | lOriginal_SetItemRef = SetItemRef; |
||
2821 | SetItemRef = LootLink_SetItemRef; |
||
2822 | |||
2823 | -- Hook our hidden tooltip's OnTooltipAddMoney |
||
2824 | lOriginal_OnTooltipAddMoney = LLHiddenTooltip:GetScript("OnTooltipAddMoney"); |
||
2825 | LLHiddenTooltip:SetScript("OnTooltipAddMoney", LootLink_OnTooltipAddMoney); |
||
2826 | |||
2827 | -- Hook chat edit box |
||
2828 | lOriginal_ChatEdit_OnTabPressed = ChatEdit_OnTabPressed; |
||
2829 | ChatEdit_OnTabPressed = LootLink_ChatEdit_OnTabPressed; |
||
2830 | lOriginal_ChatEdit_OnTextChanged = ChatEdit_OnTextChanged; |
||
2831 | ChatEdit_OnTextChanged = LootLink_ChatEdit_OnTextChanged; |
||
2832 | |||
2833 | -- Hook CloseWindows |
||
2834 | lOriginal_CloseWindows = CloseWindows; |
||
2835 | CloseWindows = LootLink_CloseWindows; |
||
2836 | |||
2837 | if( DEFAULT_CHAT_FRAME ) then |
||
2838 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_LOADED); |
||
2839 | end |
||
2840 | UIErrorsFrame:AddMessage(LOOTLINK_LOADED, 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME); |
||
2841 | end |
||
2842 | |||
2843 | function LootLink_Minimap_OnEnter() |
||
2844 | GameTooltip:SetOwner(this, "ANCHOR_BOTTOMLEFT"); |
||
2845 | GameTooltip:AddLine(LOOTLINK_TITLE); |
||
2846 | if ( not LootLinkState.lockminimap ) then |
||
2847 | GameTooltip:AddLine("|cffaaaaaa "..LOOTLINK_MINIMAP_DRAG); |
||
2848 | end |
||
2849 | if ( LootLinkFrame.process ) then |
||
2850 | GameTooltip:AddLine("|cffaaaaaa "..getglobal("LLP_"..LootLinkFrame.process.."_LABEL")); |
||
2851 | if ( LootLink_Process:IsVisible() ) then |
||
2852 | GameTooltip:AddLine("|cffaaaaaa "..LOOTLINK_MINIMAP_PROCESS_SHOW); |
||
2853 | else |
||
2854 | GameTooltip:AddLine("|cffaaaaaa "..LOOTLINK_MINIMAP_PROCESS_HIDE); |
||
2855 | end |
||
2856 | end |
||
2857 | GameTooltip:Show(); |
||
2858 | end |
||
2859 | |||
2860 | function LootLink_Minimap_Position(x,y) |
||
2861 | if ( x or y ) then |
||
2862 | if ( x ) then if ( x < 0 ) then x = x + 360; end LootLinkState.x = x; end |
||
2863 | if ( y ) then LootLinkState.y = y; end |
||
2864 | end |
||
2865 | x, y = LootLinkState.x, LootLinkState.y |
||
2866 | |||
2867 | if ( LootLinkOptionsFrame:IsVisible() ) then |
||
2868 | LLO_MinimapPos:SetValue( x or LLO_MINIMAP_X ); |
||
2869 | LLO_MinimapOffset:SetValue( y or LLO_MINIMAP_Y ); |
||
2870 | end |
||
2871 | LootLinkMinimapButton:SetPoint("TOPLEFT","Minimap","TOPLEFT",53-((80+(y or LLO_MINIMAP_Y))*cos(x or LLO_MINIMAP_X)),((80+(y or LLO_MINIMAP_Y))*sin(x or LLO_MINIMAP_X))-55); |
||
2872 | end |
||
2873 | |||
2874 | function LootLink_Minimap_DragStart() |
||
2875 | if ( LootLinkState.lockminimap ) then return; end |
||
2876 | this:SetScript("OnUpdate", LootLink_Minimap_DragUpdate); |
||
2877 | end |
||
2878 | function LootLink_Minimap_DragStop() |
||
2879 | LootLinkMinimapButton:UnlockHighlight() |
||
2880 | this:SetScript("OnUpdate", nil); |
||
2881 | end |
||
2882 | function LootLink_Minimap_DragUpdate() |
||
2883 | -- Thanks to Gello for making this a ton shorter |
||
2884 | LootLinkMinimapButton:LockHighlight(); |
||
2885 | local curX, curY = GetCursorPosition(); |
||
2886 | local mapX, mapY = Minimap:GetCenter(); |
||
2887 | local x, y; |
||
2888 | if ( IsShiftKeyDown() ) then |
||
2889 | y = math.pow( math.pow(curY - mapY * Minimap:GetEffectiveScale(), 2) + math.pow(mapX * Minimap:GetEffectiveScale() - curX, 2), 0.5) - 70; |
||
2890 | y = min( max( y, -30 ), 30 ); |
||
2891 | end |
||
2892 | x = math.deg(math.atan2( curY - mapY * Minimap:GetEffectiveScale(), mapX * Minimap:GetEffectiveScale() - curX )); |
||
2893 | LootLink_Minimap_Position(x,y); |
||
2894 | end |
||
2895 | |||
2896 | function LootLink_CanSendAuctionQuery() |
||
2897 | local value = lOriginal_CanSendAuctionQuery(); |
||
2898 | if( value ) then |
||
2899 | LootLink_AuctionNextQuery(); |
||
2900 | return nil; |
||
2901 | end |
||
2902 | return value; |
||
2903 | end |
||
2904 | |||
2905 | function LootLink_AuctionFrameBrowse_OnEvent() |
||
2906 | -- Intentionally empty; don't allow the auction UI to update while we're scanning |
||
2907 | end |
||
2908 | |||
2909 | function LootLink_GameTooltip_SetOwner(this, owner, anchor) |
||
2910 | lOriginal_GameTooltip_SetOwner(this, owner, anchor); |
||
2911 | lGameToolTipOwner = owner; |
||
2912 | end |
||
2913 | |||
2914 | function LootLink_GameTooltip_ClearMoney() |
||
2915 | lOriginal_GameTooltip_ClearMoney(); |
||
2916 | if( not lSuppressInfoAdd ) then |
||
2917 | lCheckTooltip = LootLink_CheckTooltipInfo(); |
||
2918 | end |
||
2919 | end |
||
2920 | |||
2921 | function LootLink_GameTooltip_ClearMoney_Temp() |
||
2922 | -- Intentionally empty; don't clear money while we use our hidden tooltip |
||
2923 | end |
||
2924 | |||
2925 | function LootLink_ContainerFrameItemButton_OnEnter() |
||
2926 | LootLink_AutoInfoOff(); |
||
2927 | lOriginal_ContainerFrameItemButton_OnEnter(); |
||
2928 | if( not InRepairMode() and not MerchantFrame:IsVisible() ) then |
||
2929 | local frameID = this:GetParent():GetID(); |
||
2930 | local buttonID = this:GetID(); |
||
2931 | local link = GetContainerItemLink(frameID, buttonID); |
||
2932 | local name = LootLink_NameFromLink(link); |
||
2933 | |||
2934 | if( name and ItemLinks[name] ) then |
||
2935 | local texture, itemCount, locked, quality, readable = GetContainerItemInfo(frameID, buttonID); |
||
2936 | LootLink_AddTooltipInfo(name, GameTooltip, itemCount); |
||
2937 | GameTooltip:Show(); |
||
2938 | end |
||
2939 | end |
||
2940 | LootLink_AutoInfoOn(); |
||
2941 | end |
||
2942 | |||
2943 | function LootLink_ContainerFrame_Update(frame) |
||
2944 | LootLink_AutoInfoOff(); |
||
2945 | lOriginal_ContainerFrame_Update(frame); |
||
2946 | if( not InRepairMode() and not MerchantFrame:IsVisible() and GameTooltip:IsVisible() ) then |
||
2947 | local frameID = frame:GetID(); |
||
2948 | local frameName = frame:GetName(); |
||
2949 | local iButton; |
||
2950 | for iButton = 1, frame.size do |
||
2951 | local button = getglobal(frameName.."Item"..iButton); |
||
2952 | if( GameTooltip:IsOwned(button) ) then |
||
2953 | local buttonID = button:GetID(); |
||
2954 | local link = GetContainerItemLink(frameID, buttonID); |
||
2955 | local name = LootLink_NameFromLink(link); |
||
2956 | |||
2957 | if( name and ItemLinks[name] ) then |
||
2958 | local texture, itemCount, locked, quality, readable = GetContainerItemInfo(frameID, buttonID); |
||
2959 | LootLink_AddTooltipInfo(name, GameTooltip, itemCount); |
||
2960 | GameTooltip:Show(); |
||
2961 | end |
||
2962 | end |
||
2963 | end |
||
2964 | end |
||
2965 | LootLink_AutoInfoOn(); |
||
2966 | end |
||
2967 | |||
2968 | function LootLink_GameTooltip_OnHide() |
||
2969 | lOriginal_GameTooltip_OnHide(); |
||
2970 | GameTooltip.llDone = nil; |
||
2971 | lCheckTooltip = nil; |
||
2972 | end |
||
2973 | |||
2974 | function LootLink_GameTooltip_SetLootItem(this, slot) |
||
2975 | LootLink_AutoInfoOff(); |
||
2976 | lOriginal_GameTooltip_SetLootItem(this, slot); |
||
2977 | |||
2978 | local link = GetLootSlotLink(slot); |
||
2979 | local name = LootLink_NameFromLink(link); |
||
2980 | if( name and ItemLinks[name] and ItemLinks[name].p ) then |
||
2981 | local texture, item, quantity, quality = GetLootSlotInfo(slot); |
||
2982 | LootLink_AddTooltipInfo(name, GameTooltip, quantity); |
||
2983 | end |
||
2984 | LootLink_AutoInfoOn(); |
||
2985 | end |
||
2986 | |||
2987 | function LootLink_ShoppingTooltip1_SetMerchantCompareItem(this, id, num) |
||
2988 | LootLink_MoneyToggle(); |
||
2989 | local retval = lOriginal_ShoppingTooltip1_SetMerchantCompareItem(this, id, num); |
||
2990 | LootLink_MoneyToggle(1); |
||
2991 | return retval; |
||
2992 | end |
||
2993 | |||
2994 | function LootLink_ShoppingTooltip2_SetMerchantCompareItem(this, id, num) |
||
2995 | LootLink_MoneyToggle(); |
||
2996 | local retval = lOriginal_ShoppingTooltip2_SetMerchantCompareItem(this, id, num); |
||
2997 | LootLink_MoneyToggle(1); |
||
2998 | return retval; |
||
2999 | end |
||
3000 | |||
3001 | function LootLink_ShoppingTooltip1_SetAuctionCompareItem(this, _type, index, num) |
||
3002 | LootLink_MoneyToggle(); |
||
3003 | local retval = lOriginal_ShoppingTooltip1_SetAuctionCompareItem(this, _type, index, num); |
||
3004 | LootLink_MoneyToggle(1); |
||
3005 | return retval; |
||
3006 | end |
||
3007 | |||
3008 | function LootLink_ShoppingTooltip2_SetAuctionCompareItem(this, _type, index, num) |
||
3009 | LootLink_MoneyToggle(); |
||
3010 | local retval = lOriginal_ShoppingTooltip2_SetAuctionCompareItem(this, _type, index, num); |
||
3011 | LootLink_MoneyToggle(1); |
||
3012 | return retval; |
||
3013 | end |
||
3014 | |||
3015 | function LootLink_SetItemRef(link, text, button) |
||
3016 | lOriginal_SetItemRef(link, text, button); |
||
3017 | |||
3018 | -- If this is a tooltip-creating link, add our information to it |
||
3019 | if( strsub(link, 1, 6) ~= "Player" ) then |
||
3020 | ItemRefTooltipMoneyFrame:SetPoint("LEFT", "ItemRefTooltipTextLeft1", "LEFT", 0, 0); |
||
3021 | ItemRefTooltipMoneyFrame:Hide(); |
||
3022 | |||
3023 | if( ItemRefTooltip:IsVisible() ) then |
||
3024 | local field = getglobal("ItemRefTooltipTextLeft1"); |
||
3025 | if( field and field:IsShown() ) then |
||
3026 | local name = field:GetText(); |
||
3027 | if( name and ItemLinks[name] ) then |
||
3028 | LootLink_AddTooltipInfo(name, ItemRefTooltip); |
||
3029 | end |
||
3030 | end |
||
3031 | end |
||
3032 | end |
||
3033 | end |
||
3034 | |||
3035 | function LootLink_OnTooltipAddMoney() |
||
3036 | lOriginal_OnTooltipAddMoney(); |
||
3037 | if( lBagID and lSlotID ) then |
||
3038 | LootLink_ScanSellPrice(arg1); |
||
3039 | end |
||
3040 | end |
||
3041 | |||
3042 | function LootLink_OnEvent() |
||
3043 | if( event == "PLAYER_TARGET_CHANGED" ) then |
||
3044 | if( UnitIsUnit("target", "player") ) then |
||
3045 | return; |
||
3046 | elseif( UnitIsPlayer("target") ) then |
||
3047 | LootLink_Inspect("target"); |
||
3048 | end |
||
3049 | elseif( event == "UPDATE_MOUSEOVER_UNIT" ) then |
||
3050 | LootLink_Inspect("mouseover"); |
||
3051 | elseif( event == "PLAYER_ENTERING_WORLD" ) then |
||
3052 | this:RegisterEvent("UNIT_INVENTORY_CHANGED"); |
||
3053 | -- Now that we're in the world, we want to watch for inventory changes |
||
3054 | this:RegisterEvent("UNIT_INVENTORY_CHANGED"); |
||
3055 | |||
3056 | -- Check to see if the user needs to upgrade their database |
||
3057 | LootLink_CheckVersionReminder(); |
||
3058 | |||
3059 | -- Do initial scan of inventory and equipped items |
||
3060 | LootLink_ScanInventory(); |
||
3061 | LootLink_Inspect("player"); |
||
3062 | elseif( event == "PLAYER_LEAVING_WORLD" ) then |
||
3063 | -- When we leave the world, we don't need to watch for inventory changes, |
||
3064 | -- especially since zoning will cause one UNIT_INVENTORY_CHANGED event for |
||
3065 | -- each item in the player's inventory and that they have equipped |
||
3066 | this:UnregisterEvent("UNIT_INVENTORY_CHANGED"); |
||
3067 | elseif( event == "UNIT_INVENTORY_CHANGED" ) then |
||
3068 | if( arg1 == "player" ) then |
||
3069 | LootLink_ScanInventory(); |
||
3070 | LootLink_Inspect("player"); |
||
3071 | end |
||
3072 | elseif( event == "BANKFRAME_OPENED" ) then |
||
3073 | LootLink_ScanBank(); |
||
3074 | elseif( event == "VARIABLES_LOADED" ) then |
||
3075 | LootLink_VariablesLoaded(); |
||
3076 | elseif( event == "AUCTION_HOUSE_SHOW" ) then |
||
3077 | if( lScanAuction ) then |
||
3078 | LootLink_StartAuctionScan(); |
||
3079 | end |
||
3080 | elseif( event == "AUCTION_HOUSE_CLOSED" ) then |
||
3081 | LootLink_StopAuctionScan(); |
||
3082 | elseif( event == "AUCTION_ITEM_LIST_UPDATE" ) then |
||
3083 | LootLink_ScanAuction(); |
||
3084 | elseif( event == "MERCHANT_SHOW" ) then |
||
3085 | LootLink_ScanSellPrices(); |
||
3086 | --elseif( event == "PLAYER_LOGOUT" ) then |
||
3087 | --LootLink_ClearDelayed(); |
||
3088 | elseif( event == "MEMORY_EXHAUSTED" ) then |
||
3089 | LLP_OUTOFMEM = 1; |
||
3090 | elseif( event == "MEMORY_RECOVERED" ) then |
||
3091 | LLP_OUTOFMEM = nil; |
||
3092 | else |
||
3093 | local name = LootLink_ProcessLinks(arg1, event == "CHAT_MSG_LOOT"); |
||
3094 | if( name and ItemLinks[name] ) then |
||
3095 | LootLink_Event_ScanChat(name, ItemLinks[name], arg1); |
||
3096 | end |
||
3097 | end |
||
3098 | end |
||
3099 | |||
3100 | function LootLink_RemoveItem(name, link, displayindex, index) |
||
3101 | local value = ItemLinks[name]; |
||
3102 | if ( not value ) then |
||
3103 | return; |
||
3104 | end |
||
3105 | local found; |
||
3106 | if ( link and string.sub(link, 1, 5) == "item:" ) then |
||
3107 | link = string.sub( link, 6 ); |
||
3108 | end |
||
3109 | if ( displayindex and not link and not index ) then |
||
3110 | link = DisplayIndices[displayindex][2].i; |
||
3111 | end |
||
3112 | if ( not link and not index ) then |
||
3113 | index = 0; |
||
3114 | end |
||
3115 | if ( link or index ) then |
||
3116 | if ( (index and index == 0) or (value.i and value.i == link) ) then |
||
3117 | found = 1; |
||
3118 | if ( value.m and value.m[1] ) then |
||
3119 | for k, v in value.m[1] do |
||
3120 | value[k] = v; |
||
3121 | end |
||
3122 | tremove( value.m, 1 ); |
||
3123 | |||
3124 | if ( getn(value.m) == 0 ) then |
||
3125 | value.m = nil; |
||
3126 | end |
||
3127 | else |
||
3128 | ItemLinks[name] = nil; |
||
3129 | di = 0; |
||
3130 | end |
||
3131 | else |
||
3132 | if ( value.m ) then |
||
3133 | for i=1, getn(value.m) do |
||
3134 | if ( (index and index == i) or (value.m[i].i == link) ) then |
||
3135 | found = 1; |
||
3136 | tremove( value.m, i ); |
||
3137 | break; |
||
3138 | end |
||
3139 | end |
||
3140 | end |
||
3141 | end |
||
3142 | |||
3143 | if ( found ) then |
||
3144 | LootLink_SortAlternates( name ); |
||
3145 | |||
3146 | if ( DisplayIndices and LootLinkFrame:IsVisible() ) then |
||
3147 | local dName, start; |
||
3148 | local i = 1; |
||
3149 | if ( DisplayIndices[i] ) then |
||
3150 | dName = DisplayIndices[i][1]; |
||
3151 | end |
||
3152 | while dName do |
||
3153 | if dName == name then |
||
3154 | if not start then |
||
3155 | start = i; |
||
3156 | end |
||
3157 | elseif start then |
||
3158 | break; |
||
3159 | end |
||
3160 | i = i+1; |
||
3161 | if ( DisplayIndices[i] ) then |
||
3162 | dName = DisplayIndices[i][1]; |
||
3163 | else |
||
3164 | dName = nil; |
||
3165 | end |
||
3166 | end |
||
3167 | if ( start and i ) then |
||
3168 | tremove(DisplayIndices, i-1); |
||
3169 | DisplayIndices.onePastEnd = DisplayIndices.onePastEnd - 1; |
||
3170 | if ( displayindex ) then |
||
3171 | LootLink_Update(); |
||
3172 | LootLink_SetTitle(); |
||
3173 | end |
||
3174 | end |
||
3175 | else |
||
3176 | DisplayIndices = nil; |
||
3177 | end |
||
3178 | return 1; |
||
3179 | end |
||
3180 | end |
||
3181 | end |
||
3182 | |||
3183 | function LootLinkItemButton_OnClick(button) |
||
3184 | local name = this:GetText(); |
||
3185 | local index = this.i; |
||
3186 | if( button == "LeftButton" ) then |
||
3187 | local data = DisplayIndices[this:GetID()+FauxScrollFrame_GetOffset(LootLinkListScrollFrame)]; |
||
3188 | if( IsShiftKeyDown() and ChatFrameEditBox:IsVisible() ) then |
||
3189 | if ( not LootLink_CheckItemServer(data[2], lServerIndex) ) then |
||
3190 | local dialog = StaticPopup_Show("LOOTLINK_LINK_CONFIRM", LOOTLINK_STATICPOPUP_SERVER, LOOTLINK_STATICPOPUP_LINKITEM); |
||
3191 | if ( dialog ) then |
||
3192 | dialog.data = data; |
||
3193 | end |
||
3194 | elseif ( not GetItemInfo("item:"..data[2].i) ) then |
||
3195 | local dialog = StaticPopup_Show("LOOTLINK_LINK_CONFIRM", LOOTLINK_STATICPOPUP_INVALID, LOOTLINK_STATICPOPUP_LINKITEM); |
||
3196 | if ( dialog ) then |
||
3197 | dialog.data = data; |
||
3198 | end |
||
3199 | else |
||
3200 | ChatFrameEditBox:Insert(LootLink_GetLink(name, data[3])); |
||
3201 | end |
||
3202 | end |
||
3203 | if( IsControlKeyDown() ) then |
||
3204 | if ( not LootLink_CheckItemServer(data[2], lServerIndex) ) then |
||
3205 | local dialog = StaticPopup_Show("LOOTLINK_DRESSUP_CONFIRM", LOOTLINK_STATICPOPUP_SERVER, LOOTLINK_STATICPOPUP_DRESSUP); |
||
3206 | if ( dialog ) then |
||
3207 | dialog.data = data; |
||
3208 | end |
||
3209 | elseif ( not GetItemInfo("item:"..data[2].i) ) then |
||
3210 | local dialog = StaticPopup_Show("LOOTLINK_DRESSUP_CONFIRM", LOOTLINK_STATICPOPUP_INVALID, LOOTLINK_STATICPOPUP_DRESSUP); |
||
3211 | if ( dialog ) then |
||
3212 | dialog.data = data; |
||
3213 | end |
||
3214 | else |
||
3215 | DressUpItemLink(LootLink_GetLink(name, data[3])); |
||
3216 | end |
||
3217 | end |
||
3218 | elseif( button == "RightButton" ) then |
||
3219 | if( IsShiftKeyDown() and IsControlKeyDown() ) then |
||
3220 | local data = DisplayIndices[this:GetID()+FauxScrollFrame_GetOffset(LootLinkListScrollFrame)]; |
||
3221 | local dialog = StaticPopup_Show("LOOTLINK_DELETEITEM_CONFIRM", data[2].c, name); |
||
3222 | if ( dialog ) then |
||
3223 | dialog.data = data; |
||
3224 | end |
||
3225 | --if ( LootLink_RemoveItem(name, nil, this:GetID()+FauxScrollFrame_GetOffset(LootLinkListScrollFrame)) ) then |
||
3226 | -- LootLink_SortAlternates(name); |
||
3227 | --end |
||
3228 | end |
||
3229 | end |
||
3230 | --@todo Telo: add a method to correct the color of items |
||
3231 | end |
||
3232 | |||
3233 | function LootLink_OnShow() |
||
3234 | PlaySound("igMainMenuOpen"); |
||
3235 | LootLink_Update(); |
||
3236 | end |
||
3237 | |||
3238 | function LootLink_OnHide() |
||
3239 | PlaySound("igMainMenuClose"); |
||
3240 | end |
||
3241 | |||
3242 | function LootLink_ClearDelayed() |
||
3243 | if ( LootLinkFrame.schedule ) then |
||
3244 | for k, v in LootLinkFrame.schedule do |
||
3245 | local value, index = LootLink_GetValue( v[1], nil, v[2] ); |
||
3246 | if ( v and not v.t ) then |
||
3247 | if ( LootLink_RemoveItem(v[1], v[2]) ) then |
||
3248 | LootLink_SortAlternates(v[1]); |
||
3249 | end |
||
3250 | end |
||
3251 | end |
||
3252 | end |
||
3253 | LootLinkFrame.schedule = nil; |
||
3254 | end |
||
3255 | |||
3256 | function LootLink_ScheduleItem(name,link,time) |
||
3257 | if ( not LootLinkFrame.schedule ) then |
||
3258 | LootLinkFrame.schedule = {}; |
||
3259 | end |
||
3260 | for k, v in LootLinkFrame.schedule do |
||
3261 | if ( v[1] == name and v[2] == link ) then |
||
3262 | return; |
||
3263 | end |
||
3264 | end |
||
3265 | LLHiddenTooltip:SetHyperlink("item:"..link); |
||
3266 | tinsert( LootLinkFrame.schedule, {name,link,(time or LOOTLINK_SCHEDULE_DELAY)} ); |
||
3267 | end |
||
3268 | |||
3269 | function LootLink_OnUpdate(elapsed) |
||
3270 | if( lCheckTooltip ) then |
||
3271 | lCheckTooltip = LootLink_CheckTooltipInfo(); |
||
3272 | end |
||
3273 | if ( LootLinkFrame.process ) then |
||
3274 | LootLinkProcess_Run(); |
||
3275 | end |
||
3276 | local list = LootLinkFrame.schedule; |
||
3277 | if ( list ) then |
||
3278 | for k, v in list do |
||
3279 | v[3] = v[3] - elapsed; |
||
3280 | if ( v[3] < 0 ) then |
||
3281 | local value, index = LootLink_GetValue( v[1], nil, v[2] ); |
||
3282 | if ( not value ) then |
||
3283 | -- Item was remove from ItemLinks table, stop trying to check for it. |
||
3284 | tremove( list, k ); |
||
3285 | return; |
||
3286 | elseif ( LootLink_BuildSearchData( v[1], value, index ) ) then |
||
3287 | tremove( list, k ); |
||
3288 | return; |
||
3289 | else |
||
3290 | -- Still don't have information from server. |
||
3291 | if ( v[4] and v[4] == 60 ) then |
||
3292 | -- we've tried long enough, fail this item; |
||
3293 | if ( LootLink_RemoveItem(v[1], v[2]) ) then |
||
3294 | LootLink_SortAlternates(name); |
||
3295 | end |
||
3296 | tremove( list, k ); |
||
3297 | return; |
||
3298 | end |
||
3299 | v[4] = (v[4] or 0) + 1; |
||
3300 | v[3] = LOOTLINK_SCHEDULE_DELAY; |
||
3301 | end |
||
3302 | end |
||
3303 | end |
||
3304 | if ( getn(list) == 0 ) then |
||
3305 | list = nil; |
||
3306 | end |
||
3307 | end |
||
3308 | end |
||
3309 | |||
3310 | function LootLinkItemButton_OnEnter() |
||
3311 | local link = LootLink_GetHyperlink(this:GetText(), this.i); |
||
3312 | if( link ) then |
||
3313 | LootLinkFrame.TooltipButton = this:GetID(); |
||
3314 | LootLinkTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT"); |
||
3315 | if ( LootLink_SetHyperlink(LootLinkTooltip, this:GetText(), link, this.i) ) then |
||
3316 | LootLink_Update(); |
||
3317 | end |
||
3318 | LootLink_AddTooltipTexture(link); |
||
3319 | LootLink_AddTooltipInfo(this:GetText(), nil, nil, this.i); |
||
3320 | end |
||
3321 | end |
||
3322 | |||
3323 | function LootLinkItemButton_OnLeave() |
||
3324 | if( LootLinkFrame.TooltipButton ) then |
||
3325 | LootLinkFrame.TooltipButton = nil; |
||
3326 | HideUIPanel(LootLinkTooltip); |
||
3327 | end |
||
3328 | LootLink_AddTooltipTexture(); |
||
3329 | end |
||
3330 | |||
3331 | function LootLinkFrameDropDown_OnLoad() |
||
3332 | UIDropDownMenu_Initialize(LootLinkFrameDropDown, LootLinkFrameDropDown_Initialize); |
||
3333 | LootLink_UIDropDownMenu_SetSelectedID(LootLinkFrameDropDown, 1, LOOTLINK_DROPDOWN_LIST); |
||
3334 | UIDropDownMenu_SetWidth(80); |
||
3335 | UIDropDownMenu_SetButtonWidth(24); |
||
3336 | UIDropDownMenu_JustifyText("LEFT", LootLinkFrameDropDown) |
||
3337 | end |
||
3338 | |||
3339 | function LootLinkFrameDropDownButton_OnClick() |
||
3340 | local oldID = UIDropDownMenu_GetSelectedID(LootLinkFrameDropDown); |
||
3341 | UIDropDownMenu_SetSelectedID(LootLinkFrameDropDown, this:GetID()); |
||
3342 | if( oldID ~= this:GetID() ) then |
||
3343 | LootLink_Refresh(); |
||
3344 | end |
||
3345 | LootLinkState.sortType = this:GetID(); |
||
3346 | end |
||
3347 | |||
3348 | function LLS_RarityDropDown_OnLoad() |
||
3349 | UIDropDownMenu_SetWidth(90); |
||
3350 | UIDropDownMenu_SetButtonWidth(24); |
||
3351 | UIDropDownMenu_JustifyText("LEFT", LLS_RarityDropDown); |
||
3352 | end |
||
3353 | |||
3354 | function LLS_RarityDropDown_OnClick() |
||
3355 | UIDropDownMenu_SetSelectedID(LLS_RarityDropDown, this:GetID()); |
||
3356 | end |
||
3357 | |||
3358 | function LLS_BindsDropDown_OnLoad() |
||
3359 | UIDropDownMenu_SetWidth(90); |
||
3360 | UIDropDownMenu_SetButtonWidth(24); |
||
3361 | UIDropDownMenu_JustifyText("LEFT", LLS_BindsDropDown); |
||
3362 | end |
||
3363 | |||
3364 | function LLS_BindsDropDown_OnClick() |
||
3365 | UIDropDownMenu_SetSelectedID(LLS_BindsDropDown, this:GetID()); |
||
3366 | end |
||
3367 | |||
3368 | function LLS_LocationDropDown_OnLoad() |
||
3369 | UIDropDownMenu_SetWidth(90); |
||
3370 | UIDropDownMenu_SetButtonWidth(24); |
||
3371 | UIDropDownMenu_JustifyText("LEFT", LLS_LocationDropDown); |
||
3372 | end |
||
3373 | |||
3374 | function LLS_LocationDropDown_OnClick() |
||
3375 | UIDropDownMenu_SetSelectedID(LLS_LocationDropDown, this:GetID()); |
||
3376 | end |
||
3377 | |||
3378 | function LLS_TypeDropDown_OnLoad() |
||
3379 | UIDropDownMenu_SetWidth(90); |
||
3380 | UIDropDownMenu_SetButtonWidth(24); |
||
3381 | UIDropDownMenu_JustifyText("LEFT", LLS_TypeDropDown); |
||
3382 | end |
||
3383 | |||
3384 | function LLS_TypeDropDown_OnClick() |
||
3385 | local oldID = UIDropDownMenu_GetSelectedID(LLS_TypeDropDown); |
||
3386 | UIDropDownMenu_SetSelectedID(LLS_TypeDropDown, this:GetID()); |
||
3387 | if( oldID ~= this:GetID() ) then |
||
3388 | LootLink_SetupTypeUI(this:GetID(), 1); |
||
3389 | end |
||
3390 | end |
||
3391 | |||
3392 | function LLS_SubtypeDropDown_OnLoad() |
||
3393 | UIDropDownMenu_SetWidth(90); |
||
3394 | UIDropDownMenu_SetButtonWidth(24); |
||
3395 | UIDropDownMenu_JustifyText("LEFT", LLS_SubtypeDropDown); |
||
3396 | end |
||
3397 | |||
3398 | function LLS_SubtypeDropDown_OnClick() |
||
3399 | UIDropDownMenu_SetSelectedID(LLS_SubtypeDropDown, this:GetID()); |
||
3400 | end |
||
3401 | |||
3402 | function LLO_RarityDropDown_OnLoad() |
||
3403 | UIDropDownMenu_SetWidth(90); |
||
3404 | UIDropDownMenu_SetButtonWidth(24); |
||
3405 | UIDropDownMenu_JustifyText("LEFT", LLO_RarityDropDown); |
||
3406 | end |
||
3407 | |||
3408 | function LLO_RarityDropDown_OnClick() |
||
3409 | UIDropDownMenu_SetSelectedID(LLO_RarityDropDown, this:GetID()); |
||
3410 | end |
||
3411 | |||
3412 | -------------------------------------------------------------------------------------------------- |
||
3413 | -- Callback functions |
||
3414 | -------------------------------------------------------------------------------------------------- |
||
3415 | function ToggleLootLink() |
||
3416 | if( LootLinkFrame:IsVisible() ) then |
||
3417 | HideUIPanel(LootLinkFrame); |
||
3418 | else |
||
3419 | ShowUIPanel(LootLinkFrame); |
||
3420 | end |
||
3421 | end |
||
3422 | |||
3423 | function LootLink_SlashCommandHandler(msg) |
||
3424 | local reset; |
||
3425 | local makehome; |
||
3426 | local light; |
||
3427 | local aborted; |
||
3428 | |||
3429 | if( not lDisableVersionReminder ) then |
||
3430 | LootLink_CheckVersionReminder(); |
||
3431 | end |
||
3432 | if( not msg or msg == "" ) then |
||
3433 | ToggleLootLink(); |
||
3434 | else |
||
3435 | local command = string.lower(msg); |
||
3436 | if( command == LOOTLINK_HELP ) then |
||
3437 | local index = 0; |
||
3438 | local value = getglobal("LOOTLINK_HELP_TEXT"..index); |
||
3439 | while( value ) do |
||
3440 | DEFAULT_CHAT_FRAME:AddMessage(value); |
||
3441 | index = index + 1; |
||
3442 | value = getglobal("LOOTLINK_HELP_TEXT"..index); |
||
3443 | end |
||
3444 | elseif( command == LOOTLINK_STATUS ) then |
||
3445 | LootLink_Status(); |
||
3446 | elseif( command == LOOTLINK_AUCTION or command == LOOTLINK_SCAN ) then |
||
3447 | if( AuctionFrame and AuctionFrame:IsVisible() ) then |
||
3448 | local iButton; |
||
3449 | local button; |
||
3450 | |||
3451 | -- Hide the UI from any current results, show the no results text so we can use it |
||
3452 | BrowseNoResultsText:Show(); |
||
3453 | for iButton = 1, NUM_BROWSE_TO_DISPLAY do |
||
3454 | button = getglobal("BrowseButton"..iButton); |
||
3455 | button:Hide(); |
||
3456 | end |
||
3457 | BrowsePrevPageButton:Hide(); |
||
3458 | BrowseNextPageButton:Hide(); |
||
3459 | BrowseSearchCountText:Hide(); |
||
3460 | |||
3461 | LootLink_StartAuctionScan(); |
||
3462 | else |
||
3463 | lScanAuction = 1; |
||
3464 | LootLink_Status(); |
||
3465 | end |
||
3466 | elseif( command == LOOTLINK_SHOWINFO ) then |
||
3467 | LootLinkState.HideInfo = nil; |
||
3468 | LootLink_Status(); |
||
3469 | elseif( command == LOOTLINK_HIDEINFO ) then |
||
3470 | LootLinkState.HideInfo = 1; |
||
3471 | LootLink_Status(); |
||
3472 | elseif( command == LOOTLINK_FULLMODE ) then |
||
3473 | LootLinkState.LightMode = nil; |
||
3474 | LootLink_Status(); |
||
3475 | else |
||
3476 | local iStart; |
||
3477 | local iEnd; |
||
3478 | local args; |
||
3479 | |||
3480 | iStart, iEnd, command, args = string.find(command, "^(%w+)%s*(.*)$"); |
||
3481 | |||
3482 | if( command == LOOTLINK_RESET ) then |
||
3483 | if( lResetNeedsConfirm ) then |
||
3484 | if( args == LOOTLINK_CONFIRM ) then |
||
3485 | LootLink_Reset(); |
||
3486 | lResetNeedsConfirm = nil; |
||
3487 | lDisableVersionReminder = nil |
||
3488 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_RESET_DONE); |
||
3489 | end |
||
3490 | else |
||
3491 | reset = 1; |
||
3492 | lResetNeedsConfirm = 1; |
||
3493 | lDisableVersionReminder = 1; |
||
3494 | end |
||
3495 | elseif( LootLink_GetDataVersion() < 110 and command == LOOTLINK_MAKEHOME ) then |
||
3496 | if( lMakeHomeNeedsConfirm ) then |
||
3497 | if( args == LOOTLINK_CONFIRM ) then |
||
3498 | LootLink_MakeHome(); |
||
3499 | lMakeHomeNeedsConfirm = nil; |
||
3500 | lDisableVersionReminder = nil; |
||
3501 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_MAKEHOME_DONE); |
||
3502 | end |
||
3503 | else |
||
3504 | makehome = 1; |
||
3505 | lMakeHomeNeedsConfirm = 1; |
||
3506 | lDisableVersionReminder = 1; |
||
3507 | end |
||
3508 | elseif( command == LOOTLINK_LIGHTMODE ) then |
||
3509 | if( lLightModeNeedsConfirm ) then |
||
3510 | if( args == LOOTLINK_CONFIRM ) then |
||
3511 | LootLink_LightMode(); |
||
3512 | lLightModeNeedsConfirm = nil; |
||
3513 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_LIGHTMODE_DONE); |
||
3514 | end |
||
3515 | else |
||
3516 | light = 1; |
||
3517 | lLightModeNeedsConfirm = 1; |
||
3518 | end |
||
3519 | end |
||
3520 | end |
||
3521 | end |
||
3522 | |||
3523 | if( not reset ) then |
||
3524 | if( lResetNeedsConfirm ) then |
||
3525 | aborted = 1; |
||
3526 | lResetNeedsConfirm = nil; |
||
3527 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_RESET_ABORTED); |
||
3528 | end |
||
3529 | end |
||
3530 | |||
3531 | if( not makehome ) then |
||
3532 | if( lMakeHomeNeedsConfirm ) then |
||
3533 | aborted = 1; |
||
3534 | lMakeHomeNeedsConfirm = nil; |
||
3535 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_MAKEHOME_ABORTED); |
||
3536 | end |
||
3537 | end |
||
3538 | |||
3539 | if( not light ) then |
||
3540 | if( lLightModeNeedsConfirm ) then |
||
3541 | lLightModeNeedsConfirm = nil; |
||
3542 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_LIGHTMODE_ABORTED); |
||
3543 | end |
||
3544 | end |
||
3545 | |||
3546 | if( reset ) then |
||
3547 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_RESET_NEEDS_CONFIRM); |
||
3548 | end |
||
3549 | |||
3550 | if( makehome ) then |
||
3551 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_MAKEHOME_NEEDS_CONFIRM); |
||
3552 | end |
||
3553 | |||
3554 | if( light ) then |
||
3555 | DEFAULT_CHAT_FRAME:AddMessage(LOOTLINK_LIGHTMODE_NEEDS_CONFIRM); |
||
3556 | end |
||
3557 | |||
3558 | if( aborted and not reset and not makehome ) then |
||
3559 | lDisableVersionReminder = nil |
||
3560 | end |
||
3561 | end |
||
3562 | |||
3563 | function LootLink_Update() |
||
3564 | local iItem; |
||
3565 | |||
3566 | if( not DisplayIndices ) then |
||
3567 | LootLink_BuildDisplayIndices(); |
||
3568 | end |
||
3569 | FauxScrollFrame_Update(LootLinkListScrollFrame, DisplayIndices.onePastEnd - 1, LOOTLINK_ITEMS_SHOWN, LOOTLINK_ITEM_HEIGHT, nil, nil, nil, LootLinkHighlightFrame, 293, 316); |
||
3570 | LootLinkHighlightFrame:Hide(); |
||
3571 | for iItem = 1, LOOTLINK_ITEMS_SHOWN, 1 do |
||
3572 | local itemIndex = iItem + FauxScrollFrame_GetOffset(LootLinkListScrollFrame); |
||
3573 | local lootLinkItem = getglobal("LootLinkItem"..iItem); |
||
3574 | |||
3575 | if( itemIndex < DisplayIndices.onePastEnd ) then |
||
3576 | local value = DisplayIndices[itemIndex][2]; --LootLink_GetValue(DisplayIndices[itemIndex]); |
||
3577 | if ( not value ) then |
||
3578 | LootLink_Refresh(); |
||
3579 | return; |
||
3580 | end |
||
3581 | if ( value ) then |
||
3582 | local color = { }; |
||
3583 | local name = DisplayIndices[itemIndex][1]; --LootLink_GetName(DisplayIndices[itemIndex]); |
||
3584 | local index = DisplayIndices[itemIndex][3]; |
||
3585 | local extra = getglobal(lootLinkItem:GetName().."Type"); |
||
3586 | lootLinkItem.i = nil; |
||
3587 | local text = getglobal(lootLinkItem:GetName().."Text"); |
||
3588 | local indexed = getglobal(lootLinkItem:GetName().."Indexed"); |
||
3589 | text:SetPoint( "LEFT", 20, 0 ); |
||
3590 | text:SetWidth(275); |
||
3591 | getglobal(lootLinkItem:GetName().."Indexed"):Hide(); |
||
3592 | if ( index and index > 0 ) then |
||
3593 | lootLinkItem.i = index; |
||
3594 | if ( DisplayIndices[itemIndex-1] and DisplayIndices[itemIndex-1][1] == name ) then |
||
3595 | local _,_, enchant, bonus = string.find(value.i, "%d+:(%d+):(%d+):%d+"); |
||
3596 | bonus = tonumber(bonus); |
||
3597 | enchant = tonumber(enchant); |
||
3598 | if ( bonus > 0 or enchant > 0 ) then |
||
3599 | text:SetPoint( "LEFT", 30, 0 ); |
||
3600 | text:SetWidth(245); |
||
3601 | indexed:Show(); |
||
3602 | end |
||
3603 | if ( enchant > 0 ) then |
||
3604 | indexed:SetVertexColor(0,1,0); |
||
3605 | else |
||
3606 | indexed:SetVertexColor(1,1,1); |
||
3607 | end |
||
3608 | end |
||
3609 | end |
||
3610 | local link = "item:"..value.i; |
||
3611 | local realname |
||
3612 | if ( link ) then |
||
3613 | realname = GetItemInfo( link ); |
||
3614 | end |
||
3615 | local onserver = LootLink_CheckItemServer(value, lServerIndex); |
||
3616 | extra:SetVertexColor(1.0,1.0,1.0) |
||
3617 | SetDesaturation(extra,0); |
||
3618 | extra:SetAlpha(1.0); |
||
3619 | if ( not onserver ) then |
||
3620 | extra:SetTexture("Interface\\GossipFrame\\TaxiGossipIcon"); |
||
3621 | extra:Show(); |
||
3622 | elseif ( not realname ) then |
||
3623 | extra:SetTexture("Interface\\GossipFrame\\ActiveQuestIcon"); |
||
3624 | extra:SetAlpha(0.5); |
||
3625 | SetDesaturation(extra,1); |
||
3626 | extra:Show(); |
||
3627 | elseif ( not LootLink_ValidateItem(name, link) ) then |
||
3628 | extra:SetTexture("Interface\\GossipFrame\\AvailableQuestIcon"); |
||
3629 | extra:SetVertexColor(1.0,0,0) |
||
3630 | extra:Show(); |
||
3631 | else |
||
3632 | extra:Hide(); |
||
3633 | end |
||
3634 | |||
3635 | lootLinkItem:SetText(name); |
||
3636 | if( value.c ) then |
||
3637 | color.r, color.g, color.b = LootLink_GetRGBFromHexColor(value.c); |
||
3638 | lootLinkItem:SetTextColor(color.r, color.g, color.b); |
||
3639 | lootLinkItem.r = color.r; |
||
3640 | lootLinkItem.g = color.g; |
||
3641 | lootLinkItem.b = color.b; |
||
3642 | else |
||
3643 | lootLinkItem.r = 0; |
||
3644 | lootLinkItem.g = 0; |
||
3645 | lootLinkItem.b = 0; |
||
3646 | end |
||
3647 | if ( LootLinkFrame.qs and LootLinkFrame.qs == itemIndex ) then |
||
3648 | if ( color ) then |
||
3649 | LootLinkHighlight:SetVertexColor(color.r, color.g, color.b); |
||
3650 | else |
||
3651 | LootLinkHighlight:SetVertexColor(0.5, 0.5, 0.5); |
||
3652 | end |
||
3653 | lootLinkItem:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b); |
||
3654 | LootLinkHighlightFrame:SetPoint("TOPLEFT", "LootLinkItem"..iItem, "TOPLEFT", 0, 0); |
||
3655 | LootLinkHighlightFrame:Show(); |
||
3656 | end |
||
3657 | lootLinkItem:Show(); |
||
3658 | |||
3659 | if( LootLinkFrame.TooltipButton and LootLinkFrame.TooltipButton == iItem ) then |
||
3660 | if( value.i ) then |
||
3661 | local link = LootLink_GetHyperlink(name, index); |
||
3662 | LootLinkTooltip:SetOwner(lootLinkItem, "ANCHOR_BOTTOMRIGHT"); |
||
3663 | LootLink_SetHyperlink(LootLinkTooltip, name, link, index); |
||
3664 | LootLink_AddTooltipInfo(name); |
||
3665 | LootLink_AddTooltipTexture(link); |
||
3666 | LootLinkTooltip:Show(); |
||
3667 | else |
||
3668 | LootLinkItemButton_OnLeave(); |
||
3669 | end |
||
3670 | end |
||
3671 | end |
||
3672 | else |
||
3673 | lootLinkItem:Hide(); |
||
3674 | end |
||
3675 | end |
||
3676 | end |
||
3677 | |||
3678 | function LootLink_Search() |
||
3679 | LootLinkSearchFrame:Show(); |
||
3680 | end |
||
3681 | |||
3682 | function LootLink_Refresh() |
||
3683 | FauxScrollFrame_SetOffset(LootLinkListScrollFrame, 0); |
||
3684 | getglobal("LootLinkListScrollFrameScrollBar"):SetValue(0); |
||
3685 | LootLink_BuildDisplayIndices(); |
||
3686 | LootLink_Update(); |
||
3687 | end |
||
3688 | |||
3689 | function LootLink_DoSearch() |
||
3690 | LootLink_Refresh(); |
||
3691 | end |
||
3692 | |||
3693 | function LootLinkSearch_LoadValues() |
||
3694 | local sp = LootLinkFrame.SearchParams; |
||
3695 | local field; |
||
3696 | |||
3697 | if( LootLinkState.LightMode ) then |
||
3698 | getglobal("LLS_TextDisabled"):Show(); |
||
3699 | getglobal("LLS_TextEditBox"):Hide(); |
||
3700 | getglobal("LLS_NameEditBox"):SetFocus(); |
||
3701 | else |
||
3702 | getglobal("LLS_TextDisabled"):Hide(); |
||
3703 | field = getglobal("LLS_TextEditBox"); |
||
3704 | field:Show(); |
||
3705 | field:SetFocus(); |
||
3706 | if( sp and sp.text ) then |
||
3707 | field:SetText(sp.text); |
||
3708 | else |
||
3709 | field:SetText(""); |
||
3710 | end |
||
3711 | end |
||
3712 | |||
3713 | field = getglobal("LLS_NameEditBox"); |
||
3714 | if( sp and sp.name ) then |
||
3715 | field:SetText(sp.name); |
||
3716 | else |
||
3717 | field:SetText(""); |
||
3718 | end |
||
3719 | |||
3720 | UIDropDownMenu_Initialize(LLS_RarityDropDown, LLS_RarityDropDown_Initialize); |
||
3721 | if( sp and sp.rarity ) then |
||
3722 | LootLink_UIDropDownMenu_SetSelectedID(LLS_RarityDropDown, sp.rarity, LLS_RARITY_LIST); |
||
3723 | else |
||
3724 | LootLink_UIDropDownMenu_SetSelectedID(LLS_RarityDropDown, 1, LLS_RARITY_LIST); |
||
3725 | end |
||
3726 | |||
3727 | if( sp and sp.server ) then |
||
3728 | getglobal("LLS_ServerCheckButton"):SetChecked(1); |
||
3729 | else |
||
3730 | getglobal("LLS_ServerCheckButton"):SetChecked(0); |
||
3731 | end |
||
3732 | |||
3733 | UIDropDownMenu_Initialize(LLS_BindsDropDown, LLS_BindsDropDown_Initialize); |
||
3734 | if( sp and sp.binds ) then |
||
3735 | LootLink_UIDropDownMenu_SetSelectedID(LLS_BindsDropDown, sp.binds, LLS_BINDS_LIST); |
||
3736 | else |
||
3737 | LootLink_UIDropDownMenu_SetSelectedID(LLS_BindsDropDown, 1, LLS_BINDS_LIST); |
||
3738 | end |
||
3739 | |||
3740 | if( sp and sp.unique ) then |
||
3741 | getglobal("LLS_UniqueCheckButton"):SetChecked(1); |
||
3742 | else |
||
3743 | getglobal("LLS_UniqueCheckButton"):SetChecked(0); |
||
3744 | end |
||
3745 | |||
3746 | UIDropDownMenu_Initialize(LLS_LocationDropDown, LLS_LocationDropDown_Initialize); |
||
3747 | if( sp and sp.location ) then |
||
3748 | LootLink_UIDropDownMenu_SetSelectedID(LLS_LocationDropDown, sp.location, LLS_LOCATION_LIST); |
||
3749 | else |
||
3750 | LootLink_UIDropDownMenu_SetSelectedID(LLS_LocationDropDown, 1, LLS_LOCATION_LIST); |
||
3751 | end |
||
3752 | |||
3753 | if( LootLinkState and LootLinkState.spoof ) then |
||
3754 | LLS_SpoofCheckButton:Hide(); |
||
3755 | else |
||
3756 | LLS_SpoofCheckButton:Show(); |
||
3757 | if( sp and sp.spoof ) then |
||
3758 | getglobal("LLS_SpoofCheckButton"):SetChecked(1); |
||
3759 | else |
||
3760 | getglobal("LLS_SpoofCheckButton"):SetChecked(0); |
||
3761 | end |
||
3762 | end |
||
3763 | |||
3764 | if( sp and sp.usable ) then |
||
3765 | getglobal("LLS_UsableCheckButton"):SetChecked(1); |
||
3766 | else |
||
3767 | getglobal("LLS_UsableCheckButton"):SetChecked(0); |
||
3768 | end |
||
3769 | |||
3770 | field = getglobal("LLS_MinimumLevelEditBox"); |
||
3771 | if( sp and sp.minLevel ) then |
||
3772 | field:SetText(sp.minLevel); |
||
3773 | else |
||
3774 | field:SetText(""); |
||
3775 | end |
||
3776 | |||
3777 | field = getglobal("LLS_MaximumLevelEditBox"); |
||
3778 | if( sp and sp.maxLevel ) then |
||
3779 | field:SetText(sp.maxLevel); |
||
3780 | else |
||
3781 | field:SetText(""); |
||
3782 | end |
||
3783 | |||
3784 | UIDropDownMenu_Initialize(LLS_TypeDropDown, LLS_TypeDropDown_Initialize); |
||
3785 | if( sp and sp.type ) then |
||
3786 | LootLink_UIDropDownMenu_SetSelectedID(LLS_TypeDropDown, sp.type, LLS_TYPE_LIST); |
||
3787 | else |
||
3788 | LootLink_UIDropDownMenu_SetSelectedID(LLS_TypeDropDown, 1, LLS_TYPE_LIST); |
||
3789 | end |
||
3790 | |||
3791 | if( sp and sp.type ) then |
||
3792 | LootLink_SetupTypeUI(sp.type, sp.subtype); |
||
3793 | else |
||
3794 | LootLink_SetupTypeUI(1, 1); |
||
3795 | end |
||
3796 | |||
3797 | field = getglobal("LLS_MinimumDamageEditBox"); |
||
3798 | if( sp and sp.minMinDamage ) then |
||
3799 | field:SetText(sp.minMinDamage); |
||
3800 | else |
||
3801 | field:SetText(""); |
||
3802 | end |
||
3803 | |||
3804 | field = getglobal("LLS_MaximumDamageEditBox"); |
||
3805 | if( sp and sp.minMaxDamage ) then |
||
3806 | field:SetText(sp.minMaxDamage); |
||
3807 | else |
||
3808 | field:SetText(""); |
||
3809 | end |
||
3810 | |||
3811 | field = getglobal("LLS_MaximumSpeedEditBox"); |
||
3812 | if( sp and sp.maxSpeed ) then |
||
3813 | field:SetText(sp.maxSpeed); |
||
3814 | else |
||
3815 | field:SetText(""); |
||
3816 | end |
||
3817 | |||
3818 | field = getglobal("LLS_MinimumDPSEditBox"); |
||
3819 | if( sp and sp.minDPS ) then |
||
3820 | field:SetText(sp.minDPS); |
||
3821 | else |
||
3822 | field:SetText(""); |
||
3823 | end |
||
3824 | |||
3825 | field = getglobal("LLS_MinimumArmorEditBox"); |
||
3826 | if( sp and sp.minArmor ) then |
||
3827 | field:SetText(sp.minArmor); |
||
3828 | else |
||
3829 | field:SetText(""); |
||
3830 | end |
||
3831 | |||
3832 | field = getglobal("LLS_MinimumBlockEditBox"); |
||
3833 | if( sp and sp.minBlock ) then |
||
3834 | field:SetText(sp.minBlock); |
||
3835 | else |
||
3836 | field:SetText(""); |
||
3837 | end |
||
3838 | |||
3839 | field = getglobal("LLS_MinimumSlotsEditBox"); |
||
3840 | if( sp and sp.minSlots ) then |
||
3841 | field:SetText(sp.minSlots); |
||
3842 | else |
||
3843 | field:SetText(""); |
||
3844 | end |
||
3845 | |||
3846 | field = getglobal("LLS_MinimumSkillEditBox"); |
||
3847 | if( sp and sp.minSkill ) then |
||
3848 | field:SetText(sp.minSkill); |
||
3849 | else |
||
3850 | field:SetText(""); |
||
3851 | end |
||
3852 | |||
3853 | field = getglobal("LLS_MaximumSkillEditBox"); |
||
3854 | if( sp and sp.maxSkill ) then |
||
3855 | field:SetText(sp.maxSkill); |
||
3856 | else |
||
3857 | field:SetText(""); |
||
3858 | end |
||
3859 | |||
3860 | --[[if( sp and sp.set ) then |
||
3861 | getglobal("LLS_SetCheckButton"):SetChecked(1); |
||
3862 | else |
||
3863 | getglobal("LLS_SetCheckButton"):SetChecked(0); |
||
3864 | end]] |
||
3865 | end |
||
3866 | |||
3867 | function LootLinkSearch_SaveValues() |
||
3868 | local sp; |
||
3869 | local interesting; |
||
3870 | local field; |
||
3871 | local value; |
||
3872 | |||
3873 | LootLinkFrame.SearchParams = { }; |
||
3874 | sp = LootLinkFrame.SearchParams; |
||
3875 | |||
3876 | field = getglobal("LLS_TextEditBox"); |
||
3877 | value = field:GetText(); |
||
3878 | if( value and value ~= "" ) then |
||
3879 | sp.text = value; |
||
3880 | interesting = 1; |
||
3881 | end |
||
3882 | |||
3883 | field = getglobal("LLS_NameEditBox"); |
||
3884 | value = field:GetText(); |
||
3885 | if( value and value ~= "" ) then |
||
3886 | sp.name = value; |
||
3887 | interesting = 1; |
||
3888 | end |
||
3889 | |||
3890 | value = UIDropDownMenu_GetSelectedID(LLS_RarityDropDown); |
||
3891 | if( value and value ~= 1 ) then |
||
3892 | sp.rarity = value; |
||
3893 | interesting = 1; |
||
3894 | end |
||
3895 | |||
3896 | field = getglobal("LLS_ServerCheckButton"); |
||
3897 | value = field:GetChecked(); |
||
3898 | if( value ) then |
||
3899 | sp.server = value; |
||
3900 | interesting = 1; |
||
3901 | end |
||
3902 | |||
3903 | value = UIDropDownMenu_GetSelectedID(LLS_BindsDropDown); |
||
3904 | if( value and value ~= 1 ) then |
||
3905 | sp.binds = value; |
||
3906 | interesting = 1; |
||
3907 | end |
||
3908 | |||
3909 | field = getglobal("LLS_UniqueCheckButton"); |
||
3910 | value = field:GetChecked(); |
||
3911 | if( value ) then |
||
3912 | sp.unique = value; |
||
3913 | interesting = 1; |
||
3914 | end |
||
3915 | |||
3916 | value = UIDropDownMenu_GetSelectedID(LLS_LocationDropDown); |
||
3917 | if( value and value ~= 1 ) then |
||
3918 | sp.location = value; |
||
3919 | interesting = 1; |
||
3920 | end |
||
3921 | |||
3922 | field = getglobal("LLS_UsableCheckButton"); |
||
3923 | value = field:GetChecked(); |
||
3924 | if( value ) then |
||
3925 | sp.usable = value; |
||
3926 | interesting = 1; |
||
3927 | end |
||
3928 | |||
3929 | field = getglobal("LLS_MinimumLevelEditBox"); |
||
3930 | value = field:GetText(); |
||
3931 | if( value and LootLink_CheckNumeric(value) ) then |
||
3932 | sp.minLevel = tonumber(value); |
||
3933 | interesting = 1; |
||
3934 | end |
||
3935 | |||
3936 | field = getglobal("LLS_MaximumLevelEditBox"); |
||
3937 | value = field:GetText(); |
||
3938 | if( value and LootLink_CheckNumeric(value) ) then |
||
3939 | sp.maxLevel = tonumber(value); |
||
3940 | interesting = 1; |
||
3941 | end |
||
3942 | |||
3943 | value = UIDropDownMenu_GetSelectedID(LLS_TypeDropDown); |
||
3944 | if( value and value ~= 1 ) then |
||
3945 | sp.type = value; |
||
3946 | interesting = 1; |
||
3947 | end |
||
3948 | |||
3949 | field = getglobal("LLS_SpoofCheckButton"); |
||
3950 | value = field:GetChecked(); |
||
3951 | if( value ) then |
||
3952 | sp.spoof = value; |
||
3953 | interesting = 1; |
||
3954 | end |
||
3955 | |||
3956 | value = UIDropDownMenu_GetSelectedID(LLS_SubtypeDropDown); |
||
3957 | if( value and value ~= 1 ) then |
||
3958 | sp.subtype = value; |
||
3959 | if( sp.type and sp.type ~= 1 ) then |
||
3960 | interesting = 1; |
||
3961 | end |
||
3962 | end |
||
3963 | |||
3964 | field = getglobal("LLS_MinimumDamageEditBox"); |
||
3965 | value = field:GetText(); |
||
3966 | if( value and LootLink_CheckNumeric(value) ) then |
||
3967 | sp.minMinDamage = tonumber(value); |
||
3968 | interesting = 1; |
||
3969 | end |
||
3970 | |||
3971 | field = getglobal("LLS_MaximumDamageEditBox"); |
||
3972 | value = field:GetText(); |
||
3973 | if( value and LootLink_CheckNumeric(value) ) then |
||
3974 | sp.minMaxDamage = tonumber(value); |
||
3975 | interesting = 1; |
||
3976 | end |
||
3977 | |||
3978 | field = getglobal("LLS_MaximumSpeedEditBox"); |
||
3979 | value = field:GetText(); |
||
3980 | if( value and LootLink_CheckNumeric(value) ) then |
||
3981 | sp.maxSpeed = tonumber(value); |
||
3982 | interesting = 1; |
||
3983 | end |
||
3984 | |||
3985 | field = getglobal("LLS_MinimumDPSEditBox"); |
||
3986 | value = field:GetText(); |
||
3987 | if( value and LootLink_CheckNumeric(value) ) then |
||
3988 | sp.minDPS = tonumber(value); |
||
3989 | interesting = 1; |
||
3990 | end |
||
3991 | |||
3992 | field = getglobal("LLS_MinimumArmorEditBox"); |
||
3993 | value = field:GetText(); |
||
3994 | if( value and LootLink_CheckNumeric(value) ) then |
||
3995 | sp.minArmor = tonumber(value); |
||
3996 | interesting = 1; |
||
3997 | end |
||
3998 | |||
3999 | field = getglobal("LLS_MinimumBlockEditBox"); |
||
4000 | value = field:GetText(); |
||
4001 | if( value and LootLink_CheckNumeric(value) ) then |
||
4002 | sp.minBlock = tonumber(value); |
||
4003 | interesting = 1; |
||
4004 | end |
||
4005 | |||
4006 | field = getglobal("LLS_MinimumSlotsEditBox"); |
||
4007 | value = field:GetText(); |
||
4008 | if( value and LootLink_CheckNumeric(value) ) then |
||
4009 | sp.minSlots = tonumber(value); |
||
4010 | interesting = 1; |
||
4011 | end |
||
4012 | |||
4013 | field = getglobal("LLS_MinimumSkillEditBox"); |
||
4014 | value = field:GetText(); |
||
4015 | if( value and LootLink_CheckNumeric(value) ) then |
||
4016 | sp.minSkill = tonumber(value); |
||
4017 | interesting = 1; |
||
4018 | end |
||
4019 | |||
4020 | field = getglobal("LLS_MaximumSkillEditBox"); |
||
4021 | value = field:GetText(); |
||
4022 | if( value and LootLink_CheckNumeric(value) ) then |
||
4023 | sp.maxSkill = tonumber(value); |
||
4024 | interesting = 1; |
||
4025 | end |
||
4026 | |||
4027 | --[[value = getglobal("LLS_SetCheckButton"):GetChecked(); |
||
4028 | if ( value ) then |
||
4029 | sp.set = value; |
||
4030 | interesting = 1; |
||
4031 | end]] |
||
4032 | |||
4033 | -- Only save search params if we had interesting data on the page |
||
4034 | if( not interesting ) then |
||
4035 | LootLinkFrame.SearchParams = nil; |
||
4036 | else |
||
4037 | if( IsControlKeyDown() ) then |
||
4038 | sp.plain = nil; |
||
4039 | else |
||
4040 | sp.plain = 1; |
||
4041 | end |
||
4042 | end |
||
4043 | end |
||
4044 | |||
4045 | function LootLinkSearchFrame_SaveSearchParams() |
||
4046 | LootLinkSearchFrame.OldSearchParams = LootLinkFrame.SearchParams; |
||
4047 | end |
||
4048 | |||
4049 | function LootLinkSearchFrame_RestoreSearchParams() |
||
4050 | LootLinkFrame.SearchParams = LootLinkSearchFrame.OldSearchParams; |
||
4051 | end |
||
4052 | |||
4053 | function LootLinkSearchFrame_ChangeFocus() |
||
4054 | local frames = {"LLS_TextEditBox", |
||
4055 | "LLS_NameEditBox", |
||
4056 | "LLS_MinimumLevelEditBox", |
||
4057 | "LLS_MaximumLevelEditBox", |
||
4058 | "LLS_MinimumSlotsEditBox", |
||
4059 | "LLS_MinimumDamageEditBox", |
||
4060 | "LLS_MaximumDamageEditBox", |
||
4061 | "LLS_MaximumSpeedEditBox", |
||
4062 | "LLS_MinimumDPSEditBox", |
||
4063 | "LLS_MinimumArmorEditBox", |
||
4064 | "LLS_MinimumBlockEditBox", |
||
4065 | "LLS_MinimumSkillEditBox", |
||
4066 | "LLS_MaximumSkillEditBox", |
||
4067 | } |
||
4068 | |||
4069 | local name = this:GetName(); |
||
4070 | for i=1, 13 do |
||
4071 | if ( frames[i] == name ) then |
||
4072 | if ( IsShiftKeyDown() ) then |
||
4073 | i = i-1; |
||
4074 | else |
||
4075 | i = i+1; |
||
4076 | end |
||
4077 | while frames[i] do |
||
4078 | local nextframe = getglobal(frames[i]); |
||
4079 | if ( nextframe:IsVisible() ) then |
||
4080 | nextframe:SetFocus(); |
||
4081 | return; |
||
4082 | end |
||
4083 | if ( IsShiftKeyDown() ) then |
||
4084 | i = i-1; |
||
4085 | else |
||
4086 | i = i+1; |
||
4087 | end |
||
4088 | end |
||
4089 | return; |
||
4090 | end |
||
4091 | end |
||
4092 | end |
||
4093 | |||
4094 | function LootLinkSearchFrame_Cancel() |
||
4095 | PlaySound("gsTitleOptionExit"); |
||
4096 | LootLinkSearchFrame:Hide(); |
||
4097 | LootLinkSearchFrame_RestoreSearchParams(); |
||
4098 | end |
||
4099 | |||
4100 | function LootLinkSearchFrame_Okay() |
||
4101 | PlaySound("gsTitleOptionOK"); |
||
4102 | LootLinkSearchFrame:Hide(); |
||
4103 | LootLinkSearch_SaveValues(); |
||
4104 | LootLink_DoSearch(); |
||
4105 | end |
||
4106 | |||
4107 | function LootLinkQuickSearch_Search(Next) |
||
4108 | if ( not Next ) then |
||
4109 | Next = 0; |
||
4110 | end |
||
4111 | local text = LootLinkFrameQuickSearch:GetText(); |
||
4112 | local length = string.len( text ); |
||
4113 | local last = LootLinkFrameQuickSearch.last; |
||
4114 | local function DoScroll(i) |
||
4115 | local offset = FauxScrollFrame_GetOffset(LootLinkListScrollFrame); |
||
4116 | if ( i < offset or i > offset + LOOTLINK_ITEMS_SHOWN ) then |
||
4117 | if ( i > DisplayIndices.onePastEnd - LOOTLINK_ITEMS_SHOWN ) then |
||
4118 | i = DisplayIndices.onePastEnd - LOOTLINK_ITEMS_SHOWN; |
||
4119 | end |
||
4120 | i = i-1; |
||
4121 | local val = (i * 16) - 0.5 |
||
4122 | LootLinkListScrollFrameScrollBar:SetValue(val); |
||
4123 | LootLinkListScrollFrame.offset = i; |
||
4124 | end |
||
4125 | end |
||
4126 | local function DoSearch(index, offset) |
||
4127 | if ( not offset ) then |
||
4128 | offset = getn(DisplayIndices); |
||
4129 | end |
||
4130 | for i=index+Next, offset do |
||
4131 | local name = LootLink_GetName(DisplayIndices[i]); |
||
4132 | if ( name and string.find( string.lower(name), string.lower(text), 1, 1 ) ) then |
||
4133 | LootLinkFrame.qs = i; |
||
4134 | DoScroll(i); |
||
4135 | return 1; |
||
4136 | end |
||
4137 | end |
||
4138 | end |
||
4139 | if ( text and text ~= "" ) then |
||
4140 | if ( not last or length < last ) then |
||
4141 | if ( not DoSearch(LootLinkFrame.qs) and not DoSearch(1, LootLinkFrame.qs+1) ) then |
||
4142 | LootLinkFrameQuickSearch.last = length; |
||
4143 | LootLinkFrameQuickSearch:SetTextColor(1,0,0); |
||
4144 | LootLinkFrame.qs = 0; |
||
4145 | else |
||
4146 | LootLinkFrameQuickSearch:SetTextColor(1,1,1); |
||
4147 | LootLinkFrameQuickSearch.last = nil; |
||
4148 | end |
||
4149 | end |
||
4150 | else |
||
4151 | LootLinkFrame.qs = 0; |
||
4152 | LootLinkFrameQuickSearch:SetTextColor(1,1,1); |
||
4153 | end |
||
4154 | LootLink_Update(); |
||
4155 | end |
||
4156 | |||
4157 | function LootLinkQuickSearch_FullSearch() |
||
4158 | local name = this:GetText(); |
||
4159 | if ( name ) then |
||
4160 | if ( name == "" ) then |
||
4161 | name = nil; |
||
4162 | end |
||
4163 | if ( name and not LootLinkFrame.SearchParams ) then |
||
4164 | LootLinkFrame.SearchParams = { }; |
||
4165 | end |
||
4166 | if ( LootLinkFrame.SearchParams ) then |
||
4167 | LootLinkFrame.SearchParams.name = name; |
||
4168 | end |
||
4169 | end |
||
4170 | LootLink_DoSearch(); |
||
4171 | LootLinkFrameQuickSearch:SetText(name or ""); |
||
4172 | end |
||
4173 | |||
4174 | function LootLinkQuickSearch_Clear() |
||
4175 | LootLinkFrameQuickSearch:SetText(""); |
||
4176 | LootLinkFrameQuickSearch.last = nil; |
||
4177 | end |
||
4178 | |||
4179 | LootLinkOptionsList = { |
||
4180 | hideminimap = { frame = "LLO_HideMinimap", flip = 1 }, |
||
4181 | lockminimap = { frame = "LLO_LockMinimap" }, |
||
4182 | hideicon = { frame = "LLO_IconCheckButton", flip = 1 }, |
||
4183 | HideInfo = { frame = "LLO_ExtraInfoCheckButton", flip = 1 }, |
||
4184 | mouseover = { frame = "LLO_MouseoverCheckButton" }, |
||
4185 | typelinks = { frame = "LLO_TypeLinksCheckButton" }, |
||
4186 | autotypelinks = { frame = "LLO_AutoTypeLinksCheckButton", dependancy = "typelinks" }, |
||
4187 | |||
4188 | server = { frame = "LLO_ServerCheckButton", refresh = 1 }, |
||
4189 | spoof = { frame = "LLO_SpoofCheckButton", refresh = 1 }, |
||
4190 | nosame = { frame = "LLO_SameNameCheckButton", flip = 1, refresh = 1 }, |
||
4191 | novariants = { frame = "LLO_VariantCheckButton", flip = 1, dependancy = "nosame", refresh = 1 }, |
||
4192 | enchants = { frame = "LLO_EnchantsCheckButton", flip = 1, dependancy = "nosame", refresh = 1 }, |
||
4193 | |||
4194 | x = { frame = "LLO_MinimapPos", slider = LLO_MINIMAP_X}, |
||
4195 | y = { frame = "LLO_MinimapOffset", slider = LLO_MINIMAP_Y }, |
||
4196 | |||
4197 | rarityfilter = { frame = "LLO_RarityDropDown", dropdown = {LLO_RarityDropDown_Initialize, 2, LLO_RARITY_LIST}, refresh = 1 }, |
||
4198 | }; |
||
4199 | |||
4200 | function LootLinkOptions_LoadValues() |
||
4201 | local op = LootLinkState; |
||
4202 | |||
4203 | for k, v in LootLinkOptionsList do |
||
4204 | local frame = getglobal( v.frame ); |
||
4205 | if ( frame ) then |
||
4206 | if ( v.dropdown ) then |
||
4207 | UIDropDownMenu_Initialize(frame, v.dropdown[1]); |
||
4208 | LootLink_UIDropDownMenu_SetSelectedID(frame, 1, v.dropdown[3]); |
||
4209 | end |
||
4210 | local value = op[k]; |
||
4211 | if value then |
||
4212 | if ( v.slider ) then |
||
4213 | frame:SetValue( value ); |
||
4214 | LootLinkOptionsFrame[k] = value; |
||
4215 | elseif ( v.dropdown ) then |
||
4216 | LootLink_UIDropDownMenu_SetSelectedID(frame, value+v.dropdown[2], v.dropdown[3]); |
||
4217 | end |
||
4218 | elseif ( v.slider ) then |
||
4219 | frame:SetValue( v.slider ); |
||
4220 | LootLinkOptionsFrame[k] = nil; |
||
4221 | end |
||
4222 | if ( not v.slider and not v.dropdown ) then |
||
4223 | if ( v.flip ) then |
||
4224 | frame:SetChecked(1-(value or 0)) |
||
4225 | else |
||
4226 | frame:SetChecked(value) |
||
4227 | end |
||
4228 | end |
||
4229 | if ( v.dependancy ) then |
||
4230 | if ( getglobal(LootLinkOptionsList[v.dependancy].frame):GetChecked() ) then |
||
4231 | frame:Enable(); |
||
4232 | getglobal(frame:GetName().."Text"):SetTextColor(1, 0.82, 0); |
||
4233 | else |
||
4234 | frame:Disable(); |
||
4235 | getglobal(frame:GetName().."Text"):SetTextColor(0.3, 0.3, 0.3); |
||
4236 | end |
||
4237 | end |
||
4238 | else |
||
4239 | ChatFrame1:AddMessage(k.." no frame?"); |
||
4240 | end |
||
4241 | end |
||
4242 | |||
4243 | LootLinkOptionsFrame.needsave = 1; |
||
4244 | end |
||
4245 | |||
4246 | function LootLinkOptions_SaveValues() |
||
4247 | local op = LootLinkState; |
||
4248 | local refresh; |
||
4249 | |||
4250 | for k, v in LootLinkOptionsList do |
||
4251 | local frame = getglobal( v.frame ); |
||
4252 | if ( frame ) then |
||
4253 | local value = op[k]; |
||
4254 | if ( v.dropdown ) then |
||
4255 | value = UIDropDownMenu_GetSelectedID(frame); |
||
4256 | if ( value == 1 ) then |
||
4257 | value = nil; |
||
4258 | else |
||
4259 | value = value - (v.dropdown[2] or 0); |
||
4260 | end |
||
4261 | elseif ( not v.slider ) then |
||
4262 | local checked = frame:GetChecked(); |
||
4263 | if ( v.flip ) then |
||
4264 | if ( checked ) then |
||
4265 | checked = nil |
||
4266 | else |
||
4267 | checked = 1; |
||
4268 | end |
||
4269 | end |
||
4270 | value = checked; |
||
4271 | end |
||
4272 | if ( v.refresh and op[k] ~= value ) then |
||
4273 | refresh = 1; |
||
4274 | end |
||
4275 | op[k] = value; |
||
4276 | else |
||
4277 | ChatFrame1:AddMessage(k.." no frame?"); |
||
4278 | end |
||
4279 | end |
||
4280 | |||
4281 | if ( refresh ) then |
||
4282 | LootLink_Refresh(); |
||
4283 | end |
||
4284 | LootLinkOptionsFrame.needsave = nil; |
||
4285 | end |
||
4286 | |||
4287 | function LootLinkOptionsFrame_Defaults() |
||
4288 | local op = LootLinkState; |
||
4289 | for k, v in LootLinkOptionsList do |
||
4290 | op[k] = nil; |
||
4291 | end |
||
4292 | LootLinkOptions_LoadValues(); |
||
4293 | end |
||
4294 | |||
4295 | function LootLinkOptionsFrame_Cancel() |
||
4296 | if ( LootLinkOptionsFrame.needsave ) then |
||
4297 | LootLinkOptionsFrame.needsave = nil; |
||
4298 | if ( LootLinkOptionsFrame.x or LootLinkOptionsFrame.y ) then |
||
4299 | LootLink_Minimap_Position( LootLinkOptionsFrame.x, LootLinkOptionsFrame.y ); |
||
4300 | end |
||
4301 | end |
||
4302 | PlaySound("gsTitleOptionExit"); |
||
4303 | LootLinkOptionsFrame:Hide(); |
||
4304 | end |
||
4305 | |||
4306 | function LootLinkOptionsFrame_Okay() |
||
4307 | PlaySound("gsTitleOptionOK"); |
||
4308 | LootLinkOptions_SaveValues(); |
||
4309 | LootLinkOptionsFrame:Hide(); |
||
4310 | end |
||
4311 | |||
4312 | function LootLink_CloseWindows(ignoreCenter) |
||
4313 | if ( LootLinkOptionsFrame:IsVisible() ) then |
||
4314 | LootLinkOptionsFrame_Cancel(); |
||
4315 | return 1; |
||
4316 | end |
||
4317 | if ( LootLinkSearchFrame:IsVisible() ) then |
||
4318 | LootLinkSearchFrame_Cancel(); |
||
4319 | return 1; |
||
4320 | end |
||
4321 | return lOriginal_CloseWindows(ignoreCenter); |
||
4322 | end |
||
4323 | |||
4324 | function LootLink_ValidateItem(name, link, fixlink) |
||
4325 | -- Basic validation of enchants and stat bonuses |
||
4326 | -- todo : more complex evaluation of the stat bonuses taking in to account item level and base stats |
||
4327 | if ( not link ) then return nil; |
||
4328 | elseif ( string.sub(link, 1, 5) ~= "item:" ) then |
||
4329 | link = "item:"..link; |
||
4330 | end |
||
4331 | local realname, ilink, quality, level, sType, sSubType, count, equip = GetItemInfo(link); |
||
4332 | if ( realname ) then |
||
4333 | if ( realname ~= name ) then |
||
4334 | -- quickly kill anything that's really wrong. |
||
4335 | if ( not fixlink ) then return nil; end |
||
4336 | name = realname; |
||
4337 | end |
||
4338 | |||
4339 | local _,_, itemid, enchant, stat = string.find( link, "(%d+):(%d+):(%d+):%d+" ); |
||
4340 | |||
4341 | if ( tonumber(stat) > 0 ) then |
||
4342 | if ( quality ~= 2 and quality ~= 3 and itemid ~= "20039" ) then -- special case for Dark Iron Boots, grr. |
||
4343 | -- Nothing but Uncommon and Rare items have stat bonuses |
||
4344 | if ( not fixlink ) then return nil; end |
||
4345 | stat = 0; |
||
4346 | elseif( lNoBonuses[equip] == 2 ) then |
||
4347 | -- Nothing that can't be equiped can't have stat bonuses |
||
4348 | if ( not fixlink ) then return nil; end |
||
4349 | stat = 0; |
||
4350 | end |
||
4351 | end |
||
4352 | if ( tonumber(enchant) > 0 ) then |
||
4353 | if ( lNoBonuses[equip] ) then |
||
4354 | -- Nothing that isn't armor or weapons can have enchants |
||
4355 | if ( not fixlink ) then return nil; end |
||
4356 | enchant = 0; |
||
4357 | end |
||
4358 | end |
||
4359 | |||
4360 | return name, itemid..":"..enchant..":"..stat..":0"; |
||
4361 | else |
||
4362 | if ( not fixlink ) then return 1; end |
||
4363 | return name, string.sub(link,6); |
||
4364 | end |
||
4365 | end |
||
4366 | |||
4367 | |||
4368 | -------------------------------------------------------------------------------------------------- |
||
4369 | -- Clean and Purge functions |
||
4370 | -------------------------------------------------------------------------------------------------- |
||
4371 | |||
4372 | local LLPtodo; |
||
4373 | local LLPvars; |
||
4374 | |||
4375 | function LootLink_CheckDuplicate(name) |
||
4376 | local links = {}; |
||
4377 | local value = ItemLinks[name]; |
||
4378 | local dups = 0; |
||
4379 | if ( value and value.m ) then |
||
4380 | links[value.i] = 1; |
||
4381 | local i = 1; |
||
4382 | --while value and value.m and value.m[i] do |
||
4383 | for i=getn(value.m), 1, -1 do |
||
4384 | if ( links[value.m[i].i] ) then |
||
4385 | dups = dups + 1; |
||
4386 | LootLink_RemoveItem(name, nil, nil, i); |
||
4387 | else |
||
4388 | links[value.m[i].i] = 1; |
||
4389 | end |
||
4390 | end |
||
4391 | end |
||
4392 | return dups; |
||
4393 | end |
||
4394 | |||
4395 | function LootLink_Process_Cancel() |
||
4396 | LootLink_Process:Hide(); |
||
4397 | LootLink_Process:SetScript("OnUpdate", nil); |
||
4398 | LootLink_Process.fade = nil; |
||
4399 | LootLinkFrame.process = nil; |
||
4400 | LootLink_Process_ToggleButtons(1); |
||
4401 | |||
4402 | if ( LLPtodo ) then |
||
4403 | local text = getglobal("LLP_"..LLPvars.functype.."_CANCEL"); |
||
4404 | text = string.gsub( text, "%%r", LLPvars.total-LLPvars.done ); |
||
4405 | text = string.gsub( text, "%%u", LLPvars.updated ); |
||
4406 | text = string.gsub( text, "%%t", LLPvars.total ); |
||
4407 | text = string.gsub( text, "%%f", LLPvars.failed ); |
||
4408 | DEFAULT_CHAT_FRAME:AddMessage(text); |
||
4409 | |||
4410 | LootLink_Process_Time:SetText(""); |
||
4411 | |||
4412 | LLPvars = nil; |
||
4413 | LLPtodo = nil; |
||
4414 | end |
||
4415 | end |
||
4416 | |||
4417 | function LootLink_Process_Memory() |
||
4418 | LootLink_Process_Cancel(); |
||
4419 | DEFAULT_CHAT_FRAME:AddMessage(LLP_ABORT1); |
||
4420 | DEFAULT_CHAT_FRAME:AddMessage(LLP_ABORT2); |
||
4421 | end |
||
4422 | |||
4423 | function LootLink_Process_ToggleButtons(on) |
||
4424 | if ( on ) then |
||
4425 | LLO_Purge:Enable(); |
||
4426 | LLO_Fix:Enable(); |
||
4427 | else |
||
4428 | LLO_Purge:Disable(); |
||
4429 | LLO_Fix:Disable(); |
||
4430 | end |
||
4431 | end |
||
4432 | |||
4433 | function LootLinkProcess_PURGE() |
||
4434 | local todo = LLPtodo[LLPvars.done+1]; |
||
4435 | |||
4436 | local name, link = todo[1], todo[2]; |
||
4437 | local _,_,itemid,enchantid,suffixid=string.find(link, "(%d+):(%d+):(%d+):%d+"); |
||
4438 | |||
4439 | LootLink_SortAlternates(name); |
||
4440 | local op = LootLinkState; |
||
4441 | local value = ItemLinks[name]; |
||
4442 | |||
4443 | if ( value and value.m ) then |
||
4444 | if ( op.nosame or (op.novariants and tonumber(suffixid) > 0) ) then |
||
4445 | LLPvars.updated = LLPvars.updated + getn(value.m); |
||
4446 | value.m = nil; |
||
4447 | end |
||
4448 | if ( op.enchants ) then |
||
4449 | if ( tonumber(enchantid) > 0 ) then |
||
4450 | if ( LootLink_RemoveItem(name, link) ) then |
||
4451 | return 1; |
||
4452 | end |
||
4453 | end |
||
4454 | end |
||
4455 | end |
||
4456 | value = LootLink_GetValue(name, link); |
||
4457 | if ( not value ) then |
||
4458 | return 2; |
||
4459 | end |
||
4460 | if ( value.c and op.rarityfilter ) then |
||
4461 | local rarity = lRarityFilter[value.c]; |
||
4462 | if ( rarity and rarity < op.rarityfilter ) then |
||
4463 | if ( LootLink_RemoveItem(name, link) ) then |
||
4464 | return 1; |
||
4465 | end |
||
4466 | end |
||
4467 | end |
||
4468 | if ( LootLinkState.spoof ) then |
||
4469 | local valid = LootLink_ValidateItem(name, link) |
||
4470 | if ( not valid ) then |
||
4471 | if ( LootLink_RemoveItem(name, link) ) then |
||
4472 | return 1; |
||
4473 | end |
||
4474 | elseif ( valid == 1 ) then |
||
4475 | return 2; |
||
4476 | end |
||
4477 | end |
||
4478 | end |
||
4479 | |||
4480 | function LootLinkProcess_FIXCACHE() |
||
4481 | local todo = LLPtodo[LLPvars.done+1]; |
||
4482 | local name, link, index = todo[1], todo[2], todo[3]; |
||
4483 | local realname = GetItemInfo("item:"..link); |
||
4484 | local value = LootLink_GetValue( name, nil, link ); |
||
4485 | if ( not value ) then return; end |
||
4486 | value.i = string.gsub(link,"(%d+:%d+:%d+:)%d+","%10"); |
||
4487 | if ( realname ) then |
||
4488 | if ( LootLink_BuildSearchData( name, value, index ) == 2 ) then |
||
4489 | return 1; |
||
4490 | end |
||
4491 | elseif ( not value.t or value.t == "" ) then |
||
4492 | value.t = name.."·Bad Search Data·"; |
||
4493 | return 1; |
||
4494 | else |
||
4495 | local changes; |
||
4496 | if ( value.t ) then |
||
4497 | local t = value.t; |
||
4498 | local d = value.d; |
||
4499 | local s, e, val = string.find(t, "^(.-)·"); |
||
4500 | if ( not val or not string.find(name, val) ) then |
||
4501 | return 2; |
||
4502 | end |
||
4503 | if ( string.find(t, "%/") ) then |
||
4504 | -- cull out durability data. |
||
4505 | t = string.gsub(t, "Durability %d+ %/ %d+·", ""); |
||
4506 | -- check set data. |
||
4507 | s,e,val = string.find(t, ".+·(.-) %(%d%/%d+%)·.+"); |
||
4508 | if ( val ) then |
||
4509 | t = string.gsub(t, "(.+ %()%d+(%/%d+%)·.+)", "%10%2"); |
||
4510 | local newset = LootLink_GetSet(val); |
||
4511 | local setnum = LL_SearchData(value, "se"); |
||
4512 | if ( d ) then |
||
4513 | if ( not setnum ) then |
||
4514 | d = d.."se"..newset.."·"; |
||
4515 | changes = 1; |
||
4516 | elseif( newset ~= setnum ) then |
||
4517 | d = string.gsub(d, "(.+·se)%d+(·.+)", "%1"..newset.."%2"); |
||
4518 | changes = 1; |
||
4519 | end |
||
4520 | end |
||
4521 | end |
||
4522 | end |
||
4523 | |||
4524 | if ( value.t ~= t ) then |
||
4525 | changes = 1; |
||
4526 | end |
||
4527 | value.t = t; |
||
4528 | value.d = d; |
||
4529 | end |
||
4530 | if ( changes ) then |
||
4531 | return 1; |
||
4532 | end |
||
4533 | return 2; |
||
4534 | end |
||
4535 | end |
||
4536 | |||
4537 | function LootLinkProcess_Process(func) |
||
4538 | if ( not LLPvars ) then |
||
4539 | LootLink_Process_ToggleButtons(); |
||
4540 | |||
4541 | LLPvars = {}; |
||
4542 | |||
4543 | LLPvars.func = getglobal( "LootLinkProcess_"..func ); |
||
4544 | |||
4545 | if ( not LLPvars.func ) then |
||
4546 | LootLink_Process_ToggleButtons(1); |
||
4547 | preprocess = nil; |
||
4548 | return; |
||
4549 | end |
||
4550 | |||
4551 | HideUIPanel(LootLinkFrame); |
||
4552 | |||
4553 | LootLink_Process_Header:SetText(getglobal("LLP_"..func.."_LABEL") ); |
||
4554 | LootLink_Process_Num:SetText("Preprocessing"); |
||
4555 | LootLink_Process_Bar:SetMinMaxValues(0,1); |
||
4556 | LootLink_Process_Bar:SetValue(0); |
||
4557 | |||
4558 | LLPvars.functype = func; |
||
4559 | LLPvars.elapsed = 0; |
||
4560 | LLPvars.done = 0; |
||
4561 | LLPvars.updated = 0; |
||
4562 | LLPvars.failed = 0; |
||
4563 | LLPvars.wait = 0; |
||
4564 | LLPvars.total = 0; |
||
4565 | |||
4566 | LootLink_Process:SetAlpha( 1 ); |
||
4567 | LootLink_Process:Show(); |
||
4568 | |||
4569 | LootLinkFrame.process = func; |
||
4570 | end |
||
4571 | end |
||
4572 | |||
4573 | function LootLinkProcess_Run() |
||
4574 | local thisprocess = 0; |
||
4575 | local func = LLPvars.func; |
||
4576 | |||
4577 | if ( LLP_OUTOFMEM ) then |
||
4578 | LootLink_Process_Memory(); |
||
4579 | end |
||
4580 | |||
4581 | if ( LLPvars.wait ) then |
||
4582 | LLPvars.wait = LLPvars.wait - arg1; |
||
4583 | if ( LLPvars.wait <= 0 ) then |
||
4584 | LLPvars.wait = nil; |
||
4585 | end |
||
4586 | return; |
||
4587 | end |
||
4588 | |||
4589 | if ( not LLPtodo ) then |
||
4590 | local normal, mult = 0,0; |
||
4591 | LLPtodo = {}; |
||
4592 | for k, v in ItemLinks do |
||
4593 | if ( strlen(k) == 0 ) then |
||
4594 | ItemLinks[k] = nil; |
||
4595 | LLPvars.updated = LLPvars.updated + 1; |
||
4596 | elseif ( v.i ) then |
||
4597 | normal = normal + 1; |
||
4598 | tinsert( LLPtodo, {k, v.i} ); |
||
4599 | if ( GetItemInfo("item:"..v.i) ) then |
||
4600 | LLHiddenTooltip:SetHyperlink("item:"..v.i); |
||
4601 | end |
||
4602 | if ( v.m ) then |
||
4603 | for i=1, getn(v.m) do |
||
4604 | if v.m[i].i then |
||
4605 | mult = mult + 1; |
||
4606 | tinsert( LLPtodo, {k, v.m[i].i, i} ); |
||
4607 | if ( GetItemInfo("item:"..v.m[i].i) ) then |
||
4608 | LLHiddenTooltip:SetHyperlink("item:"..v.m[i].i); |
||
4609 | end |
||
4610 | else |
||
4611 | LootLink_RemoveItem(k, i); |
||
4612 | LLPvars.updated = LLPvars.updated + 1; |
||
4613 | end |
||
4614 | end |
||
4615 | end |
||
4616 | else |
||
4617 | LootLink_RemoveItem(k); |
||
4618 | LLPvars.updated = LLPvars.updated + 1; |
||
4619 | end |
||
4620 | end |
||
4621 | LLPvars.total = normal + mult; |
||
4622 | LootLink_Process_Bar:SetValue(0) |
||
4623 | LootLink_Process_Bar:SetMinMaxValues(0, LLPvars.total) |
||
4624 | LLPvars.wait = 2; |
||
4625 | return; |
||
4626 | end |
||
4627 | |||
4628 | local todo = LLPtodo; |
||
4629 | |||
4630 | LLPvars.elapsed = LLPvars.elapsed + arg1; |
||
4631 | |||
4632 | while todo and todo[LLPvars.done+1] do |
||
4633 | local ret = func(); |
||
4634 | if ( ret ) then |
||
4635 | if ( ret == 1 ) then |
||
4636 | LLPvars.updated = LLPvars.updated + 1; |
||
4637 | else |
||
4638 | LLPvars.failed = LLPvars.failed + 1; |
||
4639 | end |
||
4640 | end |
||
4641 | |||
4642 | LLPvars.updated = LLPvars.updated + LootLink_CheckDuplicate(todo[LLPvars.done+1][1]); |
||
4643 | LootLink_SortAlternates(todo[LLPvars.done+1][1]); |
||
4644 | |||
4645 | thisprocess = thisprocess + 1; |
||
4646 | LLPvars.done = LLPvars.done + 1; |
||
4647 | |||
4648 | if ( thisprocess == 50 ) then |
||
4649 | thisprocess = 0; |
||
4650 | LootLink_Process_Bar:SetValue( LLPvars.done ); |
||
4651 | LootLink_Process_Num:SetText( LLPvars.done .. "/".. LLPvars.total ); |
||
4652 | local time = (LLPvars.elapsed / LLPvars.done ) * (LLPvars.total - LLPvars.done); |
||
4653 | local s = mod( time, 60 ); |
||
4654 | local m = (time-s) / 60; |
||
4655 | s = floor(s) |
||
4656 | if ( strlen(s) == 1 ) then |
||
4657 | s = "0"..s; |
||
4658 | end |
||
4659 | LootLink_Process_Time:SetText( "Estimated "..m..":"..s.." remaining" ); |
||
4660 | |||
4661 | if ( DisplayIndices and LootLinkFrame:IsVisible() ) then |
||
4662 | LootLink_Update(); |
||
4663 | LootLink_SetTitle(); |
||
4664 | end |
||
4665 | |||
4666 | return; |
||
4667 | end |
||
4668 | end |
||
4669 | |||
4670 | if ( todo and not todo[LLPvars.done+1] ) then |
||
4671 | local text = getglobal("LLP_"..LLPvars.functype.."_END"); |
||
4672 | text = string.gsub( text, "%%u", LLPvars.updated ); |
||
4673 | text = string.gsub( text, "%%t", LLPvars.total ); |
||
4674 | text = string.gsub( text, "%%f", LLPvars.failed ); |
||
4675 | DEFAULT_CHAT_FRAME:AddMessage(text); |
||
4676 | LootLink_Process_Time:SetText(""); |
||
4677 | LootLink_Process_Num:SetText("Finished"); |
||
4678 | LootLink_Process_Bar:SetValue(LLPvars.total); |
||
4679 | |||
4680 | LootLink_Process_ToggleButtons(1); |
||
4681 | |||
4682 | LLPvars = nil; |
||
4683 | LLPtodo = nil; |
||
4684 | LootLinkFrame.process = nil; |
||
4685 | |||
4686 | LootLink_Process.fade = 2; |
||
4687 | LootLink_Process:SetScript("OnUpdate", LootLink_Process_Fade); |
||
4688 | end |
||
4689 | end |
||
4690 | |||
4691 | function LootLink_Process_Fade() |
||
4692 | if ( LootLink_Process.fade ) then |
||
4693 | LootLink_Process.fade = LootLink_Process.fade - (arg1 / 2); |
||
4694 | if ( LootLink_Process.fade < 1 ) then |
||
4695 | this:SetAlpha( LootLink_Process.fade ); |
||
4696 | if ( LootLink_Process.fade <= 0 ) then |
||
4697 | this:Hide(); |
||
4698 | LootLink_Process.fade = nil; |
||
4699 | LootLink_Process:SetScript("OnUpdate", nil); |
||
4700 | end |
||
4701 | end |
||
4702 | end |
||
4703 | end |
||
4704 | |||
4705 | -------------------------------------------------------------------------------------------------- |
||
4706 | -- External functions |
||
4707 | -------------------------------------------------------------------------------------------------- |
||
4708 | |||
4709 | -- Looks for and deconstructs links contained in a text string; if trusted, existing information will be verified |
||
4710 | -- Trusted sources are everything except chat links; since these can be spoofed, we want to allow them to be replaced |
||
4711 | function LootLink_ProcessLinks(text, trusted) |
||
4712 | local enchants, spoof, nosame, rarityfilter, lastName = LootLinkState.enchants, LootLinkState.spoof, LootLinkState.nosame, LootLinkState.rarityfilter; |
||
4713 | if( text ) then |
||
4714 | for color, item, name in string.gfind(text, "|c(%x+)|Hitem:(%d+:%d+:%d+:%d+)|h%[(.-)%]|h|r") do |
||
4715 | if ( item ~= "0:0:0:0" and ( not rarityfilter or lRarityFilter[color] > rarityfilter ) and LootLink_CheckSame(name, item) ) then |
||
4716 | local fixedname, fixeditem; |
||
4717 | if ( not trusted ) then |
||
4718 | if ( spoof ) then |
||
4719 | name, item = LootLink_ValidateItem(name, item, 1); |
||
4720 | else |
||
4721 | fixedname, fixeditem = LootLink_ValidateItem(name, item, 1); |
||
4722 | if ( fixedname and fixedname ~= name ) then |
||
4723 | LootLink_AddItem(fixedname, fixeditem, color, trusted); |
||
4724 | end |
||
4725 | end |
||
4726 | end |
||
4727 | local enchant; |
||
4728 | if ( not enchants and not nosame ) then |
||
4729 | enchant = string.gsub(item, "^(%d+):(%d+):(%d+):%d+$", "%1:%2:%3:0"); |
||
4730 | end |
||
4731 | item = string.gsub(item, "^(%d+):%d+:(%d+):%d+$", "%1:0:%2:0"); |
||
4732 | LootLink_AddItem(name, item, color, trusted); |
||
4733 | if ( enchant and enchant ~= item ) then |
||
4734 | LootLink_AddItem(name, enchant, color, trusted); |
||
4735 | end |
||
4736 | LootLink_SortAlternates(name); |
||
4737 | lastName = name; |
||
4738 | end |
||
4739 | end |
||
4740 | end |
||
4741 | return lastName; |
||
4742 | end |
||
4743 | |||
4744 | function LootLink_CheckSame(name, item) |
||
4745 | local _,_,itemid,suffixid=string.find(item, "(%d+):%d+:(%d+):%d+"); |
||
4746 | local value = ItemLinks[name]; |
||
4747 | if ( value and (LootLinkState.nosame or LootLinkState.novariants) ) then |
||
4748 | -- Assumes no same name items are both different itemid and have suffixids |
||
4749 | if ( value.i and value.i ~= item ) then |
||
4750 | for id, suf in string.gfind( value.i, "(%d+):%d+:(%d+):") do |
||
4751 | if ( nosame and tonumber(id) > tonumber(itemid) ) then |
||
4752 | return; |
||
4753 | elseif ( tonumber(suf) > tonumber(suffixid) ) then |
||
4754 | return; |
||
4755 | end |
||
4756 | end |
||
4757 | end |
||
4758 | end |
||
4759 | return 1; |
||
4760 | end |
||
4761 | |||
4762 | -- old filter function, keeping for posterity |
||
4763 | --[[function LootLink_FilterCheck(name, item, color) |
||
4764 | if ( item == "0:0:0:0" ) then |
||
4765 | return; |
||
4766 | end |
||
4767 | local op = LootLinkState; |
||
4768 | if ( op.rarityfilter ) then |
||
4769 | local rarity = lRarityFilter[color]; |
||
4770 | if ( rarity and rarity < op.rarityfilter ) then |
||
4771 | return; |
||
4772 | end |
||
4773 | end |
||
4774 | local _,_,itemid,enchantid,suffixid=string.find(item, "(%d+):(%d+):(%d+):%d+"); |
||
4775 | if ( not tonumber(enchantid) ) then |
||
4776 | --ChatFrame1:AddMessage((name or "??").." no enchant id "..(item or "???")); |
||
4777 | return; |
||
4778 | end |
||
4779 | local value = ItemLinks[name]; |
||
4780 | if ( value and (op.nosame or op.novariants) ) then |
||
4781 | -- Assumes no same name items are both different itemid and have suffixids |
||
4782 | if ( value.i and value.i ~= item ) then |
||
4783 | for id, suf in string.gfind( value.i, "(%d+):%d+:(%d+):") do |
||
4784 | if ( op.nosame and tonumber(id) > tonumber(itemid) ) then |
||
4785 | return; |
||
4786 | elseif ( tonumber(suf) > tonumber(suffixid) ) then |
||
4787 | return; |
||
4788 | end |
||
4789 | end |
||
4790 | end |
||
4791 | end |
||
4792 | return 1; |
||
4793 | end]] |
||
4794 | |||
4795 | -- Add items to the database |
||
4796 | function LootLink_AddItem(name, link, color, trusted) |
||
4797 | local nosame, value, index = LootLinkState.nosame; |
||
4798 | if ( name and link ) then |
||
4799 | if ( not ItemLinks[name] ) then |
||
4800 | ItemLinks[name] = { }; |
||
4801 | lItemLinksSizeTotal = lItemLinksSizeTotal + 1; |
||
4802 | if( LootLink_GetDataVersion() < 110 ) then |
||
4803 | -- Set a flag to indicate that this item is new and should be skipped on a makehome |
||
4804 | ItemLinks[name]._ = 1; |
||
4805 | end |
||
4806 | end |
||
4807 | value = ItemLinks[name]; |
||
4808 | if ( not nosame and LootLinkState.novariants ) then |
||
4809 | for suffixid in string.gfind(link, "%d+:%d+:(%d+):%d+") do |
||
4810 | if ( tonumber(suffixid) > 0 ) then |
||
4811 | nosame = 1; |
||
4812 | end |
||
4813 | end |
||
4814 | end |
||
4815 | if ( not nosame and value.i and value.i ~= link ) then |
||
4816 | if ( value.m and getn(value.m) > 0 ) then |
||
4817 | for k, v in value.m do |
||
4818 | if ( v.i == link ) then |
||
4819 | if ( not trusted ) then |
||
4820 | return nil; |
||
4821 | end |
||
4822 | index = k; |
||
4823 | break; |
||
4824 | end |
||
4825 | end |
||
4826 | end |
||
4827 | if ( index ) then |
||
4828 | value = value.m[index]; |
||
4829 | else |
||
4830 | if ( not value.m ) then |
||
4831 | value.m = {}; |
||
4832 | end |
||
4833 | tinsert( value.m, {} ); |
||
4834 | index = getn(value.m); |
||
4835 | value = value.m[index]; |
||
4836 | lItemLinksSizeTotal = lItemLinksSizeTotal + 1; |
||
4837 | end |
||
4838 | end |
||
4839 | |||
4840 | value.i = link; |
||
4841 | value.c = color; |
||
4842 | |||
4843 | LootLink_BuildSearchData(name, value, index); |
||
4844 | if( not LootLink_CheckItemServerRaw(value, lServerIndex) ) then |
||
4845 | LootLink_AddItemServer(value, lServerIndex); |
||
4846 | end |
||
4847 | return value; |
||
4848 | end |
||
4849 | end |
||
4850 | |||
4851 | -- Sort same name items by ids |
||
4852 | function LootLink_SortAlternates(name) |
||
4853 | if ( not name ) then return; end |
||
4854 | local value = ItemLinks[name]; |
||
4855 | local newval; |
||
4856 | local values = {}; |
||
4857 | local itemval = {}; |
||
4858 | |||
4859 | -- cleaned up by Adrine |
||
4860 | function sortByLink(e1, e2) |
||
4861 | if ( not e1 ) then return true; elseif ( not e2 ) then return false; end |
||
4862 | local _,_,a,b,c = string.find(e1.i, "(%d+):(%d+):(%d+)"); |
||
4863 | local _,_,d,e,f = string.find(e2.i, "(%d+):(%d+):(%d+)"); |
||
4864 | |||
4865 | if a ~= d then return tonumber(a) > tonumber(d); end |
||
4866 | if c ~= f then return tonumber(c) > tonumber(f); end |
||
4867 | if b ~= e then return tonumber(b) < tonumber(e); end |
||
4868 | return false; |
||
4869 | end |
||
4870 | |||
4871 | if value and value.m then |
||
4872 | if ( getn(value.m) == 0 ) then |
||
4873 | value.m = nil; |
||
4874 | return nil; |
||
4875 | end |
||
4876 | for k, v in value do |
||
4877 | if ( k ~= "m" ) then |
||
4878 | itemval[k] = v; |
||
4879 | end |
||
4880 | end |
||
4881 | tinsert( values, itemval ); |
||
4882 | for k, v in value.m do |
||
4883 | tinsert( values, v ); |
||
4884 | end |
||
4885 | |||
4886 | table.sort(values, sortByLink); |
||
4887 | |||
4888 | newval = values[1]; |
||
4889 | newval.m = {}; |
||
4890 | for i=2, getn(values) do |
||
4891 | tinsert( newval.m, values[i] ); |
||
4892 | end |
||
4893 | else |
||
4894 | return nil; |
||
4895 | end |
||
4896 | ItemLinks[name] = {}; |
||
4897 | ItemLinks[name] = newval; |
||
4898 | end |
||
4899 | |||
4900 | -- Adds icon of the item if it's valid |
||
4901 | function LootLink_AddTooltipTexture(link) |
||
4902 | if ( link and not LootLinkState.hideicon) then |
||
4903 | local _, _, _, _, _, _, _, _, itemTexture = GetItemInfo(link); |
||
4904 | if ( itemTexture ) then |
||
4905 | local iItem = LootLinkFrame.TooltipButton or 0; |
||
4906 | LootLinkTooltipIconTexture:SetTexture( itemTexture ); |
||
4907 | LootLinkTooltipIcon:ClearAllPoints(); |
||
4908 | LootLinkTooltipIcon:SetPoint("BOTTOMLEFT", getglobal("LootLinkItem"..iItem), "BOTTOMRIGHT"); |
||
4909 | LootLinkTooltipIcon:Show(); |
||
4910 | return; |
||
4911 | end |
||
4912 | end |
||
4913 | LootLinkTooltipIcon:Hide(); |
||
4914 | end |
||
4915 | |||
4916 | -- Adds extra tooltip information for the item with the given name |
||
4917 | function LootLink_AddTooltipInfo(name, tooltip, quantity, index) |
||
4918 | if( not tooltip ) then |
||
4919 | tooltip = LootLinkTooltip; |
||
4920 | end |
||
4921 | if( not quantity ) then |
||
4922 | quantity = 1; |
||
4923 | end |
||
4924 | if( tooltip == LootLinkTooltip ) then |
||
4925 | LootLink_HideTooltipMoney(); |
||
4926 | end |
||
4927 | if( not LootLinkState.HideInfo and ItemLinks[name] ) then |
||
4928 | if( tooltip == GameTooltip ) then |
||
4929 | GameTooltip.llDone = 1; |
||
4930 | end |
||
4931 | if( ItemLinks[name].p ) then |
||
4932 | LootLink_SetTooltipMoney(tooltip, quantity, ItemLinks[name].p, ItemLinks[name].x); |
||
4933 | end |
||
4934 | LootLink_AddExtraTooltipInfo(tooltip, name, quantity, ItemLinks[name]); |
||
4935 | tooltip:Show(); |
||
4936 | end |
||
4937 | end |
||
4938 | |||
4939 | -- This will set up a tooltip with item information for the given name if it's known |
||
4940 | function LootLink_SetTooltip(tooltip, name, quantity) |
||
4941 | local link; |
||
4942 | |||
4943 | if( tooltip and name ) then |
||
4944 | link = LootLink_GetHyperlink(name); |
||
4945 | if( link ) then |
||
4946 | LootLink_SetHyperlink(tooltip, name, link); |
||
4947 | if( quantity ) then |
||
4948 | quantity = tonumber(quantity); |
||
4949 | else |
||
4950 | quantity = 1; |
||
4951 | end |
||
4952 | if( quantity > 0 ) then |
||
4953 | LootLink_AddTooltipInfo(name, tooltip, quantity); |
||
4954 | end |
||
4955 | end |
||
4956 | end |
||
4957 | end |
||
4958 | |||
4959 | -- |
||
4960 | function LootLink_ChatEdit_OnTabPressed() |
||
4961 | |||
4962 | lOriginal_ChatEdit_OnTabPressed(); |
||
4963 | end |
||
4964 | |||
4965 | function LootLink_ChatEdit_OnTextChanged() |
||
4966 | local text = this:GetText(); |
||
4967 | if (string.sub(text, 1, 7) ~= "/script" or string.sub(text, 1, 5) ~= "/dump") then |
||
4968 | --text = string.gsub(text, "([|]?[h]?)%[(.-)%]([|]?[h]?)", FLT_LinkifyName); |
||
4969 | --end |
||
4970 | end |
||
4971 | lOriginal_ChatEdit_OnTextChanged(); |
||
4972 | end |
||
4973 | |||
4974 | -- Calling this will allow LootLink to automatically add information to tooltips when needed |
||
4975 | function LootLink_AutoInfoOn() |
||
4976 | lSuppressInfoAdd = nil; |
||
4977 | end |
||
4978 | |||
4979 | -- Calling this will prevent LootLink from automatically adding information to tooltips |
||
4980 | function LootLink_AutoInfoOff() |
||
4981 | lSuppressInfoAdd = 1; |
||
4982 | end |
||
4983 | |||
4984 | -- Use this function to get the current server name from LootLink's perspective |
||
4985 | function LootLink_GetCurrentServerName() |
||
4986 | return lServer; |
||
4987 | end |
||
4988 | |||
4989 | -- Use this function to get the current server index |
||
4990 | function LootLink_GetCurrentServerIndex() |
||
4991 | return lServerIndex; |
||
4992 | end |
||
4993 | |||
4994 | -- Use this function to map a server name to the server index for the ItemLinks[name].servers array |
||
4995 | function LootLink_GetServerIndex(name) |
||
4996 | if( not LootLinkState or not LootLinkState.ServerNamesToIndices ) then |
||
4997 | return nil; |
||
4998 | end |
||
4999 | return LootLinkState.ServerNamesToIndices[name]; |
||
5000 | end |
||
5001 | |||
5002 | -- Use this function to check whether an ItemLinks[name] entry is valid for a given server index |
||
5003 | function LootLink_CheckItemServer(item, serverIndex) |
||
5004 | -- If we haven't converted and this item predates multiple server support, count it as valid |
||
5005 | if( LootLink_GetDataVersion() < 110 and not item._ ) then |
||
5006 | return 1; |
||
5007 | end |
||
5008 | return LootLink_CheckItemServerRaw(item, serverIndex); |
||
5009 | end |
||
5010 | |||
5011 | -- Used for debugging changes in item data and tooltip format |
||
5012 | function LootLink_Validate() |
||
5013 | for index, value in ItemLinks do |
||
5014 | if( not value.d ) then |
||
5015 | DEFAULT_CHAT_FRAME:AddMessage(index.." has no search data"); |
||
5016 | -- else |
||
5017 | -- if( not LL_SearchData(value, "su") ) then |
||
5018 | -- DEFAULT_CHAT_FRAME:AddMessage(index.." has no subtype"); |
||
5019 | -- end |
||
5020 | end |
||
5021 | end |
||
5022 | end |
||
5023 | |||
5024 | -------------------------------------------------------------------------------------------------- |
||
5025 | -- Hookable callback functions |
||
5026 | -------------------------------------------------------------------------------------------------- |
||
5027 | |||
5028 | -- Hook this function to add any extra information you like to the tooltip |
||
5029 | function LootLink_AddExtraTooltipInfo(tooltip, name, quantity, item) |
||
5030 | -- tooltip: the current tooltip frame |
||
5031 | -- name: the name of the item |
||
5032 | -- quantity: the number of items, if known, else 1 |
||
5033 | -- item: ItemLinks[name]; LootLink's data for this item |
||
5034 | end |
||
5035 | |||
5036 | -- Hook this function to be called whenever an equipment slot is successfully inspected |
||
5037 | function LootLink_Event_InspectSlot(name, count, item, unit, slotid) |
||
5038 | -- name: the name of the item |
||
5039 | -- count: the number of items, if known, else 1 |
||
5040 | -- item: ItemLinks[name]; LootLink's data for this item |
||
5041 | -- unit: "target", "player", etc. |
||
5042 | -- slotid: the id of the slot inspected |
||
5043 | end |
||
5044 | |||
5045 | -- Hook this function to be called whenever an inventory slot is successfully inspected |
||
5046 | function LootLink_Event_ScanInventory(name, count, item, bagid, slotid) |
||
5047 | -- name: the name of the item |
||
5048 | -- count: the number of items, if known, else 1 |
||
5049 | -- item: ItemLinks[name]; LootLink's data for this item |
||
5050 | -- bagid: the id of the bag containing the item |
||
5051 | -- slotid: the id of the slot inspected |
||
5052 | end |
||
5053 | |||
5054 | -- Hook this function to be called whenever a bank slot is successfully inspected |
||
5055 | function LootLink_Event_ScanBank(name, count, item, bagid, slotid) |
||
5056 | -- name: the name of the item |
||
5057 | -- count: the number of items, if known, else 1 |
||
5058 | -- item: ItemLinks[name]; LootLink's data for this item |
||
5059 | -- bagid: the id of the bag containing the item |
||
5060 | -- slotid: the id of the slot inspected |
||
5061 | end |
||
5062 | |||
5063 | -- Hook this function to be called whenever an auction entry is successfully inspected |
||
5064 | function LootLink_Event_ScanAuction(name, count, item, auctionpage, auctionid) |
||
5065 | -- name: the name of the item |
||
5066 | -- count: the number of items, if known, else 1 |
||
5067 | -- item: ItemLinks[name]; LootLink's data for this item |
||
5068 | -- auctionpage: the page number this item was found on |
||
5069 | -- auctionid: the id of the inspected item |
||
5070 | end |
||
5071 | |||
5072 | -- Hook this function to be called whenever a chat message is successfully inspected |
||
5073 | function LootLink_Event_ScanChat(name, item, text) |
||
5074 | -- name: the name of the last item in the chat message |
||
5075 | -- item: ItemLinks[name]; LootLink's data for this item |
||
5076 | -- text: the inspected chat message |
||
5077 | end |
||
5078 | |||
5079 | -- Hook this function to be called whenever LootLink starts an auction scan |
||
5080 | function LootLink_Event_StartAuctionScan() |
||
5081 | end |
||
5082 | |||
5083 | -- Hook this function to be called whenever LootLink stops an auction scan |
||
5084 | function LootLink_Event_StopAuctionScan() |
||
5085 | end |
||
5086 | |||
5087 | -- Hook this function to be called whenever LootLink completes a full auction scan |
||
5088 | function LootLink_Event_FinishedAuctionScan() |
||
5089 | end |
||
5090 | |||
5091 | -- Hook this function to be called whenever LootLink sends a new auction query |
||
5092 | function LootLink_Event_AuctionQuery(auctionpage) |
||
5093 | -- auctionpage: the page number for the query that was just sent |
||
5094 | end |
||
5095 | |||
5096 | |||
5097 | -------------------------------------------------------------------------------------------------- |
||
5098 | -- Static Popup Dialogs |
||
5099 | -------------------------------------------------------------------------------------------------- |
||
5100 | |||
5101 | StaticPopupDialogs["LOOTLINK_DELETEITEM_CONFIRM"] = { |
||
5102 | text = TEXT(LOOTLINK_STATICPOPUP_DELETE_ITEM_CONFIRM), |
||
5103 | button1 = TEXT(YES), |
||
5104 | button2 = TEXT(NO), |
||
5105 | OnAccept = function(data) |
||
5106 | if ( not data ) then return; end |
||
5107 | if ( LootLink_RemoveItem(data[1], data[2].i, data[3] ) ) then |
||
5108 | LootLink_Update(); |
||
5109 | LootLink_SetTitle(); |
||
5110 | end |
||
5111 | end, |
||
5112 | showAlert = 1, |
||
5113 | timeout = 0, |
||
5114 | exclusive = 1, |
||
5115 | whileDead = 1, |
||
5116 | hideOnEscape = 1, |
||
5117 | }; |
||
5118 | |||
5119 | StaticPopupDialogs["LOOTLINK_LITEMODE_CONFIRM"] = { |
||
5120 | text = TEXT(LOOTLINK_STATICPOPUP_LITE_MODE_CONFIRM), |
||
5121 | button1 = TEXT(OKAY), |
||
5122 | button2 = TEXT(CANCEL), |
||
5123 | OnCancel = function() |
||
5124 | LLO_LiteModeCheckButton:SetChecked(); |
||
5125 | end, |
||
5126 | showAlert = 1, |
||
5127 | timeout = 0, |
||
5128 | exclusive = 1, |
||
5129 | whileDead = 1, |
||
5130 | hideOnEscape = 1, |
||
5131 | }; |
||
5132 | |||
5133 | StaticPopupDialogs["LOOTLINK_LINK_CONFIRM"] = { |
||
5134 | text = TEXT(LOOTLINK_STATICPOPUP_ITEM_CONFIRM), |
||
5135 | button1 = TEXT(OKAY), |
||
5136 | button2 = TEXT(CANCEL), |
||
5137 | OnAccept = function(data) |
||
5138 | ChatFrameEditBox:Insert(LootLink_GetLink(data[1], data[3])); |
||
5139 | end, |
||
5140 | showAlert = 1, |
||
5141 | timeout = 0, |
||
5142 | exclusive = 1, |
||
5143 | whileDead = 1, |
||
5144 | hideOnEscape = 1, |
||
5145 | }; |
||
5146 | |||
5147 | StaticPopupDialogs["LOOTLINK_DRESSUP_CONFIRM"] = { |
||
5148 | text = TEXT(LOOTLINK_STATICPOPUP_ITEM_CONFIRM), |
||
5149 | button1 = TEXT(OKAY), |
||
5150 | button2 = TEXT(CANCEL), |
||
5151 | OnAccept = function(data) |
||
5152 | DressUpItemLink(LootLink_GetLink(data[1], data[3])); |
||
5153 | end, |
||
5154 | showAlert = 1, |
||
5155 | timeout = 0, |
||
5156 | exclusive = 1, |
||
5157 | whileDead = 1, |
||
5158 | hideOnEscape = 1, |
||
5159 | }; |
||
5160 | |||
5161 | |||
5162 | -------------------------------------------------------------------------------------------------- |
||
5163 | -- Type links - borrowed from Gazmik Fizzwidget's Linkerator |
||
5164 | -------------------------------------------------------------------------------------------------- |
||
5165 | |||
5166 | function LootLink_TypeLinks_LinkifyName(head, text, tail) |
||
5167 | if (head ~= "|h" and tail ~= "|h") then -- only linkify things text that isn't linked already |
||
5168 | local link = LootLink_GetLink(text); |
||
5169 | if (link) then return link; end |
||
5170 | end |
||
5171 | return head.."["..text.."]"..tail; |
||
5172 | end |
||
5173 | |||
5174 | function LootLink_TypeLinks_ParseChatMessage(text) |
||
5175 | return string.gsub(text, "([|]?[h]?)%[(.-)%]([|]?[h]?)", LootLink_TypeLinks_LinkifyName); |
||
5176 | end |
||
5177 | |||
5178 | -- thank you ckknight |
||
5179 | function LootLink_TypeLinks_AutoComplete(text) |
||
5180 | local _,_,body,name = string.find( text, "(.*%[)(%S[^%[^%]]+)$" ); |
||
5181 | if ( name ) then |
||
5182 | local textlen, namelen, found = strlen(text), strlen(name); |
||
5183 | if ( this.lastLength and this.lastItem and textlen > this.lastLength ) then |
||
5184 | if string.find(strlower(this.lastItem), strlower(name)) then |
||
5185 | this.lastLength = textlen; |
||
5186 | this:SetText(body..this.lastItem); |
||
5187 | this:HighlightText(textlen); |
||
5188 | return 1; |
||
5189 | end |
||
5190 | end |
||
5191 | this.lastLength = textlen; |
||
5192 | for k, v in ItemLinks do |
||
5193 | if ( strlen(k) >= namelen and strlower(strsub(k,1,namelen)) == strlower(name) ) then |
||
5194 | found = 1; |
||
5195 | if ( (not this.itemComplete or not this.itemComplete[k]) ) then |
||
5196 | if ( not this.itemComplete ) then |
||
5197 | this.itemComplete = {}; |
||
5198 | end |
||
5199 | this.ignoreTextChange = 1; |
||
5200 | this:SetText(body..k); |
||
5201 | this:HighlightText(textlen); |
||
5202 | this.lastItem = k; |
||
5203 | this.itemComplete[k] = 1; |
||
5204 | return 1; |
||
5205 | end |
||
5206 | end |
||
5207 | end |
||
5208 | if ( found ) then |
||
5209 | this.lastLength = nil; |
||
5210 | this.lastItem = nil; |
||
5211 | this.itemComplete = nil; |
||
5212 | return LootLink_TypeLinks_AutoComplete(text); |
||
5213 | end |
||
5214 | end |
||
5215 | this.lastItem = nil; |
||
5216 | this.itemComplete = nil; |
||
5217 | end |
||
5218 | |||
5219 | -- Hooks |
||
5220 | |||
5221 | lOrig_ChatEdit_OnTextChanged = ChatEdit_OnTextChanged; |
||
5222 | function ChatEdit_OnTextChanged() |
||
5223 | if ( LootLinkState.typelinks ) then |
||
5224 | local text = this:GetText(); |
||
5225 | if (string.find(text, "^/script") or string.find(text, "^/dump")) then |
||
5226 | -- don't parse |
||
5227 | else |
||
5228 | local newtext = LootLink_TypeLinks_ParseChatMessage(text); |
||
5229 | if ( text ~= newtext ) then |
||
5230 | this:SetText(newtext); |
||
5231 | return; |
||
5232 | end |
||
5233 | end |
||
5234 | end |
||
5235 | lOrig_ChatEdit_OnTextChanged(this); |
||
5236 | end |
||
5237 | |||
5238 | lOrig_ChatEdit_OnChar = ChatFrameEditBox:GetScript("OnChar"); |
||
5239 | function ChatEdit_OnChar() |
||
5240 | if ( LootLinkState.typelinks and LootLinkState.autotypelinks ) then |
||
5241 | local text = this:GetText(); |
||
5242 | if ( string.find(text, "^/script") or string.find(text, "^/dump")) then |
||
5243 | else |
||
5244 | LootLink_TypeLinks_AutoComplete(text); |
||
5245 | end |
||
5246 | elseif ( lOrig_ChatEdit_OnChar ) then |
||
5247 | lOrig_ChatEdit_OnChar(this); |
||
5248 | end |
||
5249 | end |
||
5250 | ChatFrameEditBox:SetScript("OnChar", ChatEdit_OnChar); |
||
5251 | |||
5252 | lOrig_ChatEdit_OnTabPressed = ChatEdit_OnTabPressed; |
||
5253 | function ChatEdit_OnTabPressed() |
||
5254 | this.lastLength = nil; |
||
5255 | if ( LootLinkState.typelinks and LootLinkState.autotypelinks and this.lastItem ) then |
||
5256 | this:Insert(""); |
||
5257 | else |
||
5258 | lOrig_ChatEdit_OnTabPressed(); |
||
5259 | end |
||
5260 | end |
||
5261 | |||
5262 | lOrig_ChatEdit_OnEnterPressed = ChatEdit_OnEnterPressed; |
||
5263 | function ChatEdit_OnEnterPressed() |
||
5264 | if ( LootLinkState.typelinks and LootLinkState.autotypelinks and this.itemComplete ) then |
||
5265 | this:SetText(this:GetText().."]"); |
||
5266 | else |
||
5267 | lOrig_ChatEdit_OnEnterPressed(); |
||
5268 | end |
||
5269 | this.itemComplete = nil; |
||
5270 | end |