From f6b86d3f383c557401dc536abdf7ad702794d140 Mon Sep 17 00:00:00 2001 From: CraftyBoss Date: Tue, 9 Jun 2026 01:23:05 -0700 Subject: [PATCH] actually get some ap functionality going getting items from the server works now mostly, for now we're ignoring inventory fills as its going to require a bit of work to reset the inventory on connection. --- files.cmake | 2 + include/dusk/settings.h | 7 + src/dusk/archipelago/archipelago_context.cpp | 225 ++++++++++++++++++ src/dusk/archipelago/archipelago_context.hpp | 53 +++++ src/dusk/imgui/ImGuiArchipelagoDebug.cpp | 34 ++- src/dusk/imgui/ImGuiArchipelagoDebug.h | 6 + src/dusk/randomizer/generator/data/items.yaml | 145 +++++++++++ src/dusk/settings.cpp | 12 +- 8 files changed, 482 insertions(+), 2 deletions(-) create mode 100644 src/dusk/archipelago/archipelago_context.cpp create mode 100644 src/dusk/archipelago/archipelago_context.hpp diff --git a/files.cmake b/files.cmake index de7251418f..2acebe320e 100644 --- a/files.cmake +++ b/files.cmake @@ -1624,6 +1624,8 @@ set(DUSK_FILES src/dusk/randomizer/generator/utility/time.cpp src/dusk/randomizer/generator/utility/time.hpp src/dusk/randomizer/generator/utility/yaml.hpp + # Archipelago Files + src/dusk/archipelago/archipelago_context.cpp ) set(DUSK_HTTP_BACKEND_FILES diff --git a/include/dusk/settings.h b/include/dusk/settings.h index e676e425d3..3a69dc84cf 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -289,6 +289,13 @@ struct UserSettings { std::array openDusklightMenu; std::array turboSpeedButton; } actionBindings; + + // Archipelago Settings + struct { + ConfigVar serverIP; + ConfigVar serverPass; + ConfigVar slotName; + } archipelago; }; UserSettings& getSettings(); diff --git a/src/dusk/archipelago/archipelago_context.cpp b/src/dusk/archipelago/archipelago_context.cpp new file mode 100644 index 0000000000..ce7b9e32e7 --- /dev/null +++ b/src/dusk/archipelago/archipelago_context.cpp @@ -0,0 +1,225 @@ +#include + +#include + +#include "Archipelago.h" +#include "d/d_item.h" +#include "dusk/config.hpp" +#include "dusk/logging.h" +#include "dusk/ui/ui.hpp" + +namespace dusk::archi +{ + +static constexpr int ARCHI_ITEM_OFFSET = 2320000; + +ArchipelagoContext& instance() { + static ArchipelagoContext instance; + return instance; +} + +const char* getMessageTypeName(AP_MessageType type) { + switch (type) { + case AP_MessageType::Plaintext: + return "Plaintext"; + case AP_MessageType::ItemSend: + return "ItemSend"; + case AP_MessageType::ItemRecv: + return "ItemRecv"; + case AP_MessageType::Hint: + return "Hint"; + case AP_MessageType::Countdown: + return "Countdown"; + default: + return nullptr; + } +} + +void ParseMessageData() { + auto msg = AP_GetLatestMessage(); + + switch (msg->type) { + case AP_MessageType::ItemRecv: { + auto recvMsg = (AP_ItemRecvMessage*)msg; + + ui::push_toast({ + .title = "Item Received", + .content = fmt::format("Got {} From {}", recvMsg->item, recvMsg->sendPlayer), + .duration = std::chrono::seconds(3), + }); + // fallthrough for debug logging text contents + } + case AP_MessageType::Plaintext: + case AP_MessageType::ItemSend: + case AP_MessageType::Hint: + case AP_MessageType::Countdown: + DuskLog.info("[{}] {}", getMessageTypeName(msg->type), msg->text); + break; + default: + DuskLog.warn("Unknown message type! Type: {}", fmt::underlying(msg->type)); + break; + } + + AP_ClearLatestMessage(); +} + +void ArchipelagoContext::LoadTempItemInfo() { + auto itemDataTree = LOAD_EMBED_YAML(RANDO_DATA_PATH "items.yaml"); + for (const auto& itemNode : itemDataTree) { + if (!itemNode["APItemId"]) { + DuskLog.warn("Item {} missing APItemId field!", itemNode["Name"].as()); + continue; + } + auto apItemId = itemNode["APItemId"].as(); + + if (apItemId == -1) + continue; + + auto id = itemNode["Id"].as(); + auto importance = randomizer::logic::item::ImportanceFromStr(itemNode["Importance"].as()); + auto itemName = itemNode["Name"].as(); + + m_apItemToGameItem[apItemId] = { + id, + importance, + itemName + }; + } +} + +void ArchipelagoContext::itemRecvImpl(int id) { + if (!m_apItemToGameItem.contains(id)) { + DuskLog.warn("Got an invalid Item Id: {}", id); + return; + } + + auto& item = m_apItemToGameItem[id]; + + DuskLog.info("[AP] Adding Item: {}", item.itemName); + + if (item.importance == randomizer::logic::item::Importance::MAJOR) { + g_randomizerState.addItemToEventQueue(item.itemId); + }else { + execItemGet(item.itemId); + } +} + +ArchipelagoContext::ArchipelagoContext() { + +} + +void ArchipelagoContext::SetServerIp(const std::string_view& ip) { + getSettings().archipelago.serverIP.setValue(std::string(ip)); +} + +void ArchipelagoContext::SetSlotName(const std::string_view& name) { + getSettings().archipelago.slotName.setValue(std::string(name)); +} + +void ArchipelagoContext::SetPassword(const std::string_view& pass) { + getSettings().archipelago.serverPass.setValue(std::string(pass)); +} + +const std::string& ArchipelagoContext::GetServerIp() { + return getSettings().archipelago.serverIP.getValue(); +} + +const std::string& ArchipelagoContext::GetSlotName() { + return getSettings().archipelago.slotName.getValue(); +} + +const std::string& ArchipelagoContext::GetPassword() { + return getSettings().archipelago.serverPass.getValue(); +} + +void ArchipelagoContext::ConnectToServer() { + config::Save(); + + instance().LoadTempItemInfo(); + + AP_Init(GetServerIp().c_str(), "Twilight Princess", GetSlotName().c_str(), GetPassword().c_str()); + + AP_NetworkVersion ver{0, 6,7}; + AP_SetClientVersion(&ver); + + AP_SetItemClearCallback([]() { + DuskLog.info("Item Clear Callback Called!"); + }); + + AP_SetItemRecvCallback([](int id, bool notify) { + DuskLog.info("Item Receive Callback Called! Item: {} Notify: {}", id, notify); + HandleItemReceived(id, notify); + }); + + AP_SetLocationCheckedCallback([](int loc) { + DuskLog.info("Location Checked Callback Called! Location: {}", loc); + }); + + AP_Start(); + + if (AP_GetConnectionStatus() == AP_ConnectionStatus::ConnectionRefused) { + DuskLog.warn("Failed to Connect to Archipelago Server."); + return; + } + + std::thread messageThread = std::thread(MainThreadFunc); + messageThread.detach(); +} + +void ArchipelagoContext::DisconnectFromServer() { + if (!IsConnected()) { + DuskLog.warn("Attempted to disconnect from an already disconnected state!"); + return; + } + + AP_Shutdown(); +} + +bool ArchipelagoContext::IsConnected() { + auto status = AP_GetConnectionStatus(); + return status == AP_ConnectionStatus::Connected || status == AP_ConnectionStatus::Authenticated; +} + +void ArchipelagoContext::MainThreadFunc() { + // wait a bit before checking connection state, as websocket is probably not connected yet + std::this_thread::sleep_for(std::chrono::seconds(1)); + + DuskLog.info("AP Thread started."); + + while (IsConnected()) { + if (AP_IsMessagePending()) + ParseMessageData(); + + instance().m_queueMutex.lock(); + if (randomizer_IsActive() && !instance().m_inactiveItemsQueue.empty()) { + for (auto item : instance().m_inactiveItemsQueue) { + instance().itemRecvImpl(item); + } + + instance().m_inactiveItemsQueue.clear(); + } + instance().m_queueMutex.unlock(); + } + + DuskLog.info("AP Thread ended."); +} + +void ArchipelagoContext::HandleItemReceived(int id, bool notify) { + // TODO: instead of skipping inventory fill, we should clear the inventory when the clear item callback is called. + if (!notify) { + DuskLog.info("Skipping Item."); + return; + } + + if (!randomizer_IsActive()) { + DuskLog.info("Randomizer not active, adding item to queue."); + + instance().m_queueMutex.lock(); + instance().m_inactiveItemsQueue.push_back(id - ARCHI_ITEM_OFFSET); + instance().m_queueMutex.unlock(); + return; + } + + instance().itemRecvImpl(id - ARCHI_ITEM_OFFSET); +} +} // dusk::archi \ No newline at end of file diff --git a/src/dusk/archipelago/archipelago_context.hpp b/src/dusk/archipelago/archipelago_context.hpp new file mode 100644 index 0000000000..77a68b9ac7 --- /dev/null +++ b/src/dusk/archipelago/archipelago_context.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +namespace dusk::archi +{ + class ArchipelagoContext { + private: + struct TEMP_GameItemInfo { + int itemId; + randomizer::logic::item::Importance importance; + std::string itemName; + }; + + std::vector m_inactiveItemsQueue; + std::mutex m_queueMutex; + + // TEMP + std::map m_apItemToGameItem; + + void LoadTempItemInfo(); + + void itemRecvImpl(int id); + public: + ArchipelagoContext(); + + // Config Getters/Setters + + static void SetServerIp(const std::string_view& ip); + static void SetSlotName(const std::string_view& name); + static void SetPassword(const std::string_view& pass); + + static const std::string& GetServerIp(); + static const std::string& GetSlotName(); + static const std::string& GetPassword(); + + // Connection Handlers + + static void ConnectToServer(); + + static void DisconnectFromServer(); + + static bool IsConnected(); + + // State Handlers + + static void MainThreadFunc(); + + static void HandleItemReceived(int id, bool notify); + + }; +} // dusk::archi \ No newline at end of file diff --git a/src/dusk/imgui/ImGuiArchipelagoDebug.cpp b/src/dusk/imgui/ImGuiArchipelagoDebug.cpp index ac1239e71c..2d042d278e 100644 --- a/src/dusk/imgui/ImGuiArchipelagoDebug.cpp +++ b/src/dusk/imgui/ImGuiArchipelagoDebug.cpp @@ -3,6 +3,7 @@ #include "imgui.h" #include "Archipelago.h" +#include "dusk/archipelago/archipelago_context.hpp" namespace dusk { ImGuiArchipelagoDebug::ImGuiArchipelagoDebug() { @@ -20,7 +21,38 @@ void ImGuiArchipelagoDebug::drawWindow() { if (!m_drawWindow) return; - ImGui::Begin("Archipelago Debug"); + if (!m_hasInitValues) { + m_hasInitValues = true; + SAFE_STRCPY(m_serverIpInputBuffer, archi::ArchipelagoContext::GetServerIp().c_str()); + SAFE_STRCPY(m_serverPassInputBuffer, archi::ArchipelagoContext::GetPassword().c_str()); + SAFE_STRCPY(m_slotNameInputBuffer, archi::ArchipelagoContext::GetSlotName().c_str()); + } + + ImGui::Begin("Archipelago Debug", &m_drawWindow); + + if (ImGui::InputText("Server IP", m_serverIpInputBuffer, sizeof(m_serverIpInputBuffer))) { + archi::ArchipelagoContext::SetServerIp(m_serverIpInputBuffer); + } + + ImGuiInputTextFlags flags = m_showPassword ? ImGuiInputTextFlags_None : ImGuiInputTextFlags_Password; + if (ImGui::InputText("Server Pass", m_serverPassInputBuffer, sizeof(m_serverPassInputBuffer), flags)) { + archi::ArchipelagoContext::SetPassword(m_serverPassInputBuffer); + } + ImGui::Checkbox("Show Password", &m_showPassword); + + if (ImGui::InputText("Slot Name", m_slotNameInputBuffer, sizeof(m_slotNameInputBuffer))) { + archi::ArchipelagoContext::SetSlotName(m_slotNameInputBuffer); + } + + if (archi::ArchipelagoContext::IsConnected()) { + if (ImGui::Button("Disconnect")) { + archi::ArchipelagoContext::DisconnectFromServer(); + } + }else { + if (ImGui::Button("Connect")) { + archi::ArchipelagoContext::ConnectToServer(); + } + } ImGui::End(); } diff --git a/src/dusk/imgui/ImGuiArchipelagoDebug.h b/src/dusk/imgui/ImGuiArchipelagoDebug.h index 1c156be979..0d2388a4b5 100644 --- a/src/dusk/imgui/ImGuiArchipelagoDebug.h +++ b/src/dusk/imgui/ImGuiArchipelagoDebug.h @@ -4,6 +4,12 @@ namespace dusk { class ImGuiArchipelagoDebug { private: bool m_drawWindow = false; + bool m_showPassword = false; + bool m_hasInitValues = false; + + char m_serverIpInputBuffer[0x40] = {}; + char m_serverPassInputBuffer[0x40] = {}; + char m_slotNameInputBuffer[0x40] = {}; public: ImGuiArchipelagoDebug(); diff --git a/src/dusk/randomizer/generator/data/items.yaml b/src/dusk/randomizer/generator/data/items.yaml index 5b34d4ee79..18e0f72949 100644 --- a/src/dusk/randomizer/generator/data/items.yaml +++ b/src/dusk/randomizer/generator/data/items.yaml @@ -13,30 +13,37 @@ - Name: Green Rupee Importance: Junk Id: 0x01 + APItemId: 0 - Name: Blue Rupee Importance: Junk Id: 0x02 + APItemId: 1 - Name: Yellow Rupee Importance: Junk Id: 0x03 + APItemId: 2 - Name: Red Rupee Importance: Junk Id: 0x04 + APItemId: 3 - Name: Purple Rupee Importance: Junk Id: 0x05 + APItemId: 4 - Name: Orange Rupee Importance: Junk Id: 0x06 + APItemId: 5 - Name: Silver Rupee Importance: Junk Id: 0x07 + APItemId: 6 #- Name: Unused (Gives text about combining bombs) # Importance: @@ -49,30 +56,37 @@ - Name: Bombs 5 Importance: Junk Id: 0x0A + APItemId: 8 - Name: Bombs 10 Importance: Junk Id: 0x0B + APItemId: 9 - Name: Bombs 20 Importance: Junk Id: 0x0C + APItemId: 10 - Name: Bombs 30 Importance: Junk Id: 0x0D + APItemId: 11 - Name: Arrows 10 Importance: Junk Id: 0x0E + APItemId: 12 - Name: Arrows 20 Importance: Junk Id: 0x0F + APItemId: 13 - Name: Arrows 30 Importance: Junk Id: 0x10 + APItemId: 14 #- Name: Arrows 1 # Importance: Junk @@ -81,30 +95,37 @@ - Name: Seeds 50 Importance: Junk Id: 0x12 + APItemId: 15 - Name: Foolish Item # Custom Rando Item Importance: Junk Id: 0x13 + APItemId: 131 - Name: Ordon Spring Portal # Custom Rando item Importance: Major Id: 0x14 + APItemId: -1 - Name: South Faron Portal # Custom Rando Item Importance: Major Id: 0x15 + APItemId: -1 - Name: Water Bombs 5 Importance: Junk Id: 0x16 + APItemId: 17 - Name: Water Bombs 10 Importance: Junk Id: 0x17 + APItemId: 18 - Name: Water Bombs 15 Importance: Junk Id: 0x18 + APItemId: 19 #- Name: Water Bombs 3 # Importance: Junk @@ -113,10 +134,12 @@ - Name: Bomblings 5 Importance: Junk Id: 0x1A + APItemId: 21 - Name: Bomblings 10 Importance: Junk Id: 0x1B + APItemId: 22 #- Name: Bomblings 3 # Importance: Junk @@ -141,10 +164,12 @@ - Name: Piece of Heart Importance: Junk Id: 0x21 + APItemId: 23 - Name: Heart Container Importance: Junk Id: 0x22 + APItemId: 24 #- Name: Dungeon Map # Importance: Junk @@ -177,14 +202,17 @@ - Name: Ordon Shield Importance: Major Id: 0x2A + APItemId: 26 - Name: Wooden Shield Importance: Junk Id: 0x2B + APItemId: 26 - Name: Hylian Shield Importance: Major Id: 0x2C + APItemId: 27 #- Name: Ooccoo's Note # Importance: Junk @@ -201,14 +229,17 @@ - Name: Magic Armor Importance: Major Id: 0x30 + APItemId: 28 - Name: Zora Armor Importance: Major Id: 0x31 + APItemId: 29 - Name: Shadow Crystal Importance: Major Id: 0x32 + APItemId: 30 #- Name: Ooccoo Dungeon # Importance: Junk @@ -221,6 +252,7 @@ - Name: Progressive Wallet # Also Large Wallet Importance: Major Id: 0x35 + APItemId: 31 #- Name: Giant Wallet # Importance: Major @@ -237,18 +269,22 @@ - Name: Upper Zoras River Portal Importance: Major Id: 0x39 + APItemId: -1 - Name: Castle Town Portal Importance: Major Id: 0x3A + APItemId: -1 - Name: Gerudo Desert Portal Importance: Major Id: 0x3B + APItemId: -1 - Name: North Faron Portal Importance: Major Id: 0x3C + APItemId: -1 #- Name: Coral Earring # Importance: Major @@ -257,38 +293,47 @@ - Name: Hawkeye Importance: Minor Id: 0x3E + APItemId: 32 - Name: Progressive Sword # Also Wooden Sword Importance: Major Id: 0x3F + APItemId: 25 - Name: Gale Boomerang Importance: Major Id: 0x40 + APItemId: 33 - Name: Spinner Importance: Major Id: 0x41 + APItemId: 34 - Name: Ball and Chain Importance: Major Id: 0x42 + APItemId: 35 - Name: Progressive Bow Importance: Major Id: 0x43 + APItemId: 36 - Name: Progressive Clawshot Importance: Major Id: 0x44 + APItemId: 37 - Name: Iron Boots Importance: Major Id: 0x45 + APItemId: 38 - Name: Progressive Dominion Rod Importance: Major Id: 0x46 + APItemId: 39 #- Name: Double Clawshots # Importance: Major @@ -297,6 +342,7 @@ - Name: Lantern Importance: Major Id: 0x48 + APItemId: 40 #- Name: Master Sword with Light # Importance: Major @@ -305,10 +351,12 @@ - Name: Progressive Fishing Rod Importance: Major Id: 0x4A + APItemId: 41 - Name: Slingshot Importance: Major Id: 0x4B + APItemId: 44 #- Name: Dominion Rod Uncharged # Importance: Major @@ -317,18 +365,22 @@ - Name: Kakariko Gorge Portal Importance: Major Id: 0x4D + APItemId: -1 - Name: Kakariko Village Portal Importance: Major Id: 0x4E + APItemId: -1 - Name: Giant Bomb Bag Importance: Minor Id: 0x4F + APItemId: 133 - Name: Bomb Bag Importance: Major Id: 0x50 + APItemId: 45 #- Name: Also Bomb Bag (different text) # Importance: Major @@ -337,6 +389,7 @@ - Name: Death Mountain Portal Importance: Major Id: 0x52 + APItemId: -1 #- Name: Light Arrow # Importance: Major @@ -357,6 +410,7 @@ - Name: Zoras Domain Portal Importance: Major Id: 0x57 + APItemId: -1 #- Name: Fising Rod Lure # Importance: Junk @@ -393,10 +447,12 @@ - Name: Empty Bottle Importance: Major Id: 0x60 + APItemId: 46 - Name: Red Potion Shop Importance: Junk Id: 0x61 + APItemId: -1 #- Name: Green Potion Shop # Importance: Junk @@ -405,6 +461,7 @@ - Name: Blue Potion Shop Importance: Junk Id: 0x63 + APItemId: -1 #- Name: Milk # Importance: Junk @@ -413,6 +470,7 @@ - Name: Bottle with Half Milk Importance: Major Id: 0x65 + APItemId: 47 #- Name: Lantern Oil Shop # Importance: Junk @@ -469,6 +527,7 @@ - Name: Fairy Tears Importance: Junk Id: 0x73 + APItemId: -1 #- Name: Worm # Importance: Junk @@ -477,6 +536,7 @@ - Name: Bottle with Great Fairies Tears Importance: Major Id: 0x75 + APItemId: 49 #- Name: Bee Larva Scooped # Importance: Junk @@ -521,133 +581,161 @@ - Name: Renados Letter Importance: Major Id: 0x80 + APItemId: -1 - Name: Invoice Importance: Major Id: 0x81 + APItemId: -1 - Name: Wooden Statue Importance: Major Id: 0x82 + APItemId: -1 - Name: Ilias Charm Importance: Major Id: 0x83 + APItemId: -1 - Name: Horse Call Importance: Minor Id: 0x84 + APItemId: -1 - Name: Forest Temple Small Key Importance: Major Id: 0x85 Dungeon Small Key: Forest Temple + APItemId: 54 - Name: Goron Mines Small Key Importance: Major Id: 0x86 Dungeon Small Key: Goron Mines + APItemId: 55 - Name: Lakebed Temple Small Key Importance: Major Id: 0x87 Dungeon Small Key: Lakebed Temple + APItemId: 56 - Name: Arbiters Grounds Small Key Importance: Major Id: 0x88 Dungeon Small Key: Arbiters Grounds + APItemId: 57 - Name: Snowpeak Ruins Small Key Importance: Major Id: 0x89 Dungeon Small Key: Snowpeak Ruins + APItemId: 58 - Name: Temple of Time Small Key Importance: Major Id: 0x8A Dungeon Small Key: Temple of Time + APItemId: 59 - Name: City in the Sky Small Key Importance: Major Id: 0x8B Dungeon Small Key: City in the Sky + APItemId: 60 - Name: Palace of Twilight Small Key Importance: Major Id: 0x8C Dungeon Small Key: Palace of Twilight + APItemId: 61 - Name: Hyrule Castle Small Key Importance: Major Id: 0x8D Dungeon Small Key: Hyrule Castle + APItemId: 62 - Name: Gerudo Desert Bulblin Camp Key Importance: Major Id: 0x8E + APItemId: 66 - Name: Lake Hylia Portal Importance: Major Id: 0x8F + APItemId: -1 - Name: Aurus Memo Importance: Major Id: 0x90 + APItemId: 67 - Name: Asheis Sketch Importance: Major Id: 0x91 + APItemId: 68 - Name: Forest Temple Big Key Importance: Major Id: 0x92 Dungeon Big Key: Forest Temple + APItemId: 69 - Name: Lakebed Temple Big Key Importance: Major Id: 0x93 Dungeon Big Key: Lakebed Temple + APItemId: 70 - Name: Arbiters Grounds Big Key Importance: Major Id: 0x94 Dungeon Big Key: Arbiters Grounds + APItemId: 72 - Name: Temple of Time Big Key Importance: Major Id: 0x95 Dungeon Big Key: Temple of Time + APItemId: 74 - Name: City in the Sky Big Key Importance: Major Id: 0x96 Dungeon Big Key: City in the Sky + APItemId: 75 - Name: Palace of Twilight Big Key Importance: Major Id: 0x97 Dungeon Big Key: Palace of Twilight + APItemId: 76 - Name: Hyrule Castle Big Key Importance: Major Id: 0x98 Dungeon Big Key: Hyrule Castle + APItemId: 77 - Name: Forest Temple Compass Importance: Junk Id: 0x99 Dungeon Compass: Forest Temple + APItemId: 78 - Name: Goron Mines Compass Importance: Junk Id: 0x9A Dungeon Compass: Goron Mines + APItemId: 79 - Name: Lakebed Temple Compass Importance: Junk Id: 0x9B Dungeon Compass: Lakebed Temple + APItemId: 80 #- Name: Lantern Yellow Chu Chu # Importance: Junk @@ -656,6 +744,7 @@ - Name: Bottle with Lantern Oil Importance: Major Id: 0x9D + APItemId: 48 #- Name: Bee Larva Shop # Importance: Junk @@ -688,6 +777,7 @@ - Name: Progressive Mirror Shard Importance: Major Id: 0xA5 + APItemId: 120 #- Name: Mirror Piece 3 # Importance: Junk @@ -701,39 +791,47 @@ Importance: Junk Id: 0xA8 Dungeon Compass: Arbiters Grounds + APItemId: 81 - Name: Snowpeak Ruins Compass Importance: Junk Id: 0xA9 Dungeon Compass: Snowpeak Ruins + APItemId: 82 - Name: Temple of Time Compass Importance: Junk Id: 0xAA Dungeon Compass: Temple of Time + APItemId: 83 - Name: City in the Sky Compass Importance: Junk Id: 0xAB Dungeon Compass: City in the Sky + APItemId: 84 - Name: Palace of Twilight Compass Importance: Junk Id: 0xAC Dungeon Compass: Palace of Twilight + APItemId: 85 - Name: Hyrule Castle Compass Importance: Junk Id: 0xAD Dungeon Compass: Hyrule Castle + APItemId: 86 - Name: Mirror Chamber Portal Importance: Major Id: 0xAE + APItemId: -1 - Name: Snowpeak Portal Importance: Major Id: 0xAF + APItemId: -1 #- Name: Ilias Scent # Importance: Junk @@ -763,150 +861,185 @@ Importance: Junk Id: 0xB6 Dungeon Map: Forest Temple + APItemId: 87 - Name: Goron Mines Dungeon Map Importance: Junk Id: 0xB7 Dungeon Map: Goron Mines + APItemId: 88 - Name: Lakebed Temple Dungeon Map Importance: Junk Id: 0xB8 Dungeon Map: Lakebed Temple + APItemId: 89 - Name: Arbiters Grounds Dungeon Map Importance: Junk Id: 0xB9 Dungeon Map: Arbiters Grounds + APItemId: 90 - Name: Snowpeak Ruins Dungeon Map Importance: Junk Id: 0xBA Dungeon Map: Snowpeak Ruins + APItemId: 91 - Name: Temple of Time Dungeon Map Importance: Junk Id: 0xBB Dungeon Map: Temple of Time + APItemId: 92 - Name: City in the Sky Dungeon Map Importance: Junk Id: 0xBC Dungeon Map: City in the Sky + APItemId: 93 - Name: Palace of Twilight Dungeon Map Importance: Junk Id: 0xBD Dungeon Map: Palace of Twilight + APItemId: 94 - Name: Hyrule Castle Dungeon Map Importance: Junk Id: 0xBE Dungeon Compass: Hyrule Castle + APItemId: 95 - Name: Sacred Grove Portal Importance: Major Id: 0xBF + APItemId: -1 - Name: Male Beetle Importance: Major Id: 0xC0 + APItemId: 96 - Name: Female Beetle Importance: Major Id: 0xC1 + APItemId: 97 - Name: Male Butterfly Importance: Major Id: 0xC2 + APItemId: 98 - Name: Female Butterfly Importance: Major Id: 0xC3 + APItemId: 99 - Name: Male Stag Beetle Importance: Major Id: 0xC4 + APItemId: 100 - Name: Female Stag Beetle Importance: Major Id: 0xC5 + APItemId: 101 - Name: Male Grasshopper Importance: Major Id: 0xC6 + APItemId: 102 - Name: Female Grasshopper Importance: Major Id: 0xC7 + APItemId: 103 - Name: Male Phasmid Importance: Major Id: 0xC8 + APItemId: 104 - Name: Female Phasmid Importance: Major Id: 0xC9 + APItemId: 105 - Name: Male Pill Bug Importance: Major Id: 0xCA + APItemId: 106 - Name: Female Pill Bug Importance: Major Id: 0xCB + APItemId: 107 - Name: Male Mantis Importance: Major Id: 0xCC + APItemId: 108 - Name: Female Mantis Importance: Major Id: 0xCD + APItemId: 109 - Name: Male Ladybug Importance: Major Id: 0xCE + APItemId: 110 - Name: Female Ladybug Importance: Major Id: 0xCF + APItemId: 111 - Name: Male Snail Importance: Major Id: 0xD0 + APItemId: 112 - Name: Female Snail Importance: Major Id: 0xD1 + APItemId: 113 - Name: Male Dragonfly Importance: Major Id: 0xD2 + APItemId: 114 - Name: Female Dragonfly Importance: Major Id: 0xD3 + APItemId: 115 - Name: Male Ant Importance: Major Id: 0xD4 + APItemId: 116 - Name: Female Ant Importance: Major Id: 0xD5 + APItemId: 117 - Name: Male Dayfly Importance: Major Id: 0xD6 + APItemId: 118 - Name: Female Dayfly Importance: Major Id: 0xD7 + APItemId: 119 - Name: Progressive Fused Shadow Importance: Major Id: 0xD8 + APItemId: 121 #- Name: Fused Shadow 2 # Importance: Junk @@ -939,10 +1072,12 @@ - Name: Poe Soul Importance: Major Id: 0xE0 + APItemId: 124 - Name: Progressive Hidden Skill # Also Ending Blow Importance: Major Id: 0xE1 + APItemId: 122 #- Name: Shield Attack # Importance: Major @@ -971,10 +1106,12 @@ - Name: Bridge of Eldin Portal Importance: Major Id: 0xE8 + APItemId: -1 - Name: Progressive Sky Book Importance: Major Id: 0xE9 + APItemId: 123 #- Name: Partially Filled Sky Book # Importance: Major @@ -991,10 +1128,12 @@ - Name: Purple Rupee Links House Importance: Junk Id: 0xED + APItemId: 7 - Name: North Faron Woods Gate Key Importance: Major Id: 0xEE + APItemId: -1 #- Name: Blue Fire # Importance: Major @@ -1015,19 +1154,23 @@ - Name: Gate Keys Importance: Major Id: 0xF3 + APItemId: 65 - Name: Ordon Pumpkin Importance: Major Id: 0xF4 + APItemId: 129 - Name: Ordon Cheese Importance: Major Id: 0xF5 + APItemId: 130 - Name: Snowpeak Ruins Bedroom Key Importance: Major Id: 0xF6 Dungeon Big Key: Snowpeak Ruins + APItemId: 73 #- Name: Surfboard (Unused) # Importance: Major @@ -1041,6 +1184,7 @@ Importance: Major Id: 0xF9 Dungeon Big Key: Goron Mines + APItemId: 71 #- Name: Got Lantern Back # Importance: Major @@ -1061,6 +1205,7 @@ - Name: Coro Key Importance: Major Id: 0xFE + APItemId: -1 #- Name: Invalid # Importance: Major diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index 0a58dfd1ec..59b7e90a78 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -185,7 +185,13 @@ UserSettings g_userSettings = { ActionBindConfigVar{"actionBindings.turboButton_port2", PAD_NATIVE_BUTTON_INVALID}, ActionBindConfigVar{"actionBindings.turboButton_port3", PAD_NATIVE_BUTTON_INVALID}, }, - } + }, + + .archipelago = { + .serverIP {"archipelago.serverIP", "archipelago.gg"}, + .serverPass {"archipelago.serverPass", ""}, + .slotName {"archipelago.slotName", ""}, + }, }; UserSettings& getSettings() { @@ -339,6 +345,10 @@ void registerSettings() { Register(g_userSettings.actionBindings.turboSpeedButton[1]); Register(g_userSettings.actionBindings.turboSpeedButton[2]); Register(g_userSettings.actionBindings.turboSpeedButton[3]); + + Register(g_userSettings.archipelago.serverIP); + Register(g_userSettings.archipelago.serverPass); + Register(g_userSettings.archipelago.slotName); } // Transient settings