View difference between Paste ID: XARE9gjW and VFTUmPTm
SHOW: | | - or go back to the newest paste.
1
local NPCENTRY = 123123 -- Your NPC's entry
2
3
-- Warning! Executes quite some code. Delay in milliseconds. (applies transmogs)
4
local DELAY = 500 -- 500 (best visual update, very low population), 1000 (good visual update, very low population), 2000+ (slow visual update, medium  to high population)
5
6
-- DO NOT TOUCH ANYTHING BELOW!
7
8
-- Transmog table and functions.
9
local Transmogs, Hello, Select, AddTransmog, RemoveTransmog, GetValidSources, LoadTransmogs, ApplyTransmogs
10
11
-- Key0 is the key for inv_slots table, which contains the slotID. Key0 is also used for the inv_slot_names table
12
local inv_slots =		{0,			2,				4,			5,			6,		7,		8,			9,			14,		15,				16,			17}
13
local inv_slot_names =	{"Head",	"Shoulders",	"Chest",	"Waist",	"Legs",	"Feet",	"Wrists",	"Hands",	"Back",	"Main hand",	"Off hand",	"Ranged"}
14
15
local INV_BAG, INV_START, INV_END = 255, 1, #inv_slots
16
local VISIBLE_ITEM_ENTRY_0 = 283
17
local BAGS =
18
{
19-
	{BAG = INV_BAG, START = 23, END = 38},
19+
{BAG = INV_BAG, START = 23, END = 38},
20-
	{BAG = 19, START = 0, END = 35},
20+
{BAG = 19, START = 0, END = 35},
21-
	{BAG = 20, START = 0, END = 35},
21+
{BAG = 20, START = 0, END = 35},
22-
	{BAG = 21, START = 0, END = 35},
22+
{BAG = 21, START = 0, END = 35},
23-
	{BAG = 22, START = 0, END = 35},
23+
{BAG = 22, START = 0, END = 35},
24
}
25
26
-- bags -1 inventory and backpack, 19-22 other bags
27
-- slots 0-18 equipment
28
-- slots 19-22 bags
29
-- slots 23-38 backpack
30
-- slots 0-35 other bags
31
32
local space = 20
33
local opt_space = 100
34
local opt_amount = 13 -- Warning! Do not use over 30
35
36
local Data = {}
37
38
function Hello(unit, event, player)
39-
	Data[tostring(player:GetGUID())] = nil
39+
Data[tostring(player:GetGUID())] = nil
40-
	unit:GossipCreateMenu(100, player, 0)
40+
unit:GossipCreateMenu(100, player, 0)
41-
	for Key0 = INV_START, INV_END do
41+
for Key0 = INV_START, INV_END do
42-
		unit:GossipMenuAddItem(3, inv_slot_names[Key0], Key0+space, 0, "", 0)
42+
unit:GossipMenuAddItem(3, inv_slot_names[Key0], Key0+space, 0, "", 0)
43-
	end
43+
44-
	unit:GossipMenuAddItem(4, "Remove all transmogrifications", 0, 0, "Remove transmogrifications from equipped items?", 0)
44+
unit:GossipMenuAddItem(4, "Remove all transmogrifications", 0, 0, "Remove transmogrifications from equipped items?", 0)
45-
	unit:GossipSendMenu(player)
45+
unit:GossipSendMenu(player)
46
end
47
48
function Select(unit, event, player, id, intid, code)
49-
	local pGUID = tostring(player:GetGUID())
49+
local pGUID = tostring(player:GetGUID())
50-
	if(intid == 0) then -- remove all transmogs
50+
if(intid == 0) then -- remove all transmogs
51-
		for Key0 = INV_START, INV_END do
51+
for Key0 = INV_START, INV_END do
52-
			RemoveTransmog(inv_slots[Key0], player)
52+
RemoveTransmog(inv_slots[Key0], player)
53-
		end
53+
54-
		player:SendAreaTriggerMessage("Transmogrifications removed")
54+
player:SendAreaTriggerMessage("Transmogrifications removed")
55-
		Hello(unit, event, player)
