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.
This commit is contained in:
Altiami 2023-09-15 11:18:03 -07:00 committed by GitHub
parent 44f1a93d31
commit f9120c620f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 7 deletions

View File

@ -67,6 +67,7 @@ local itemsObtained = 0x0677
local takeAnyCavesChecked = 0x0678 local takeAnyCavesChecked = 0x0678
local localTriforce = 0x0679 local localTriforce = 0x0679
local bonusItemsObtained = 0x067A local bonusItemsObtained = 0x067A
local itemsObtainedHigh = 0x067B
itemAPids = { itemAPids = {
["Boomerang"] = 7100, ["Boomerang"] = 7100,
@ -173,11 +174,18 @@ for key, value in pairs(itemAPids) do
itemIDNames[value] = key itemIDNames[value] = key
end 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) local function determineItem(array)
memdomain.ram() memdomain.ram()
currentItemsObtained = u8(itemsObtained) currentItemsObtained = getItemsObtained()
end end
@ -364,8 +372,8 @@ local function gotItem(item)
wU8(0x505, itemCode) wU8(0x505, itemCode)
wU8(0x506, 128) wU8(0x506, 128)
wU8(0x602, 4) wU8(0x602, 4)
numberObtained = u8(itemsObtained) + 1 numberObtained = getItemsObtained() + 1
wU8(itemsObtained, numberObtained) setItemsObtained(numberObtained)
if itemName == "Boomerang" then gotBoomerang() end if itemName == "Boomerang" then gotBoomerang() end
if itemName == "Bow" then gotBow() end if itemName == "Bow" then gotBow() end
if itemName == "Magical Boomerang" then gotMagicalBoomerang() end if itemName == "Magical Boomerang" then gotMagicalBoomerang() end
@ -476,7 +484,7 @@ function processBlock(block)
if i > u8(bonusItemsObtained) then if i > u8(bonusItemsObtained) then
if u8(0x505) == 0 then if u8(0x505) == 0 then
gotItem(item) gotItem(item)
wU8(itemsObtained, u8(itemsObtained) - 1) setItemsObtained(getItemsObtained() - 1)
wU8(bonusItemsObtained, u8(bonusItemsObtained) + 1) wU8(bonusItemsObtained, u8(bonusItemsObtained) + 1)
end end
end end
@ -494,7 +502,7 @@ function processBlock(block)
for i, item in ipairs(itemsBlock) do for i, item in ipairs(itemsBlock) do
memDomain.ram() memDomain.ram()
if u8(0x505) == 0 then if u8(0x505) == 0 then
if i > u8(itemsObtained) then if i > getItemsObtained() then
gotItem(item) gotItem(item)
end end
end end
@ -546,7 +554,7 @@ function receive()
retTable["gameMode"] = gameMode retTable["gameMode"] = gameMode
retTable["overworldHC"] = getHCLocation() retTable["overworldHC"] = getHCLocation()
retTable["overworldPB"] = getPBLocation() retTable["overworldPB"] = getPBLocation()
retTable["itemsObtained"] = u8(itemsObtained) retTable["itemsObtained"] = getItemsObtained()
msg = json.encode(retTable).."\n" msg = json.encode(retTable).."\n"
local ret, error = zeldaSocket:send(msg) local ret, error = zeldaSocket:send(msg)
if ret == nil then if ret == nil then