diff --git a/Babelfish.lua b/Babelfish.lua new file mode 100644 index 0000000..84e67a6 --- /dev/null +++ b/Babelfish.lua @@ -0,0 +1,27 @@ +#!/usr/local/bin/lua + +local strings = {} + +for i=1,#arg do + local file = io.open(arg[i], "r") + assert(file, "Could not open " .. arg[i]) + local text = file:read("*all") + + for match in string.gmatch(text, "L%[\"(.-)\"%]") do + strings[match] = true + end +end + +local work = {} + +for k,v in pairs(strings) do table.insert(work, k) end +table.sort(work) + +print("--Localization.enUS.lua\n") +print("DressToKillLocals = {") +for idx,match in ipairs(work) do + local val = match + print(string.format("\t[\"%s\"] = \"%s\",", match, val)) +end +print("}\n") +print("setmetatable(DressToKillLocals, {__index=function(t,k) rawset(t, k, k); return k; end})") diff --git a/DressToKill.lua b/DressToKill.lua new file mode 100644 index 0000000..bd0173d --- /dev/null +++ b/DressToKill.lua @@ -0,0 +1,301 @@ +-- 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 +--]] diff --git a/DressToKill.toc b/DressToKill.toc new file mode 100644 index 0000000..f1f1d5d --- /dev/null +++ b/DressToKill.toc @@ -0,0 +1,10 @@ +## Interface: 20400 +## Title: DressToKill +## Version: wowi:revision +## Notes: When you go out, make sure you're prepared to kill.. +## Author: Cladhaire +## SavedVariables: DressToKillDB + +Localization.enUS.lua + +DressToKill.lua diff --git a/Localization.enUS.lua b/Localization.enUS.lua new file mode 100644 index 0000000..437d5fb --- /dev/null +++ b/Localization.enUS.lua @@ -0,0 +1,33 @@ +--Localization.enUS.lua + +DressToKillLocals = { + ["All done trying clothes on!"] = "All done trying clothes on!", + ["Back"] = "Back", + ["Beginning an inventory scan"] = "Beginning an inventory scan", + ["Chest"] = "Chest", + ["Clearing non-soulbound item"] = "Clearing non-soulbound item", + ["Could not get inventory slot information for %s"] = "Could not get inventory slot information for %s", + ["Dressing to kill..."] = "Dressing to kill...", + ["Equipping winning item"] = "Equipping winning item", + ["Feet"] = "Feet", + ["Hands"] = "Hands", + ["Head"] = "Head", + ["Item blacklisted, skipping..."] = "Item blacklisted, skipping...", + ["Item not equipped... skipping..."] = "Item not equipped... skipping...", + ["Left Finger"] = "Left Finger", + ["Legs"] = "Legs", + ["Main Hand"] = "Main Hand", + ["Neck Slot"] = "Neck Slot", + ["Out of inventory space, cannot proceed"] = "Out of inventory space, cannot proceed", + ["Ranged Slot"] = "Ranged Slot", + ["Right Finger"] = "Right Finger", + ["Scanning for inventory slot Ids"] = "Scanning for inventory slot Ids", + ["Secondary Hand"] = "Secondary Hand", + ["Shoulders"] = "Shoulders", + ["Trinket 0"] = "Trinket 0", + ["Trinket 1"] = "Trinket 1", + ["Waist"] = "Waist", + ["Wrist"] = "Wrist", +} + +setmetatable(DressToKillLocals, {__index=function(t,k) rawset(t, k, k); return k; end})