55+
Hello(unit, event, player)
56-
	elseif(intid == 1) then
56+
elseif(intid == 1) then
57-
		Hello(unit, event, player)
57+
Hello(unit, event, player)
58-
	elseif(intid > INV_START and intid <= INV_END+1) then -- remove one transmog
58+
elseif(intid > INV_START and intid <= INV_END+1) then -- remove one transmog
59-
		RemoveTransmog(inv_slots[intid-1], player)
59+
RemoveTransmog(inv_slots[intid-1], player)
60-
		player:SendAreaTriggerMessage("Transmogrification removed from "..inv_slot_names[intid-1])
60+
player:SendAreaTriggerMessage("Transmogrification removed from "..inv_slot_names[intid-1])
61-
		Select(unit, event, player, id, intid+space-1, code)
61+
Select(unit, event, player, id, intid+space-1, code)
62-
	elseif(intid >= INV_START+space and intid <= INV_END+space) then
62+
elseif(intid >= INV_START+space and intid <= INV_END+space) then
63-
		local Key0 = intid-space
63+
local Key0 = intid-space
64-
		local sources = GetValidSources(inv_slots[Key0], player)
64+
local sources = GetValidSources(inv_slots[Key0], player)
65-
		if(not sources) then
65+
if(not sources) then
66-
			player:SendAreaTriggerMessage("No item in that slot")
66+
player:SendAreaTriggerMessage("No item in that slot")
67-
			Hello(unit, event, player)
