summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/itemizer
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/itemizer')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/itemizer/itemizer.lua380
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/itemizer/readme.md64
2 files changed, 444 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/itemizer/itemizer.lua b/Data/BuiltIn/Libraries/lua-addons/addons/itemizer/itemizer.lua
new file mode 100644
index 0000000..5074ee9
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/itemizer/itemizer.lua
@@ -0,0 +1,380 @@
+_addon.name = 'Itemizer'
+_addon.author = 'Ihina'
+_addon.version = '3.0.1.3'
+_addon.command = 'itemizer'
+
+require('luau')
+
+defaults = {}
+defaults.AutoNinjaTools = true
+defaults.AutoItems = true
+defaults.Delay = 0.5
+defaults.version = "3.0.1.1"
+defaults.UseUniversalTools = {}
+
+defaults.UseUniversalTools.Katon = false
+defaults.UseUniversalTools.Hyoton = false
+defaults.UseUniversalTools.Huton = false
+defaults.UseUniversalTools.Doton = false
+defaults.UseUniversalTools.Raiton = false
+defaults.UseUniversalTools.Suiton = false
+defaults.UseUniversalTools.Utsusemi = false
+defaults.UseUniversalTools.Jubaku = false
+defaults.UseUniversalTools.Hojo = false
+defaults.UseUniversalTools.Kurayami = false
+defaults.UseUniversalTools.Dokumori = false
+defaults.UseUniversalTools.Tonko = false
+defaults.UseUniversalTools.Monomi = false
+defaults.UseUniversalTools.Aisha = false
+defaults.UseUniversalTools.Yurin = false
+defaults.UseUniversalTools.Myoshu = false
+defaults.UseUniversalTools.Migawari = false
+defaults.UseUniversalTools.Kakka = false
+defaults.UseUniversalTools.Gekka = false
+defaults.UseUniversalTools.Yain = false
+
+settings = config.load(defaults)
+bag_ids = res.bags:key_map(string.gsub-{' ', ''} .. string.lower .. table.get-{'english'} .. table.get+{res.bags}):map(table.get-{'id'})
+-- Remove temporary bag, because items cannot be moved from/to there, as such it's irrelevant to Itemizer
+bag_ids.temporary = nil
+
+--Added this function for first load on new version. Because of the newly added features that weren't there before.
+windower.register_event("load", function()
+ if settings.version == "3.0.1.1" then
+ windower.add_to_chat(207,"Itemizer v3.0.1.2: New features added. (use //itemizer help to find out about them)")
+ settings.version = "3.0.1.2"
+ settings:save()
+ end
+end)
+
+find_items = function(ids, bag, limit)
+ local res = S{}
+ local found = 0
+
+ for bag_index, bag_name in bag_ids:filter(table.get-{'enabled'} .. windower.ffxi.get_bag_info):it() do
+ if not bag or bag_index == bag then
+ for _, item in ipairs(windower.ffxi.get_items(bag_index)) do
+ if ids:contains(item.id) then
+ local count = limit and math.min(limit, item.count) or item.count
+ found = found + count
+
+ res:add({
+ bag = bag_index,
+ slot = item.slot,
+ count = count,
+ })
+
+ if limit then
+ limit = limit - count
+
+ if limit == 0 then
+ return res, found
+ end
+ end
+ end
+ end
+ end
+ end
+
+ return res, found
+end
+
+windower.register_event("addon command", function(command, arg2, ...)
+ if command == 'help' then
+ local helptext = [[Itemizer - Command List:')
+ 1. Delay <delay> - Sets the time delay.
+ 2. Autoninjatools - toggles Automatically getting ninja tools (Shortened ant)
+ 3. Autoitems - Toggles automatically getting items from bags (shortened ai)
+ 4. Useuniversaltool <spell> - toggles using universal ninja tools for <spell> (shortened uut)
+ i.e. uut katon - will toggle katon either true or false depending on your setting
+ all defaulted false.
+ 5. help --Shows this menu.]]
+ for _, line in ipairs(helptext:split('\n')) do
+ windower.add_to_chat(207, line)
+ end
+ elseif command:lower() == "delay" and arg2 ~= nil then
+ if type(arg2) == 'number' then
+ settings.delay = arg2
+ settings:save()
+ else
+ error('The delay must be a number')
+ end
+ elseif T{'autoninjatools','ant'}:contains(command:lower()) then
+ settings.AutoNinjaTools = not settings.AutoNinjaTools
+ settings:save()
+ elseif T{'autoitems','ai'}:contains(command:lower()) then
+ settings.AutoItems = not settings.AutoItems
+ settings:save()
+ elseif T{'useuniversaltool','uut'}:contains(command:lower()) then
+ if settings.UseUniversalTools[arg2:ucfirst()] ~= nil then
+ settings.UseUniversalTools[arg2:ucfirst()] = not settings.UseUniversalTools[arg2:ucfirst()]
+ settings:save()
+ else
+ error('Argument 2 must be a ninjutsu spell (sans :ichi or :ni) i.e. uut katon')
+ end
+ end
+end)
+
+
+windower.register_event('unhandled command', function(command, ...)
+ local args = L{...}:map(string.lower)
+
+ if command == 'get' or command == 'put' or command == 'gets' or command == 'puts' then
+ local count
+ if command == 'gets' or command == 'puts' then
+ command = command:sub(1, -2)
+ else
+ local last = args[#args]
+ if last == 'all' then
+ args:remove()
+ elseif tonumber(last) then
+ count = tonumber(last)
+ args:remove()
+ else
+ count = 1
+ end
+ end
+
+ local bag = args[#args]
+ local specified_bag = rawget(bag_ids, bag)
+ if specified_bag then
+ if not windower.ffxi.get_bag_info(specified_bag).enabled then
+ error('%s currently not enabled':format(res.bags[specified_bag].name))
+ return
+ end
+
+ args:remove()
+ elseif command == 'put' and not specified_bag then
+ error('Specify a valid destination bag to put items in.')
+ return
+ end
+
+ local source_bag
+ local destination_bag
+ if command == 'get' then
+ source_bag = specified_bag
+ destination_bag = bag_ids.inventory
+ else
+ destination_bag = specified_bag
+ source_bag = bag_ids.inventory
+ end
+
+ local destination_bag_info = windower.ffxi.get_bag_info(destination_bag)
+ if destination_bag_info.max - destination_bag_info.count == 0 then
+ error('Not enough space in %s to move items.':format(res.bags[destination_bag].name))
+ return
+ end
+
+ local item_name = args:concat(' ')
+
+ local item_ids = (S(res.items:name(windower.wc_match-{item_name})) + S(res.items:name_log(windower.wc_match-{item_name}))):map(table.get-{'id'})
+ if item_ids:length() == 0 then
+ error('Unknown item: %s':format(item_name))
+ return
+ end
+
+ local matches, results = find_items(item_ids, source_bag, count)
+ if results == 0 then
+ error('Item "%s" not found in %s.':format(item_name, source_bag and res.bags[source_bag].name or 'any accessible bags'))
+ return
+ end
+
+ if count and results < count then
+ warning('Only %u "%s" found in %s.':format(results, item_name, source_bag and res.bags[source_bag].name or 'all accessible bags'))
+ end
+
+ for match in matches:it() do
+ windower.ffxi[command .. '_item'](command == 'get' and match.bag or destination_bag, match.slot, match.count)
+ end
+ end
+end)
+
+ninjutsu = res.spells:type('Ninjutsu')
+patterns = L{'"(.+)"', '\'(.+)\'', '.- (.+) .-', '.- (.+)'}
+spec_tools = T{
+ Katon = 1161,
+ Hyoton = 1164,
+ Huton = 1167,
+ Doton = 1170,
+ Raiton = 1173,
+ Suiton = 1176,
+ Utsusemi = 1179,
+ Jubaku = 1182,
+ Hojo = 1185,
+ Kurayami = 1188,
+ Dokumori = 1191,
+ Tonko = 1194,
+ Monomi = 2553,
+ Aisha = 2555,
+ Yurin = 2643,
+ Myoshu = 2642,
+ Migawari = 2970,
+ Kakka = 2644,
+ Gekka = 8803,
+ Yain = 8804
+}
+gen_tools = T{
+ Katon = 2971,
+ Hyoton = 2971,
+ Huton = 2971,
+ Doton = 2971,
+ Raiton = 2971,
+ Suiton = 2971,
+ Utsusemi = 2972,
+ Jubaku = 2973,
+ Hojo = 2973,
+ Kurayami = 2973,
+ Dokumori = 2973,
+ Tonko = 2972,
+ Monomi = 2972,
+ Aisha = 2973,
+ Yurin = 2973,
+ Myoshu = 2972,
+ Migawari = 2972,
+ Kakka = 2972,
+ Gekka = 2972,
+ Yain = 2972
+}
+
+active = S{}
+
+-- Returning true resends the command in settings.Delay seconds
+-- Returning false doesn't resend the command and executes it
+collect_item = function(id, items)
+ items = items or {inventory = windower.ffxi.get_items(bag_ids.inventory)}
+
+ local item = T(items.inventory):with('id', id)
+ if item then
+ active = active:remove(id)
+ return false
+ end
+
+ -- Current ID already being processed?
+ if active:contains(id) then
+ return true
+ end
+
+ -- Check for all items
+ local match = find_items(S{id}, nil, 1):it()()
+
+ if match then
+ windower.ffxi.get_item(match.bag, match.slot, match.count)
+
+ -- Add currently processing ID to set of active IDs
+ active:add(id)
+ else
+ error('Item "%s" not found in any accessible bags':format(res.items[id].name))
+ end
+
+ return match ~= nil
+end
+
+reschedule = function(text, ids, items)
+ if not items then
+ local info = windower.ffxi.get_bag_info(bag_ids.inventory)
+ items = {inventory = windower.ffxi.get_items(bag_ids.inventory)}
+ items.max_inventory = info.max
+ items.count_inventory = info.count
+ end
+
+ -- Inventory full?
+ if items.max_inventory - items.count_inventory == 0 then
+ return false
+ end
+
+ for id in L(ids):it() do
+ if collect_item(id, items) then
+ windower.send_command:prepare('input %s':format(text)):schedule(settings.Delay)
+ return true
+ end
+ end
+end
+
+windower.register_event('outgoing text', function()
+ local item_names = T{}
+
+ return function(text)
+ -- Ninjutsu
+ if settings.AutoNinjaTools and (text:startswith('/ma ') or text:startswith('/nin ') or text:startswith('/magic ') or text:startswith('/ninjutsu ')) then
+ local name
+ for pattern in patterns:it() do
+ local match = text:match(pattern)
+ if match then
+ if ninjutsu:with('name', string.imatch-{match}) then
+ name = match:lower():capitalize():match('%w+')
+ break
+ end
+ end
+ end
+
+ if name then
+ if settings.UseUniversalTools[name] == false or windower.ffxi.get_player().main_job ~= 'NIN' then
+ return reschedule(text, {spec_tools[name], windower.ffxi.get_player().main_job == 'NIN' and gen_tools[name] or nil})
+ else
+ return reschedule(text, {windower.ffxi.get_player().main_job == 'NIN' and gen_tools[name] or nil})
+ end
+ end
+
+ -- Item usage
+ elseif settings.AutoItems and text:startswith('/item ') then
+ local items = windower.ffxi.get_items()
+ local inventory_items = S{}
+ local wardrobe_items = S{}
+ for bag in bag_ids:keyset():it() do
+ for _, item in ipairs(items[bag]) do
+ if item.id > 0 and not item_names[item.id] then
+ item_names[item.id] = res.items[item.id].name
+ end
+
+ if bag == 'inventory' then
+ inventory_items:add(item.id)
+ elseif S{'wardrobe','wardrobe2','wardrobe3','wardrobe4'}:contains(bag) then
+ wardrobe_items:add(item.id)
+ end
+ end
+ end
+
+ local parsed_text = item_count and text:match(' (.+) (%d+)$') or text:match(' (.+)')
+ local mid_name = parsed_text:match('"(.+)"') or parsed_text:match('\'(.+)\'') or parsed_text:match('(.+) ')
+ local full_name = parsed_text:match('(.+)')
+ local id = item_names:find(string.imatch-{mid_name}) or item_names:find(string.imatch-{full_name})
+ if id then
+ if not inventory_items:contains(id) and not wardrobe_items:contains(id) then
+ return reschedule(text, {id}, items)
+ else
+ active:remove(id)
+ end
+ end
+
+ end
+ end
+end())
+
+--[[
+Copyright © 2013-2015, Ihina
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Silence nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL IHINA BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+]]
+--Original plugin by Aureus
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/itemizer/readme.md b/Data/BuiltIn/Libraries/lua-addons/addons/itemizer/readme.md
new file mode 100644
index 0000000..954ef68
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/itemizer/readme.md
@@ -0,0 +1,64 @@
+#Itemizer
+
+Provides a chat/console interface for moving items around between bags. Optionally also automatically fetches items into the main inventory before item usage (both regular usage and Ninjutsu tools).
+
+### Commands
+```
+itemizer delay <delay>
+```
+
+Sets the delay for pulling items into your inventory to 'delay'. (Default 0.5)
+
+```
+itemizer autoitems (shortened: ai)
+```
+
+Toggles the auto-pulling of items from bags if not in your inventory. (Default: True)
+
+```
+itemizer autoninjatools (shortened: ant)
+```
+
+Toggles the auto-pulling of ninja tools from bags when not in your bag. Prioritizes specific tools then moves to universal unless the next command is used to set the tools to only use universal tools for specific spells. (Default: True)
+
+```
+itemizer useuniversaltools <spell> (shortened: uut)
+```
+
+Toggles the use of only universal tools for `spell`. Does not use :ichi or :ni suffixes. (Default: False for all spells)
+For Example: itemiser uut katon
+
+```
+get <item> [bag] [count]
+```
+
+Retrieves the specified item from the specified bag. If `bag` is omitted it will fetch the item from any accessible bag, if available. If `count` is omitted only a single item is fetched. If `count` is `all` all items will be fetched.
+
+```
+put <item> <bag> [count]
+```
+
+Places the specified item into the specified bag. If `count` is omitted only a single item is put away. If `count` is `all` all items will be put away.
+
+```
+gets <item> [bag]
+puts <item> <bag>
+```
+
+Same as the `get` and `put` variants if `all` was specified for the `count` argument.
+
+### Notes
+
+Both the full name and the abbrevited names are valid entries. Wildcards are allowed. For example, `//get *ore` would fetch all ores from all accessible bags to the main inventory.
+
+### Examples
+
+```
+//put Mandau sack
+//put Whirlpool mask satchel
+//get Hct. Subligar +1 storage
+//get Raider's armlets +2 safe
+//get "HoPe toRQue" locker
+//get earth crystal 5
+//get *crystal
+```