summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/addons/addons/temps/temps.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/addons/addons/temps/temps.lua')
-rw-r--r--Data/BuiltIn/Libraries/addons/addons/temps/temps.lua345
1 files changed, 0 insertions, 345 deletions
diff --git a/Data/BuiltIn/Libraries/addons/addons/temps/temps.lua b/Data/BuiltIn/Libraries/addons/addons/temps/temps.lua
deleted file mode 100644
index 1ec0f89..0000000
--- a/Data/BuiltIn/Libraries/addons/addons/temps/temps.lua
+++ /dev/null
@@ -1,345 +0,0 @@
---[[
-temps v1.0
-
-Copyright © 2017, Mojo
-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 temps 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 Mojo 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 = 'temps'
-_addon.author = 'Mojo'
-_addon.version = '1.0'
-_addon.command = 'temps'
-
-require('chat')
-require('logger')
-require('pack')
-
-config = require('config')
-items = require('items')
-packets = require('packets')
-
-local help_text = [[
-temps - Command List:
-1. help - Displays this help menu.
-2. buy - Buys all temporary items in an escha zone.
-* buy - Buys all temporary items.
-* buy radialens - Buys all temporary items and also
- attempts to buy a radialens, even if it is on your
- blacklist or if you already have one.
-3. blacklist - Add(a)/Remove(r) items from your blacklist.
-* blacklist add radialens - Adds radialens to your
- blacklist.
-* blacklist a radialens - Adds radialens to your blacklist.
-* blacklist remove radialens - Removes radialens from
- your blacklist.
-* blacklist r radialens - Removes radialens from your
- blacklist.
-4. turbo - Toggle the turbo feature.
-* turbo - Enables or disables the turbo feature.
-
-Notes:
- You must be near an escha NPC that sells temporary
- items. A buy radialens command will refresh your
- radialens duration in the event that you already have
- one.
-]]
-
-local defaults = {
- turbo = false,
- blacklist = S{
- 'mollifier',
- 'primeval brew',
- 'radialens',
- }
-}
-
-local settings = config.load('settings.xml', defaults)
-local handlers = {}
-local state = 'idle'
-local zone = nil
-local force = nil
-local silt = 0
-local key_ids = {}
-local key_items = 0
-local outstanding = 0
-local inflight = {}
-
-local temp_items = {
- [1] = 0,
- [2] = 0,
-}
-
-local conditions = {
- temps = false,
- busy = false,
-}
-
-local zones = {
- [288] = {npc = "Affi", menu = 9701},
- [289] = {npc = "Dremi", menu = 9701},
- [291] = {npc = "Shiftrix", menu = 9701},
-}
-
-local function busy_wait(block, timeout, message)
- local start = os.time()
- while conditions[block] and ((os.time() - start) < timeout) do
- coroutine.sleep(.1)
- end
- if os.time() - start >= timeout then
- conditions[block] = false
- return "timed out - %s":format(message)
- end
-end
-
-local function validate(constrain)
- zone = windower.ffxi.get_info()['zone']
- if zones[zone] then
- local npc = windower.ffxi.get_mob_by_name(zones[zone].npc)
- if npc and ((math.sqrt(npc.distance) < 6) or (not constrain)) then
- return npc
- else
- error("Too far from %s.":format(zones[zone].npc))
- end
- else
- error("Not in an Escha zone.")
- end
-end
-
-local function has_item(item)
- if item.key_item then
- return (math.floor(key_items/math.pow(2, item.offset)) % 2) == 1
- else
- return (math.floor(temp_items[math.floor(item.offset/32) + 1]/math.pow(2, item.offset % 32)) % 2) == 1
- end
-end
-
-local function force_purchase(item)
- return (item.name == force)
-end
-
-local function ignore_item(item)
- return settings.blacklist:contains(item.name:lower())
-end
-
-local function purchase_items()
- local npc = validate()
- local count = 0
- for item_id, item in pairs(items) do
- if force_purchase(item) or (not has_item(item)) then
- if ignore_item(item) and (not force_purchase(item)) then
- windower.add_to_chat(100, string.format("Ignoring \30\2%s\30\43.", item.name))
- else
- local p = packets.new('outgoing', 0x5b, {
- ["Target"] = npc.id,
- ["Option Index"] = item.option,
- ["Target Index"] = npc.index,
- ["Automated Message"] = true,
- ["Zone"] = zone,
- ["Menu ID"] = zones[zone].menu,
- })
- windower.add_to_chat(100, string.format("Purchasing \30\2%s\30\43.", item.name))
- packets.inject(p)
- state = 'purchase'
- inflight[item_id] = true
- count = count + 1
- if not settings.turbo then
- coroutine.sleep(1)
- end
- end
- end
- end
- if count == 0 then
- windower.add_to_chat(100, "No temporary items to buy.")
- else
- outstanding = outstanding + count
- if outstanding == 0 then
- windower.add_to_chat(100, "Finished purchasing all temporary items.")
- end
- end
-end
-
-local function exit_menu(id, data, modified, injected, blocked)
- if (id == 0x5b) and ((state == 'init') or (state == 'purchase')) then
- local p = packets.parse('outgoing', data)
- local npc = validate()
- if (p['Target'] == npc.id) and not p['Automated Message'] then
- outstanding = 0
- state = 'idle'
- end
- end
-end
-
-local function observe_temps(id, data, modified, injected, blocked)
- if (id == 0x5c) and conditions['temps'] then
- local p = packets.parse('incoming', data)
- temp_items[1] = p['Menu Parameters']:unpack('I', 1)
- temp_items[2] = p['Menu Parameters']:unpack('I', 5)
- conditions['temps'] = false
- end
-end
-
-local function process_dialogue_event(id, data, modified, injected, blocked)
- if (id == 0x34) and (state == 'init') then
- local p = packets.parse('incoming', data)
- state = 'purchase'
- silt = p['Menu Parameters']:unpack('I', 5)
- key_items = p['Menu Parameters']:unpack('I', 9)
- conditions['temps'] = true
- busy_wait('temps', 10, 'observe temp items')
- purchase_items()
- end
-end
-
-local function check_inflight(iid)
- if (inflight[iid]) then
- inflight[iid] = nil
- outstanding = outstanding - 1
- if outstanding == 0 then
- windower.add_to_chat(100, "Finished purchasing all temporary items.")
- end
- end
-end
-
-local function receive_item(id, data, modified, injected, blocked)
- if (id == 0x20) and (state == 'purchase') then
- local p = packets.parse('incoming', data)
- check_inflight(p['Item'])
- end
-end
-
-local function obtained_key_item(p, item_id)
- if (math.floor(item_id/512) == p['Type']) then
- local bit = item_id % 512
- local n = bit % 8
- local character = math.floor(bit/8) + 1
- return ((math.floor(p['Key item available']:byte(character)/math.pow(2, n)) % 2) == 1)
- else
- return false
- end
-end
-
-local function receive_key_items(id, data, modified, injected, blocked)
- if (id == 0x55) and (state == 'purchase') then
- local p = packets.parse('incoming', data)
- for k, v in pairs(inflight) do
- if obtained_key_item(p, k) then
- check_inflight(k)
- end
- end
- end
-end
-
-local function validate_item(item)
- for k, v in pairs(items) do
- if item:lower() == v.name:lower() then
- return v.name
- end
- end
- error("%s not found in items list.":format(item))
-end
-
-local function start(override)
- if not (state == 'idle') then
- return error("Addon is busy.")
- elseif override then
- force = validate_item(override)
- if not force then
- return
- else
- notice("Override provided for %s.":format(force))
- end
- else
- force = nil
- end
- local npc = validate(true)
- if npc then
- local p = packets.new('outgoing', 0x01a, {
- ["Target"] = npc.id,
- ["Target Index"] = npc.index,
- })
- packets.inject(p)
- state = 'init'
- else
- state = 'idle'
- end
-end
-
-local function help()
- windower.add_to_chat(100, help_text)
-end
-
-local function blacklist(cmd, name)
- if not cmd then
- return error("No blacklist command provided.")
- elseif not S{'add', 'a', 'remove', 'r'}:contains(cmd) then
- return error("Unknown blacklist command %s.":format(cmd))
- elseif not name then
- return error("No blacklist command parameter provided.")
- end
- local item = validate_item(name)
- if not item then
- return
- elseif S{'add', 'a'}:contains(cmd) then
- notice("Adding %s to your blacklist.":format(item))
- settings.blacklist:add(item:lower())
- else
- notice("Removing %s from your blacklist.":format(item))
- settings.blacklist:remove(item:lower())
- end
- settings:save()
-end
-
-local function turbo()
- if settings.turbo then
- notice("Disabling turbo.")
- settings.turbo = false
- else
- notice("Enabling turbo.")
- settings.turbo = true
- end
- settings:save()
-end
-
-local function handle_command(cmd, ...)
- local cmd = cmd and cmd:lower() or 'help'
- if handlers[cmd] then
- handlers[cmd](...)
- else
- error("Unknown command %s.":format(cmd))
- end
-end
-
-handlers['buy'] = start
-handlers['help'] = help
-handlers['blacklist'] = blacklist
-handlers['turbo'] = turbo
-
-windower.register_event('incoming chunk', process_dialogue_event)
-windower.register_event('incoming chunk', receive_item)
-windower.register_event('incoming chunk', receive_key_items)
-windower.register_event('incoming chunk', observe_temps)
-windower.register_event('outgoing chunk', exit_menu)
-windower.register_event('addon command', handle_command)