From f9120c620fefb18ca273313d4ea1adc510944ced Mon Sep 17 00:00:00 2001 From: Altiami Date: Fri, 15 Sep 2023 11:18:03 -0700 Subject: [PATCH] The Legend of Zelda Conntector: Make items obtained counter in save data 16 bits. (#2117) Certain multiworld settings (bug observed with item link settings) can cause the total item count in TLoZ world to exceed 255. This causes an overflow in the loop to receive all pending items. This adds an additional byte to be used as a high byte for the items obtained counter. This approach was taken due to the surrounding bytes being occupied, preventing a direct 16-bit number from being used without moving to a different location and leaving more empty bytes in the memory block for save data. --- data/lua/connector_tloz.lua | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/data/lua/connector_tloz.lua b/data/lua/connector_tloz.lua index f48e4dfa..4a2d2f25 100644 --- a/data/lua/connector_tloz.lua +++ b/data/lua/connector_tloz.lua @@ -67,6 +67,7 @@ local itemsObtained = 0x0677 local takeAnyCavesChecked = 0x0678 local localTriforce = 0x0679 local bonusItemsObtained = 0x067A +local itemsObtainedHigh = 0x067B itemAPids = { ["Boomerang"] = 7100, @@ -173,11 +174,18 @@ for key, value in pairs(itemAPids) do itemIDNames[value] = key end +local function getItemsObtained() + return bit.bor(bit.lshift(u8(itemsObtainedHigh), 8), u8(itemsObtained)) +end +local function setItemsObtained(value) + wU8(itemsObtainedHigh, bit.rshift(value, 8)) + wU8(itemsObtained, bit.band(value, 0xFF)) +end local function determineItem(array) memdomain.ram() - currentItemsObtained = u8(itemsObtained) + currentItemsObtained = getItemsObtained() end @@ -364,8 +372,8 @@ local function gotItem(item) wU8(0x505, itemCode) wU8(0x506, 128) wU8(0x602, 4) - numberObtained = u8(itemsObtained) + 1 - wU8(itemsObtained, numberObtained) + numberObtained = getItemsObtained() + 1 + setItemsObtained(numberObtained) if itemName == "Boomerang" then gotBoomerang() end if itemName == "Bow" then gotBow() end if itemName == "Magical Boomerang" then gotMagicalBoomerang() end @@ -476,7 +484,7 @@ function processBlock(block) if i > u8(bonusItemsObtained) then if u8(0x505) == 0 then gotItem(item) - wU8(itemsObtained, u8(itemsObtained) - 1) + setItemsObtained(getItemsObtained() - 1) wU8(bonusItemsObtained, u8(bonusItemsObtained) + 1) end end @@ -494,7 +502,7 @@ function processBlock(block) for i, item in ipairs(itemsBlock) do memDomain.ram() if u8(0x505) == 0 then - if i > u8(itemsObtained) then + if i > getItemsObtained() then gotItem(item) end end @@ -546,7 +554,7 @@ function receive() retTable["gameMode"] = gameMode retTable["overworldHC"] = getHCLocation() retTable["overworldPB"] = getPBLocation() - retTable["itemsObtained"] = u8(itemsObtained) + retTable["itemsObtained"] = getItemsObtained() msg = json.encode(retTable).."\n" local ret, error = zeldaSocket:send(msg) if ret == nil then @@ -606,4 +614,4 @@ function main() end end -main() \ No newline at end of file +main()