diff options
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer')
5 files changed, 808 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/README b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/README new file mode 100644 index 0000000..a34f5b9 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/README @@ -0,0 +1,12 @@ +This script is a treasure casket helper addon to be used with Windower +for Final Fantasy XI. + +You can report issues, get the latest version, and view the source at: + https://github.com/svanheulen/boxdestroyer-windower-addon + +Donations are welcome in the form of Alexandrite: + Acacia on Odin (http://www.ffxiah.com/player/Odin/Acacia) + +With this addon loaded, just click on any brown treasure casket and it +will display info about possible combinations, the best number to guess +and the worst case chance of guessing correctly. diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/boxdestroyer.lua b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/boxdestroyer.lua new file mode 100644 index 0000000..af70616 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/boxdestroyer.lua @@ -0,0 +1,466 @@ +--[[ +Copyright (c) 2014, Seth VanHeulen +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. 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. +3. Neither the name of the copyright holder 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 THE COPYRIGHT +HOLDER OR CONTRIBUTORS 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 information + +_addon.name = 'boxdestroyer' +_addon.version = '1.0.5' +_addon.command = 'boxdestroyer' +_addon.author = 'Seth VanHeulen (Acacia@Odin)' + +-- modules + +require('pack') +require('tables') +require('chat') + +-- load message constants + +require('messages') + +-- config + +config = require('config') +defaults = { + HighlightResult = false, + HighlightColor = 36, +} +settings = config.load(defaults) +-- global constants + +default = { + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 +} + +observed_default = { + ['second_even_odd'] = false, + ['first_even_odd'] = false, + ['range'] = false, + ['equal'] = false, + ['second_multiple'] = false, + ['first_multiple'] = false, + ['thief_tools_active'] = false +} + +thief_tools = {[1022] = true} + +-- global variables + +box = {} +observed = {} +zone_id = windower.ffxi.get_info().zone + +-- filter helper functions + +function greater_less(id, greater, num) + local new = {} + for _,v in pairs(box[id]) do + if greater and v > num or not greater and v < num then + table.insert(new, v) + end + end + return new +end + +function even_odd(id, div, rem) + local new = {} + for _,v in pairs(box[id]) do + if (math.floor(v / div) % 2) == rem then + table.insert(new, v) + end + end + return new +end + +function equal(id, first, num) + local new = {} + for _,v in pairs(box[id]) do + if first and math.floor(v / 10) == num or not first and (v % 10) == num then + table.insert(new, v) + end + end + return new +end + +function exclusive_mean(counts) + total = 0 + for _,v in pairs(counts) do + total = total + v + end + weighted_mean = 0 + for _,v in pairs(counts) do + weighted_mean = weighted_mean + (total - v) * v / total + end + return weighted_mean +end + +function calculate_odds(id,chances) + local reductions = {} + if not observed[id].first_even_odd then + local counter = {0} + counter[0] = 0 + for _,v in pairs(box[id]) do + counter[math.floor(v / 10) % 2] = counter[math.floor(v / 10) % 2] + 1 + end + reductions[#reductions+1] = exclusive_mean(counter) + end + if not observed[id].second_even_odd then + local counter = {0} + counter[0] = 0 + for _,v in pairs(box[id]) do + counter[v % 2] = counter[v % 2] + 1 + end + reductions[#reductions+1] = exclusive_mean(counter) + end + if not observed[id].range then + local new = {} + local reduction = 0 + for i,v in pairs(box[id]) do + new[i] = 0 + for _,m in pairs(box[id]) do + if m-v > 16 then break end + new[i] = new[i] + math.max(16-math.abs(m - v),0)^2/256 + end + reduction = reduction + (#box[id] - new[i])/#box[id] + end + + reductions[#reductions+1] = reduction + end + if not observed[id].equal then + local counter = {0,0,0,0,0,0,0,0,0} + counter[0] = 0 + local eliminated = {0,0,0,0,0,0,0,0,0} + eliminated[0] = 0 + for _,v in pairs(box[id]) do + counter[math.floor(v / 10)] = counter[math.floor(v / 10)] + 1/2 + counter[v % 10] = counter[v % 10] + 1/2 + for i = 0,9 do + if i ~= v % 10 and i ~= math.floor(v / 10) then + eliminated[i] = eliminated[i] + 1 + end + end + end + + reduction = 0 + for i,v in pairs(counter) do + reduction = reduction + eliminated[i] * v / #box[id] + end + + reductions[#reductions+1] = reduction + end + if not observed[id].second_multiple then + local counter = {0,0,0,0,0,0,0,0,0} + counter[0] = 0 + for _,v in pairs(box[id]) do + counter[v % 10] = counter[v % 10] + 1 + end + + local weights = { + counter[0] + counter[1]/2 + counter[2]/3, + counter[1]/2 + counter[2]/3 + counter[3]/3, + counter[2]/3 + counter[3]/3 + counter[4]/3, + counter[3]/3 + counter[4]/3 + counter[5]/3, + counter[4]/3 + counter[5]/3 + counter[6]/3, + counter[5]/3 + counter[6]/3 + counter[7]/3, + counter[6]/3 + counter[7]/3 + counter[8]/2, + counter[7]/3 + counter[8]/2 + counter[9] + } + + local eliminated = { + counter[3] + counter[4] + counter[5] + counter[6] + counter[7] + counter[8] + counter[9], + counter[0] + counter[4] + counter[5] + counter[6] + counter[7] + counter[8] + counter[9], + counter[0] + counter[1] + counter[5] + counter[6] + counter[7] + counter[8] + counter[9], + counter[0] + counter[1] + counter[2] + counter[6] + counter[7] + counter[8] + counter[9], + counter[0] + counter[1] + counter[2] + counter[3] + counter[7] + counter[8] + counter[9], + counter[0] + counter[1] + counter[2] + counter[3] + counter[4] + counter[8] + counter[9], + counter[0] + counter[1] + counter[2] + counter[3] + counter[4] + counter[5] + counter[9], + counter[0] + counter[1] + counter[2] + counter[3] + counter[4] + counter[5] + counter[6] + } + + local reduction = 0 + for i,v in pairs(weights) do + reduction = reduction + eliminated[i] * v / #box[id] + end + + reductions[#reductions + 1] = reduction + end + if not observed[id].first_multiple then + local counter = {0,0,0,0,0,0,0,0,0} + for _,v in pairs(box[id]) do + counter[math.floor(v / 10)] = counter[math.floor(v / 10)] + 1 + end + + local weights = { + counter[1] + counter[2]/2 + counter[3]/3, + counter[2]/2 + counter[3]/3 + counter[4]/3, + counter[3]/3 + counter[4]/3 + counter[5]/3, + counter[4]/3 + counter[5]/3 + counter[6]/3, + counter[5]/3 + counter[6]/3 + counter[7]/3, + counter[6]/3 + counter[7]/3 + counter[8]/2, + counter[7]/3 + counter[8]/2 + counter[9] + } + + local eliminated = { + counter[4] + counter[5] + counter[6] + counter[7] + counter[8] + counter[9], + counter[1] + counter[5] + counter[6] + counter[7] + counter[8] + counter[9], + counter[1] + counter[2] + counter[6] + counter[7] + counter[8] + counter[9], + counter[1] + counter[2] + counter[3] + counter[7] + counter[8] + counter[9], + counter[1] + counter[2] + counter[3] + counter[4] + counter[8] + counter[9], + counter[1] + counter[2] + counter[3] + counter[4] + counter[5] + counter[9], + counter[1] + counter[2] + counter[3] + counter[4] + counter[5] + counter[6] + } + + local reduction = 0 + for i,v in pairs(weights) do + reduction = reduction + eliminated[i] * v / #box[id] + end + + reductions[#reductions + 1] = reduction + end + + local expected_examine_value = 0 + for _,v in pairs(reductions) do + expected_examine_value = expected_examine_value + v/#reductions + end + + local optimal_guess = math.ceil(#box[id] / 2) + + local expected_guess_value = 2*optimal_guess - 2*optimal_guess^2 / #box[id] + 2*optimal_guess/#box[id] - 1 / #box[id] + + return expected_examine_value, expected_guess_value +end + +-- display helper function + +function display(id, chances) + if #box[id] == 90 then + windower.add_to_chat(207, 'Possible combinations: 10~99') + else + windower.add_to_chat(207, 'Possible combinations: ' .. table.concat(box[id], ' ')) + end + local remaining = math.floor(#box[id] / math.pow(2, (chances - 1))) + if remaining == 0 then + remaining = 1 + end + + if chances == 1 and observed[id].equal then + -- The "equal" message (== "X") for X in 1..9 gives an unequal probability to the remaining options + -- because "XX" is twice as likely to be indicated by the "equal" message. + -- This is too annoying to propagate to the rest of the addon, although it should be some day. + local printed = false + for _,v in pairs(box[id]) do + if math.floor(v/10) == v%10 then + windower.add_to_chat(207, 'Best guess: %d (%d%%)':format(v, 1 / remaining * 100)) + printed = true + break + end + end + if not printed then + windower.add_to_chat(207, 'Best guess: %d (%d%%)':format(box[id][math.ceil(#box[id] / 2)], 1 / remaining * 100)) + end + else + windower.add_to_chat(207, 'best guess: %d (%d%%)':format(box[id][math.ceil(#box[id] / 2)], 1 / remaining * 100)) + local clue_value,guess_value = calculate_odds(id,chances) + local result = clue_value > guess_value and remaining ~= 1 and 'examining the chest' or 'guessing ' .. '%d':format(box[id][math.ceil(#box[id] / 2)]) + local formatted_result = settings.HighlightResult and result:color(settings.HighlightColor) or result + windower.add_to_chat(207, 'boxdestroyer recommends ' .. formatted_result .. '.') + end + +end + +-- ID obtaining helper function +function get_id(zone_id,str) + return messages[zone_id] + offsets[str] +end + +-- event callback functions + +function check_incoming_chunk(id, original, modified, injected, blocked) + if id == 0x0A then + zone_id = original:unpack('H', 49) + elseif messages[zone_id] then + if id == 0x0B then + box = {} + observed = {} + elseif id == 0x2A then + local box_id = original:unpack('I', 5) + local param0 = original:unpack('I', 9) + local param1 = original:unpack('I', 13) + local param2 = original:unpack('I', 17) + local message_id = original:unpack('H', 27) % 0x8000 + + if box[box_id] == nil then + box[box_id] = table.copy(default) + end + if observed[box_id] == nil then + observed[box_id] = table.copy(observed_default) + end + + if get_id(zone_id,'greater_less') == message_id then + box[box_id] = greater_less(box_id, param1 == 0, param0) + elseif get_id(zone_id,'second_even_odd') == message_id then + -- tells whether the second digit is even or odd + box[box_id] = even_odd(box_id, 1, param0) + observed[box_id].second_even_odd = true + elseif get_id(zone_id,'first_even_odd') == message_id then + -- tells whether the first digit is even or odd + box[box_id] = even_odd(box_id, 10, param0) + observed[box_id].first_even_odd = true + elseif get_id(zone_id,'range') == message_id then + if observed[box_id].thief_tools_active then + -- Thief tools are the same as normal ranges but with larger bounds. + -- lower bound (param0) = solution - RANDINT(8,32) + -- upper bound (param1) = solution + RANDINT(8,32) + -- param0 + 33 > solution > param0 + 7 + -- param1 - 7 > solution > param1 - 33 + -- if the bound is less than 11 or greater than 98, the message changes to "greater" or "less" respectively + box[box_id] = greater_less(box_id, true, math.max(param1-33,param0+7) ) + box[box_id] = greater_less(box_id, false, math.min(param0+33,param1-7) ) + observed[box_id].thief_tools_active = false + else + -- lower bound (param0) = solution - RANDINT(5,20) + -- upper bound (param1) = solution + RANDINT(5,20) + -- param0 + 21 > solution > param0 + 4 + -- param1 - 4 > solution > param1 - 21 + -- if the bound is less than 11 or greater than 98, the message changes to "greater" or "less" respectively + box[box_id] = greater_less(box_id, true, math.max(param1-21,param0+4) ) + box[box_id] = greater_less(box_id, false, math.min(param0+21,param1-4) ) + observed[box_id].range = true + end + elseif get_id(zone_id,'less') == message_id then + -- Less is a range with 9 as the lower bound + if observed[box_id].thief_tools_active then + box[box_id] = greater_less(box_id, true, math.max(9, param0-33) ) + box[box_id] = greater_less(box_id, false, math.min(10+33,param0-7) ) + observed[box_id].thief_tools_active = false + else + box[box_id] = greater_less(box_id, true, math.max(9, param0-21) ) + box[box_id] = greater_less(box_id, false, math.min(10+21,param0-4) ) + observed[box_id].range = true + end + elseif get_id(zone_id,'greater') == message_id then + -- Greater is a range with 100 as the upper bound + if observed[box_id].thief_tools_active then + box[box_id] = greater_less(box_id, true, math.max(99-33,param0+7) ) + box[box_id] = greater_less(box_id, false, math.min(100,param0+33) ) + observed[box_id].thief_tools_active = false + else + box[box_id] = greater_less(box_id, true, math.max(99-21,param0+4) ) + box[box_id] = greater_less(box_id, false, math.min(100,param0+21) ) + observed[box_id].range = true + end + elseif get_id(zone_id,'equal') == message_id then + -- single number that is either the first or second digit of the solution + local new = equal(box_id, true, param0) + local duplicate = param0 * 10 + param0 + for k,v in pairs(new) do + if v == duplicate then + table.remove(new, k) + end + end + for _,v in pairs(equal(box_id, false, param0)) do table.insert(new, v) end + table.sort(new) + box[box_id] = new + observed[box_id].equal = true + elseif get_id(zone_id,'second_multiple') == message_id then + -- three digit range including the second digit of the solution + local new = equal(box_id, false, param0) + for _,v in pairs(equal(box_id, false, param1)) do table.insert(new, v) end + for _,v in pairs(equal(box_id, false, param2)) do table.insert(new, v) end + table.sort(new) + box[box_id] = new + observed[box_id].second_multiple = true + elseif get_id(zone_id,'first_multiple') == message_id then + -- three digit range including the first digit of the solution + local new = equal(box_id, true, param0) + for _,v in pairs(equal(box_id, true, param1)) do table.insert(new, v) end + for _,v in pairs(equal(box_id, true, param2)) do table.insert(new, v) end + table.sort(new) + box[box_id] = new + observed[box_id].first_multiple = true + elseif get_id(zone_id,'success') == message_id or get_id(zone_id,'failure') == message_id then + box[box_id] = nil + elseif get_id(zone_id,'tool_failure') == message_id then + observed[box_id].thief_tools_active = false + end + elseif id == 0x34 then + local box_id = original:unpack('I', 5) + if windower.ffxi.get_mob_by_id(box_id).name == 'Treasure Casket' then + local chances = original:byte(9) + if box[box_id] == nil then + box[box_id] = table.copy(default) + observed[box_id] = table.copy(observed_default) + end + if chances > 0 and chances < 7 then + display(box_id, chances) + end + end + elseif id == 0x5B then + box[original:unpack('I', 17)] = nil + observed[original:unpack('I', 17)] = nil + end + end +end + +function watch_for_keys(id, original, modified, injected, blocked) + if blocked then + elseif (id == 0x036 or id == 0x037) and + windower.ffxi.get_mob_by_id(modified:unpack('I',0x05)).name == 'Treasure Casket' and + (windower.ffxi.get_player().main_job == 'THF' or windower.ffxi.get_player().sub_job == 'THF') then + + local box_id = modified:unpack('I',0x05) + if not box[box_id] then + box[box_id] = table.copy(default) + observed[box_id] = table.copy(observed_default) + end + + if id == 0x037 and thief_tools[windower.ffxi.get_items(modified:byte(0x11))[modified:byte(0xF)].id] then + observed[box_id].thief_tools_active = true + elseif id == 0x036 then + for i = 1,9 do + if thief_tools[windower.ffxi.get_items(0)[modified:byte(0x30+i)].id] then + observed[box_id].thief_tools_active = true + break + end + end + end + end +end + +-- register event callbacks + +windower.register_event('incoming chunk', check_incoming_chunk) + +windower.register_event('outgoing chunk', watch_for_keys) diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/make_messages/make_messages.py b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/make_messages/make_messages.py new file mode 100644 index 0000000..932ea3b --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/make_messages/make_messages.py @@ -0,0 +1,77 @@ +# Python 3 +import array +import os +import struct +import winreg + +from settings import search, zones + + +def find_dat(dat_id): + key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\WOW6432Node\\PlayOnlineUS\\InstallFolder') + ffxi_path = winreg.QueryValueEx(key, '0001')[0] + key.Close() + for i in range(1, 10): + vtable = None + if i == 1: + vtable = open(os.path.join(ffxi_path, 'VTABLE.DAT'), 'rb') + else: + vtable = open(os.path.join(ffxi_path, 'ROM{}'.format(i), 'VTABLE{}.DAT'.format(i)), 'rb') + vtable.seek(dat_id) + temp = vtable.read(1)[0] + vtable.close() + if temp != i: + continue + ftable = None + if i == 1: + ftable = open(os.path.join(ffxi_path, 'FTABLE.DAT'), 'rb') + else: + ftable = open(os.path.join(ffxi_path, 'ROM{}'.format(i), 'FTABLE{}.DAT'.format(i)), 'rb') + ftable.seek(dat_id * 2) + path = struct.unpack('H', ftable.read(2))[0] + ftable.close() + if i == 1: + return os.path.join(ffxi_path, 'ROM', '{}'.format(path >> 7), '{}.DAT'.format(path & 0x7f)) + else: + return os.path.join(ffxi_path, 'ROM{}'.format(i), '{}'.format(path >> 7), '{}.DAT'.format(path & 0x7f)) + return None + +def decipher_dialog(dat_file): + dat = open(dat_file, 'rb') + dat_size, first_entry = struct.unpack('II', dat.read(8)) + dat_size -= 0x10000000 + first_entry ^= 0x80808080 + dat.seek(4) + data = bytearray(dat.read()) + dat.close() + for i in range(len(data)): + data[i] ^= 0x80 + offsets = array.array('I', data[:first_entry]) + offsets.append(dat_size) + for i in range(len(offsets)): + offsets[i] -= first_entry + return offsets, bytes(data[first_entry:]) + +def search_dialog(zones, search): + messages = {} + for zone_id, dat_id in zones.items(): + offsets, data = decipher_dialog(find_dat(dat_id)) + for i in range(len(offsets) - 1): + message = data[offsets[i]:offsets[i+1]] + if message == search: + messages[zone_id] = str(i) + return messages + +def write_lua(messages): + o = open('messages.lua', 'w') + print('messages = { -- These dialogue IDs match "You were unable to enter a combination" for the associated zone IDs', file=o) + zone_ids = list(messages.keys()) + zone_ids.sort() + for zone_id in zone_ids: + line = messages[zone_id]+',' + print(" [{}] = {}".format(zone_id, line), file=o) + print('}',file=o) + print('offsets = {greater_less=1, failure=2, success=4, second_even_odd=5, first_even_odd=6, range=7, less=8, greater=9, equal=10, second_multiple=11, first_multiple=12, tool_failure=13}',file=o) + o.close() + +write_lua(search_dialog(zones, search)) diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/make_messages/settings.py b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/make_messages/settings.py new file mode 100644 index 0000000..ccc6b1b --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/make_messages/settings.py @@ -0,0 +1,190 @@ +search = b'You were unable to enter a combination.\x7f1\x00\x07' + +zones = { + #1: 6421, # phanauet channel + #2: 6422, # carpenters' landing + #3: 6423, # manaclipper + #4: 6424, # bibiki bay + #11: 6431, # oldton movalpolos + #15: 6435, # abyssea - konschtat + #24: 6444, # lufaise meadows + #25: 6445, # misareaux coast + #26: 6446, # tavnazian safehold + #27: 6447, # phomiuna aquaducts + #33: 6453, # al'taieu + #39: 6459, # dynamis - valkurm + #40: 6460, # dynamis - buburimu + #41: 6461, # dynamis - qufim + #42: 6462, # dynamis - tavnazia + #43: 6463, # diorama abdhaljs-ghelsba + #44: 6464, # abdhaljs isle-purgonorgo + #45: 6465, # abyssea - tahrongi + #46: 6466, # open sea route to al zahbi + #47: 6467, # open sea route to mhaura + #48: 6468, # al zahbi + #50: 6470, # aht urhgan whitegate + #51: 6471, # wajaom woodlands + #52: 6472, # bhaflau thickets + #53: 6473, # nashmau + #54: 6474, # arrapago reef + #55: 6475, # ilrusi atoll + #56: 6476, # periqia + #57: 6477, # talacca cove + #58: 6478, # silver sea route to nashmau + #59: 6479, # silver sea route to al zahbi + #60: 6480, # the ashu talif + #61: 6481, # mount zhayolm + #65: 6485, # mamook + #66: 6486, # mamool ja training grounds + #67: 6487, # jade sepulcher + #68: 6488, # aydeewa subterrane + #69: 6489, # leujaoam sanctum + #79: 6499, # caedarva mire + #81: 6501, # east ronfaure [s] + #82: 6502, # jugner forest [s] + #83: 6503, # vunkerl inlet [s] + #84: 6504, # batallia downs [s] + #85: 6505, # la vaule [s] + #86: 6506, # everbloom hollow + #87: 6507, # bastok markets [s] + #88: 6508, # north gustaberg [s] + #89: 6509, # grauberg [s] + #90: 6510, # pashhow marshlands [s] + #91: 6511, # rolanberry fields [s] + #93: 6513, # ruhotz silvermines + #94: 6514, # windurst waters [s] + #95: 6515, # west sarutabaruta [a] + #96: 6516, # fort karugo-narugo [s] + #99: 6519, # castle oztroja [s] + 100: 6520, # west ronfaure + 101: 6521, # east ronfaure + 102: 6522, # la theine plateau + 103: 6523, # valkurm dunes + 104: 6524, # jugner forest + 105: 6525, # batallia downs + 106: 6526, # north gustaberg + 107: 6527, # south gustaberg + 108: 6528, # konschtat highlands + 109: 6529, # pashhow marshlands + 110: 6530, # rolanberry fields + 111: 6531, # beaucedine glacier + 112: 6532, # xarcabard + 113: 6533, # cape teriggan + 114: 6534, # eastern altepa desert + 115: 6535, # west sarutabaruta + 116: 6536, # east sarutabaruta + 117: 6537, # tahrongi canyon + 118: 6538, # buburimu peninsula + 119: 6539, # meriphataud mountains + 120: 6540, # sauromugue champaign + 121: 6541, # the sanctuary of zi'tah + 122: 6542, # ro'maeve + 123: 6543, # yuhtunga jungle + 124: 6544, # yhoator jungle + 125: 6545, # western altepa desert + 126: 6546, # qufim island + 127: 6547, # behemoth's dominion + 128: 6548, # valley of sorrows + 130: 6550, # ru'aun gardens + #132: 6552, # abyssea - la theine + #134: 6554, # dynamis - beaucedine + #136: 6556, # beaucedine glacier [s] + #139: 6559, # horlais peak + #140: 6560, # ghelsba outpost + #141: 6561, # fort ghelsba + #142: 6562, # yughott grotto + #143: 6563, # palborough mines + #145: 6565, # giddeus + #148: 6568, # qulun dome + #149: 6569, # davoi + #151: 6571, # castle oztroja + 153: 6573, # the boyahda tree + #154: 6574, # dragon's aery + 157: 6577, # middle delkfutt's tower + 158: 6578, # upper delkfutt's tower + 159: 6579, # temple of uggalepih + 160: 6580, # den of rancor + 166: 6586, # ranguemont pass + 167: 6587, # bostaunieux oubliette + 169: 6589, # torimarai canal + 172: 6592, # zeruhn mines + 173: 6593, # korroloka tunnel + 174: 6594, # kuftal tunnel + 176: 6596, # sea serpent grotto + 177: 6597, # ve'lugannon palace + 178: 6598, # the shrine of ru'avitau + 184: 6604, # lower delkfutt's tower + #186: 6606, # dynamis - bastok + #187: 6607, # dynamis - windurst + 190: 6610, # king ranpere's tomb + 191: 6611, # dangruf wadi + 192: 6612, # inner horutoto ruins + 193: 6613, # ordelle's caves + 194: 6614, # outer horutoto ruins + 195: 6615, # eldieme necropolis + 196: 6616, # gusgan mines + 197: 6617, # crawler's nest + 198: 6618, # maze of shakrami + 200: 6620, # garlaige citadel + 204: 6624, # fei'yin + 205: 6625, # ifrit's cauldron + 208: 6628, # quicksand caves + 212: 6632, # gustav tunnel + 213: 6633, # labyrinth of onzozo + #216: 6636, # abyssea - misareaux + #217: 6637, # abyssea - vunkerl + #218: 6638, # abyssea - altepa + #220: 6640, # ship bound for selbina + #221: 6641, # ship bound for mhaura + #222: 6642, # provenance + #227: 6647, # ship bound for selbina + #228: 6648, # ship bound for mhaura + #231: 6651, # northern san d'oria + #232: 6652, # port san d'oria + #234: 6654, # bastok mines + #235: 6655, # bastok markets + #236: 6656, # port bastok + #237: 6657, # metalworks + #238: 6658, # windurst waters + #239: 6659, # windurst walls + #240: 6660, # port windurst + #241: 6661, # windurst woods + #242: 6662, # heavens tower + #245: 6665, # lower jeuno + #246: 6666, # port jeuno + #247: 6667, # rabao + #248: 6668, # selbina + #249: 6669, # mhaura + #250: 6670, # kazham + #251: 6671, # hall of the gods + #252: 6672, # norg + #253: 6473, # abyssea - uleguerand + #254: 6674, # abyssea - grauberg + #256: 85591, # western adoulin + #257: 85592, # eastern adoulin + #258: 85593, # rala waterways + #259: 85594, # rala waterways [u] + #260: 85595, # yahse hunting grounds + #261: 85596, # ceizak battlegrounds + #262: 85597, # foret de hennetiel + #263: 85598, # yorcia weald + #264: 85599, # yorcia weald [u] + #265: 85600, # morimar basalt fields + #266: 85601, # marjami ravine + #267: 85602, # kamihr drifts + #268: 85603, # sih gates + #269: 85604, # moh gates + #270: 85605, # cirdas caverns + #271: 85606, # cirdas caverns [u] + #272: 85607, # dho gates + #273: 85608, # woh gates + #274: 85609, # outer ra'kaznar + #275: 85610, # outer ra'kaznar [u] + #276: 85611, # ra'kaznar inner court + #277: 85612, # ra'kaznar turris + #280: 85615, # mog garden + #281: 85616, # leafallia + #288: 85623, # escha - zi'tah + #289: 85624, # escha - ru'aun + #291: 85626, # reisenjima +} diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/messages.lua b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/messages.lua new file mode 100644 index 0000000..6624a95 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/boxdestroyer/messages.lua @@ -0,0 +1,63 @@ +messages = { -- These dialogue IDs match "You were unable to enter a combination" for the associated zone IDs + [100] = 8078, + [101] = 7509, + [102] = 7929, + [103] = 8104, + [104] = 8669, + [105] = 7720, + [106] = 8094, + [107] = 7555, + [108] = 7624, + [109] = 8487, + [110] = 7611, + [111] = 8588, + [112] = 8190, + [113] = 7932, + [114] = 7789, + [115] = 7885, + [116] = 7581, + [117] = 7588, + [118] = 8130, + [119] = 8367, + [120] = 7527, + [121] = 8107, + [122] = 7438, + [123] = 7890, + [124] = 7841, + [125] = 7651, + [126] = 8074, + [127] = 7355, + [128] = 7510, + [130] = 7574, + [153] = 11400, + [157] = 7380, + [158] = 7386, + [159] = 8449, + [160] = 7413, + [166] = 10582, + [167] = 10596, + [169] = 7543, + [172] = 7416, + [173] = 10521, + [174] = 11399, + [176] = 7608, + [177] = 11223, + [178] = 11403, + [184] = 8633, + [190] = 8257, + [191] = 8377, + [192] = 7413, + [193] = 8389, + [194] = 8269, + [195] = 7600, + [196] = 8309, + [197] = 7354, + [198] = 8275, + [200] = 7531, + [204] = 7519, + [205] = 11486, + [208] = 8288, + [212] = 10642, + [213] = 10452, +} +offsets = {greater_less=1, failure=2, success=4, second_even_odd=5, first_even_odd=6, range=7, less=8, greater=9, equal=10, second_multiple=11, first_multiple=12, tool_failure=13} |