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 |