diff --git a/QuickTrade/QuickTrade.lua b/QuickTrade/QuickTrade.lua index 85aa196..8a5fdbf 100644 --- a/QuickTrade/QuickTrade.lua +++ b/QuickTrade/QuickTrade.lua @@ -1,3 +1,4 @@ +<<<<<<< HEAD --[[ This is free and unencumbered software released into the public domain. @@ -532,4 +533,496 @@ windower.register_event('incoming text', function(original, modified, mode) end return modified +======= +--[[ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +]] + +_addon.name = 'QuickTrade' +_addon.author = 'Valok@Asura' +_addon.version = '1.4.0' +_addon.command = 'qtr' + +require('tables') +require('coroutine') + +exampleOnly = false +textSkipTimer = 1 +lastNPC = '' + +windower.register_event('addon command', function(arg1, ...) + -- Table of the tradeable itemIDs that may be found in the player inventory + local crystalIDs = { + {id = 4096, name = 'fire crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4097, name = 'ice crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4098, name = 'wind crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4099, name = 'earth crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4100, name = 'lightning crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4101, name = 'water crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4102, name = 'light crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4103, name = 'dark crystal', count = 0, stacks = 0, stacksize = 12}, + {id = 4104, name = 'fire cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4105, name = 'ice cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4106, name = 'wind cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4107, name = 'earth cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4108, name = 'lightning cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4109, name = 'water cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4110, name = 'light cluster', count = 0, stacks = 0, stacksize = 12}, + {id = 4111, name = 'dark cluster', count = 0, stacks = 0, stacksize = 12}, + } + + local sealIDs = { + {id = 1126, name = "beastmen's seal", count = 0, stacks = 0, stacksize = 99}, + {id = 1127, name = "kindred's seal", count = 0, stacks = 0, stacksize = 99}, + {id = 2955, name = "kindred's crest", count = 0, stacks = 0, stacksize = 99}, + {id = 2956, name = "high kindred's crest", count = 0, stacks = 0, stacksize = 99}, + {id = 2957, name = "sacred kindred's crest", count = 0, stacks = 0, stacksize = 99}, + } + + local moatCarpIDs = { + {id = 4401, name = 'moat carp', count = 0, stacks = 0, stacksize = 12}, + } + + local copperVoucherIDs = { + {id = 8711, name = 'copper voucher', count = 0, stacks = 0, stacksize = 99}, + } + + local remsTaleIDs = { + {id = 4064, name = "copy of rem's tale, chapter 1", count = 0, stacks = 0, stacksize = 12}, + {id = 4065, name = "copy of rem's tale, chapter 2", count = 0, stacks = 0, stacksize = 12}, + {id = 4066, name = "copy of rem's tale, chapter 3", count = 0, stacks = 0, stacksize = 12}, + {id = 4067, name = "copy of rem's tale, chapter 4", count = 0, stacks = 0, stacksize = 12}, + {id = 4068, name = "copy of rem's tale, chapter 5", count = 0, stacks = 0, stacksize = 12}, + {id = 4069, name = "copy of rem's tale, chapter 6", count = 0, stacks = 0, stacksize = 12}, + {id = 4070, name = "copy of rem's tale, chapter 7", count = 0, stacks = 0, stacksize = 12}, + {id = 4071, name = "copy of rem's tale, chapter 8", count = 0, stacks = 0, stacksize = 12}, + {id = 4072, name = "copy of rem's tale, chapter 9", count = 0, stacks = 0, stacksize = 12}, + {id = 4073, name = "copy of rem's tale, chapter 10", count = 0, stacks = 0, stacksize = 12}, + } + + local mellidoptWingIDs = { + {id = 9050, name = 'mellidopt wing', count = 0, stacks = 0, stacksize = 12}, + } + + local salvagePlanIDs = { + {id = 3880, name = 'copy of bloodshed plans', count = 0, stacks = 0, stacksize = 99}, + {id = 3881, name = 'copy of umbrage plans', count = 0, stacks = 0, stacksize = 99}, + {id = 3882, name = 'copy of ritualistic plans' , count = 0, stacks = 0, stacksize = 99}, + } + + local alexandriteIDs = { + {id = 2488, name = 'alexandrite', count = 0, stacks = 0, stacksize = 99}, + } + + local spGobbieKeyIDs = { + {id = 8973, name = 'special gobbiedial key', count = 0, stacks = 0, stacksize = 99}, + } + + local zincOreIDs = { + {id = 642, name = 'zinc ore', count = 0, stacks = 0, stacksize = 12}, + } + + local yagudoNecklaceIDs = { + {id = 498, name = 'yagudo necklace', count = 0, stacks = 0, stacksize = 12}, + } + + local mandragoraMadIDs = { + {id = 17344, name = 'cornette', count = 0, stacks = 0, stacksize = 1}, + {id = 4369, name = 'four-leaf mandragora bud', count = 0, stacks = 0, stacksize = 1}, + {id = 1150, name = 'snobby letter', count = 0, stacks = 0, stacksize = 1}, + {id = 1154, name = 'three-leaf mandragora bud', count = 0, stacks = 0, stacksize = 1}, + {id = 934, name = 'pinch of yuhtunga sulfur', count = 0, stacks = 0, stacksize = 1}, + } + + local onlyTheBestIDs = { + {id = 4366, name = 'la theine cabbage', count = 0, stacks = 0, stacksize = 12}, + {id = 629, name = 'millioncorn', count = 0, stacks = 0, stacksize = 12}, + {id = 919, name = 'boyahda moss', count = 0, stacks = 0, stacksize = 12}, + } + + local soulPlateIDs = { + {id = 2477, name = 'soul plate', count = 0, stacks = 0, stacksize = 1}, -- Can only trade 10 per Vana'diel day + } + + local jseCapeIDs = { + {id = 28617, name = "mauler's mantle", count = 0, stacks = 0, stacksize = 1}, + {id = 28618, name = "anchoret's mantle", count = 0, stacks = 0, stacksize = 1}, + {id = 28619, name = 'mending cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28620, name = 'bane cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28621, name = 'ghostfyre cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28622, name = 'canny cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28623, name = 'weard mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28624, name = 'niht mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28625, name = "pastoralist's mantle", count = 0, stacks = 0, stacksize = 1}, + {id = 28626, name = "rhapsode's cape", count = 0, stacks = 0, stacksize = 1}, + {id = 28627, name = 'lutian cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28628, name = 'takaha mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28629, name = 'yokaze mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28630, name = 'updraft mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28631, name = 'conveyance cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28632, name = 'cornflower cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28633, name = "gunslinger's cape", count = 0, stacks = 0, stacksize = 1}, + {id = 28634, name = 'dispersal mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28635, name = 'toetapper mantle', count = 0, stacks = 0, stacksize = 1}, + {id = 28636, name = "bookworm's cape", count = 0, stacks = 0, stacksize = 1}, + {id = 28637, name = 'lifestream cape', count = 0, stacks = 0, stacksize = 1}, + {id = 28638, name = "evasionist's cape", count = 0, stacks = 0, stacksize = 1}, + } + + local npcTable = { + {name = 'Shami', idTable = sealIDs, tableType = 'Seals'}, + {name = 'Ephemeral Moogle', idTable = crystalIDs, tableType = 'Crystals'}, + {name = 'Waypoint', idTable = crystalIDs, tableType = 'Crystals'}, + {name = 'Joulet', idTable = moatCarpIDs, tableType = 'Moat Carp'}, + {name = 'Gallijaux', idTable = moatCarpIDs, tableType = 'Moat Carp'}, + {name = 'Isakoth', idTable = copperVoucherIDs, tableType = 'Copper Vouchers'}, + {name = 'Rolandienne', idTable = copperVoucherIDs, tableType = 'Copper Vouchers'}, + {name = 'Fhelm Jobeizat', idTable = copperVoucherIDs, tableType = 'Copper Vouchers'}, + {name = 'Eternal Flame', idTable = copperVoucherIDs, tableType = 'Copper Vouchers'}, + {name = 'Monisette', idTable = remsTaleIDs, tableType = "Rem's Tales"}, + {name = '???', idTable = mellidoptWingIDs, tableType = 'Mellidopt Wings'}, + {name = 'Mrohk Sahjuuli', idTable = salvagePlanIDs, tableType = 'Salvage Plans'}, + {name = 'Paparoon', idTable = alexandriteIDs, tableType = 'Alexandrite'}, + {name = 'Mystrix', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Habitox', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Bountibox', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Specilox', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Arbitrix', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Funtrox', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Priztrix', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Sweepstox', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Wondrix', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Rewardox', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Winrix', idTable = spGobbieKeyIDs, tableType = 'Special Gobbiedial Keys'}, + {name = 'Talib', idTable = zincOreIDs, tableType = 'Zinc Ore'}, + {name = 'Nanaa Mihgo', idTable = yagudoNecklaceIDs, tableType = 'Yagudo Necklaces'}, + {name = 'Yoran-Oran', idTable = mandragoraMadIDs, tableType = 'Mandragora Mad Items'}, + {name = 'Melyon', idTable = onlyTheBestIDs, tableType = 'Only the Best Items'}, + {name = 'Sanraku', idTable = soulPlateIDs, tableType = 'Soul Plates'}, + {name = 'A.M.A.N. Reclaimer', idTable = jseCapeIDs, tableType = 'JSE Capes'}, + {name = 'Makel-Pakel', idTable = jseCapeIDs, tableType = 'JSE Capes x3'}, + } + + local idTable = {} + local tableType = '' + local target = windower.ffxi.get_mob_by_target('t') + + if not target then + windower.send_command('input /targetnpc') + coroutine.sleep(0.4) + target = windower.ffxi.get_mob_by_target('t') + + if not target then + print('QuickTrade: No target selected') + return + end + end + + for i = 1, #npcTable do + if target.name == npcTable[i].name then + idTable = npcTable[i].idTable + tableType = npcTable[i].tableType + break + end + end + + + + -- FOR TESTING WITHOUT NPC PRESENT!!!!!!!!!!!!! + --idTable = table.copy(alexandriteIDs) + --tableType = 'Alexandrite' + --exampleOnly = true + + + + if #idTable == 0 or tableType == '' then + print('QuickTrade: Invalid target') + lastNPC = '' + return + end + + mogSackTable = table.copy(idTable) + mogCaseTable = table.copy(idTable) + + -- Scan the mog sack for each item in idTable + local mogSack = windower.ffxi.get_items('sack') + if not mogSack then + print('mogSack read error') + else + for i = 1, #mogSackTable do + for k, v in ipairs(mogSack) do + if v.id == mogSackTable[i].id then + mogSackTable[i].count = mogSackTable[i].count + v.count -- Updates the total number of items of each type + mogSackTable[i].stacks = mogSackTable[i].stacks + 1 -- Updates the total number of stacks of each type + end + end + end + end + + -- Scan the mog case for each item in idTable + local mogCase = windower.ffxi.get_items('case') + if not mogCase then + print('mogCase read error') + else + for i = 1, #mogCaseTable do + for k, v in ipairs(mogCase) do + if v.id == mogCaseTable[i].id then + mogCaseTable[i].count = mogCaseTable[i].count + v.count -- Updates the total number of items of each type + mogCaseTable[i].stacks = mogCaseTable[i].stacks + 1 -- Updates the total number of stacks of each type + end + end + end + end + + -- Uses the Itemizer addon to move tradable items from the mog case/sack into the player's inventory + if arg1 == 'all' and mogCase and mogSack then + inventory = windower.ffxi.get_items('inventory') + for i = 1, #idTable do + for k, v in ipairs(inventory) do + if v.id == idTable[i].id then + idTable[i].count = idTable[i].count + v.count -- Updates the total number of items of each type + idTable[i].stacks = idTable[i].stacks + 1 -- Updates the total number of stacks of each type + end + end + end + + for i = 1, #mogSackTable do + if mogSackTable[i].count + mogCaseTable[i].count > 0 then + if exampleOnly then + print('//get "'..mogSackTable[i].name.. '" '..idTable[i].count + mogSackTable[i].count + mogCaseTable[i].count) + else + windower.add_to_chat(8, 'QuickTrade: Please wait - Using Itemizer to transfer '..mogSackTable[i].count + mogCaseTable[i].count..' '..mogSackTable[i].name..' to inventory') + windower.send_command('input //get "'..mogSackTable[i].name.. '" '..idTable[i].count + mogSackTable[i].count + mogCaseTable[i].count) + coroutine.sleep(2.5) + end + end + end + + for i = 1, #idTable do + idTable[i].count = 0 + idTable[i].stacks = 0 + end + else + if target.name ~= lastNPC then + lastNPC = target.name + local mogCount = 0 + + for i = 1, #mogSackTable do + mogCount = mogCount + mogSackTable[i].count + mogCaseTable[i].count + end + + if mogCount > 0 then + windower.add_to_chat(8, 'QuickTrade: '..mogCount..' of these items are in your mog sack/case. Type "//qtr all" if you wish to move them into your inventory and trade them. Requires Itemizer') + end + end + end + + -- Read the player inventory + inventory = windower.ffxi.get_items('inventory') + + if not inventory then + print('QuickTrade: Unable to read inventory') + return + end + + -- Scan the inventory for each item in idTable + for i = 1, #idTable do + for k, v in ipairs(inventory) do + if v.id == idTable[i].id then + idTable[i].count = idTable[i].count + v.count -- Updates the total number of items of each type + idTable[i].stacks = idTable[i].stacks + 1 -- Updates the total number of stacks of each type + end + end + end + + + + local numTrades = 0 -- Number of times //qtr needs to be run to empty the player inventory + local availableTradeSlots = 8 + + if tableType == 'Crystals' then + for i = 1, 8 do + if idTable[i].stacks > 0 or idTable[i + 8].stacks > 0 then + numTrades = numTrades + math.ceil((idTable[i].stacks + idTable[i + 8].stacks) / 8) + end + end + elseif tableType == 'Zinc Ore' or tableType == 'Yagudo Necklaces' then -- 4 at a time + numTrades = math.floor(idTable[1].count / 4) + elseif tableType == 'Mandragora Mad Items' or tableType == 'JSE Capes' then -- 1 at a time + for i = 1, #idTable do + numTrades = numTrades + idTable[i].count + end + elseif tableType == 'JSE Capes x3' then -- 3 of the same kind + for i = 1, #idTable do + if idTable[i].count >= 3 then + numTrades = numTrades + math.min(1, math.floor(idTable[i].count / 3)) + end + end + elseif tableType == 'Only the Best Items' then -- Unique for this quest + numTrades = numTrades + math.floor(idTable[1].count / 5) + numTrades = numTrades + math.floor(idTable[2].count / 3) + numTrades = numTrades + idTable[3].count + elseif tableType == 'Special Gobbiedial Keys' or tableType == 'Soul Plates' then + numTrades = idTable[1].count + else + for i = 1, #idTable do + if idTable[i].stacks > 0 then + numTrades = numTrades + math.ceil(idTable[i].stacks / 8) + end + end + end + + if exampleOnly then + print(numTrades..' total trades') + end + + -- Prepare and send command through TradeNPC if there are trades to be made + if numTrades > 0 then + local tradeString = '//tradenpc ' + availableTradeSlots = 8 + + if tableType == 'Crystals' then + for i = 1, 8 do + -- Build the string that will be used as the command + tradeString = '//tradenpc ' + availableTradeSlots = 8 + + if idTable[i].count > 0 then + tradeString = tradeString..math.min(availableTradeSlots * idTable[i].stacksize, idTable[i].count)..' "'..idTable[i].name..'"' + availableTradeSlots = math.max(0, availableTradeSlots - idTable[i].stacks) + end + + if availableTradeSlots > 0 and idTable[i + 8].count > 0 then + tradeString = tradeString..' '..math.min(availableTradeSlots * idTable[i + 8].stacksize, idTable[i + 8].count)..' "'..idTable[i + 8].name..'"' + end + + if idTable[i].count > 0 or idTable[i + 8].count > 0 then + break + end + end + elseif tableType == 'Special Gobbiedial Keys' or tableType == 'Soul Plates' then -- 1 item at a time + tradeString = '//tradenpc 1 "'..idTable[1].name..'"' + elseif tableType == 'Zinc Ore' or tableType == 'Yagudo Necklaces' then -- 4 items at a time + if idTable[1].count >= 4 then + tradeString = '//tradenpc 4 "'..idTable[1].name..'"' + end + elseif tableType == 'Mandragora Mad Items' or tableType == 'JSE Capes' then + for i = 1, #idTable do + tradeString = '//tradenpc ' + + if idTable[i].count > 0 then + tradeString = tradeString..'1 "'..idTable[i].name..'"' + break + end + end + elseif tableType == 'JSE Capes x3' then + for i = 1, #idTable do + tradeString = '//tradenpc ' + + if idTable[i].count >= 3 then + tradeString = tradeString..'3 "'..idTable[i].name..'"' + break + end + end + elseif tableType == 'Only the Best Items' then + for i = 1, #idTable do + tradeString = '//tradenpc ' + + if idTable[1].count >= 5 then + tradeString = tradeString..'5 "'..idTable[1].name..'"' + break + end + + if idTable[2].count >= 3 then + tradeString = tradeString..'3 "'..idTable[2].name..'"' + break + end + + if idTable[3].count > 0 then + tradeString = tradeString..'1 "'..idTable[3].name..'"' + break + end + end + else + for i = 1, #idTable do + tradeString = '//tradenpc ' + availableTradeSlots = 8 + + if idTable[i].count > 0 then + availableTradeSlots = math.max(1, availableTradeSlots - idTable[i].stacks) + tradeString = tradeString..math.min(availableTradeSlots * idTable[i].stacksize, idTable[i].count)..' "'..idTable[i].name..'"' + break + end + end + end + + if tradeString ~= '//tradenpc ' then + if numTrades - 1 == 0 then + windower.add_to_chat(8, 'QuickTrade: Trading Complete') + elseif numTrades - 1 == 1 then + windower.add_to_chat(8, 'QuickTrade: '..(numTrades - 1)..' trade remaining') + else + windower.add_to_chat(8, 'QuickTrade: '..(numTrades - 1)..' trades remaining') + end + + if exampleOnly then + print(tradeString) + else + if tableType ~= 'JSE Capes' and tableType ~= 'JSE Capes x3' then + textSkipTimer = os.time() + end + + windower.send_command('input '..tradeString) + end + end + else + if arg1 == 'all' then + windower.add_to_chat(8, "QuickTrade - No "..tableType.." in inventory, mog case, or mog sack") + else + windower.add_to_chat(8, "QuickTrade - No "..tableType.." in inventory") + end + end +end) + +windower.register_event('incoming text', function(original, modified, mode) + -- Allow the addon to skip the conversation text for up to 10 seconds after the trade + if os.time() - textSkipTimer > 10 then + return + end + + local target = windower.ffxi.get_mob_by_target('t') + + if not target then + return false + end + + if mode == 150 or mode == 151 then + modified = modified:gsub(string.char(0x7F, 0x31), '') + end + + return modified +>>>>>>> c9035841f1e3eb1461c46cdd123f383fc12b8df4 end) \ No newline at end of file diff --git a/QuickTrade/readme.md b/QuickTrade/readme.md index 19ef08d..2b88722 100644 --- a/QuickTrade/readme.md +++ b/QuickTrade/readme.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD IMPORTANT --------- @@ -122,4 +123,119 @@ v1.1.0 v1.0.0 2018.07.16 +======= +IMPORTANT +--------- + +This addon requires the addon "TradeNPC" to be installed and loaded before use. +TradeNPC can be found here: https://github.com/Ivaar/Windower-addons + +The addon Itemizer is required if you would like to use the command '//qtr all' to also trade items that are in your Mog Sack or Mog Case. +Itemizer can be downloaded from the Windower launcher or found here: http://docs.windower.net/addons/itemizer/ + + +What does this addon do? +------------------------ + +Example Video: https://youtu.be/TVFWjjP_Dh0 + +QuickTrade searches your inventory for items that are tradeable or storable with certain NPCs, then sends a command to be used by TradeNPC. +This allows you to automatically trade multiple stacks of items repeatedly with a command instead of using the much slower trade menu. +QuickTrade will inform you of how many times you need to enter //qtr in order to complete all available trades. +For up to 10 seconds after the trade is complete, it will skip any conversations with the NPC. + +Valid trades are as follow: + +* Elemental Crystals and Clusters: Trade with Ephemeral Moogles for storage or with Waypoints to accumulate Kinetic Units. +* Seals and Crests: Trade with Shami in Port Jeuno to store your various seals and crests. +* Moat Carp: Trade with Joulet or Gallijaux in Port San d'Oria for the Lu Shang's Rod quest. +* Copper Vouchers: Trade with Isakoth, Rolandienne, Fhelm Jobeizat, or Eternal Flame to store your vouchers. +* Rem's Tale Chapters: Trade with Monisette in Port Jeuno to store your chapters. +* UNTESTED - Mellidopt Wings: Trade with the ??? in Yorcia Weald +* UNTESTED - Salvage Plans: Trade with Mrohk Sahjuuli in Aht Urhgan Whitegate to store your plans. +* Alexandrite: Trade with Paparoon in Nashmau for the quest 'Duties, Tasks, and Deeds.' +* Special Gobbie Keys: Trade with one of the various goblins throughout Vana'diel. +* Zinc Ore: Trade with Talib in Port Bastok for the repeatable quest 'Shady Business.' +* Yagudo Necklaces: Trade with Nanaa Mihgo in Windurst Woods for the repeeatable quest 'Mihgo's Amigo.' +* Cornettes: Trade with Yoran-Oran in Windurst Walls for the repeatable quest 'Manragora-Mad.' + * The other 4 items that Yoran-Oran accepts are also supported. +* La Theine Cabbage, Millioncorn, Boyahda Moss: Trade with Melyon in Selbina for the repeatable quest 'Only the Best.' +* UNTESTED - Soul Plates: Trade with Sanraku in Aht Urhgan Whitegate in exchange for Zeni. + * Currently set to trade only 1 at a time. This can be changed if needed. +* JSE Capes: Trade with an A.M.A.N. Reclaimer to trade a single cape, or trade with Makel-Pakel in the Celennia Memorial Library to trade 3 of the same cape. + * Currently set to NOT skip dialogue when trading JSE capes. Make sure your inventory does not have any capes that you want to keep. + + + +Example +------- + +You have 3 stacks of Fire Crystals, 1 stack of Ice Crystals, and 2 Fire Clusters in your inventory that you would like to store. +Travel to and target one of the Ephemeral Moogles or Waypoints you would like to trade to. +In the chat window, enter '//qtr' without the quotes and press enter, or enter 'qtr' in the console. +The addon will cause TradeNPC to instantly trade all 3 stacks of Fire Crystals and the 2 Fire Clusters with one command. +After waiting a few seconds, target the moogle or Waypoint again and re-enter the command. +The addon will then cause TradeNPC to instantly trade the stack of Ice Crystals. +If you run the command again, you will be informed that you have no more items to trade. + +The behavior is similiar when trading other valid items with valid NPCs. + +You will need to enter the command once for each crystal element or item type you possess in your inventory. +This seems to be a game limitation since most NPCs accept only one type of item at a time. + +If you have the Itemizer addon and would like to also trade any valid items that you may have in your Mog Case or Mog Sack, +enter the command '//qtr all'. This will allow QuickTrade to search your other valid storage areas and use Itemizer to move the items +into your inventory automatically. + +If you wish to test this addon before having it perform a trade, you may edit line 36 in the QuickTrade.lua file. + +Change + exampleOnly = false +to + exampleOnly = true + +This will cause the addon to print the command to be issued in the windower console. +When you are ready to allow the addon to trade for you, change the 'true' back to 'false'. + + +Installation +------------ + +Browse to your Windower\addons folder and create a new folder inside called "QuickTrade" +Place QuickTrade.lua in this new folder. +Load the addon by accessing the console from within FFXI and typing 'lua l QuickTrade' + +If you want this addon to be loaded automatically every time you launch the game, +add 'lua l QuickTrade' to the bottom of the file "Windower\scripts\init.txt" + +I would also recommend having the addons TradeNPC and Itemizer load automatically by adding +'lua l TradeNPC' and 'lua l itemizer' to your init.txt. + +If TradeNPC is not loaded when using this addon, the trade command will be issued but nothing will happen. + + + +Version History +--------------- +v1.4.0 +2018.08.11 +* Added functionality '//qtr all' to use the Itemizer addon to include items in your Mog Case and Mog Sack +* QuickTrade will target the nearest NPC automatically if you run the command without a target + +v1.3.0 +2018.07.21 +* Added JSE Capes: 1x to the A.M.A.N. Reclaimers, 3x to Makel-Pakel + +v1.2.0 +2018.07.20 +* Added Zinc Ore, Yagudo Necklaces, Mandragora-Mad items, Only the Best items, and Soul Plates + +v1.1.0 +2018.07.20 +* Bugfix - Alexandrite should be detected properly +* Added Special Gobbiedial Keys + +v1.0.0 +2018.07.16 +>>>>>>> c9035841f1e3eb1461c46cdd123f383fc12b8df4 * Initial Release \ No newline at end of file