diff --git a/soh/include/z64save.h b/soh/include/z64save.h index acee40aad..c9748fac1 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -170,16 +170,18 @@ typedef struct ShipBossRushSaveContextData { } ShipBossRushSaveContextData; typedef struct ArchipelagoLocationData { + u8 itemType; char itemName[100]; char locationName[100]; char playerName[17]; - u8 itemType; } ArchipelagoLocationData; typedef struct ShipArchipelagoSaveContextData { + u8 isArchipelago; + u32 lastReceivedItemIndex; + u8 deathLink; char roomHash[100]; char slotName[17]; - u32 lastReceivedItemIndex; ArchipelagoLocationData locations[RC_MAX]; } ShipArchipelagoSaveContextData; diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index e1a92c07c..8a13770ba 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -406,11 +406,11 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce-Fragment" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_TRIFORCE_PIECES, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); // Archipelago - itemTable[RG_ARCHIPELAGO_ITEM_USEFUL] = Item(RG_ARCHIPELAGO_ITEM_USEFUL, Text{"AP Item (useful)", "AP Item (useful)", "AP Item (useful)"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, RG_ARCHIPELAGO_ITEM_USEFUL, OBJECT_GI_LETTER, GID_LETTER_ZELDA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); + itemTable[RG_ARCHIPELAGO_ITEM_USEFUL] = Item(RG_ARCHIPELAGO_ITEM_USEFUL, Text{"Useful AP Item", "Useful AP Item", "Useful AP Item"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, RG_ARCHIPELAGO_ITEM_USEFUL, OBJECT_GI_LETTER, GID_LETTER_ZELDA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_ARCHIPELAGO_ITEM_USEFUL].SetCustomDrawFunc(Randomizer_DrawArchipelagoItem); - itemTable[RG_ARCHIPELAGO_ITEM_JUNK] = Item(RG_ARCHIPELAGO_ITEM_JUNK, Text{"AP Item (junk)", "AP Item (junk)", "AP Item (junk)"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, RG_ARCHIPELAGO_ITEM_JUNK, OBJECT_GI_LETTER, GID_LETTER_ZELDA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_RANDOMIZER); + itemTable[RG_ARCHIPELAGO_ITEM_JUNK] = Item(RG_ARCHIPELAGO_ITEM_JUNK, Text{"Junk AP Item", "Junk AP Item", "Junk AP Item"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, RG_ARCHIPELAGO_ITEM_JUNK, OBJECT_GI_LETTER, GID_LETTER_ZELDA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_RANDOMIZER); itemTable[RG_ARCHIPELAGO_ITEM_JUNK].SetCustomDrawFunc(Randomizer_DrawArchipelagoItem); - itemTable[RG_ARCHIPELAGO_ITEM_PROGRESSIVE] = Item(RG_ARCHIPELAGO_ITEM_PROGRESSIVE, Text{"AP Item (progressive)", "AP Item (progressive)", "AP Item (progressive)"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, RG_ARCHIPELAGO_ITEM_PROGRESSIVE, OBJECT_GI_LETTER, GID_LETTER_ZELDA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ARCHIPELAGO_ITEM_PROGRESSIVE] = Item(RG_ARCHIPELAGO_ITEM_PROGRESSIVE, Text{"Progressive AP Item", "Progressive AP Item", "Progressive AP Item"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, LOGIC_NONE, RHT_NONE, RG_ARCHIPELAGO_ITEM_PROGRESSIVE, OBJECT_GI_LETTER, GID_LETTER_ZELDA, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_ARCHIPELAGO_ITEM_PROGRESSIVE].SetCustomDrawFunc(Randomizer_DrawArchipelagoItem); // clang-format on diff --git a/soh/soh/Network/Archipelago/Archipelago.cpp b/soh/soh/Network/Archipelago/Archipelago.cpp index 7d6de525e..2a181c8ff 100644 --- a/soh/soh/Network/Archipelago/Archipelago.cpp +++ b/soh/soh/Network/Archipelago/Archipelago.cpp @@ -210,22 +210,81 @@ const char* ArchipelagoClient::GetConnectionStatus() { void LoadArchipelagoData() { + SaveManager::Instance->LoadData("isArchipelago", gSaveContext.ship.quest.data.archipelago.isArchipelago); + SaveManager::Instance->LoadData("lastReceivedItemIndex", + gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex); + SaveManager::Instance->LoadData("deathLink", gSaveContext.ship.quest.data.archipelago.deathLink); + SaveManager::Instance->LoadCharArray("roomHash", gSaveContext.ship.quest.data.archipelago.roomHash, ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.roomHash)); - SaveManager::Instance->LoadData("lastReceivedItemIndex", gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex); + SaveManager::Instance->LoadCharArray("slotName", gSaveContext.ship.quest.data.archipelago.slotName, + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.slotName)); + + SaveManager::Instance->LoadArray( + "locations", ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations), + [](size_t i) { + SaveManager::Instance->LoadStruct("", [&i]() { + SaveManager::Instance->LoadData("itemType", + gSaveContext.ship.quest.data.archipelago.locations[i].itemType); + + SaveManager::Instance->LoadCharArray( + "itemName", gSaveContext.ship.quest.data.archipelago.locations[i].itemName, + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations[i].itemName)); + SaveManager::Instance->LoadCharArray( + "locationName", gSaveContext.ship.quest.data.archipelago.locations[i].locationName, + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations[i].locationName)); + SaveManager::Instance->LoadCharArray( + "playerName", gSaveContext.ship.quest.data.archipelago.locations[i].playerName, + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations[i].playerName)); + }); + }); } void SaveArchipelagoData(SaveContext* saveContext, int sectionID, bool fullSave) { - SaveManager::Instance->SaveData("roomHash", saveContext->ship.quest.data.archipelago.roomHash); + SaveManager::Instance->SaveData("isArchipelago", saveContext->ship.quest.data.archipelago.isArchipelago); SaveManager::Instance->SaveData("lastReceivedItemIndex", saveContext->ship.quest.data.archipelago.lastReceivedItemIndex); + SaveManager::Instance->SaveData("deathLink", saveContext->ship.quest.data.archipelago.deathLink); + + SaveManager::Instance->SaveData("roomHash", saveContext->ship.quest.data.archipelago.roomHash); + SaveManager::Instance->SaveData("slotName", saveContext->ship.quest.data.archipelago.slotName); + + SaveManager::Instance->SaveArray( + "locations", ARRAY_COUNT(saveContext->ship.quest.data.archipelago.locations), [&](size_t i) { + SaveManager::Instance->SaveStruct("", [&]() { + SaveManager::Instance->SaveData("itemType", + saveContext->ship.quest.data.archipelago.locations[i].itemType); + + SaveManager::Instance->SaveData("itemName", + saveContext->ship.quest.data.archipelago.locations[i].itemName); + SaveManager::Instance->SaveData("locationName", + saveContext->ship.quest.data.archipelago.locations[i].locationName); + SaveManager::Instance->SaveData("playerName", + saveContext->ship.quest.data.archipelago.locations[i].playerName); + }); + }); } void InitArchipelagoData(bool isDebug) { + gSaveContext.ship.quest.data.archipelago.isArchipelago = 0; + gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex = 0; + gSaveContext.ship.quest.data.archipelago.deathLink = 0; + SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.roomHash, "", ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.roomHash)); + SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.slotName, "", + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.slotName)); - gSaveContext.ship.quest.data.archipelago.lastReceivedItemIndex = 0; + for (uint32_t i; i < ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations); i++) { + gSaveContext.ship.quest.data.archipelago.locations[i].itemType = 0; + + SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.locations[i].itemName, "", + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations[i].itemName)); + SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.locations[i].locationName, "", + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations[i].locationName)); + SohUtils::CopyStringToCharArray(gSaveContext.ship.quest.data.archipelago.locations[i].playerName, "", + ARRAY_COUNT(gSaveContext.ship.quest.data.archipelago.locations[i].playerName)); + } } // Implement this properly once we have some kind of indication within a save file wether the player is in a normal