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