67+
Hello(unit, event, player)
68-
		elseif(#sources < 2) then
68+
elseif(#sources < 2) then
69-
			player:SendAreaTriggerMessage("No suitable items in bags")
69+
player:SendAreaTriggerMessage("No suitable items in bags")
70-
			Hello(unit, event, player)
70+
Hello(unit, event, player)
71-
		else
71+
else
72-
			Data[pGUID] = {Key0, sources}
72+
Data[pGUID] = {Key0, sources}
73-
			unit:GossipCreateMenu(100, player, 0)
73+
unit:GossipCreateMenu(100, player, 0)
74-
			for k = 1, #sources-1 do
74+
for k = 1, #sources-1 do
75-
				unit:GossipMenuAddItem(4, sources[k]:GetName(), k+INV_END+space, 0, "", 0)
75+
unit:GossipMenuAddItem(4, sources[k]:GetName(), k+INV_END+space, 0, "", 0)
76-
			end
76+
77-
			unit:GossipMenuAddItem(4, "Remove transmogrification from "..inv_slot_names[Key0], Key0+1, 0, "Remove transmogrif ication from "..inv_slot_names[Key0].."?", 0)
77+
unit:GossipMenuAddItem(4, "Remove transmogrification from "..inv_slot_names[Key0], Key0+1, 0, "Remove transmogrif ication from "..inv_slot_names[Key0].."?", 0)
78-
			unit:GossipMenuAddItem(7, "Back..", 1, 0, "", 0)
78+
unit:GossipMenuAddItem(7, "Back..", 1, 0, "", 0)
79-
			unit:GossipSendMenu(player)
79+
unit:GossipSendMenu(player)
80-
		end
80+
81-
	elseif(intid > INV_END+space and intid <= INV_END+space+opt_amount) then
81+
elseif(intid > INV_END+space and intid <= INV_END+space+opt_amount) then
82-
		local slot = inv_slots[Data[pGUID][1]]
82+
local slot = inv_slots[Data[pGUID][1]]
83-
		local target = player:GetInventoryItem(INV_BAG, slot)
83+
local target = player:GetInventoryItem(INV_BAG, slot)
84-
		local origGUID = Data[pGUID][2][#Data[pGUID][2]] -- no cheating with swapping items on the fly
84+
local origGUID = Data[pGUID][2][#Data[pGUID][2]] -- no cheating with swapping items on the fly
85-
		if(target and tostring(target:GetGUID()) == origGUID) then
85+
if(target and tostring(target:GetGUID()) == origGUID) then
86-
			local source = Data[pGUID][2][intid-INV_END-space]
86+
local source = Data[pGUID][2][intid-INV_END-space]
87-
			if(source and source:GetOwner():IsInWorld() and pGUID == tostring(source:GetOwner():GetGUID())) then
87+
if(source and source:GetOwner():IsInWorld() and pGUID == tostring(source:GetOwner():GetGUID())) then
88-
				AddTransmog(slot, player, source:GetEntryId())
88+
AddTransmog(slot, player, source:GetEntryId())
89-
				player:SendAreaTriggerMessage(inv_slot_names[Data[pGUID][1]].." transmogrified")
89+
player:SendAreaTriggerMessage(inv_slot_names[Data[pGUID][1]].." transmogrified")
90-
			else
90+
else
91-
				player:SendAreaTriggerMessage("Source item is not in bags")
91+
player:SendAreaTriggerMessage("Source item is not in bags")
92-
			end
92+
93-
		else
93+
else
94-
			player:SendAreaTriggerMessage("Target item was unequipped")
94+
player:SendAreaTriggerMessage("Target item was unequipped")
95-
		end
95+
96-
		Select(unit, event, player, id, Data[pGUID][1]+space, code)
96+
Select(unit, event, player, id, Data[pGUID][1]+space, code)
97-
	end
97+
98
end
99
100
function AddTransmog(slot, player, fake)
101-
	local item = player:GetInventoryItem(INV_BAG, slot)
101+
local item = player:GetInventoryItem(INV_BAG, slot)
102-
	if (item) then
102+
if (item) then
103-
		local pGUID, iGUID = tostring(player:GetGUID()), tostring(item:GetGUID())
103+
local pGUID, iGUID = tostring(player:GetGUID()), tostring(item:GetGUID())
104-
		player:SetUInt32Value(VISIBLE_ITEM_ENTRY_0+(slot * 2), fake)
104+
player:SetUInt32Value(VISIBLE_ITEM_ENTRY_0+(slot * 2), fake)
105-
		if (not Transmogs[pGUID]) then
105+
if (not Transmogs[pGUID]) then
106-
			Transmogs[pGUID] = {}
106+
Transmogs[pGUID] = {}
107-
		end
107+
108-
		if (not Transmogs[pGUID][slot]) then
108+
if (not Transmogs[pGUID][slot]) then
109-
			Transmogs[pGUID][slot] = {}
109+
Transmogs[pGUID][slot] = {}
110-
		end
110+
111-
		Transmogs[pGUID][slot][iGUID] = fake
111+
Transmogs[pGUID][slot][iGUID] = fake
112-
		CharDBQuery('REPLACE INTO Transmog_items (player_GUID, item_GUID, slot, fake) VALUES ("'..pGUID..'", "'..iGUID..'", '..slot..', '..fake..')')
112+
CharDBQuery('REPLACE INTO Transmog_items (player_GUID, item_GUID, slot, fake) VALUES ("'..pGUID..'", "'..iGUID..'", '..slot..', '..fake..')')
113-
		return true
113+
return true
114-
	end
114+
115-
	return false
115+
return false
116
end
117
118
function RemoveTransmog(slot, player)
119-
	local pGUID = tostring(player:GetGUID())
119+
local pGUID = tostring(player:GetGUID())
120-
	if (Transmogs[pGUID] and Transmogs[pGUID][slot]) then
120+
if (Transmogs[pGUID] and Transmogs[pGUID][slot]) then
121-
		local item = player:GetInventoryItem(INV_BAG, slot)
121+
local item = player:GetInventoryItem(INV_BAG, slot)
122-
		if (item) then
122+
if (item) then
123-
			local iGUID = tostring(item:GetGUID())
123+
local iGUID = tostring(item:GetGUID())
124-
			if (Transmogs[pGUID][slot][iGUID]) then
124+
if (Transmogs[pGUID][slot][iGUID]) then
125-
				player:SetUInt32Value(VISIBLE_ITEM_ENTRY_0+(slot * 2), item:GetEntryId())
125+
player:SetUInt32Value(VISIBLE_ITEM_ENTRY_0+(slot * 2), item:GetEntryId())
126-
				Transmogs[pGUID][slot][iGUID] = nil
126+
Transmogs[pGUID][slot][iGUID] = nil
127-
				CharDBQuery('DELETE FROM Transmog_items WHERE item_GUID = "'..iGUID..'"')
127+
CharDBQuery('DELETE FROM Transmog_items WHERE item_GUID = "'..iGUID..'"')
128-
				return true
128+
return true
129-
			end
129+
130-
		end
130+
131-
	end
131+
132-
	return false
132+
return false
133
end
134
135
function GetValidSources(inv_slot, player) -- returns nil or a table containing the items (can be empty)
136-
	local item = player:GetInventoryItem(INV_BAG, inv_slot)
136+
local item = player:GetInventoryItem(INV_BAG, inv_slot)
137-
	if (not item) then return nil end
137+
if (not item) then return nil end
138-
	local items = {}
138+
local items = {}
139-
	local entries = {}
139+
local entries = {}
140-
	local hasitems = false
140+
local hasitems = false
141-
	for k, DATA in ipairs(BAGS) do
141+
for k, DATA in ipairs(BAGS) do
142-
		if (DATA.BAG == INV_BAG or player:GetInventoryItem(INV_BAG, DATA.BAG)) then -- skip nonexistant bags
142+
if (DATA.BAG == INV_BAG or player:GetInventoryItem(INV_BAG, DATA.BAG)) then -- skip nonexistant bags
143-
			for slot = DATA.START, DATA.END do
143+
for slot = DATA.START, DATA.END do
144-
				local item = player:GetInventoryItem(DATA.BAG, slot)
144+
local item = player:GetInventoryItem(DATA.BAG, slot)
145-
				if(item) then
145+
if(item) then
146-
					table.insert(entries, item:GetEntryId())
146+
table.insert(entries, item:GetEntryId())
147-
					items[item:GetEntryId()] = item
147+
items[item:GetEntryId()] = item
148-
					if (not hasitems) then hasitems = true end
148+
if (not hasitems) then hasitems = true end
149-
				end
149+
150-
			end
150+
151-
		end
151+
152-
	end
152+
153-
	if (hasitems) then
153+
if (hasitems) then
154-
		local Q = WorldDBQuery("SELECT inventorytype FROM items WHERE entry = "..item:GetEntryId())
154+
local Q = WorldDBQuery("SELECT inventorytype FROM items WHERE entry = "..item:GetEntryId())
155-
		if (Q) then
155+
if (Q) then
156-
			local Q = WorldDBQuery("SELECT entry FROM items WHERE entry IN("..table.concat(entries, ',')..") and inventorytype = "..Q:GetColumn(0):GetULong().." LIMIT "..opt_amount)
156+
local Q = WorldDBQuery("SELECT entry FROM items WHERE entry IN("..table.concat(entries, ',')..") and inventorytype = "..Q:GetColumn(0):GetULong().." LIMIT "..opt_amount)
157-
			if (Q) then
157+
if (Q) then
158-
				local suitable = {}
158+
local suitable = {}
159-
				for i = 1, Q:GetRowCount() do
159+
for i = 1, Q:GetRowCount() do
160-
					table.insert(suitable, items[Q:GetColumn(0):GetULong()]) -- Could possibly add performance if we let this security off
160+
table.insert(suitable, items[Q:GetColumn(0):GetULong()]) -- Could possibly add performance if we let this security off
161-
					Q:NextRow()
161+
Q:NextRow()
162-
				end
162+
163-
				table.insert(suitable, tostring(item:GetGUID()))
163+
table.insert(suitable, tostring(item:GetGUID()))
164-
				return suitable
164+
return suitable
165-
			end
165+
166-
		end
166+
167-
	end
167+
168-
	return {}
168+
return {}
169
end
170
171
function LoadTransmogs()
172-
	local Time = os.time()
172+
local Time = os.time()
173-
	print("Loading transmogrifications..")
173+
print("Loading transmogrifications..")
174-
	Transmogs = {}
174+
Transmogs = {}
175-
	-- CharDBQuery("DELETE FROM transmog_items WHERE NOT EXISTS (SELECT 1 FROM playeritems WHERE item_GUID = guid) OR NOT EXISTS (SELECT 1 FROM characters WHERE player_GUID = guid)") -- cleanup before load
175+
-- CharDBQuery("DELETE FROM transmog_items WHERE NOT EXISTS (SELECT 1 FROM playeritems WHERE item_GUID = guid) OR NOT EXISTS (SELECT 1 FROM characters WHERE player_GUID = guid)") -- cleanup before load
176-
	local Q = CharDBQuery("SELECT player_GUID, item_GUID, slot, fake FROM Transmog_items")
176+
local Q = CharDBQuery("SELECT player_GUID, item_GUID, slot, fake FROM Transmog_items")
177-
	if (Q) then
177+
if (Q) then
178-
		for i = 1, Q:GetRowCount() do
178+
for i = 1, Q:GetRowCount() do
179-
			local pGUID, iGUID, slot, fake = Q:GetColumn(0):GetString(), Q:GetColumn(1):GetString(), Q:GetColumn(2):GetULong(), Q:GetColumn(3):GetULong()
179+
local pGUID, iGUID, slot, fake = Q:GetColumn(0):GetString(), Q:GetColumn(1):GetString(), Q:GetColumn(2):GetULong(), Q:GetColumn(3):GetULong()
180-
			if (not Transmogs[pGUID]) then
180+
if (not Transmogs[pGUID]) then
181-
				Transmogs[pGUID] = {}
181+
Transmogs[pGUID] = {}
182-
			end
182+
183-
			if (not Transmogs[pGUID][slot]) then
183+
if (not Transmogs[pGUID][slot]) then
184-
				Transmogs[pGUID][slot] = {}
184+
Transmogs[pGUID][slot] = {}
185-
			end
185+
186-
			Transmogs[pGUID][slot][iGUID] = fake
186+
Transmogs[pGUID][slot][iGUID] = fake
187-
			Q:NextRow()
187+
Q:NextRow()
188-
		end
188+
189-
	end
189+
190-
	print("Transmogrifications loaded in "..(os.time()-Time).." seconds")
190+
print("Transmogrifications loaded in "..(os.time()-Time).." seconds")
191
end
192
193
function ApplyTransmogs() -- minimum looping and checking
194-
	local players = GetPlayersInWorld()
194+
local players = GetPlayersInWorld()
195-
	for k, player in ipairs(players) do -- loop players
195+
for k, player in ipairs(players) do -- loop players
196-
		if (player and player:IsInWorld()) then -- player exists
196+
if (player and player:IsInWorld()) then -- player exists
197-
			local pGUID = tostring(player:GetGUID())
197+
local pGUID = tostring(player:GetGUID())
198-
			if (Transmogs[pGUID]) then -- has transmogs
198+
if (Transmogs[pGUID]) then -- has transmogs
199-
				for slot, Data in pairs(Transmogs[pGUID]) do -- looop transmog slots
199+
for slot, Data in pairs(Transmogs[pGUID]) do -- looop transmog slots
200-
					local item = player:GetInventoryItem(INV_BAG, slot)
200+
local item = player:GetInventoryItem(INV_BAG, slot)
201-
					if (item) then -- has item in slot
201+
if (item) then -- has item in slot
202-
						local iGUID = tostring(item:GetGUID())
202+
local iGUID = tostring(item:GetGUID())
203-
						if(Data[iGUID]) then -- check if item has transmog saved
203+
if(Data[iGUID]) then -- check if item has transmog saved
204-
							player:SetUInt32Value(283+(slot * 2), Data[iGUID]) -- apply transmog
204+
player:SetUInt32Value(283+(slot * 2), Data[iGUID]) -- apply transmog
205-
						end
205+
206-
					end
206+
207-
				end
207+
208-
			end
208+
209-
		end
209+
210-
	end
210+
211
end
212
213
RegisterUnitGossipEvent(NPCENTRY, 1, Hello)
214
RegisterUnitGossipEvent(NPCENTRY, 2, Select)
215
LoadTransmogs()
216
CreateLuaEvent(ApplyTransmogs, DELAY, 0)