diff --git a/addons/boxdestroyer/README b/addons/boxdestroyer/README index a34f5b9833..a8d0983c69 100644 --- a/addons/boxdestroyer/README +++ b/addons/boxdestroyer/README @@ -8,5 +8,6 @@ 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. +will recommend whether to examine the chest or guess a number. When it +recommends guessing a number, your probability of success with an +optimal guess-only strategy is also displayed. diff --git a/addons/boxdestroyer/boxdestroyer.lua b/addons/boxdestroyer/boxdestroyer.lua index af70616bba..7b538a774d 100644 --- a/addons/boxdestroyer/boxdestroyer.lua +++ b/addons/boxdestroyer/boxdestroyer.lua @@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- addon information _addon.name = 'boxdestroyer' -_addon.version = '1.0.5' +_addon.version = '1.0.6' _addon.command = 'boxdestroyer' _addon.author = 'Seth VanHeulen (Acacia@Odin)' @@ -48,6 +48,7 @@ config = require('config') defaults = { HighlightResult = false, HighlightColor = 36, + DisplayRemainingCombinations = false, } settings = config.load(defaults) -- global constants @@ -265,39 +266,37 @@ 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], ' ')) + if settings.DisplayRemainingCombinations then + 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 end - local remaining = math.floor(#box[id] / math.pow(2, (chances - 1))) + local probability = math.min(100, math.floor(100 * (math.pow(2, chances) - 1) / #box[id] )) + local remaining = math.floor(#box[id] / math.pow(2, chances - 1)) if remaining == 0 then remaining = 1 end + + local guess_number = box[id][math.ceil(#box[id] / 2)] 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 + -- 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 + guess_number = v 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 - + local clue_value,guess_value = calculate_odds(id,chances) + local result = clue_value > guess_value and remaining ~= 1 and 'examining the lock' or 'guessing %d (%d%%)':format(guess_number, probability) + local formatted_result = settings.HighlightResult and result:color(settings.HighlightColor) or result + windower.add_to_chat(207, 'boxdestroyer recommends ' .. formatted_result) + end -- ID obtaining helper function diff --git a/addons/instaLS/instaLS.lua b/addons/instaLS/instaLS.lua index 26b7e8b784..ca729bec52 100644 --- a/addons/instaLS/instaLS.lua +++ b/addons/instaLS/instaLS.lua @@ -25,27 +25,27 @@ --SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. _addon.name = 'instaLS' -_addon.version = 0.160309 +_addon.version = 0.220213 _addon.author = 'Byrth' -flag=false +linkshell_inventories_loaded = true chatmode = {} chatcolor = {} message = false require 'strings' - +bit = require 'bit' function translate_escape(str) return str:escape():gsub(string.char(0xFD)..".-"..string.char(0xFD),string.char(0xEF,0x27).."(.-)"..string.char(0xEF,0x25,0x25,0x28)) end windower.register_event('zone change',function() - flag=false + linkshell_inventories_loaded = false end) -windower.register_event('incoming chunk',function(id) - if id == 0x1D then - flag = true +windower.register_event('incoming chunk', function(id,org) + if not linkshell_inventories_loaded and id == 0x01D then + linkshell_inventories_loaded = bit.band(org:byte(0x09), 225) == 225 end end) @@ -68,7 +68,7 @@ windower.register_event('incoming text',function(org, mod, col) end) windower.register_event('outgoing text',function(org,mod,bool) - if bool or flag then return end + if bool or linkshell_inventories_loaded then return end if mod:sub(1,3) == '/l ' then chatmode[#chatmode+1] = 0x05 chatcolor[#chatcolor+1] = 6 @@ -90,4 +90,4 @@ windower.register_event('outgoing text',function(org,mod,bool) end return '/s '..message -end) \ No newline at end of file +end) diff --git a/addons/libs/packets/fields.lua b/addons/libs/packets/fields.lua index 02d4c60cd9..98525c1fe7 100644 --- a/addons/libs/packets/fields.lua +++ b/addons/libs/packets/fields.lua @@ -164,7 +164,7 @@ local function emote(val) end local function bag(val) - return res.bags[val].name + return res.bags[val] and res.bags[val].name or 'Unknown' end local function race(val) @@ -1582,11 +1582,16 @@ fields.incoming[0x01C] = L{ {ctype='data[28]', label='_padding2', const=''}, -- 48 } +types.bagbits= L{ + {ctype='boolbit', label='Finished'} +} -- Finish Inventory fields.incoming[0x01D] = L{ - {ctype='unsigned char', label='Flag'}, -- 04 0 for bag finished updates, 1 for finished loading inventories - {ctype='unsigned char', label='Bag'}, -- 05 18 (0x12) when flag is 1, and 18 is not a valid bag id (last bag + 1) - {ctype='data[6]', label='_junk1'}, -- 06 + {ctype='unsigned char', label='Flag'}, -- 04 0 for bag finished updates, 1 for finished loading all bags + {ctype='unsigned char', label='Bag', fn=bag}, -- 05 18 (0x12) when Flag is 1, and 18 is not a valid bag id (currently last bag + 1) + {ctype='data[2]', label='_junk1'}, -- 06 + {ref=types.bagbits, lookup={res.bags, 0x00}, count=0x12}, -- 08 due to the way packets are sent, false does not necsarilly mean its not Finished, true simple means that it is Finished. + {ctype='data[1]', label='_junk2'}, -- 0B } -- Modify Inventory @@ -3203,14 +3208,48 @@ fields.incoming[0x070] = L{ } -- Unity Start --- Only observed being used for Unity fights. -fields.incoming[0x075] = L{ +-- Only observed being used for Unity fights. Also observed on DynaD, Odyssey for mask//weapon/neck/izzat progression bars, Escutcheons progression and mandragora minigame. +func.incoming[0x075] = {} +fields.incoming[0x075] = function() + local fields = func.incoming[0x075] + + return function(data, type) + return fields.base + (fields[type] or (data:byte(0x025) > 1 and fields.bars) or fields.default) + end +end() + +enums[0x075] = { + [0] = 'No Timer', + [1] = 'Timer', + [2] = 'Bars', + [3] = 'Timer and Bars', +} + +types.bars = L{ + {ctype='unsigned char', label='Bar Progress'}, -- 28 0xFF if inactive + {ctype='data[3]', label='_unknown4'}, -- 29 Observed 0x000000 if active, 0xFFFFF7 if inactive + {ctype='char[16]', label='Bar String'}, -- 2C Bar 1 for mask/izzat | Bar 2 Main slot | Bar 3 Sub slot | Bar 4 Ranged slot | Bar 5 Neck slot +} + +func.incoming[0x075].base = L{ {ctype='unsigned int', label='Fight Designation'}, -- 04 Anything other than 0 makes a timer. 0 deletes the timer. {ctype='unsigned int', label='Timestamp Offset', fn=time}, -- 08 Number of seconds since 15:00:00 GMT 31/12/2002 (0x3C307D70) {ctype='unsigned int', label='Fight Duration', fn=time}, -- 0C {ctype='data[12]', label='_unknown1'}, -- 10 This packet clearly needs position information, but it's unclear how these bytes carry it {ctype='unsigned int', label='Battlefield Radius'}, -- 1C Yalms*1000, so a 50 yalm battlefield would have 50,000 for this field {ctype='unsigned int', label='Render Radius'}, -- 20 Yalms*1000, so a fence that renders when you're 25 yalms away would have 25,000 for this field + {ctype='unsigned char', label='Type', fn=e+{0x075}}, -- 24 most likely a bitflag where first bit activates the timer and bit 2 activates the bars +} + +func.incoming[0x075].default = L{ + {ctype='data[135]', label='_junk1'}, -- 28 Seems to be junk +} + +func.incoming[0x075].bars = L{ + {ctype='unsigned char', label='_unknown2'}, -- 25 + {ctype='unsigned short', label='_unknown3'}, -- 26 Value changes constatly + {ref=types.bars, count=5}, -- 28 + {ctype='data[32]', label='_unknown5'}, -- 8C } -- Party status icon update diff --git a/addons/setbgm/setbgm.lua b/addons/setbgm/setbgm.lua index 000c7be8f6..88e99c45d7 100644 --- a/addons/setbgm/setbgm.lua +++ b/addons/setbgm/setbgm.lua @@ -50,7 +50,7 @@ music_types = { } songs = { - [25]='Voracious Resurgence Unknown 1', [26]='Voracious Resurgence Unknown 2', [27]='Voracious Resurgence Unknown 3', [28]='Voracious Resurgence Unknown 4', [29]="Devils' Delight", [30]="Odyssey - Bumba", [31]='Voracious Resurgence Unknown 5', [32]='Voracious Resurgence Unknown 6', + [25]='Voracious Resurgence Unknown 1', [26]='Voracious Resurgence Unknown 2', [27]='Voracious Resurgence Unknown 3', [28]='Voracious Resurgence Unknown 4', [29]="Devils' Delight", [30]="Odyssey - Bumba", [31]='Voracious Resurgence Unknown 5', [32]='Voracious Resurgence Unknown 6', [33]='Voracious Resurgence Unknown 7', [40]='Cloister of Time and Souls', [41]='Royal Wanderlust', [42]='Snowdrift Waltz', [43]='Troubled Shadows', [44]='Where Lords Rule Not', [45]='Summers Lost', [46]='Goddess Divine', [47]='Echoes of Creation', [48]='Main Theme', [49]='Luck of the Mog', [50]='Feast of the Ladies', [51]='Abyssea - Scarlet Skies, Shadowed Plains', [52]='Melodies Errant', [53]='Shinryu', [54]='Everlasting Bonds', [55]='Provenance Watcher', [56]='Where it All Begins', [57]='Steel Sings, Blades Dance', [58]='A New Direction', [59]='The Pioneers', [60]='Into Lands Primeval - Ulbuka', [61]="Water's Umbral Knell", [62]='Keepers of the Wild', [63]='The Sacred City of Adoulin', [64]='Breaking Ground', [65]='Hades', [66]='Arciela', [67]='Mog Resort', [68]='Worlds Away', [69]="Distant Worlds (Nanaa Mihgo's version)",