-- Copyright 2008 James Whitehead II -- Credits for name 'DressToKill' go to Aska on StormReaver(EU) DressToKill = {} local L = DressToKillLocals local DEBUG = true local function debug(fmt, ...) if DEBUG then local msg = "|cffffff78DressToKill:|r " if select("#", ...) > 0 then msg = msg .. fmt:format(...) else msg = msg .. fmt end ChatFrame1:AddMessage(msg) end end local slotNames = { BackSlot = L["Back"], ChestSlot = L["Chest"], FeetSlot = L["Feet"], Finger0Slot = L["Left Finger"], Finger1Slot = L["Right Finger"], HeadSlot = L["Head"], HandsSlot = L["Hands"], LegsSlot = L["Legs"], MainHandSlot = L["Main Hand"], NeckSlot = L["Neck Slot"], RangedSlot = L["Ranged Slot"], --SecondaryHandSlot = L["Secondary Hand"], ShoulderSlot = L["Shoulders"], Trinket0Slot = L["Trinket 0"], Trinket1Slot = L["Trinket 1"], WaistSlot = L["Waist"], WristSlot = L["Wrist"], } local slotIds = {} function DressToKill:Initialize() debug(L["Scanning for inventory slot Ids"]) for slot in pairs(slotNames) do local id = GetInventorySlotInfo(slot) if id then slotIds[slot] = id else local err = string.format(L["Could not get inventory slot information for %s"], tostring(slot)) error(err) return end end end function DressToKill:FindEmptySlot() for bag=0,4 do for slot=1,GetContainerNumSlots(bag) do if not GetContainerItemInfo(bag, slot) then return bag, slot end end end end local function scanFunction() debug(L["Beginning an inventory scan"]) local blacklist = {} local slotAvail = {} for slotName,slotId in pairs(slotIds) do local avail = GetInventoryItemsForSlot(slotId) if next(avail) then slotAvail[slotId] = avail end end local stash = {} -- Loop through all of the inventory slots for slotId,avail in pairs(slotAvail) do local maxScore, winner = 0, nil local link = GetInventoryItemLink("player", slotId) if link then -- We current have an item equipped, so stash that item elsewhere local bag,slot = DressToKill:FindEmptySlot() if not bag or not slot then debug(L["Out of inventory space, cannot proceed"]) return end stash.bag = bag stash.slot = slot PickupInventoryItem(slotId) PickupContainerItem(bag, slot) coroutine.yield() end -- Loop through all of the available items, and try equipping each of them for mask,item in pairs(avail) do if not blacklist[mask] then local equipped = DressToKill:EquipItem(slotId, mask, stash) if equipped then local score = DressToKill:EvaluateScore() if score >= maxScore then maxScore = score winner = mask end -- Unequip the item DressToKill:UnequipItem(slotId, mask, stash) else debug(L["Item not equipped... skipping..."]) end else debug(L["Item blacklisted, skipping..."]) end end -- Now equip the item that won this round and blacklist debug(L["Equipping winning item"]) DressToKill:EquipItem(slotId, winner, stash) blacklist[winner] = true end debug(L["All done trying clothes on!"]) end function DressToKill:EvaluateScore() --local base,pos,neg = UnitAttackPower("player") --return base + pos - neg --[[ local health = UnitHealthMax("player") local base, pos, neg = UnitArmor("player") local armor = base + pos - neg local score = (health * 0.8) + (armor * 1.0) return score -- 1.0/0.8 - 7430 health, 7910 armor -- 1.0/1.0 - 7430 health, 7910 armor -- 0.8/1.0 - 7390 health, 7948 armor --]] local mana = UnitManaMax("player") local healing = GetSpellBonusHealing() local score = (mana * 1.0) + (healing * 1.0) return score end function DressToKill:EquipItem(slotId, mask, stash) local bag,slot = DressToKill:ItemInBag(mask) local eqslot = DressToKill:ItemEquipped(mask) if bag then -- Equip the item PickupContainerItem(bag, slot) EquipCursorItem(slotId) local equipped = coroutine.yield() return equipped elseif eqslot then -- The item was equipped, so find the current slot in the stash PickupContainerItem(stash.bag, stash.slot) EquipCursorItem(slotId) local equipped = coroutine.yield() return equipped end end function DressToKill:UnequipItem(slotId, mask, stash) local bag,slot = DressToKill:ItemInBag(mask) local eqslot = DressToKill:ItemEquipped(mask) if bag then -- Just put the item back PickupInventoryItem(slotId) PickupContainerItem(bag, slot) coroutine.yield() elseif eqslot then -- Put it back into the stash slot PickupInventoryItem(slotId) PickupContainerItem(stash.bag, stash.slot) coroutine.yield() end end local eventFrame = CreateFrame("Frame") eventFrame:RegisterEvent("UNIT_INVENTORY_CHANGED") eventFrame:RegisterEvent("EQUIP_BIND_CONFIRM") local function OnEvent(self, event) self.equipped = true if event == "EQUIP_BIND_CONFIRM" and CursorHasItem() then self.equipped = false debug(L["Clearing non-soulbound item"]) ClearCursor() end local thread = DressToKill.currentThread if thread and coroutine.status(thread) ~= "dead" then self:Show() end end local function OnUpdate(self, elapsed) self:Hide() local succ,err = coroutine.resume(DressToKill.currentThread, self.equipped) assert(succ, err) end eventFrame:SetScript("OnEvent", OnEvent) eventFrame:SetScript("OnUpdate", OnUpdate) eventFrame:Hide() SLASH_DRESSTOKILL1 = "/dtk" SLASH_DRESSTOKILL2 = "/dress" SLASH_DRESSTOKILL3 = "/dresstokill" SlashCmdList["DRESSTOKILL"] = function(msg, editbox) debug(L["Dressing to kill..."]) DressToKill:Initialize() DressToKill.currentThread = coroutine.create(scanFunction) coroutine.resume(DressToKill.currentThread) end local ITEM_INVENTORY_PLAYER = 0x00100000 local ITEM_INVENTORY_BACKPACK = 0x00200000 local ITEM_INVENTORY_BAGS = 0x00400000 local ITEM_INVENTORY_BANK = 0x00800000 local MASK_BAG = 0xf00 local MASK_SLOT = 0x3f local bagMap = { [0x100] = 1, [0x200] = 2, [0x400] = 3, [0x800] = 4, } function DressToKill:ItemInBag(mask) if bit.band(mask, ITEM_INVENTORY_BAGS) > 0 then local bag = bagMap[bit.band(mask, MASK_BAG)] local slot = bit.band(mask, MASK_SLOT) return bag, slot elseif bit.band(mask, ITEM_INVENTORY_BACKPACK) > 0 then local slot = bit.band(mask, MASK_SLOT) return 0, slot end end function DressToKill:ItemEquipped(mask) if bit.band(mask, ITEM_INVENTORY_PLAYER) > 0 then local slot = bit.band(mask, MASK_SLOT) return slot end end --[[ ITEM_INVENTORY_LOCATION_PLAYER = 0x00100000 ITEM_INVENTORY_LOCATION_BACKPACK = 0x00200000 ITEM_INVENTORY_LOCATION_BAGS = 0x00400000 ITEM_INVENTORY_LOCATION_BANK = 0x00800000 -- -- With four netherweave bags: -- In backpack, slots 1 -> 16 -- -- 001100000000000000000001 -- 001100000000000000000010 -- ... -- 001100000000000000010000 -- -- First bag, slots 1 -> 16 -- -- 010000000000000100000001 -- ... -- 010000000000000100010000 -- -- Second bag, slots 1 -> 16 -- -- 010000000000001000000001 -- ... -- 010000000000001000010000 -- -- Third bag, slots 1 -> 16 -- -- 010000000000010000000001 -- ... -- 010000000000010000010000 -- -- Fourth bag, slots 1 -> 16 -- -- 010000000000100000000001 -- ... -- 010000000000100000010000 -- -- Hands(10) -- 000100000000000000001010 -- -- Waist(6) -- 000100000000000000000110 -- -- Finger0(11) -- 000100000000000000001011 -- -- Finger1(12) -- 000100000000000000001011 --]]