# HG changeset patch # User yellowfive # Date 1468947932 25200 # Node ID 0515882856f170b9d245cf05c24ebd4a0e8d62fc # Parent 8f235b0162124b0ab2e6985c7554f670f98a69a4 updated for 7.0 diff -r 8f235b016212 -r 0515882856f1 AskMrRobot-Serializer/AskMrRobot-Serializer.lua --- a/AskMrRobot-Serializer/AskMrRobot-Serializer.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/AskMrRobot-Serializer/AskMrRobot-Serializer.lua Tue Jul 19 10:05:32 2016 -0700 @@ -1,7 +1,7 @@ -- AskMrRobot-Serializer will serialize and communicate character data between users. -- This is used primarily to associate character information to logs uploaded to askmrrobot.com. -local MAJOR, MINOR = "AskMrRobot-Serializer", 32 +local MAJOR, MINOR = "AskMrRobot-Serializer", 38 local Amr, oldminor = LibStub:NewLibrary(MAJOR, MINOR) if not Amr then return end -- already loaded by something else @@ -52,52 +52,55 @@ [250] = 1, -- DeathKnightBlood [251] = 2, -- DeathKnightFrost [252] = 3, -- DeathKnightUnholy - [102] = 4, -- DruidBalance - [103] = 5, -- DruidFeral - [104] = 6, -- DruidGuardian - [105] = 7, -- DruidRestoration - [253] = 8, -- HunterBeastMastery - [254] = 9, -- HunterMarksmanship - [255] = 10, -- HunterSurvival - [62] = 11, -- MageArcane - [63] = 12, -- MageFire - [64] = 13, -- MageFrost - [268] = 14, -- MonkBrewmaster - [270] = 15, -- MonkMistweaver - [269] = 16, -- MonkWindwalker - [65] = 17, -- PaladinHoly - [66] = 18, -- PaladinProtection - [70] = 19, -- PaladinRetribution - [256] = 20, -- PriestDiscipline - [257] = 21, -- PriestHoly - [258] = 22, -- PriestShadow - [259] = 23, -- RogueAssassination - [260] = 24, -- RogueCombat - [261] = 25, -- RogueSubtlety - [262] = 26, -- ShamanElemental - [263] = 27, -- ShamanEnhancement - [264] = 28, -- ShamanRestoration - [265] = 29, -- WarlockAffliction - [266] = 30, -- WarlockDemonology - [267] = 31, -- WarlockDestruction - [71] = 32, -- WarriorArms - [72] = 33, -- WarriorFury - [73] = 34 -- WarriorProtection + [577] = 4, -- DemonHunterHavoc + [581] = 5, -- DemonHunterVengeance + [102] = 6, -- DruidBalance + [103] = 7, -- DruidFeral + [104] = 8, -- DruidGuardian + [105] = 9, -- DruidRestoration + [253] = 10, -- HunterBeastMastery + [254] = 11, -- HunterMarksmanship + [255] = 12, -- HunterSurvival + [62] = 13, -- MageArcane + [63] = 14, -- MageFire + [64] = 15, -- MageFrost + [268] = 16, -- MonkBrewmaster + [270] = 17, -- MonkMistweaver + [269] = 18, -- MonkWindwalker + [65] = 19, -- PaladinHoly + [66] = 20, -- PaladinProtection + [70] = 21, -- PaladinRetribution + [256] = 22, -- PriestDiscipline + [257] = 23, -- PriestHoly + [258] = 24, -- PriestShadow + [259] = 25, -- RogueAssassination + [260] = 26, -- RogueOutlaw + [261] = 27, -- RogueSubtlety + [262] = 28, -- ShamanElemental + [263] = 29, -- ShamanEnhancement + [264] = 30, -- ShamanRestoration + [265] = 31, -- WarlockAffliction + [266] = 32, -- WarlockDemonology + [267] = 33, -- WarlockDestruction + [71] = 34, -- WarriorArms + [72] = 35, -- WarriorFury + [73] = 36 -- WarriorProtection } Amr.ClassIds = { ["NONE"] = 0, ["DEATHKNIGHT"] = 1, - ["DRUID"] = 2, - ["HUNTER"] = 3, - ["MAGE"] = 4, - ["MONK"] = 5, - ["PALADIN"] = 6, - ["PRIEST"] = 7, - ["ROGUE"] = 8, - ["SHAMAN"] = 9, - ["WARLOCK"] = 10, - ["WARRIOR"] = 11, + ["DEMONHUNTER"] = 2, + ["DRUID"] = 3, + ["HUNTER"] = 4, + ["MAGE"] = 5, + ["MONK"] = 6, + ["PALADIN"] = 7, + ["PRIEST"] = 8, + ["ROGUE"] = 9, + ["SHAMAN"] = 10, + ["WARLOCK"] = 11, + ["WARRIOR"] = 12, } Amr.ProfessionIds = { @@ -172,12 +175,6 @@ [1448] = true } -Amr.SPEC_WARRIORPROTECTION = 34 -Amr.SUBSPEC_WARRIORPROTECTION = 38 -Amr.SUBSPEC_WARRIORPROTECTIONGLAD = 39 -Amr.SPELL_ID_GLADIATOR_STANCE = 156291 -Amr.SPELL_ID_DEFENSIVE_STANCE = 71 - -- IDs of set tokens that we would care about in a player's inventory Amr.SetTokenIds = { [127970] = true, @@ -579,6 +576,30 @@ -- Public Utility Methods ---------------------------------------------------------------------------------------- +local function readBonusIdList(parts, first, last) + local ret = {} + for i = first, last do + table.insert(ret, tonumber(parts[i])) + end + table.sort(ret) + return ret +end + +local function setRelicId(item, index, relicBonuses) + local relicId = item.gemIds[index] .. "" + for i = 1, #relicBonuses do + relicId = relicId .. "." .. relicBonuses[i] + end + local list = item.gemItemIds or {} + list[i] = relicId +end + +--|color|Hitem:135820:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:playerlevel:spec?:flags:11:numBonusIDs:bonusID1:bonusID2...:playerlevelwhengotitem, 296 for warrior artifact:upgrade ID?:num artifact bonuses?:artifact bonus 1:artifact bonus 2:artifact bonus 3:[item name] +-- 133004 for relic on my warrior, gem2 +-- 296::3:767:1507:1809:[item name] this is for warrior artifact with the above relic in storm slot, for parts after the bonus IDs + +--|cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:unknown:unknown:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r + -- item link format: |cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:unknown:unknown:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r -- get an object with all of the parts of the item link format that we care about function Amr.ParseItemLink(itemLink) @@ -590,36 +611,81 @@ local parts = { strsplit(":", str) } local item = {} - item.id = tonumber(parts[1]) - item.enchantId = tonumber(parts[2]) - item.gemIds = { tonumber(parts[3]), tonumber(parts[4]), tonumber(parts[5]), tonumber(parts[6]) } - item.suffixId = math.abs(tonumber(parts[7])) -- convert suffix to positive number, that's what we use in our code - --item.uniqueId = tonumber(parts[8]) - --item.level = tonumber(parts[9]) - -- part 10 is unknown atm - -- part 11 is unknown atm - --item.difficultyId = tonumber(parts[12]) + item.id = tonumber(parts[1]) or 0 + item.enchantId = tonumber(parts[2]) or 0 + item.gemIds = { tonumber(parts[3]) or 0, tonumber(parts[4]) or 0, tonumber(parts[5]) or 0, tonumber(parts[6]) or 0 } + item.suffixId = math.abs(tonumber(parts[7]) or 0) -- convert suffix to positive number, that's what we use in our code + -- part 8 is some unique ID... we never really used it + -- part 9 is current player level + -- part 10 is player spec + local upgradeIdType = tonumber(parts[11]) or 0 -- part 11 indicates what kind of upgrade ID is just after the bonus IDs + -- part 12 is instance difficulty id - local numBonuses = tonumber(parts[13]) - if numBonuses and numBonuses > 0 then - item.bonusIds = {} - for i = 14, 13 + numBonuses do - table.insert(item.bonusIds, tonumber(parts[i])) - end - table.sort(item.bonusIds) + local numBonuses = tonumber(parts[13]) or 0 + local offset = numBonuses + if numBonuses > 0 then + item.bonusIds = readBonusIdList(parts, 14, 13 + numBonuses) end - -- if there is another part after bonus ids, that is the upgrade id - if numBonuses and #parts >= 14 + numBonuses then - local upgradeId = tonumber(parts[14 + numBonuses]) - item.upgradeId = upgradeId and upgradeId or 0 - else - item.upgradeId = 0 + item.upgradeId = 0 + item.level = 0 + + -- the next part after bonus IDs depends on the upgrade id type; is either the "drop level" or upgrade ID, or not sure for artifacts + if upgradeIdType == 4 then + item.upgradeId = tonumber(parts[14 + offset]) or 0 + elseif upgradeIdType == 512 then + item.level = tonumber(parts[14 + offset]) or 0 end - + + -- ignore relic stuff in the item link for now, we read the relic information directly and save it with artifact power info + --[[ + -- the next part is the number of bonus IDs on the first relic slot of the artifact + numBonuses = tonumber(parts[15 + offset]) or 0 + if numBonuses > 0 then + local relicBonuses = readBonusIdList(16 + offset, 15 + offset + numBonuses, parts) + setRelicId(item, 1, relicBonuses) + end + + -- second relic slot bonus IDs + offset = offset + numBonuses + numBonuses = tonumber(parts[16 + offset]) or 0 + if numBonuses > 0 then + local relicBonuses = readBonusIdList(17 + offset, 16 + offset + numBonuses, parts) + setRelicId(item, 2, relicBonuses) + end + + -- third relic slot bonus IDs + offset = offset + numBonuses + numBonuses = tonumber(parts[17 + offset]) or 0 + if numBonuses > 0 then + local relicBonuses = readBonusIdList(18 + offset, 17 + offset + numBonuses, parts) + setRelicId(item, 3, relicBonuses) + end + ]] + return item end +function Amr.GetItemUniqueId(item, noUpgrade) + if not item then return "" end + local ret = item.id .. "" + if item.bonusIds then + for i = 1, #item.bonusIds do + ret = ret .. "b" .. item.bonusIds[i] + end + end + if item.suffixId ~= 0 then + ret = ret .. "s" .. item.suffixId + end + if not noUpgrade and item.upgradeId ~= 0 then + ret = ret .. "u" .. item.upgradeId + end + if item.level ~= 0 then + ret = ret .. "v" .. item.level + end + return ret +end + -- returns true if this is an instance that AskMrRobot supports for logging function Amr.IsSupportedInstanceId(instanceMapID) if Amr.SupportedInstanceIds[tonumber(instanceMapID)] then @@ -635,6 +701,76 @@ return Amr.IsSupportedInstanceId(instanceMapID) end +-- helper to iterate over a table in order by its keys +local function spairs(t, order) + -- collect the keys + local keys = {} + for k in pairs(t) do keys[#keys+1] = k end + + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + if order then + table.sort(keys, function(a,b) return order(t, a, b) end) + else + table.sort(keys) + end + + -- return the iterator function + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end +end + +-- scanning tooltip b/c for some odd reason the api has no way to get basic item properties... +-- so you have to generate a fake item tooltip and search for pre-defined strings in the display text +local _scanTt +function Amr.GetScanningTooltip() + if not _scanTt then + _scanTt = CreateFrame("GameTooltip", "AmrUiScanTooltip", nil, "GameTooltipTemplate") + _scanTt:SetOwner(UIParent, "ANCHOR_NONE") + end + return _scanTt +end + +-- get the item tooltip for the specified item in one of your bags, or if bagId is nil, an equipped item, or if slotId is also nil, the specified item link +function Amr.GetItemTooltip(bagId, slotId, link) + local tt = Amr.GetScanningTooltip() + tt:ClearLines() + if bagId then + tt:SetBagItem(bagId, slotId) + elseif slotId then + tt:SetInventoryItem("player", slotId) + else + tt:SetHyperlink(link) + end + return tt +end + +function Amr.GetItemLevel(bagId, slotId, link) + local itemLevelPattern = _G["ITEM_LEVEL"]:gsub("%%d", "(%%d+)") + local tt = Amr.GetItemTooltip(bagId, slotId, link) + + local regions = { tt:GetRegions() } + for i, region in ipairs(regions) do + if region and region:GetObjectType() == "FontString" then + local text = region:GetText() + if text then + ilvl = tonumber(text:match(itemLevelPattern)) + if ilvl then + return ilvl + end + end + end + end + + -- 0 means we couldn't find it for whatever reason + return 0 +end + ---------------------------------------------------------------------------------------- -- Character Reading @@ -649,17 +785,13 @@ end end -local function getSpecId(specGroup) - local spec = GetSpecialization(false, false, specGroup); - return spec and GetSpecializationInfo(spec); -end - -local function getTalents(specGroup) +--[[ +local function getTalents(specPos) local talentInfo = {} local maxTiers = 7 for tier = 1, maxTiers do for col = 1, 3 do - local id, name, texture, selected, available = GetTalentInfo(tier, col, specGroup) + local id, name, _, _, _, spellId, _, t, c, selected = GetTalentInfoBySpecialization(specPos, tier, col) if selected then talentInfo[tier] = col end @@ -677,7 +809,9 @@ return str end +]] +--[[ local function getGlyphs(specGroup) local glyphs = {} for i = 1, NUM_GLYPH_SLOTS do @@ -688,55 +822,28 @@ end return glyphs; end +]] --- get specs, talents, and glyphs -local function readSpecs(ret, subspecs) +-- get specs and talents +local function readSpecs(ret) - for group = 1, GetNumSpecGroups() do + for pos = 1, 4 do -- spec, convert game spec id to one of our spec ids - local specId = getSpecId(group) + local specId = GetSpecializationInfo(pos) if specId then - ret.Specs[group] = Amr.SpecIds[specId] - - -- if this is a protection warrior, use buffs to determine subspec - if ret.Specs[group] == Amr.SPEC_WARRIORPROTECTION then - local subspec = 0 - - if ret.ActiveSpec ~= group then - -- this spec isn't active, so we can't use current buffs to determine spec, see if any old data is compatible - if subspecs and (subspecs[group] == Amr.SUBSPEC_WARRIORPROTECTION or subspecs[group] == Amr.SUBSPEC_WARRIORPROTECTIONGLAD) then - subspec = subspecs[group] - end - else - for i=1,40 do - local name,_,_,_,_,_,_,_,_,_,spellId = UnitAura("player", i, "HELPFUL") - if not name then break end - - if spellId == Amr.SPELL_ID_DEFENSIVE_STANCE then - subspec = Amr.SUBSPEC_WARRIORPROTECTION - break - elseif spellId == Amr.SPELL_ID_GLADIATOR_STANCE then - subspec = Amr.SUBSPEC_WARRIORPROTECTIONGLAD - break - end - end - end - - if subspec == 0 then - ret.SubSpecs[group] = nil - else - ret.SubSpecs[group] = subspec - end - end - else - ret.Specs[group] = 0 + ret.Specs[pos] = Amr.SpecIds[specId] + -- TODO: figure out how to read inactive spec talents if possible... used to be able to but they changed it + --ret.Talents[pos] = getTalents(pos) end - - ret.Talents[group] = getTalents(group) - ret.Glyphs[group] = getGlyphs(group) end end +-- TODO: hopefully we can read artifact here when there is an API to get info when the artifact UI is not open +-- get artifact info +local function readArtifact() + +end + -- get currently equipped items, store with currently active spec local function readEquippedItems(ret) local equippedItems = {}; @@ -749,7 +856,7 @@ end -- store last-seen equipped gear for each spec - ret.Equipped[GetActiveSpecGroup()] = equippedItems + ret.Equipped[GetSpecialization()] = equippedItems end -- Get all data about the player as an object, includes: @@ -760,10 +867,11 @@ -- faction -- level -- professions --- spec/talent/glyphs for both specs +-- spec/talent for all specs +-- artifact for current spec -- equipped gear for the current spec -- -function Amr:GetPlayerData(subspecs) +function Amr:GetPlayerData() local ret = {} @@ -771,7 +879,7 @@ ret.Realm = GetRealmName() ret.Name = UnitName("player") ret.Guild = GetGuildInfo("player") - ret.ActiveSpec = GetActiveSpecGroup() + ret.ActiveSpec = GetSpecialization() ret.Level = UnitLevel("player"); local cls, clsEn = UnitClass("player") @@ -791,10 +899,11 @@ readProfessionInfo(firstAid, ret) ret.Specs = {} - ret.SubSpecs = {} -- only filled in for ambiguous cases, right now just prot/glad warrior ret.Talents = {} - ret.Glyphs = {} - readSpecs(ret, subspecs) + readSpecs(ret) + + ret.Artifacts = {} + readArtifact() ret.Equipped = {} readEquippedItems(ret) @@ -843,9 +952,16 @@ local prevEnchantId = 0 local prevUpgradeId = 0 local prevBonusId = 0 + local prevLevel = 0 for i, itemData in ipairs(itemObjects) do local itemParts = {} + -- for now export the item level of artifacts as the "drop level" because it is a pain in the ass to figure it out from the bonus IDs + --local _, _, quality = GetItemInfo(itemData.link) + --if quality == 6 then + -- itemData.level = Amr.GetItemLevel(nil, nil, itemData.link) + --end + table.insert(itemParts, itemData.id - prevItemId) prevItemId = itemData.id @@ -855,24 +971,30 @@ table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId)) prevUpgradeId = itemData.upgradeId end + if itemData.level ~= 0 then + table.insert(itemParts, "v" .. (itemData.level - prevLevel)) + prevLevel = itemData.level + end if itemData.bonusIds then for bIndex, bValue in ipairs(itemData.bonusIds) do table.insert(itemParts, "b" .. (bValue - prevBonusId)) prevBonusId = bValue end - end - if itemData.gemIds[1] ~= 0 then - table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId)) - prevGemId = itemData.gemIds[1] end - if itemData.gemIds[2] ~= 0 then - table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId)) - prevGemId = itemData.gemIds[2] - end - if itemData.gemIds[3] ~= 0 then - table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId)) - prevGemId = itemData.gemIds[3] - end + + if itemData.gemIds[1] ~= 0 then + table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId)) + prevGemId = itemData.gemIds[1] + end + if itemData.gemIds[2] ~= 0 then + table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId)) + prevGemId = itemData.gemIds[2] + end + if itemData.gemIds[3] ~= 0 then + table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId)) + prevGemId = itemData.gemIds[3] + end + if itemData.enchantId ~= 0 then table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) prevEnchantId = itemData.enchantId @@ -948,25 +1070,41 @@ -- export specs table.insert(fields, data.ActiveSpec) - for spec = 1, 2 do + for spec = 1, 4 do if data.Specs[spec] and (complete or spec == data.ActiveSpec) then table.insert(fields, ".s" .. spec) -- indicates the start of a spec block + table.insert(fields, data.Specs[spec]) + table.insert(fields, data.Talents[spec]) - -- we use subspec for some ambiguous specs like prot/glad warrior - if data.SubSpecs[spec] then - table.insert(fields, string.format("s%s", data.SubSpecs[spec])) - else - table.insert(fields, data.Specs[spec]) + local powerids = {} + local powerranks = {} + local reliclinks = {} + + local artifactInfo = data.Artifacts and data.Artifacts[spec] + if artifactInfo and artifactInfo.Powers then + for k, v in spairs(artifactInfo.Powers) do + table.insert(powerids, k) + table.insert(powerranks, v) + end + end + if artifactInfo and artifactInfo.Relics then + for i, link in ipairs(artifactInfo.Relics) do + local relic = Amr.ParseItemLink(link) + table.insert(reliclinks, Amr.GetItemUniqueId(relic) or "") + end end - table.insert(fields, data.Talents[spec]) - table.insert(fields, toCompressedNumberList(data.Glyphs[spec])) + table.insert(fields, toCompressedNumberList(powerids)) + table.insert(fields, table.concat(powerranks, ",")) + table.insert(fields, table.concat(reliclinks, ",")) + + --table.insert(fields, toCompressedNumberList(data.Glyphs[spec])) end end -- export equipped gear if data.Equipped then - for spec = 1, 2 do + for spec = 1, 4 do if data.Equipped[spec] and (complete or spec == data.ActiveSpec) then table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block @@ -974,6 +1112,7 @@ for k, v in pairs(data.Equipped[spec]) do local itemData = Amr.ParseItemLink(v) itemData.slot = k + itemData.link = v table.insert(itemObjects, itemData) end @@ -1007,6 +1146,7 @@ for i, v in ipairs(data.BagItems) do local itemData = Amr.ParseItemLink(v) if itemData ~= nil and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id]) then + itemData.link = v table.insert(itemObjects, itemData) end end @@ -1015,6 +1155,7 @@ for i, v in ipairs(data.BankItems) do local itemData = Amr.ParseItemLink(v) if itemData ~= nil and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id]) then + itemData.link = v table.insert(itemObjects, itemData) end end @@ -1023,6 +1164,7 @@ for i, v in ipairs(data.VoidItems) do local itemData = Amr.ParseItemLink(v) if itemData ~= nil and (IsEquippableItem(v) or Amr.SetTokenIds[itemData.id]) then + itemData.link = v table.insert(itemObjects, itemData) end end @@ -1042,10 +1184,10 @@ return self:SerializePlayerData(data) end - +--[[ ---------------------------------------------------------------------------------------------------------------------- -- Character Snapshots --- This feature snapshots a player's gear/talents/glyphs when entering combat. It is enabled by default. Consumers +-- This feature snapshots a player's gear/talents/artifact when entering combat. It is enabled by default. Consumers -- of this library can create a setting to enable/disable it as desired per a user setting. -- -- You should register for the AMR_SNAPSHOT_STATE_CHANGED message (sent via AceEvent-3.0 messaging) to ensure that @@ -1088,4 +1230,5 @@ end Amr:RegisterEvent("PLAYER_REGEN_DISABLED") ---Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table \ No newline at end of file +--Amr:RegisterEvent("GARRISON_MISSION_NPC_OPENED") -- for debugging, fire this event when open mission table +]] \ No newline at end of file diff -r 8f235b016212 -r 0515882856f1 AskMrRobot.toc --- a/AskMrRobot.toc Tue Apr 05 16:19:31 2016 -0700 +++ b/AskMrRobot.toc Tue Jul 19 10:05:32 2016 -0700 @@ -1,10 +1,10 @@ -## Interface: 60200 +## Interface: 70000 ## Title: Ask Mr. Robot ## Author: Team Robot, Inc. -## Version: 32 +## Version: 38 ## Notes: Gear import/export, combat logging, and more. ## URL: www.askmrrobot.com -## SavedVariables: AskMrRobotDb2 +## SavedVariables: AskMrRobotDb3 Libs\LibStub\LibStub.lua Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml @@ -20,8 +20,8 @@ Libs\AceGUI-3.0\AceGUI-3.0.xml localization\enUS.lua -localization\frFR.lua -localization\itIT.lua +##localization\frFR.lua +##localization\itIT.lua AskMrRobot-Serializer\AskMrRobot-Serializer.xml diff -r 8f235b016212 -r 0515882856f1 Constants.lua --- a/Constants.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/Constants.lua Tue Jul 19 10:05:32 2016 -0700 @@ -2,11 +2,11 @@ local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) -- min import version that we will read from the website -Amr.MIN_IMPORT_VERSION = 21 +Amr.MIN_IMPORT_VERSION = 36 -- min addon version that we will support for inter-addon communication for e.g. the team optimizer --- last update to version 24 when item link format changed -Amr.MIN_ADDON_VERSION = 24 +-- last update to version 36 for Legion pre-patch +Amr.MIN_ADDON_VERSION = 36 -- import some constants from the serializer for convenience Amr.ChatPrefix = Amr.Serializer.ChatPrefix @@ -23,6 +23,9 @@ Amr.IsSupportedInstanceId = Amr.Serializer.IsSupportedInstanceId Amr.IsSupportedInstance = Amr.Serializer.IsSupportedInstance Amr.SetTokenIds = Amr.Serializer.SetTokenIds +Amr.GetItemTooltip = Amr.Serializer.GetItemTooltip +Amr.GetItemLevel = Amr.Serializer.GetItemLevel +Amr.GetItemUniqueId = Amr.Serializer.GetItemUniqueId -- map of slot ID to display text Amr.SlotDisplayText = { @@ -67,39 +70,39 @@ [1] = "spell_deathknight_bloodpresence", -- DeathKnightBlood [2] = "spell_deathknight_frostpresence", -- DeathKnightFrost [3] = "spell_deathknight_unholypresence", -- DeathKnightUnholy - [4] = "spell_nature_starfall", -- DruidBalance - [5] = "ability_druid_catform", -- DruidFeral - [6] = "ability_racial_bearform", -- DruidGuardian - [7] = "spell_nature_healingtouch", -- DruidRestoration - [8] = "ability_hunter_bestialdiscipline", -- HunterBeastMastery - [9] = "ability_hunter_focusedaim", -- HunterMarksmanship - [10] = "ability_hunter_camouflage", -- HunterSurvival - [11] = "spell_holy_magicalsentry", -- MageArcane - [12] = "spell_fire_firebolt02", -- MageFire - [13] = "spell_frost_frostbolt02", -- MageFrost - [14] = "spell_monk_brewmaster_spec", -- MonkBrewmaster - [15] = "spell_monk_mistweaver_spec", -- MonkMistweaver - [16] = "spell_monk_windwalker_spec", -- MonkWindwalker - [17] = "spell_holy_holybolt", -- PaladinHoly - [18] = "ability_paladin_shieldofthetemplar", -- PaladinProtection - [19] = "spell_holy_auraoflight", -- PaladinRetribution - [20] = "spell_holy_powerwordshield", -- PriestDiscipline - [21] = "spell_holy_guardianspirit", -- PriestHoly - [22] = "spell_shadow_shadowwordpain", -- PriestShadow - [23] = "ability_rogue_eviscerate", -- RogueAssassination - [24] = "ability_backstab", -- RogueCombat - [25] = "ability_stealth", -- RogueSubtlety - [26] = "spell_nature_lightning", -- ShamanElemental - [27] = "spell_nature_lightningshield", -- ShamanEnhancement - [28] = "spell_nature_magicimmunity", -- ShamanRestoration - [29] = "spell_shadow_deathcoil", -- WarlockAffliction - [30] = "spell_shadow_metamorphosis", -- WarlockDemonology - [31] = "spell_shadow_rainoffire", -- WarlockDestruction - [32] = "ability_warrior_savageblow", -- WarriorArms - [33] = "ability_warrior_innerrage", -- WarriorFury - [34] = "ability_warrior_defensivestance", -- WarriorProtection - [38] = "ability_warrior_defensivestance", -- WarriorProtection, used for special subspec handling - [39] = "spell_warrior_gladiatorstance" -- WarriorProtectionGlad, used for special subspec handling + [4] = "ability_demonhunter_specdps", -- DemonHunterHavoc + [5] = "ability_demonhunter_spectank", -- DemonHunterVengeance + [6] = "spell_nature_starfall", -- DruidBalance + [7] = "ability_druid_catform", -- DruidFeral + [8] = "ability_racial_bearform", -- DruidGuardian + [9] = "spell_nature_healingtouch", -- DruidRestoration + [10] = "ability_hunter_bestialdiscipline", -- HunterBeastMastery + [11] = "ability_hunter_focusedaim", -- HunterMarksmanship + [12] = "ability_hunter_camouflage", -- HunterSurvival + [13] = "spell_holy_magicalsentry", -- MageArcane + [14] = "spell_fire_firebolt02", -- MageFire + [15] = "spell_frost_frostbolt02", -- MageFrost + [16] = "spell_monk_brewmaster_spec", -- MonkBrewmaster + [17] = "spell_monk_mistweaver_spec", -- MonkMistweaver + [18] = "spell_monk_windwalker_spec", -- MonkWindwalker + [19] = "spell_holy_holybolt", -- PaladinHoly + [20] = "ability_paladin_shieldofthetemplar", -- PaladinProtection + [21] = "spell_holy_auraoflight", -- PaladinRetribution + [22] = "spell_holy_powerwordshield", -- PriestDiscipline + [23] = "spell_holy_guardianspirit", -- PriestHoly + [24] = "spell_shadow_shadowwordpain", -- PriestShadow + [25] = "ability_rogue_eviscerate", -- RogueAssassination + [26] = "inv_sword_30", -- RogueOutlaw + [27] = "ability_stealth", -- RogueSubtlety + [28] = "spell_nature_lightning", -- ShamanElemental + [29] = "spell_nature_lightningshield", -- ShamanEnhancement + [30] = "spell_nature_magicimmunity", -- ShamanRestoration + [31] = "spell_shadow_deathcoil", -- WarlockAffliction + [32] = "spell_shadow_metamorphosis", -- WarlockDemonology + [33] = "spell_shadow_rainoffire", -- WarlockDestruction + [34] = "ability_warrior_savageblow", -- WarriorArms + [35] = "ability_warrior_innerrage", -- WarriorFury + [36] = "ability_warrior_defensivestance", -- WarriorProtection } -- instance IDs ordered in preferred display order @@ -148,8 +151,19 @@ table.insert(parts, 0) -- some unique id, doesn't seem to matter table.insert(parts, UnitLevel("player")) - table.insert(parts, 0) -- unknown - table.insert(parts, 0) -- unknown + + local specId = GetSpecializationInfo(GetSpecialization()) + table.insert(parts, specId) + + -- this indicates what kind of modifier appears after the bonus IDs + if itemObj.upgradeId and itemObj.upgradeId ~= 0 then + table.insert(parts, 4) + elseif itemObj.level and itemObj.level ~= 0 then + table.insert(parts, 512) + else + table.insert(parts, 0) + end + table.insert(parts, 0) -- difficulty id, doesn't matter if itemObj.bonusIds then @@ -161,31 +175,23 @@ table.insert(parts, 0) -- no bonus ids end - -- upgrade id is tacked onto the end now it seems - if (not itemObj.bonusIds or #itemObj.bonusIds == 0) and itemObj.upgradeId and itemObj.upgradeId ~= 0 then + -- upgrade id or level comes after bonuses + if itemObj.upgradeId and itemObj.upgradeId ~= 0 then table.insert(parts, itemObj.upgradeId) + elseif itemObj.level and itemObj.level ~= 0 then + table.insert(parts, itemObj.level) + else + table.insert(parts, 0) end + + -- technically relic stuff comes after this... but we ignore it for now, too much of a pain + table.insert(parts, 0) + table.insert(parts, 0) + table.insert(parts, 0) return table.concat(parts, ":") end --- a unique ID useful for determining if a player has an item equipped or not -function Amr.GetItemUniqueId(item, noUpgrade) - if item == nil then return "" end - local ret = item.id .. "" - if item.bonusIds then - for i = 1, #item.bonusIds do - ret = ret .. "b" .. item.bonusIds[i] - end - end - if item.suffixId ~= 0 then - ret = ret .. "s" .. item.suffixId - end - if not noUpgrade and item.upgradeId ~= 0 then - ret = ret .. "u" .. item.upgradeId - end - return ret -end -- the server event for getting item info does not specify which item it just fetched... have to track manually local _pendingItemIds = {} diff -r 8f235b016212 -r 0515882856f1 Core.lua --- a/Core.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/Core.lua Tue Jul 19 10:05:32 2016 -0700 @@ -51,8 +51,9 @@ local defaults = { char = { FirstUse = true, -- true if this is first time use, gets cleared after seeing the export help splash window - SubSpecs = {}, -- last seen subspecs for this character, used to deal with some ambiguous specs - Equipped = {}, -- for each spec group (1 or 2), slot id to item link + Talents = {}, -- for each spec, selected talents + Artifacts = {}, -- for each spec, artifact info + Equipped = {}, -- for each spec, slot id to item link BagItems = {}, -- list of item links for bag BankItems = {}, -- list of item links for bank VoidItems = {}, -- list of item links for void storage @@ -125,7 +126,7 @@ end end - Amr.db = LibStub("AceDB-3.0"):New("AskMrRobotDb2", defaults) + Amr.db = LibStub("AceDB-3.0"):New("AskMrRobotDb3", defaults) Amr.db.RegisterCallback(Amr, "OnProfileChanged", "RefreshConfig") Amr.db.RegisterCallback(Amr, "OnProfileCopied", "RefreshConfig") @@ -175,6 +176,7 @@ function Amr:OnEnable() + --[[ -- listen for changes to the snapshot enable state, and always make sure it is enabled if using the core AskMrRobot addon self:RegisterMessage("AMR_SNAPSHOT_STATE_CHANGED", function(eventName, isEnabled) if not isEnabled then @@ -183,6 +185,7 @@ end end) self.Serializer:EnableSnapshots() + ]] -- update based on current configuration whenever enabled self:RefreshConfig() @@ -496,27 +499,6 @@ end --- scanning tooltip b/c for some odd reason the api has no way to get basic item properties... --- so you have to generate a fake item tooltip and search for pre-defined strings in the display text -local _scanTt -function Amr:GetScanningTooltip() - if not _scanTt then - _scanTt = CreateFrame("GameTooltip", "AmrUiScanTooltip", nil, "GameTooltipTemplate") - _scanTt:SetOwner(UIParent, "ANCHOR_NONE") - end - return _scanTt -end - -local function scanTooltipHelper(txt, ...) - for i = 1, select("#", ...) do - local region = select(i, ...) - if region and region:GetObjectType() == "FontString" then - local text = region:GetText() -- string or nil - print(text) - end - end -end - -- search the tooltip for txt, returns true if it is encountered on any line function Amr:IsTextInTooltip(tt, txt) local regions = { tt:GetRegions() } @@ -532,13 +514,7 @@ -- helper to determine if we can equip an item (it is already soulbound or account bound) function Amr:CanEquip(bagId, slotId) - local tt = self:GetScanningTooltip() - tt:ClearLines() - if bagId then - tt:SetBagItem(bagId, slotId) - else - tt:SetInventoryItem("player", slotId) - end + local tt = Amr.GetItemTooltip(bagId, slotId) if self:IsTextInTooltip(tt, ITEM_SOULBOUND) then return true end if self:IsTextInTooltip(tt, ITEM_BNETACCOUNTBOUND) then return true end if self:IsTextInTooltip(tt, ITEM_ACCOUNTBOUND) then return true end @@ -546,13 +522,7 @@ -- helper to determine if an item has a unique constraint function Amr:IsUnique(bagId, slotId) - local tt = self:GetScanningTooltip() - tt:ClearLines() - if bagId then - tt:SetBagItem(bagId, slotId) - else - tt:SetInventoryItem("player", slotId) - end + local tt = Amr.GetItemTooltip(bagId, slotId) if self:IsTextInTooltip(tt, ITEM_UNIQUE_EQUIPPABLE) then return true end if self:IsTextInTooltip(tt, ITEM_UNIQUE) then return true end return false diff -r 8f235b016212 -r 0515882856f1 Export.lua --- a/Export.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/Export.lua Tue Jul 19 10:05:32 2016 -0700 @@ -53,6 +53,10 @@ lbl = createLabel(panel, L.ExportSplash3, 650) lbl:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text)) lbl:SetPoint("TOPLEFT", lbl2.frame, "BOTTOMLEFT", 0, -15) + + lbl2 = createLabel(panel, L.ExportSplash4, 650) + lbl2:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.Text)) + lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -15) local btn = AceGUI:Create("AmrUiButton") btn:SetText(L.ExportSplashClose) @@ -81,13 +85,10 @@ lbl2 = createLabel(container, L.ExportHelp3) lbl2:SetPoint("TOPLEFT", lbl.frame, "BOTTOMLEFT", 0, -10) - lbl = createLabel(container, L.ExportHelp4) - lbl:SetPoint("TOPLEFT", lbl2.frame, "BOTTOMLEFT", 0, -10) - _txt = AceGUI:Create("AmrUiTextarea") _txt:SetWidth(800) _txt:SetHeight(300) - _txt:SetPoint("TOP", lbl.frame, "BOTTOM", 0, -20) + _txt:SetPoint("TOP", lbl2.frame, "BOTTOM", 0, -20) _txt:SetFont(Amr.CreateFont("Regular", 12, Amr.Colors.Text)) _txt:SetCallback("OnTextChanged", onTextChanged) container:AddChild(_txt) @@ -151,11 +152,10 @@ -- get the player's current gear and save it, also returns the data from GetPlayerData for efficiency local function getEquipped() - local data = Amr.Serializer:GetPlayerData(Amr.db.char.SubSpecs) - local spec = GetActiveSpecGroup() + local data = Amr.Serializer:GetPlayerData() + local spec = GetSpecialization() Amr.db.char.Equipped[spec] = data.Equipped[spec] - Amr.db.char.SubSpecs[spec] = data.SubSpecs[spec] return data end @@ -241,6 +241,63 @@ return reps end +local function scanTalents() + local specPos = GetSpecialization() + if not specPos or specPos < 1 or specPos > 4 then return end + + local talentInfo = {} + local maxTiers = 7 + for tier = 1, maxTiers do + for col = 1, 3 do + local id, name, _, _, _, spellId, _, t, c, selected = GetTalentInfoBySpecialization(specPos, tier, col) + if selected then + talentInfo[tier] = col + end + end + end + + local str = "" + for i = 1, maxTiers do + if talentInfo[i] then + str = str .. talentInfo[i] + else + str = str .. '0' + end + end + + Amr.db.char.Talents[specPos] = str +end + +local function scanArtifact() + -- TODO: when they put in a real API for this, switch to that instead of using UI methods directly + local powers = C_ArtifactUI.GetPowers() + if not powers then return end + + local powerRanks = {} + for k,v in pairs(powers) do + local spellId, cost, rank, maxRank, relicRank = C_ArtifactUI.GetPowerInfo(v) + if rank - relicRank > 0 then + powerRanks[v] = rank - relicRank + end + end + + local relicInfo = {} + for i = 1,3 do + local _, _, _, link = C_ArtifactUI.GetRelicInfo(i); + table.insert(relicInfo, link or "") + end + + -- make sure that the artifact UI didn't get closed while we were reading it, GetPowers seems to return nil unless it is open + powers = C_ArtifactUI.GetPowers() + if not powers then return end + + local spec = GetSpecialization() + Amr.db.char.Artifacts[spec] = { + Powers = powerRanks, + Relics = relicInfo + } +end + -- Returns a data object containing all information about the current player needed for an export: -- gear, spec, reputations, bag, bank, and void storage items. function Amr:ExportCharacter() @@ -248,7 +305,11 @@ local data = getEquipped() scanBags() - -- get extra data that is not necessary for the base serializer, but that we add here for completeness + -- scan current spec's talents just before exporting + scanTalents() + + data.Talents = Amr.db.char.Talents + data.Artifacts = Amr.db.char.Artifacts data.Equipped = Amr.db.char.Equipped data.Reputations = getReputations() data.BagItems = Amr.db.char.BagItems @@ -272,3 +333,6 @@ Amr:AddEventHandler("VOID_STORAGE_CONTENTS_UPDATE", scanVoid) Amr:AddEventHandler("VOID_STORAGE_DEPOSIT_UPDATE", scanVoid) Amr:AddEventHandler("VOID_STORAGE_UPDATE", scanVoid) + +Amr:AddEventHandler("PLAYER_TALENT_UPDATE", scanTalents) +Amr:AddEventHandler("ARTIFACT_UPDATE", scanArtifact) diff -r 8f235b016212 -r 0515882856f1 Gear.lua --- a/Gear.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/Gear.lua Tue Jul 19 10:05:32 2016 -0700 @@ -14,7 +14,7 @@ return 1000 end - -- different upgrade levels of the same item (only for older gear, player has control over upgrade level) + -- different upgrade levels of the same item if item1.upgradeId ~= item2.upgradeId then return 100 end @@ -138,7 +138,7 @@ icon:SetHeight(48) local iconSpec - if player.SubSpecs[spec] then + if player.SubSpecs and player.SubSpecs[spec] then iconSpec = player.SubSpecs[spec] else iconSpec = player.Specs[spec] @@ -149,7 +149,7 @@ panelGear:AddChild(icon) local btnEquip = AceGUI:Create("AmrUiButton") - btnEquip:SetText(L.GearButtonEquip(spec)) + btnEquip:SetText(L.GearButtonEquip(L.SpecsShort[player.Specs[spec]])) btnEquip:SetBackgroundColor(Amr.Colors.Green) btnEquip:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.White)) btnEquip:SetWidth(300) @@ -161,17 +161,6 @@ end) panelGear:AddChild(btnEquip) - --[[local btnShop = AceGUI:Create("AmrUiButton") - btnShop:SetText(L.GearButtonShop) - btnShop:SetBackgroundColor(Amr.Colors.Blue) - btnShop:SetFont(Amr.CreateFont("Regular", 14, Amr.Colors.White)) - btnShop:SetWidth(300) - btnShop:SetHeight(26) - btnShop:SetPoint("LEFT", btnEquip.frame, "RIGHT", 75, 0) - btnShop:SetPoint("RIGHT", panelMods.content, "RIGHT", -20, 0) - btnShop:SetCallback("OnClick", function(widget) Amr:ShowShopWindow() end) - panelMods:AddChild(btnShop)]] - -- each physical item can only be used once, this tracks ones we have already used local usedItems = {} @@ -371,30 +360,25 @@ lbl2:SetPoint("TOP", lbl.frame, "BOTTOM", 10, -5) container:AddChild(lbl2) - --[[ - local btnClean = AceGUI:Create("AmrUiButton") - btnClean:SetText(L.GearButtonCleanText) - btnClean:SetBackgroundColor(Amr.Colors.Orange) - btnClean:SetFont(Amr.CreateFont("Bold", 16, Amr.Colors.White)) - btnClean:SetWidth(120) - btnClean:SetHeight(26) - btnClean:SetPoint("BOTTOMLEFT", container.content, "BOTTOMLEFT", 0, 5) - btnClean:SetCallback("OnClick", function(widget) Amr:CleanBags() end) - container:AddChild(btnClean) - ]] - local t = AceGUI:Create("AmrUiTabGroup") t:SetLayout("None") - t:SetTabs({ - {text=L.GearTabPrimary, value="1", style="bold"}, - {text=L.GearTabSecondary, value="2", style="bold"} - }) + + local tabz = {} + for pos = 1, 4 do + local specId = GetSpecializationInfo(pos) + if specId then + table.insert(tabz, { text = L.SpecsShort[Amr.SpecIds[specId]], value = pos .. "", style = "bold" }) + end + end + + t:SetTabs(tabz) t:SetCallback("OnGroupSelected", onGearTabSelected) t:SetPoint("TOPLEFT", container.content, "TOPLEFT", 144, -30) t:SetPoint("BOTTOMRIGHT", container.content, "BOTTOMRIGHT") container:AddChild(t) _gearTabs = t; + --[[ local btnShop = AceGUI:Create("AmrUiButton") btnShop:SetText(L.GearButtonShop) btnShop:SetBackgroundColor(Amr.Colors.Blue) @@ -404,10 +388,10 @@ btnShop:SetPoint("TOPRIGHT", container.content, "TOPRIGHT", -20, -25) btnShop:SetCallback("OnClick", function(widget) Amr:ShowShopWindow() end) container:AddChild(btnShop) - + ]] if not _activeTab then - _activeTab = tostring(GetActiveSpecGroup()) + _activeTab = tostring(GetSpecialization()) end t:SelectTab(_activeTab) @@ -707,8 +691,9 @@ end local function onActiveTalentGroupChanged() + local auto = Amr.db.profile.options.autoGear - local currentSpec = GetActiveSpecGroup() + local currentSpec = GetSpecialization() if currentSpec == _waitingForSpec or auto then -- spec is what we want, now equip the gear @@ -718,21 +703,19 @@ _waitingForSpec = 0 end --- activate the specified spec and then equip the saved gear set for either primary (1) or secondary (2) spec +-- activate the specified spec and then equip the saved gear set function Amr:EquipGearSet(spec) - -- if no argument, then toggle spec + -- if no argument, then cycle spec if not spec then - spec = GetActiveSpecGroup() == 1 and 2 or 1 + spec = GetSpecialization() + 1 end - + -- allow some flexibility in the arguments - if spec == "primary" or spec == "Primary" then spec = 1 end - if spec == "secondary" or spec == "Secondary" then spec = 2 end - if spec == "1" or spec == "2" then spec = tonumber(spec) end - - -- only spec 1 or 2 are valid - if spec ~= 1 and spec ~= 2 then return end + if spec == "1" or spec == "2" or spec == "3" or spec == "4" then spec = tonumber(spec) end + + local specId = GetSpecializationInfo(spec) + if not specId then spec = 1 end if UnitAffectingCombat("player") then Amr:Print(L.GearEquipErrorCombat) @@ -741,9 +724,9 @@ _waitingForSpec = spec - local currentSpec = GetActiveSpecGroup() + local currentSpec = GetSpecialization() if currentSpec ~= spec then - SetActiveSpecGroup(spec) + SetSpecialization(spec) else onActiveTalentGroupChanged() end @@ -754,9 +737,17 @@ -- TODO: implement end +--[[ +local function testfunc(message) + print(strsub(message, 13)) +end +]] + function Amr:InitializeGear() - Amr:AddEventHandler("ACTIVE_TALENT_GROUP_CHANGED", onActiveTalentGroupChanged) + Amr:AddEventHandler("PLAYER_SPECIALIZATION_CHANGED", onActiveTalentGroupChanged) + --Amr:AddEventHandler("CHAT_MSG_CHANNEL", testfunc) + Amr:AddEventHandler("UNIT_INVENTORY_CHANGED", function(unitID) if unitID and unitID ~= "player" then return end Amr:RefreshGearTab() diff -r 8f235b016212 -r 0515882856f1 Import.lua --- a/Import.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/Import.lua Tue Jul 19 10:05:32 2016 -0700 @@ -202,6 +202,7 @@ local prevEnchantId = 0 local prevUpgradeId = 0 local prevBonusId = 0 + local prevLevel = 0 local digits = { ["-"] = true, ["0"] = true, @@ -215,7 +216,7 @@ ["8"] = true, ["9"] = true, } - for i = 16, #parts do + for i = 18, #parts do local itemString = parts[i] if itemString ~= "" and itemString ~= "_" then local tokens = {} @@ -240,6 +241,9 @@ elseif prop == "u" then val = val + prevUpgradeId prevUpgradeId = val + elseif prop == "v" then + val = val + prevLevel + prevLevel = val elseif prop == "b" then val = val + prevBonusId prevBonusId = val @@ -272,6 +276,7 @@ obj.id = tokens["i"] obj.suffixId = tokens["f"] or 0 obj.upgradeId = tokens["u"] or 0 + obj.level = tokens["v"] or 0 obj.enchantId = tokens["e"] or 0 obj.gemIds = {} @@ -336,7 +341,7 @@ end end - gemInfo[gemObj.enchantId] = gemObj + gemInfo[gemObj.id] = gemObj elseif infoParts[1] == "e" then diff -r 8f235b016212 -r 0515882856f1 Shopping.lua --- a/Shopping.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/Shopping.lua Tue Jul 19 10:05:32 2016 -0700 @@ -6,12 +6,18 @@ local _panelContent local _cboPlayers local _selectedPlayer + local _specs = { [1] = true, - [2] = true + [2] = true, + [3] = true, + [4] = true, } + local _chk1 local _chk2 +local _chk3 +local _chk4 local _isAhOpen = false local function onShopFrameClose(widget) @@ -20,6 +26,8 @@ _cboPlayers = nil _chk1 = nil _chk2 = nil + _chk3 = nil + _chk4 = nil _panelContent = nil end @@ -94,6 +102,18 @@ _chk2:SetCallback("OnClick", onSpecClick) _frameShop:AddChild(_chk2) + _chk3 = AceGUI:Create("AmrUiCheckBox") + _chk3:SetPoint("LEFT", _chk2.frame, "RIGHT", 30, 0) + _chk3:SetUserData("spec", 3) + _chk3:SetCallback("OnClick", onSpecClick) + _frameShop:AddChild(_chk3) + + _chk4 = AceGUI:Create("AmrUiCheckBox") + _chk4:SetPoint("LEFT", _chk3.frame, "RIGHT", 30, 0) + _chk4:SetUserData("spec", 4) + _chk4:SetCallback("OnClick", onSpecClick) + _frameShop:AddChild(_chk4) + _panelContent = AceGUI:Create("AmrUiPanel") _panelContent:SetLayout("None") _panelContent:SetTransparent() @@ -199,14 +219,17 @@ _chk1:SetVisible(false) _chk2:SetVisible(false) + _chk3:SetVisible(false) + _chk4:SetVisible(false) _chk1:SetChecked(false) _chk2:SetChecked(false) + _chk3:SetChecked(false) + _chk4:SetChecked(false) -- clear out any previous data _panelContent:ReleaseChildren() - -- render required gems for the selected player local data = Amr.db.global.Shopping[_selectedPlayer] if not data then _panelContent:SetLayout("None") @@ -220,22 +243,32 @@ else -- set labels on checkboxes if data.specs[1] and data.specs[1] ~= 0 then - local id, name = GetSpecializationInfoByID(Amr.GetGameSpecId(data.specs[1])) - _chk1:SetText(name .. " " .. L.ShopSpecLabel) + _chk1:SetText(L.SpecsShort[data.specs[1]]) _chk1:SetVisible(true) _chk1:SetChecked(_specs[1]) end if data.specs[2] and data.specs[2] ~= 0 then - local id, name = GetSpecializationInfoByID(Amr.GetGameSpecId(data.specs[2])) - _chk2:SetText(name .. " " .. L.ShopSpecLabel) + _chk2:SetText(L.SpecsShort[data.specs[2]]) _chk2:SetVisible(true) _chk2:SetChecked(_specs[2]) end + if data.specs[3] and data.specs[3] ~= 0 then + _chk3:SetText(L.SpecsShort[data.specs[3]]) + _chk3:SetVisible(true) + _chk3:SetChecked(_specs[3]) + end + + if data.specs[4] and data.spes[4] ~= 0 then + _chk4:SetText(L.SpecsShort[data.specs[4]]) + _chk4:SetVisible(true) + _chk4:SetChecked(_specs[4]) + end + local spec = 0 - if not _specs[1] and not _specs[2] then - -- both unchecked, show nothing + if not _specs[1] and not _specs[2] and not _specs[3] and not _specs[4] then + -- all unchecked, show nothing else -- both is 0, otherwise the one that is selected if not _specs[1] or not _specs[2] then @@ -320,22 +353,31 @@ -- look at both gear sets and find stuff that a player needs to acquire to gem/enchant their gear function Amr:UpdateShoppingData(player) - -- 0 is combination of both specs, 1 is primary, 2 is secondary + -- TODO: re-enable shopping list when Legion comes out + do return end + + -- 0 is combination of all specs local required = { gems = { [0] = {}, [1] = {}, - [2] = {} + [2] = {}, + [3] = {}, + [4] = {} }, enchants = { [0] = {}, [1] = {}, - [2] = {} + [2] = {}, + [3] = {}, + [4] = {} }, materials = { [0] = {}, [1] = {}, - [2] = {} + [2] = {}, + [3] = {}, + [4] = {} }, specs = player.Specs } @@ -369,53 +411,56 @@ end -- now subtract stuff the player already has, and generate a list of materials as well - for spec = 0, 2 do - -- now check if the player has any of the gems or enchants in their inventory, and subtract those - for itemId, count in pairs(required.gems[spec]) do - required.gems[spec][itemId] = math.max(count - getOwnedCount(itemId), 0) - - if required.gems[spec][itemId] == 0 then - required.gems[spec][itemId] = nil - end - end - - for itemId, count in pairs(required.enchants[spec]) do - -- look in both spec extra info cache - local e = enchantItemIdToId[itemId] - local enchInfo = nil - if Amr.db.char.ExtraEnchantData[1] then - enchInfo = Amr.db.char.ExtraEnchantData[1][e] - end - if not enchInfo then - if Amr.db.char.ExtraEnchantData[2] then - enchInfo = Amr.db.char.ExtraEnchantData[2][e] + for spec = 0, 4 do + local specId = spec == 0 and 1 or GetSpecializationInfo(spec) + if specId then + -- now check if the player has any of the gems or enchants in their inventory, and subtract those + for itemId, count in pairs(required.gems[spec]) do + required.gems[spec][itemId] = math.max(count - getOwnedCount(itemId), 0) + + if required.gems[spec][itemId] == 0 then + required.gems[spec][itemId] = nil end end - if enchInfo then - required.enchants[spec][itemId] = math.max(count - getOwnedCount(itemId), 0) + for itemId, count in pairs(required.enchants[spec]) do + -- look in both spec extra info cache + local e = enchantItemIdToId[itemId] + local enchInfo = nil + if Amr.db.char.ExtraEnchantData[1] then + enchInfo = Amr.db.char.ExtraEnchantData[1][e] + end + if not enchInfo then + if Amr.db.char.ExtraEnchantData[2] then + enchInfo = Amr.db.char.ExtraEnchantData[2][e] + end + end + + if enchInfo then + required.enchants[spec][itemId] = math.max(count - getOwnedCount(itemId), 0) - if required.enchants[spec][itemId] == 0 then - required.enchants[spec][itemId] = nil - else - -- count up required materials - if enchInfo.materials then - local c = required.enchants[spec][itemId] - for k, v in pairs(enchInfo.materials) do - local prev = required.materials[spec][k] - required.materials[spec][k] = prev and prev + (v * c) or (v * c) + if required.enchants[spec][itemId] == 0 then + required.enchants[spec][itemId] = nil + else + -- count up required materials + if enchInfo.materials then + local c = required.enchants[spec][itemId] + for k, v in pairs(enchInfo.materials) do + local prev = required.materials[spec][k] + required.materials[spec][k] = prev and prev + (v * c) or (v * c) + end end - end - end - end - end - - -- check if player has any of the materials already - for itemId, count in pairs(required.materials[spec]) do - required.materials[spec][itemId] = math.max(count - getOwnedCount(itemId), 0) + end + end + end - if required.materials[spec][itemId] == 0 then - required.materials[spec][itemId] = nil + -- check if player has any of the materials already + for itemId, count in pairs(required.materials[spec]) do + required.materials[spec][itemId] = math.max(count - getOwnedCount(itemId), 0) + + if required.materials[spec][itemId] == 0 then + required.materials[spec][itemId] = nil + end end end end @@ -423,6 +468,8 @@ Amr.db.global.Shopping[player.Name .. "-" .. player.Realm] = required end +-- TODO: re-enable shopping list with Legion +--[[ Amr:AddEventHandler("AUCTION_HOUSE_SHOW", function() _isAhOpen = true if Amr.db.profile.options.shopAh then @@ -435,4 +482,5 @@ if Amr.db.profile.options.shopAh then Amr:HideShopWindow() end -end) \ No newline at end of file +end) +]] \ No newline at end of file diff -r 8f235b016212 -r 0515882856f1 localization/enUS.lua --- a/localization/enUS.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/localization/enUS.lua Tue Jul 19 10:05:32 2016 -0700 @@ -21,6 +21,45 @@ General ------------------------------------------------------------------------]] +L.SpecsShort = { + [1] = "Blood", -- DeathKnightBlood + [2] = "Frost", -- DeathKnightFrost + [3] = "Unholy", -- DeathKnightUnholy + [4] = "Havoc", -- DemonHunterHavoc + [5] = "Vengeance", -- DemonHunterVengeance + [6] = "Moon", -- DruidBalance + [7] = "Feral", -- DruidFeral + [8] = "Bear", -- DruidGuardian + [9] = "Resto", -- DruidRestoration + [10] = "BM", -- HunterBeastMastery + [11] = "Marks", -- HunterMarksmanship + [12] = "Survival", -- HunterSurvival + [13] = "Arcane", -- MageArcane + [14] = "Fire", -- MageFire + [15] = "Frost", -- MageFrost + [16] = "Brew", -- MonkBrewmaster + [17] = "Mist", -- MonkMistweaver + [18] = "Wind", -- MonkWindwalker + [19] = "Holy", -- PaladinHoly + [20] = "Prot", -- PaladinProtection + [21] = "Ret", -- PaladinRetribution + [22] = "Disc", -- PriestDiscipline + [23] = "Holy", -- PriestHoly + [24] = "Shadow", -- PriestShadow + [25] = "Assn", -- RogueAssassination + [26] = "Outlaw", -- RogueOutlaw + [27] = "Sub", -- RogueSubtlety + [28] = "Elem", -- ShamanElemental + [29] = "Enh", -- ShamanEnhancement + [30] = "Resto", -- ShamanRestoration + [31] = "Aff", -- WarlockAffliction + [32] = "Demo", -- WarlockDemonology + [33] = "Destro", -- WarlockDestruction + [34] = "Arms", -- WarriorArms + [35] = "Fury", -- WarriorFury + [36] = "Prot", -- WarriorProtection +} + -- stat strings for e.g. displaying gem/enchant abbreviations, make as short as possible without being confusing/ambiguous L.StatsShort = { ["Strength"] = "Str", @@ -80,7 +119,8 @@ Wand = "Wand", Bow = "Bow", Gun = "Gun", - Crossbow = "Crossbow" + Crossbow = "Crossbow", + Warglaive= "Warglaive" } L.ArmorTypes = { @@ -129,15 +169,15 @@ ------------------------------------------------------------------------]] L.ExportTitle = "Export Instructions" L.ExportHelp1 = "1. Copy the text below by pressing Ctrl+C (or Cmd+C on a Mac)" -L.ExportHelp2 = "2. Go to http://www.askmrrobot.com/wow/player and load your character" -L.ExportHelp3 = "3. Press the green IMPORT (from addon) link just above your character name" -L.ExportHelp4 = "4. Paste into the textbox on the website and press Import!" +L.ExportHelp2 = "2. Go to http://beta.askmrrobot.com/wow/simulator/run and open the character picker" +L.ExportHelp3 = "3. Paste into the textbox under the ADDON section" L.ExportSplashTitle = "Getting Started" L.ExportSplashSubtitle = "This is your first time using the new version of the addon. Do the following things to initialize your item database:" L.ExportSplash1 = "1. Activate each of your specs once and equip your latest gear for each spec" -L.ExportSplash2 = "2. Open your bank and leave it open for at least two seconds" -L.ExportSplash3 = "3. If you have gear in void storage, open it and leave it open for at least two seconds" +L.ExportSplash2 = "2. Equip and open your artifact weapon for each spec" +L.ExportSplash3 = "3. Open your bank and leave it open for at least two seconds" +L.ExportSplash4 = "4. If you have gear in void storage, open it and leave it open for at least two seconds" L.ExportSplashClose = "Continue" @@ -145,13 +185,10 @@ Gear Tab ------------------------------------------------------------------------]] L.GearImportNote = "Click Import to paste data from the website." -L.GearTabPrimary = "Primary Spec" -L.GearTabSecondary = "Secondary Spec" L.GearBlank = "You have not loaded any gear for this spec yet." L.GearBlank2 = "Go to askmrrobot.com to optimize your gear, then use the Import button to the left." L.GearButtonEquip = function(spec) - -- spec 1 is primary, 2 is secondary - return string.format("Activate %s Spec and Equip Gear", spec == 1 and "Primary" or "Secondary") + return string.format("Activate %s Spec and Equip Gear", spec) end L.GearButtonShop = "Show Shopping List" @@ -176,10 +213,8 @@ OR! You can use slash commands:]] L.GearTipCommands = -[[/amr equip [1 or 2] -1 = primary -2 = secondary -no arg = toggle]] +[[/amr equip [1-4] +no arg = cycle]] -- note to translators: the slash commands are literal and should stay as english diff -r 8f235b016212 -r 0515882856f1 localization/frFR.lua --- a/localization/frFR.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/localization/frFR.lua Tue Jul 19 10:05:32 2016 -0700 @@ -21,6 +21,45 @@ General ------------------------------------------------------------------------]] +L.SpecsShort = { + [1] = "Blood", -- DeathKnightBlood + [2] = "Frost", -- DeathKnightFrost + [3] = "Unholy", -- DeathKnightUnholy + [4] = "Havoc", -- DemonHunterHavoc + [5] = "Vengeance", -- DemonHunterVengeance + [6] = "Moon", -- DruidBalance + [7] = "Feral", -- DruidFeral + [8] = "Bear", -- DruidGuardian + [9] = "Resto", -- DruidRestoration + [10] = "BM", -- HunterBeastMastery + [11] = "Marks", -- HunterMarksmanship + [12] = "Survival", -- HunterSurvival + [13] = "Arcane", -- MageArcane + [14] = "Fire", -- MageFire + [15] = "Frost", -- MageFrost + [16] = "Brew", -- MonkBrewmaster + [17] = "Mist", -- MonkMistweaver + [18] = "Wind", -- MonkWindwalker + [19] = "Holy", -- PaladinHoly + [20] = "Prot", -- PaladinProtection + [21] = "Ret", -- PaladinRetribution + [22] = "Disc", -- PriestDiscipline + [23] = "Holy", -- PriestHoly + [24] = "Shadow", -- PriestShadow + [25] = "Assn", -- RogueAssassination + [26] = "Outlaw", -- RogueOutlaw + [27] = "Sub", -- RogueSubtlety + [28] = "Elem", -- ShamanElemental + [29] = "Enh", -- ShamanEnhancement + [30] = "Resto", -- ShamanRestoration + [31] = "Aff", -- WarlockAffliction + [32] = "Demo", -- WarlockDemonology + [33] = "Destro", -- WarlockDestruction + [34] = "Arms", -- WarriorArms + [35] = "Fury", -- WarriorFury + [36] = "Prot", -- WarriorProtection +} + -- stat strings for e.g. displaying gem/enchant abbreviations, make as short as possible without being confusing/ambiguous L.StatsShort = { ["Strength"] = "Str", @@ -145,13 +184,10 @@ Gear Tab ------------------------------------------------------------------------]] L.GearImportNote = "Clique Importer pour coller des données du site." -L.GearTabPrimary = "Spé primaire" -L.GearTabSecondary = "Spé secondaire" L.GearBlank = "Tu n'as pas encore chargé de stuff pour cette spé." L.GearBlank2 = "Va sur askmrrobot.com pour optimiser ton stuff. Ensuite, utilise le bouton Importer sur la gauche." L.GearButtonEquip = function(spec) - -- spec 1 is primary, 2 is secondary - return string.format("Activer la spé %s et équipper le stuff", spec == 1 and "Primaire" or "Secondaire") + return string.format("Activer la spé %s et équipper le stuff", spec) end L.GearButtonShop = "Voir Shopping List" @@ -176,10 +212,8 @@ OU! Tu peux utiliser des commandes /:]] L.GearTipCommands = -[[/amr equip [1 ou 2] -1 = spé primaire -2 = spé secondaire -pas d'argument = change de spé]] +[[/amr equip [1-4] +pas d'argument = cycle]] -- note to translators: the slash commands are literal and should stay as english diff -r 8f235b016212 -r 0515882856f1 localization/itIT.lua --- a/localization/itIT.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/localization/itIT.lua Tue Jul 19 10:05:32 2016 -0700 @@ -21,6 +21,45 @@ General ------------------------------------------------------------------------]] +L.SpecsShort = { + [1] = "Blood", -- DeathKnightBlood + [2] = "Frost", -- DeathKnightFrost + [3] = "Unholy", -- DeathKnightUnholy + [4] = "Havoc", -- DemonHunterHavoc + [5] = "Vengeance", -- DemonHunterVengeance + [6] = "Moon", -- DruidBalance + [7] = "Feral", -- DruidFeral + [8] = "Bear", -- DruidGuardian + [9] = "Resto", -- DruidRestoration + [10] = "BM", -- HunterBeastMastery + [11] = "Marks", -- HunterMarksmanship + [12] = "Survival", -- HunterSurvival + [13] = "Arcane", -- MageArcane + [14] = "Fire", -- MageFire + [15] = "Frost", -- MageFrost + [16] = "Brew", -- MonkBrewmaster + [17] = "Mist", -- MonkMistweaver + [18] = "Wind", -- MonkWindwalker + [19] = "Holy", -- PaladinHoly + [20] = "Prot", -- PaladinProtection + [21] = "Ret", -- PaladinRetribution + [22] = "Disc", -- PriestDiscipline + [23] = "Holy", -- PriestHoly + [24] = "Shadow", -- PriestShadow + [25] = "Assn", -- RogueAssassination + [26] = "Outlaw", -- RogueOutlaw + [27] = "Sub", -- RogueSubtlety + [28] = "Elem", -- ShamanElemental + [29] = "Enh", -- ShamanEnhancement + [30] = "Resto", -- ShamanRestoration + [31] = "Aff", -- WarlockAffliction + [32] = "Demo", -- WarlockDemonology + [33] = "Destro", -- WarlockDestruction + [34] = "Arms", -- WarriorArms + [35] = "Fury", -- WarriorFury + [36] = "Prot", -- WarriorProtection +} + -- stat strings for e.g. displaying gem/enchant abbreviations, make as short as possible without being confusing/ambiguous L.StatsShort = { ["Strength"] = "For", @@ -145,13 +184,10 @@ Gear Tab ------------------------------------------------------------------------]] L.GearImportNote = "Clicca Importa per importare i dati dal sito." -L.GearTabPrimary = "Spec Primaria" -L.GearTabSecondary = "Spec Secondaria" L.GearBlank = "Non hai caricato nessun equipaggiamento per questa specializzazione." L.GearBlank2 = "Vai su askmrrobot.com per ottimizzare l'equipaggiamento, quindi usa il pulsante Importa sulla sinistra." L.GearButtonEquip = function(spec) - -- spec 1 is primary, 2 is secondary - return string.format("Attiva %s Spec ed Equip", spec == 1 and "Primaria" or "Secondaria") + return string.format("Attiva %s Spec ed Equip", spec) end L.GearButtonShop = "Show Shopping List" @@ -176,10 +212,8 @@ Oppure! Puoi usare i seguenti comandi:]] L.GearTipCommands = -[[/amr equip [1 or 2] -1 = primary -2 = secondary -no arg = toggle]] +[[/amr equip [1-4] +no arg = cycle]] -- note to translators: the slash commands are literal and should stay as english diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiButton.lua --- a/ui/AmrUiButton.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiButton.lua Tue Jul 19 10:05:32 2016 -0700 @@ -50,8 +50,8 @@ -- color is an object with R, G, B ["SetBackgroundColor"] = function(self, color) - self.texNormal:SetTexture(color.R, color.G, color.B, 1) - self.texPush:SetTexture(color.R, color.G, color.B, 1) + self.texNormal:SetColorTexture(color.R, color.G, color.B, 1) + self.texPush:SetColorTexture(color.R, color.G, color.B, 1) end, ["SetDisabled"] = function(self, disabled) @@ -100,7 +100,7 @@ -- not perfect, but more or less achieves the effect of lightening the bg color slightly on hover local texHigh = frame:CreateTexture(nil, "BORDER") - texHigh:SetTexture(1, 1, 1, 0.1) + texHigh:SetColorTexture(1, 1, 1, 0.1) texHigh:SetAllPoints(true) frame:SetHighlightTexture(texHigh) diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiDropDown.lua --- a/ui/AmrUiDropDown.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiDropDown.lua Tue Jul 19 10:05:32 2016 -0700 @@ -137,7 +137,7 @@ -- not perfect, but more or less achieves the effect of lightening the bg color slightly on hover local texHigh = item:CreateTexture(nil, "BORDER") - texHigh:SetTexture(1, 1, 1, 0.1) + texHigh:SetColorTexture(1, 1, 1, 0.1) texHigh:SetAllPoints(true) item:SetHighlightTexture(texHigh) diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiFrame.lua --- a/ui/AmrUiFrame.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiFrame.lua Tue Jul 19 10:05:32 2016 -0700 @@ -95,11 +95,11 @@ -- color is an object with R, G, B ["SetBackgroundColor"] = function(self, color) - self.bg:SetTexture(color.R, color.G, color.B, 1) + self.bg:SetColorTexture(color.R, color.G, color.B, 1) end, ["SetBorderColor"] = function(self, color) - self.border:SetTexture(color.R, color.G, color.B, 1) + self.border:SetColorTexture(color.R, color.G, color.B, 1) end, ["Raise"] = function(self) diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiIcon.lua --- a/ui/AmrUiIcon.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiIcon.lua Tue Jul 19 10:05:32 2016 -0700 @@ -55,7 +55,7 @@ ["SetIcon"] = function(self, icon) if not icon then - self.icon:SetTexture(0, 0, 0, 0) + self.icon:SetColorTexture(0, 0, 0, 0) else self.icon:SetTexture(icon) end @@ -66,11 +66,11 @@ end, ["SetIconBorderColor"] = function(self, color, a) - self.bg:SetTexture(color.R, color.G, color.B, a or 1) + self.bg:SetColorTexture(color.R, color.G, color.B, a or 1) end, ["HideIconBorder"] = function(self) - self.bg:SetTexture(0, 0, 0, 0) + self.bg:SetColorTexture(0, 0, 0, 0) end, ["SetStrata"] = function(self, strata) @@ -108,25 +108,25 @@ icon:SetTexCoord(0.05, 0.95, 0.05, 0.95) local borderTop = frame:CreateTexture(nil, "ARTWORK", nil, 2) - borderTop:SetTexture(0, 0, 0, 1) + borderTop:SetColorTexture(0, 0, 0, 1) borderTop:SetHeight(1) borderTop:SetPoint("TOPLEFT", icon, "TOPLEFT") borderTop:SetPoint("TOPRIGHT", icon, "TOPRIGHT") local borderRight = frame:CreateTexture(nil, "ARTWORK", nil, 2) - borderRight:SetTexture(0, 0, 0, 1) + borderRight:SetColorTexture(0, 0, 0, 1) borderRight:SetWidth(1) borderRight:SetPoint("TOPRIGHT", icon, "TOPRIGHT") borderRight:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT") local borderBottom = frame:CreateTexture(nil, "ARTWORK", nil, 2) - borderBottom:SetTexture(0, 0, 0, 1) + borderBottom:SetColorTexture(0, 0, 0, 1) borderBottom:SetHeight(1) borderBottom:SetPoint("BOTTOMLEFT", icon, "BOTTOMLEFT") borderBottom:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT") local borderLeft = frame:CreateTexture(nil, "ARTWORK", nil, 2) - borderLeft:SetTexture(0, 0, 0, 1) + borderLeft:SetColorTexture(0, 0, 0, 1) borderLeft:SetWidth(1) borderLeft:SetPoint("TOPLEFT", icon, "TOPLEFT") borderLeft:SetPoint("BOTTOMLEFT", icon, "BOTTOMLEFT") diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiPanel.lua --- a/ui/AmrUiPanel.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiPanel.lua Tue Jul 19 10:05:32 2016 -0700 @@ -34,7 +34,7 @@ end, ["SetBackgroundColor"] = function(self, color, a) - self.bg:SetTexture(color.R, color.G, color.B, a or 1) + self.bg:SetColorTexture(color.R, color.G, color.B, a or 1) end, -- set a transparent bg to make this panel invisible diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiScrollFrame.lua --- a/ui/AmrUiScrollFrame.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiScrollFrame.lua Tue Jul 19 10:05:32 2016 -0700 @@ -230,7 +230,7 @@ local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND") scrollbg:SetPoint("TOPLEFT", scrollbar, "TOPLEFT", 0, 16) scrollbg:SetPoint("BOTTOMRIGHT", scrollbar, "BOTTOMRIGHT", 0, -16) - scrollbg:SetTexture(0, 0, 0, 0.3) + scrollbg:SetColorTexture(0, 0, 0, 0.3) --Container Support local content = CreateFrame("Frame", nil, scrollframe) diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiTabGroup.lua --- a/ui/AmrUiTabGroup.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiTabGroup.lua Tue Jul 19 10:05:32 2016 -0700 @@ -237,7 +237,7 @@ local line = border:CreateTexture(nil, "ARTWORK") line:Hide() - line:SetTexture(1, 1, 1, 1) + line:SetColorTexture(1, 1, 1, 1) line:SetHeight(4) local content = CreateFrame("Frame", nil, border) diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiTextButton.lua --- a/ui/AmrUiTextButton.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiTextButton.lua Tue Jul 19 10:05:32 2016 -0700 @@ -78,7 +78,7 @@ end, ["SetBackgroundColor"] = function(self, color, alpha) - self.bg:SetTexture(color.R, color.G, color.B, alpha) + self.bg:SetColorTexture(color.R, color.G, color.B, alpha) end, ["SetBackgroundImage"] = function(self, image) @@ -87,7 +87,7 @@ end, ["SetHoverBackgroundColor"] = function(self, color, alpha) - self.hover:SetTexture(color.R, color.G, color.B, alpha) + self.hover:SetColorTexture(color.R, color.G, color.B, alpha) end, ["SetHoverBackgroundImage"] = function(self, image) diff -r 8f235b016212 -r 0515882856f1 ui/AmrUiTextarea.lua --- a/ui/AmrUiTextarea.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/AmrUiTextarea.lua Tue Jul 19 10:05:32 2016 -0700 @@ -186,11 +186,11 @@ frame:SetScrollChild(editbox) local border = frame:CreateTexture(nil, "BACKGROUND") - border:SetTexture(Amr.Colors.BorderGray.R, Amr.Colors.BorderGray.G, Amr.Colors.BorderGray.B, 1) + border:SetColorTexture(Amr.Colors.BorderGray.R, Amr.Colors.BorderGray.G, Amr.Colors.BorderGray.B, 1) border:SetAllPoints(true) local bg = frame:CreateTexture(nil, "BORDER") - bg:SetTexture(Amr.Colors.BgInput.R, Amr.Colors.BgInput.G, Amr.Colors.BgInput.B, 1) + bg:SetColorTexture(Amr.Colors.BgInput.R, Amr.Colors.BgInput.G, Amr.Colors.BgInput.B, 1) bg:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1) bg:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1) diff -r 8f235b016212 -r 0515882856f1 ui/Ui.lua --- a/ui/Ui.lua Tue Apr 05 16:19:31 2016 -0700 +++ b/ui/Ui.lua Tue Jul 19 10:05:32 2016 -0700 @@ -87,24 +87,24 @@ -- helper to create a solid texture from a color with R,G,B properties function Amr.CreateTexture(parent, color, alpha, layer) local t = parent:CreateTexture(nil, layer or "ARTWORK") - t:SetTexture(color.R, color.G, color.B, alpha or 1) + t:SetColorTexture(color.R, color.G, color.B, alpha or 1) return t end -- helper to create a cheater shadow without having to create custom images function Amr.DropShadow(frame) local shadow = frame:CreateTexture(nil, "BACKGROUND") - shadow:SetTexture(0, 0, 0, 0.4) + shadow:SetColorTexture(0, 0, 0, 0.4) shadow:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) shadow:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 1, -1) shadow = frame:CreateTexture(nil, "BACKGROUND") - shadow:SetTexture(0, 0, 0, 0.3) + shadow:SetColorTexture(0, 0, 0, 0.3) shadow:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) shadow:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 2, -2) shadow = frame:CreateTexture(nil, "BACKGROUND") - shadow:SetTexture(0, 0, 0, 0.1) + shadow:SetColorTexture(0, 0, 0, 0.1) shadow:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) shadow:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 3, -3) end