diff options
Diffstat (limited to 'Data/BuiltIn/Libraries/addons/addons/temps/temps.lua')
-rw-r--r-- | Data/BuiltIn/Libraries/addons/addons/temps/temps.lua | 345 |
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) |