summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/EmpyPopTracker/EmpyPopTracker.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/EmpyPopTracker/EmpyPopTracker.lua')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/EmpyPopTracker/EmpyPopTracker.lua383
1 files changed, 383 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/EmpyPopTracker/EmpyPopTracker.lua b/Data/BuiltIn/Libraries/lua-addons/addons/EmpyPopTracker/EmpyPopTracker.lua
new file mode 100644
index 0000000..a6ae2aa
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/EmpyPopTracker/EmpyPopTracker.lua
@@ -0,0 +1,383 @@
+--[[
+Copyright © 2020, Dean James (Xurion of Bismarck)
+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 Empy Pop Tracker 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 Dean James (Xurion of Bismarck) 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.
+]]
+
+_addon.name = 'Empy Pop Tracker'
+_addon.author = 'Dean James (Xurion of Bismarck)'
+_addon.commands = { 'ept', 'empypoptracker' }
+_addon.version = '2.5.0'
+
+config = require('config')
+res = require('resources')
+nm_data = require('nms/index')
+
+active = false
+
+local EmpyPopTracker = {}
+
+local defaults = {}
+defaults.text = {}
+defaults.text.pos = {}
+defaults.text.pos.x = 0
+defaults.text.pos.y = 0
+defaults.text.bg = {}
+defaults.text.bg.alpha = 150
+defaults.text.bg.blue = 0
+defaults.text.bg.green = 0
+defaults.text.bg.red = 0
+defaults.text.bg.visible = true
+defaults.text.padding = 8
+defaults.text.text = {}
+defaults.text.text.font = 'Consolas'
+defaults.text.text.size = 10
+defaults.tracking = 'briareus'
+defaults.visible = true
+defaults.add_to_chat_mode = 8
+defaults.colors = {}
+defaults.colors.needed = {}
+defaults.colors.needed.red = 255
+defaults.colors.needed.green = 50
+defaults.colors.needed.blue = 50
+defaults.colors.obtained = {}
+defaults.colors.obtained.red = 100
+defaults.colors.obtained.green = 255
+defaults.colors.obtained.blue = 100
+defaults.colors.pool = {}
+defaults.colors.pool.red = 255
+defaults.colors.pool.green = 170
+defaults.colors.pool.blue = 0
+defaults.colors.bg = {}
+defaults.colors.bg.red = 0
+defaults.colors.bg.green = 0
+defaults.colors.bg.blue = 0
+defaults.colors.bgall = {}
+defaults.colors.bgall.red = 0
+defaults.colors.bgall.green = 75
+defaults.colors.bgall.blue = 0
+defaults.collectables = true
+defaults.expanded = true
+
+EmpyPopTracker.settings = config.load(defaults)
+EmpyPopTracker.text = require('texts').new(EmpyPopTracker.settings.text, EmpyPopTracker.settings)
+
+function start_color(color)
+ return '\\cs(' .. EmpyPopTracker.settings.colors[color].red .. ',' .. EmpyPopTracker.settings.colors[color].green .. ',' .. EmpyPopTracker.settings.colors[color].blue .. ')'
+end
+
+function owns_item(id, items)
+ for _, bag in pairs(items) do
+ if type(bag) == 'table' then
+ for _, item in ipairs(bag) do
+ if item.id == id then
+ return true
+ end
+ end
+ end
+ end
+
+ return false
+end
+
+function get_item_count(id, items)
+ local count = 0
+ for _, bag in pairs(items) do
+ if type(bag) == 'table' then
+ for _, item in ipairs(bag) do
+ if item.id == id then
+ count = count + item.count
+ end
+ end
+ end
+ end
+
+ return count
+end
+
+function owns_key_item(id, items)
+ local owned = false
+
+ for _, item_id in pairs(items) do
+ if item_id == id then
+ owned = true
+ break
+ end
+ end
+
+ return owned
+end
+
+function item_treasure_pool_count(id, treasure)
+ local count = 0
+
+ for _, item in pairs(treasure) do
+ if item.item_id == id then
+ count = count + 1
+ end
+ end
+
+ return count
+end
+
+function ucwords(str)
+ local result = string.gsub(str, '(%a)([%w_\']*)', function(first, rest)
+ return first:upper() .. rest:lower()
+ end)
+
+ return result
+end
+
+function get_indent(depth)
+ return string.rep(' ', depth)
+end
+
+function generate_text(data, key_items, items, depth)
+ local text = depth == 1 and data.name or ''
+ for _, pop in pairs(data.pops) do
+ local resource
+ local item_scope
+ local owns_pop
+ local in_pool_count = 0
+ local item_identifier = ''
+
+ if pop.type == 'key item' then
+ resource = res.key_items[pop.id]
+ owns_pop = owns_key_item(pop.id, key_items)
+ item_identifier = 'Ж '
+ else
+ resource = res.items[pop.id]
+ owns_pop = owns_item(pop.id, items)
+ in_pool_count = item_treasure_pool_count(pop.id, items.treasure)
+ end
+
+ local pop_name = 'Unknown pop'
+ if resource then
+ pop_name = ucwords(resource.name)
+ end
+
+ if depth == 1 and EmpyPopTracker.settings.expanded then
+ text = text .. '\n'
+ end
+
+ local item_colour = start_color(owns_pop and 'obtained' or 'needed')
+ local pool_notification = ''
+ if in_pool_count > 0 then
+ pool_notification = start_color('pool') .. ' [' .. in_pool_count .. ']' .. '\\cr'
+ end
+
+ local name_color = ''
+ local name_color_end = ''
+ if not EmpyPopTracker.settings.expanded and owns_pop then
+ name_color = item_colour
+ name_color_end = '\\cr'
+ end
+
+ text = text .. '\n' .. get_indent(depth) .. name_color .. pop.dropped_from.name .. name_color_end
+
+ if EmpyPopTracker.settings.expanded then
+ text = text .. '\n' .. get_indent(depth) .. ' >> ' .. item_colour .. item_identifier .. pop_name .. '\\cr' .. pool_notification
+ end
+
+ if pop.dropped_from.pops then
+ text = text .. generate_text(pop.dropped_from, key_items, items, depth + 1)
+ end
+ end
+
+ if data.collectable and EmpyPopTracker.settings.collectables then
+ local count = get_item_count(data.collectable, items)
+ local start = ''
+ local finish = ''
+ if count >= data.collectable_target_count then
+ start = start_color('obtained')
+ finish = '\\cr'
+ end
+
+ text = text .. '\n\n' .. start .. res.items[data.collectable].name .. ': ' .. count .. '/' .. data.collectable_target_count .. finish
+ end
+
+ return text
+end
+
+EmpyPopTracker.generate_info = function(nm, key_items, items)
+ return {
+ has_all_pops = not nm.pops or T(nm.pops):all(function(item)
+ return item.type == 'item' and owns_item(item.id, items) or owns_key_item(item.id, key_items)
+ end),
+ text = generate_text(nm, key_items, items, 1)
+ }
+end
+
+function find_nms(pattern)
+ local matching_nms = {}
+ local lower_pattern = pattern:lower()
+ for _, nm in pairs(nm_data) do
+ local nm_name = nm.name:lower()
+ local result = windower.wc_match(nm_name, lower_pattern)
+ if result then
+ table.insert(matching_nms, nm_name)
+ end
+ end
+
+ return matching_nms
+end
+
+windower.register_event('addon command', function(command, ...)
+ command = command and command:lower() or 'help'
+
+ if commands[command] then
+ commands[command](...)
+ else
+ commands.help()
+ end
+end)
+
+commands = {}
+
+commands.track = function(...)
+ local nm_search_pattern = table.concat({...}, ' ')
+ local matching_nm_names = find_nms(nm_search_pattern)
+
+ if #matching_nm_names == 0 then
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, 'Unable to find a NM using: "' .. nm_search_pattern .. '"')
+ elseif #matching_nm_names > 1 then
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '"' .. nm_search_pattern .. '" matches ' .. #matching_nm_names .. ' NMs. Please be more explicit:')
+ for key, matching_file_name in pairs(matching_nm_names) do
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, ' Match ' .. key .. ': ' .. ucwords(matching_file_name))
+ end
+ else
+ active = true
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, 'Now tracking: ' .. ucwords(matching_nm_names[1]))
+ EmpyPopTracker.settings.tracking = matching_nm_names[1]
+ EmpyPopTracker.update()
+ commands.show()
+ end
+end
+commands.t = commands.track
+
+commands.hide = function()
+ active = false
+ EmpyPopTracker.text:visible(false)
+ EmpyPopTracker.settings.visible = false
+ EmpyPopTracker.settings:save()
+end
+
+commands.show = function()
+ active = true
+ EmpyPopTracker.text:visible(true)
+ EmpyPopTracker.settings.visible = true
+ EmpyPopTracker.settings:save()
+ EmpyPopTracker.update()
+end
+
+commands.help = function()
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '---Empy Pop Tracker---')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, 'Available commands:')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept track briareus - tracks Briareus pops (search patterns such as apadem* work too!)')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept hide - hides the UI')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept show - shows the UI')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept list - lists all trackable NMs')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept mini - toggles mini/expanded mode')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept collectables - toggles the collectable item')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '//ept help - displays this help')
+end
+
+commands.list = function()
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, '---Empy Pop Tracker---')
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, 'Trackable NMs:')
+ for _, nm in pairs(nm_data) do
+ windower.add_to_chat(EmpyPopTracker.settings.add_to_chat_mode, ucwords(nm.name))
+ end
+end
+
+commands.bg = function()
+ local tracking_nm = nm_data[EmpyPopTracker.settings.tracking]
+ local url = 'https://www.bg-wiki.com/bg/' .. tracking_nm.name
+ windower.open_url(url)
+end
+
+commands.collectables = function()
+ EmpyPopTracker.settings.collectables = not EmpyPopTracker.settings.collectables
+ EmpyPopTracker.settings:save()
+ EmpyPopTracker.update()
+end
+
+commands.mini = function()
+ EmpyPopTracker.settings.expanded = not EmpyPopTracker.settings.expanded
+ EmpyPopTracker.settings:save()
+ EmpyPopTracker.update()
+end
+
+EmpyPopTracker.update = function()
+ local key_items = windower.ffxi.get_key_items()
+ local items = windower.ffxi.get_items()
+ local tracked_nm_data = nm_data[EmpyPopTracker.settings.tracking]
+ local generated_info = EmpyPopTracker.generate_info(tracked_nm_data, key_items, items)
+ EmpyPopTracker.text:text(generated_info.text)
+ if generated_info.has_all_pops then
+ EmpyPopTracker.text:bg_color(EmpyPopTracker.settings.colors.bgall.red, EmpyPopTracker.settings.colors.bgall.green, EmpyPopTracker.settings.colors.bgall.blue)
+ else
+ EmpyPopTracker.text:bg_color(EmpyPopTracker.settings.colors.bg.red, EmpyPopTracker.settings.colors.bg.green, EmpyPopTracker.settings.colors.bg.blue)
+ end
+ if EmpyPopTracker.settings.visible then
+ EmpyPopTracker.text:visible(true)
+ end
+end
+
+windower.register_event('load', function()
+ if windower.ffxi.get_info().logged_in and EmpyPopTracker.settings.visible then
+ active = true
+ EmpyPopTracker.update()
+ end
+end)
+
+windower.register_event('add item', 'remove item', function()
+ if active then
+ EmpyPopTracker.update()
+ end
+end)
+
+windower.register_event('incoming chunk', function(id)
+ --0x055: KI update
+ --0x0D2: Treasure pool addition
+ --0x0D3: Treasure pool lot/drop
+ if active and id == 0x055 or id == 0x0D2 or id == 0x0D3 then
+ EmpyPopTracker.update()
+ end
+end)
+
+windower.register_event('login', function()
+ if EmpyPopTracker.settings.visible then
+ EmpyPopTracker.text:visible(true)
+ active = true
+ end
+end)
+
+windower.register_event('logout', function()
+ EmpyPopTracker.text:visible(false)
+ active = false
+end)
+
+return EmpyPopTracker