SHOW:
|
|
- or go back to the newest paste.
1 | - | Code moved and updated: |
1 | + | --[[ |
2 | - | http://pastebin.com/Xc9yTwbK |
2 | + | Source of code: https://github.com/ElunaLuaEngine/Scripts/blob/master/Custom/Transmogrifier.lua |
3 | ||
4 | 4.0 | |
5 | Transmogrification 3.3.5a & TBC - Gossip Menu | |
6 | By Rochet2 | |
7 | ||
8 | Eluna version | |
9 | ||
10 | TODO: | |
11 | Make DB saving even better (Deleting)? What about coding? | |
12 | ||
13 | Fix the cost formula | |
14 | ||
15 | TODO in the distant future: | |
16 | ||
17 | Are the qualities right? Blizzard might have changed the quality requirements. | |
18 | What can and cant be used as source or target..? | |
19 | ||
20 | Cant transmogrify: | |
21 | rediculus items -- Foereaper: would be fun to stab people with a fish | |
22 | -- Cant think of any good way to handle this easily | |
23 | ||
24 | Cataclysm: | |
25 | Test on cata : implement UI xD? | |
26 | Item link icon to Are You sure text | |
27 | ]] | |
28 | ||
29 | local NPC_Entry = 60000 | |
30 | ||
31 | local RequireGold = 1 | |
32 | local GoldModifier = 1.0 | |
33 | local GoldCost = 100000 | |
34 | ||
35 | local RequireToken = false | |
36 | local TokenEntry = 49426 | |
37 | local TokenAmount = 1 | |
38 | ||
39 | local AllowMixedArmorTypes = false | |
40 | local AllowMixedWeaponTypes = false | |
41 | ||
42 | local Qualities = | |
43 | { | |
44 | [0] = false, -- AllowPoor | |
45 | [1] = false, -- AllowCommon | |
46 | [2] = true , -- AllowUncommon | |
47 | [3] = true , -- AllowRare | |
48 | [4] = true , -- AllowEpic | |
49 | [5] = false, -- AllowLegendary | |
50 | [6] = false, -- AllowArtifact | |
51 | [7] = true , -- AllowHeirloom | |
52 | } | |
53 | ||
54 | local EQUIPMENT_SLOT_START = 0 | |
55 | local EQUIPMENT_SLOT_HEAD = 0 | |
56 | local EQUIPMENT_SLOT_NECK = 1 | |
57 | local EQUIPMENT_SLOT_SHOULDERS = 2 | |
58 | local EQUIPMENT_SLOT_BODY = 3 | |
59 | local EQUIPMENT_SLOT_CHEST = 4 | |
60 | local EQUIPMENT_SLOT_WAIST = 5 | |
61 | local EQUIPMENT_SLOT_LEGS = 6 | |
62 | local EQUIPMENT_SLOT_FEET = 7 | |
63 | local EQUIPMENT_SLOT_WRISTS = 8 | |
64 | local EQUIPMENT_SLOT_HANDS = 9 | |
65 | local EQUIPMENT_SLOT_FINGER1 = 10 | |
66 | local EQUIPMENT_SLOT_FINGER2 = 11 | |
67 | local EQUIPMENT_SLOT_TRINKET1 = 12 | |
68 | local EQUIPMENT_SLOT_TRINKET2 = 13 | |
69 | local EQUIPMENT_SLOT_BACK = 14 | |
70 | local EQUIPMENT_SLOT_MAINHAND = 15 | |
71 | local EQUIPMENT_SLOT_OFFHAND = 16 | |
72 | local EQUIPMENT_SLOT_RANGED = 17 | |
73 | local EQUIPMENT_SLOT_TABARD = 18 | |
74 | local EQUIPMENT_SLOT_END = 19 | |
75 | ||
76 | local INVENTORY_SLOT_BAG_START = 19 | |
77 | local INVENTORY_SLOT_BAG_END = 23 | |
78 | ||
79 | local INVENTORY_SLOT_ITEM_START = 23 | |
80 | local INVENTORY_SLOT_ITEM_END = 39 | |
81 | ||
82 | local INVTYPE_CHEST = 5 | |
83 | local INVTYPE_WEAPON = 13 | |
84 | local INVTYPE_ROBE = 20 | |
85 | local INVTYPE_WEAPONMAINHAND = 21 | |
86 | local INVTYPE_WEAPONOFFHAND = 22 | |
87 | ||
88 | local ITEM_CLASS_WEAPON = 2 | |
89 | local ITEM_CLASS_ARMOR = 4 | |
90 | ||
91 | local ITEM_SUBCLASS_WEAPON_BOW = 2 | |
92 | local ITEM_SUBCLASS_WEAPON_GUN = 3 | |
93 | local ITEM_SUBCLASS_WEAPON_CROSSBOW = 18 | |
94 | local ITEM_SUBCLASS_WEAPON_FISHING_POLE = 20 | |
95 | ||
96 | local EXPANSION_WOTLK = 2 | |
97 | local PLAYER_VISIBLE_ITEM_1_ENTRYID | |
98 | local ITEM_SLOT_MULTIPLIER | |
99 | if GetCoreExpansion() < EXPANSION_WOTLK then | |
100 | PLAYER_VISIBLE_ITEM_1_ENTRYID = 346 | |
101 | ITEM_SLOT_MULTIPLIER = 16 | |
102 | else | |
103 | PLAYER_VISIBLE_ITEM_1_ENTRYID = 283 | |
104 | ITEM_SLOT_MULTIPLIER = 2 | |
105 | end | |
106 | ||
107 | local INVENTORY_SLOT_BAG_0 = 255 | |
108 | ||
109 | local SlotNames = { | |
110 | [EQUIPMENT_SLOT_HEAD ] = {"Head", nil, nil, nil, nil, nil, nil, nil, nil}, | |
111 | [EQUIPMENT_SLOT_SHOULDERS ] = {"Shoulders", nil, nil, nil, nil, nil, nil, nil, nil}, | |
112 | [EQUIPMENT_SLOT_BODY ] = {"Shirt", nil, nil, nil, nil, nil, nil, nil, nil}, | |
113 | [EQUIPMENT_SLOT_CHEST ] = {"Chest", nil, nil, nil, nil, nil, nil, nil, nil}, | |
114 | [EQUIPMENT_SLOT_WAIST ] = {"Waist", nil, nil, nil, nil, nil, nil, nil, nil}, | |
115 | [EQUIPMENT_SLOT_LEGS ] = {"Legs", nil, nil, nil, nil, nil, nil, nil, nil}, | |
116 | [EQUIPMENT_SLOT_FEET ] = {"Feet", nil, nil, nil, nil, nil, nil, nil, nil}, | |
117 | [EQUIPMENT_SLOT_WRISTS ] = {"Wrists", nil, nil, nil, nil, nil, nil, nil, nil}, | |
118 | [EQUIPMENT_SLOT_HANDS ] = {"Hands", nil, nil, nil, nil, nil, nil, nil, nil}, | |
119 | [EQUIPMENT_SLOT_BACK ] = {"Back", nil, nil, nil, nil, nil, nil, nil, nil}, | |
120 | [EQUIPMENT_SLOT_MAINHAND ] = {"Main hand", nil, nil, nil, nil, nil, nil, nil, nil}, | |
121 | [EQUIPMENT_SLOT_OFFHAND ] = {"Off hand", nil, nil, nil, nil, nil, nil, nil, nil}, | |
122 | [EQUIPMENT_SLOT_RANGED ] = {"Ranged", nil, nil, nil, nil, nil, nil, nil, nil}, | |
123 | [EQUIPMENT_SLOT_TABARD ] = {"Tabard", nil, nil, nil, nil, nil, nil, nil, nil}, | |
124 | } | |
125 | local Locales = { | |
126 | {"Update menu", nil, nil, nil, nil, nil, nil, nil, nil}, | |
127 | {"Remove all transmogrifications", nil, nil, nil, nil, nil, nil, nil, nil}, | |
128 | {"Remove transmogrifications from all equipped items?", nil, nil, nil, nil, nil, nil, nil, nil}, | |
129 | {"Using this item for transmogrify will bind it to you and make it non-refundable and non-tradeable.\nDo you wish to continue?", nil, nil, nil, nil, nil, nil, nil, nil}, | |
130 | {"Remove transmogrification from %s?", nil, nil, nil, nil, nil, nil, nil, nil}, | |
131 | {"Back..", nil, nil, nil, nil, nil, nil, nil, nil}, | |
132 | {"Remove transmogrification", nil, nil, nil, nil, nil, nil, nil, nil}, | |
133 | {"Transmogrifications removed from equipped items", nil, nil, nil, nil, nil, nil, nil, nil}, | |
134 | {"You have no transmogrified items equipped", nil, nil, nil, nil, nil, nil, nil, nil}, | |
135 | {"%s transmogrification removed", nil, nil, nil, nil, nil, nil, nil, nil}, | |
136 | {"No transmogrification on %s slot", nil, nil, nil, nil, nil, nil, nil, nil}, | |
137 | {"%s transmogrified", nil, nil, nil, nil, nil, nil, nil, nil}, | |
138 | {"Selected items are not suitable", nil, nil, nil, nil, nil, nil, nil, nil}, | |
139 | {"Selected item does not exist", nil, nil, nil, nil, nil, nil, nil, nil}, | |
140 | {"Equipment slot is empty", nil, nil, nil, nil, nil, nil, nil, nil}, | |
141 | {"You don't have enough %ss", nil, nil, nil, nil, nil, nil, nil, nil}, | |
142 | } | |
143 | local function LocText(id, p) -- "%s":format("test") | |
144 | if Locales[id] then | |
145 | local s = Locales[id][p:GetDbcLocale()+1] or Locales[id][1] | |
146 | if s then | |
147 | return s | |
148 | end | |
149 | end | |
150 | return "Text not found: "..(id or 0) | |
151 | end | |
152 | --[[ | |
153 | typedef UNORDERED_MAP<uint32, uint32> transmogData | |
154 | typedef UNORDERED_MAP<uint32, transmogData> transmogMap | |
155 | static transmogMap entryMap -- entryMap[pGUID][iGUID] = entry | |
156 | static transmogData dataMap -- dataMap[iGUID] = pGUID | |
157 | ]] | |
158 | local entryMap = {} | |
159 | local dataMap = {} | |
160 | ||
161 | local function GetSlotName(slot, locale) | |
162 | if not SlotNames[slot] then return end | |
163 | return SlotNames[slot][locale and locale+1 or 1] | |
164 | end | |
165 | ||
166 | local function GetFakePrice(item) | |
167 | local sellPrice = item:GetSellPrice() | |
168 | local minPrice = 10000 | |
169 | if sellPrice < minPrice then | |
170 | sellPrice = minPrice | |
171 | end | |
172 | return sellPrice | |
173 | end | |
174 | ||
175 | local function GetFakeEntry(item) | |
176 | local guid = item and item:GetGUIDLow() | |
177 | if guid and dataMap[guid] then | |
178 | if entryMap[dataMap[guid]] then | |
179 | return entryMap[dataMap[guid]][guid] | |
180 | end | |
181 | end | |
182 | end | |
183 | ||
184 | local function DeleteFakeFromDB(itemGUID) | |
185 | if dataMap[itemGUID] then | |
186 | if entryMap[dataMap[itemGUID]] then | |
187 | entryMap[dataMap[itemGUID]][itemGUID] = nil | |
188 | end | |
189 | dataMap[itemGUID] = nil | |
190 | end | |
191 | CharDBExecute("DELETE FROM custom_transmogrification WHERE GUID = "..itemGUID) | |
192 | end | |
193 | ||
194 | local function DeleteFakeEntry(item) | |
195 | if not GetFakeEntry(item) then | |
196 | return false | |
197 | end | |
198 | item:GetOwner():UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (item:GetSlot() * ITEM_SLOT_MULTIPLIER), item:GetEntry()) | |
199 | DeleteFakeFromDB(item:GetGUIDLow()) | |
200 | return true | |
201 | end | |
202 | ||
203 | local function SetFakeEntry(item, entry) | |
204 | local player = item:GetOwner() | |
205 | if player then | |
206 | local pGUID = player:GetGUIDLow() | |
207 | local iGUID = item:GetGUIDLow() | |
208 | player:UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (item:GetSlot() * ITEM_SLOT_MULTIPLIER), entry) | |
209 | if not entryMap[pGUID] then | |
210 | entryMap[pGUID] = {} | |
211 | end | |
212 | entryMap[pGUID][iGUID] = entry | |
213 | dataMap[iGUID] = pGUID | |
214 | CharDBExecute("REPLACE INTO custom_transmogrification (GUID, FakeEntry, Owner) VALUES ("..iGUID..", "..entry..", "..pGUID..")") | |
215 | end | |
216 | end | |
217 | ||
218 | local function IsRangedWeapon(Class, SubClass) | |
219 | return Class == ITEM_CLASS_WEAPON and ( | |
220 | SubClass == ITEM_SUBCLASS_WEAPON_BOW or | |
221 | SubClass == ITEM_SUBCLASS_WEAPON_GUN or | |
222 | SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW) | |
223 | end | |
224 | ||
225 | local function SuitableForTransmogrification(player, transmogrified, transmogrifier) | |
226 | if not transmogrified or not transmogrifier then | |
227 | return false | |
228 | end | |
229 | ||
230 | if not Qualities[transmogrifier:GetQuality()] then | |
231 | return false | |
232 | end | |
233 | ||
234 | if not Qualities[transmogrified:GetQuality()] then | |
235 | return false | |
236 | end | |
237 | ||
238 | if transmogrified:GetDisplayId() == transmogrifier:GetDisplayId() then | |
239 | return false | |
240 | end | |
241 | ||
242 | local fentry = GetFakeEntry(transmogrified) | |
243 | if fentry and fentry == transmogrifier:GetEntry() then | |
244 | return false | |
245 | end | |
246 | ||
247 | if not player:CanUseItem(transmogrifier) then | |
248 | return false | |
249 | end | |
250 | ||
251 | local fierClass = transmogrifier:GetClass() | |
252 | local fiedClass = transmogrified:GetClass() | |
253 | local fierSubClass = transmogrifier:GetSubClass() | |
254 | local fiedSubClass = transmogrified:GetSubClass() | |
255 | local fierInventorytype = transmogrifier:GetInventoryType() | |
256 | local fiedInventorytype = transmogrified:GetInventoryType() | |
257 | ||
258 | if fiedInventorytype == INVTYPE_BAG or | |
259 | fiedInventorytype == INVTYPE_RELIC or | |
260 | -- fiedInventorytype == INVTYPE_BODY or | |
261 | fiedInventorytype == INVTYPE_FINGER or | |
262 | fiedInventorytype == INVTYPE_TRINKET or | |
263 | fiedInventorytype == INVTYPE_AMMO or | |
264 | fiedInventorytype == INVTYPE_QUIVER then | |
265 | return false | |
266 | end | |
267 | ||
268 | if fierClass ~= fiedClass then | |
269 | return false | |
270 | end | |
271 | ||
272 | if IsRangedWeapon(fiedClass, fiedSubClass) ~= IsRangedWeapon(fierClass, fierSubClass) then | |
273 | return false | |
274 | end | |
275 | ||
276 | if fierSubClass ~= fiedSubClass and not IsRangedWeapon(fiedClass, fiedSubClass) then | |
277 | if fierClass == ITEM_CLASS_ARMOR and not AllowMixedArmorTypes then | |
278 | return false | |
279 | end | |
280 | if fierClass == ITEM_CLASS_WEAPON and not AllowMixedWeaponTypes then | |
281 | return false | |
282 | end | |
283 | end | |
284 | ||
285 | if fierInventorytype ~= fiedInventorytype and | |
286 | (fierClass ~= ITEM_CLASS_WEAPON or (fiedInventorytype ~= INVTYPE_WEAPON or fierInventorytype ~= INVTYPE_WEAPONOFFHAND or fierInventorytype ~= INVTYPE_WEAPONMAINHAND)) and | |
287 | (fierClass ~= ITEM_CLASS_ARMOR or ((fierInventorytype ~= INVTYPE_CHEST or fiedInventorytype ~= INVTYPE_ROBE) and (fierInventorytype ~= INVTYPE_ROBE or fiedInventorytype ~= INVTYPE_CHEST))) then | |
288 | return false | |
289 | end | |
290 | ||
291 | return true | |
292 | end | |
293 | ||
294 | local menu_id = math.random(1000) | |
295 | ||
296 | local function OnGossipHello(event, player, creature) | |
297 | player:GossipClearMenu() | |
298 | for slot = EQUIPMENT_SLOT_START, EQUIPMENT_SLOT_END-1 do | |
299 | local transmogrified = player:GetItemByPos(INVENTORY_SLOT_BAG_0, slot) | |
300 | if transmogrified then | |
301 | if Qualities[transmogrified:GetQuality()] then | |
302 | local slotName = GetSlotName(slot, player:GetDbcLocale()) | |
303 | if slotName then | |
304 | player:GossipMenuAddItem(3, slotName, EQUIPMENT_SLOT_END, slot) | |
305 | end | |
306 | end | |
307 | end | |
308 | end | |
309 | player:GossipMenuAddItem(4, LocText(2, player), EQUIPMENT_SLOT_END+2, 0, false, LocText(3, player), 0) | |
310 | player:GossipMenuAddItem(7, LocText(1, player), EQUIPMENT_SLOT_END+1, 0) | |
311 | player:GossipSendMenu(100, creature, menu_id) | |
312 | end | |
313 | ||
314 | local _items = {} | |
315 | local function OnGossipSelect(event, player, creature, slotid, uiAction) | |
316 | if slotid == EQUIPMENT_SLOT_END then -- Show items you can use | |
317 | local transmogrified = player:GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction) | |
318 | if transmogrified then | |
319 | local lowGUID = player:GetGUIDLow() | |
320 | _items[lowGUID] = {} -- Remove this with logix | |
321 | local limit = 0 | |
322 | local price = 0 | |
323 | if RequireGold == 1 then | |
324 | price = GetFakePrice(transmogrified)*GoldModifier | |
325 | elseif RequireGold == 2 then | |
326 | price = GoldCost | |
327 | end | |
328 | ||
329 | for i = INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END-1 do | |
330 | if limit > 30 then | |
331 | break | |
332 | end | |
333 | local transmogrifier = player:GetItemByPos(INVENTORY_SLOT_BAG_0, i) | |
334 | if transmogrifier then | |
335 | local display = transmogrifier:GetDisplayId() | |
336 | if SuitableForTransmogrification(player, transmogrified, transmogrifier) then | |
337 | if not _items[lowGUID][display] then | |
338 | limit = limit + 1 | |
339 | _items[lowGUID][display] = {transmogrifier:GetBagSlot(), transmogrifier:GetSlot()} | |
340 | local popup = LocText(4, player).."\n\n"..transmogrifier:GetItemLink(player:GetDbcLocale()).."\n" | |
341 | if RequireToken then | |
342 | popup = popup.."\n"..TokenAmount.." x "..GetItemLink(TokenEntry, player:GetDbcLocale()) | |
343 | end | |
344 | player:GossipMenuAddItem(4, transmogrifier:GetItemLink(player:GetDbcLocale()), uiAction, display, false, popup, price) | |
345 | end | |
346 | end | |
347 | end | |
348 | end | |
349 | ||
350 | for i = INVENTORY_SLOT_BAG_START, INVENTORY_SLOT_BAG_END-1 do | |
351 | local bag = player:GetItemByPos(INVENTORY_SLOT_BAG_0, i) | |
352 | if bag then | |
353 | for j = 0, bag:GetBagSize()-1 do | |
354 | if limit > 30 then | |
355 | break | |
356 | end | |
357 | local transmogrifier = player:GetItemByPos(i, j) | |
358 | if transmogrifier then | |
359 | local display = transmogrifier:GetDisplayId() | |
360 | if SuitableForTransmogrification(player, transmogrified, transmogrifier) then | |
361 | if not _items[lowGUID][display] then | |
362 | limit = limit + 1 | |
363 | _items[lowGUID][display] = {transmogrifier:GetBagSlot(), transmogrifier:GetSlot()} | |
364 | player:GossipMenuAddItem(4, transmogrifier:GetItemLink(player:GetDbcLocale()), uiAction, display, false, popup, price) | |
365 | end | |
366 | end | |
367 | end | |
368 | end | |
369 | end | |
370 | end | |
371 | ||
372 | player:GossipMenuAddItem(4, LocText(7, player), EQUIPMENT_SLOT_END+3, uiAction, false, LocText(5, player):format(GetSlotName(uiAction, player:GetDbcLocale()))) | |
373 | player:GossipMenuAddItem(7, LocText(6, player), EQUIPMENT_SLOT_END+1, 0) | |
374 | player:GossipSendMenu(100, creature, menu_id) | |
375 | else | |
376 | OnGossipHello(event, player, creature) | |
377 | end | |
378 | elseif slotid == EQUIPMENT_SLOT_END+1 then -- Back | |
379 | OnGossipHello(event, player, creature) | |
380 | elseif slotid == EQUIPMENT_SLOT_END+2 then -- Remove Transmogrifications | |
381 | local removed = false | |
382 | for slot = EQUIPMENT_SLOT_START, EQUIPMENT_SLOT_END-1 do | |
383 | local transmogrifier = player:GetItemByPos(INVENTORY_SLOT_BAG_0, slot) | |
384 | if transmogrifier then | |
385 | if DeleteFakeEntry(transmogrifier) and not removed then | |
386 | removed = true | |
387 | end | |
388 | end | |
389 | end | |
390 | if removed then | |
391 | player:SendAreaTriggerMessage(LocText(8, player)) | |
392 | -- player:PlayDirectSound(3337) | |
393 | else | |
394 | player:SendNotification(LocText(9, player)) | |
395 | end | |
396 | OnGossipHello(event, player, creature) | |
397 | elseif slotid == EQUIPMENT_SLOT_END+3 then -- Remove Transmogrification from single item | |
398 | local transmogrifier = player:GetItemByPos(INVENTORY_SLOT_BAG_0, uiAction) | |
399 | if transmogrifier then | |
400 | if DeleteFakeEntry(transmogrifier) then | |
401 | player:SendAreaTriggerMessage(LocText(10, player):format(GetSlotName(uiAction, player:GetDbcLocale()))) | |
402 | -- player:PlayDirectSound(3337) | |
403 | else | |
404 | player:SendNotification(LocText(11, player):format(GetSlotName(uiAction, player:GetDbcLocale()))) | |
405 | end | |
406 | end | |
407 | OnGossipSelect(event, player, creature, EQUIPMENT_SLOT_END, uiAction) | |
408 | else -- Transmogrify | |
409 | local lowGUID = player:GetGUIDLow() | |
410 | if not RequireToken or player:GetItemCount(TokenEntry) >= TokenAmount then | |
411 | local transmogrified = player:GetItemByPos(INVENTORY_SLOT_BAG_0, slotid) | |
412 | if transmogrified then | |
413 | if _items[lowGUID] and _items[lowGUID][uiAction] and _items[lowGUID][uiAction] then | |
414 | local transmogrifier = player:GetItemByPos(_items[lowGUID][uiAction][1], _items[lowGUID][uiAction][2]) | |
415 | if transmogrifier:GetOwnerGUID() == player:GetGUID() and (transmogrifier:IsInBag() or transmogrifier:GetBagSlot() == INVENTORY_SLOT_BAG_0) and SuitableForTransmogrification(player, transmogrified, transmogrifier) then | |
416 | local price | |
417 | if RequireGold == 1 then | |
418 | price = GetFakePrice(transmogrified)*GoldModifier | |
419 | elseif RequireGold == 2 then | |
420 | price = GoldCost | |
421 | end | |
422 | if price then player:ModifyMoney(-1*price) end | |
423 | if RequireToken then | |
424 | player:RemoveItem(TokenEntry, TokenAmount) | |
425 | end | |
426 | SetFakeEntry(transmogrified, transmogrifier:GetEntry()) | |
427 | -- transmogrifier:SetNotRefundable(player) | |
428 | transmogrifier:SetBinding(true) | |
429 | -- player:PlayDirectSound(3337) | |
430 | player:SendAreaTriggerMessage(LocText(12, player):format(GetSlotName(slotid, player:GetDbcLocale()))) | |
431 | else | |
432 | player:SendNotification(LocText(13, player)) | |
433 | end | |
434 | else | |
435 | player:SendNotification(LocText(14, player)) | |
436 | end | |
437 | else | |
438 | player:SendNotification(LocText(15, player)) | |
439 | end | |
440 | else | |
441 | player:SendNotification(LocText(16, player):format(GetItemLink(TokenEntry, player:GetDbcLocale()))) | |
442 | end | |
443 | _items[lowGUID] = {} | |
444 | OnGossipSelect(event, player, creature, EQUIPMENT_SLOT_END, slotid) | |
445 | end | |
446 | end | |
447 | ||
448 | local function OnLogin(event, player) | |
449 | local playerGUID = player:GetGUIDLow() | |
450 | entryMap[playerGUID] = {} | |
451 | local result = CharDBQuery("SELECT GUID, FakeEntry FROM custom_transmogrification WHERE Owner = "..playerGUID) | |
452 | if result then | |
453 | repeat | |
454 | local itemGUID = result:GetUInt32(0) | |
455 | local fakeEntry = result:GetUInt32(1) | |
456 | -- if sObjectMgr:GetItemTemplate(fakeEntry) then | |
457 | -- { | |
458 | dataMap[itemGUID] = playerGUID | |
459 | entryMap[playerGUID][itemGUID] = fakeEntry | |
460 | -- } | |
461 | -- else | |
462 | -- sLog:outError(LOG_FILTER_SQL, "Item entry (Entry: %u, itemGUID: %u, playerGUID: %u) does not exist, deleting.", fakeEntry, itemGUID, playerGUID) | |
463 | -- Transmogrification::DeleteFakeFromDB(itemGUID) | |
464 | -- end | |
465 | until not result:NextRow() | |
466 | ||
467 | for slot = EQUIPMENT_SLOT_START, EQUIPMENT_SLOT_END-1 do | |
468 | local item = player:GetItemByPos(INVENTORY_SLOT_BAG_0, slot) | |
469 | if item then | |
470 | if entryMap[playerGUID] then | |
471 | if entryMap[playerGUID][item:GetGUIDLow()] then | |
472 | player:UpdateUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (item:GetSlot() * ITEM_SLOT_MULTIPLIER), entryMap[playerGUID][item:GetGUIDLow()]) | |
473 | end | |
474 | end | |
475 | end | |
476 | end | |
477 | end | |
478 | end | |
479 | ||
480 | local function OnLogout(event, player) | |
481 | local pGUID = player:GetGUIDLow() | |
482 | entryMap[pGUID] = nil | |
483 | end | |
484 | ||
485 | local function OnEquip(event, player, item, bag, slot) | |
486 | local fentry = GetFakeEntry(item) | |
487 | if fentry then | |
488 | if item:GetOwnerGUID() ~= player:GetGUID() then | |
489 | DeleteFakeFromDB(item:GetGUIDLow()) | |
490 | return | |
491 | end | |
492 | player:SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * ITEM_SLOT_MULTIPLIER), fentry) | |
493 | end | |
494 | end | |
495 | ||
496 | -- Note, Query is instant when Execute is delayed | |
497 | CharDBQuery([[ | |
498 | CREATE TABLE IF NOT EXISTS `custom_transmogrification` ( | |
499 | `GUID` INT(10) UNSIGNED NOT NULL COMMENT 'Item guidLow', | |
500 | `FakeEntry` INT(10) UNSIGNED NOT NULL COMMENT 'Item entry', | |
501 | `Owner` INT(10) UNSIGNED NOT NULL COMMENT 'Player guidLow', | |
502 | PRIMARY KEY (`GUID`) | |
503 | ) | |
504 | COMMENT='version 4.0' | |
505 | COLLATE='latin1_swedish_ci' | |
506 | ENGINE=InnoDB; | |
507 | ]]) | |
508 | ||
509 | print("Deleting non-existing transmogrification entries...") | |
510 | CharDBQuery("DELETE FROM custom_transmogrification WHERE NOT EXISTS (SELECT 1 FROM item_instance WHERE item_instance.guid = custom_transmogrification.GUID)") | |
511 | ||
512 | RegisterPlayerEvent(3, OnLogin) | |
513 | RegisterPlayerEvent(4, OnLogout) | |
514 | RegisterPlayerEvent(29, OnEquip) | |
515 | ||
516 | -- Test code | |
517 | --RegisterPlayerEvent(18, function(e,p,m,t,l) if m == "test" then OnGossipHello(e,p,p) end end) | |
518 | --RegisterPlayerGossipEvent(menu_id, 2, OnGossipSelect) | |
519 | ||
520 | RegisterCreatureGossipEvent(NPC_Entry, 1, OnGossipHello) | |
521 | RegisterCreatureGossipEvent(NPC_Entry, 2, OnGossipSelect) | |
522 | ||
523 | local plrs = GetPlayersInWorld() | |
524 | if plrs then | |
525 | for k, player in ipairs(plrs) do | |
526 | OnLogin(k, player) | |
527 | end | |
528 | end |