From a0696518b1b8fe204b500afadc61e387ef573967 Mon Sep 17 00:00:00 2001 From: Jerom Venneker Date: Sun, 11 May 2025 21:47:29 +0200 Subject: [PATCH] Replaced APCpp library with APClientpp, project builds but doesn't work yet --- APCpp | 1 - soh/CMakeLists.txt | 11 - .../Enhancements/randomizer/archipelago.cpp | 319 ++++++++++-------- soh/soh/Enhancements/randomizer/archipelago.h | 42 ++- soh/soh/Enhancements/randomizer/context.cpp | 9 +- soh/soh/Enhancements/randomizer/context.h | 5 +- .../Enhancements/randomizer/hook_handlers.cpp | 6 +- soh/soh/SohGui/SohGui.cpp | 5 + soh/soh/SohGui/SohGui.hpp | 1 + soh/soh/SohGui/SohMenuBar.cpp | 1 + soh/soh/SohGui/SohMenuRandomizer.cpp | 9 + 11 files changed, 227 insertions(+), 182 deletions(-) delete mode 160000 APCpp diff --git a/APCpp b/APCpp deleted file mode 160000 index 505a174a3..000000000 --- a/APCpp +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 505a174a3b0f55f71f69e221d23003b223836fd7 diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 520b022eb..ded7bcf15 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -96,10 +96,6 @@ if (NOT TARGET ZAPDLib) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) endif() -if (NOT TARGET APCpp) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../APCpp ${CMAKE_BINARY_DIR}/APCpp) -endif() - set(PROJECT_NAME soh) ################################################################################ @@ -344,7 +340,6 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets ${SDL2-INCLUDE} ${SDL2-NET-INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR}/assets/ - ${CMAKE_CURRENT_SOURCE_DIR}/../APCpp . ) @@ -628,9 +623,6 @@ endif() add_dependencies(${PROJECT_NAME} libultraship ) -add_dependencies(${PROJECT_NAME} - APCpp -) if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS") add_dependencies(${PROJECT_NAME} ZAPDLib @@ -643,7 +635,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" "ZAPDLib;" - "APCpp;" "glu32;" "SDL2::SDL2;" "SDL2::SDL2main;" @@ -658,7 +649,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" "ZAPDLib;" - "APCpp;" "glu32;" "SDL2::SDL2;" "SDL2::SDL2main;" @@ -697,7 +687,6 @@ else() set(ADDITIONAL_LIBRARY_DEPENDENCIES "libultraship;" "ZAPDLib;" - "APCpp" SDL2::SDL2 "$<$:SDL2_net::SDL2_net>" ${CMAKE_DL_LIBS} diff --git a/soh/soh/Enhancements/randomizer/archipelago.cpp b/soh/soh/Enhancements/randomizer/archipelago.cpp index b14df700b..40bbfe4a7 100644 --- a/soh/soh/Enhancements/randomizer/archipelago.cpp +++ b/soh/soh/Enhancements/randomizer/archipelago.cpp @@ -1,6 +1,8 @@ #include "archipelago.h" -#include "soh/UIWidgets.hpp" +#include "soh/SohGui/UIWidgets.hpp" #include "soh/util.h" +#include +#include #include #include @@ -35,6 +37,8 @@ auto SubscribeToSlotData() { } ArchipelagoClient::ArchipelagoClient() { + std::string uuid = ap_get_uuid("uuid"); + ItemRecievedCallback = nullptr; game_won = false; @@ -54,117 +58,89 @@ void ArchipelagoClient::add_slot_data(std::string_view key, int id) { slot_data.insert(std::pair(key, id)); } -void registerSlotCallbacks() { - SubscribeToSlotData<"open_forest">(); - SubscribeToSlotData<"open_kakoriko">(); - SubscribeToSlotData<"open_door_of_time">(); - SubscribeToSlotData<"zora_fountain">(); - SubscribeToSlotData<"gerudo_fortress">(); - SubscribeToSlotData<"bridge">(); - SubscribeToSlotData<"bridge_stones">(); - SubscribeToSlotData<"bridge_medallions">(); - SubscribeToSlotData<"bridge_rewards">(); - SubscribeToSlotData<"bridge_tokens">(); -// SubscribeToSlotData<"bridge_hearts">(); - SubscribeToSlotData<"shuffle_ganon_bosskey">(); - SubscribeToSlotData<"ganon_bosskey_medallions">(); - SubscribeToSlotData<"ganon_bosskey_stones">(); - SubscribeToSlotData<"ganon_bosskey_rewards">(); - SubscribeToSlotData<"ganon_bosskey_tokens">(); -// SubscribeToSlotData<"ganon_bosskey_hearts">(); - SubscribeToSlotData<"trials">(); - SubscribeToSlotData<"triforce_hunt">(); - SubscribeToSlotData<"triforce_goal">(); -// SubscribeToSlotData<"extra_triforce_percentage">(); -// SubscribeToSlotData<"shopsanity">(); -// SubscribeToSlotData<"shop_slots">(); - SubscribeToSlotData<"shopsanity_prices">(); -// SubscribeToSlotData<"tokensanity">(); -// SubscribeToSlotData<"dungeon_shortcuts">(); -// SubscribeToSlotData<"mq_dungeons_mode">(); -// SubscribeToSlotData<"mq_dungeons_count">(); -// SubscribeToSlotData<"shuffle_interior_entrances">(); -// SubscribeToSlotData<"shuffle_grotto_entrances">(); -// SubscribeToSlotData<"shuffle_dungeon_entrances">(); -// SubscribeToSlotData<"shuffle_overworld_entrances">(); -// SubscribeToSlotData<"shuffle_bosses">(); -// SubscribeToSlotData<"key_rings">(); -// SubscribeToSlotData<"enhance_map_compass">(); -// SubscribeToSlotData<"shuffle_mapcompass">(); -// SubscribeToSlotData<"shuffle_smallkeys">(); -// SubscribeToSlotData<"shuffle_hideoutkeys">(); -// SubscribeToSlotData<"shuffle_bosskeys">(); -// SubscribeToSlotData<"logic_rules">(); -// SubscribeToSlotData<"logic_no_night_tokens_without_suns_song">(); -// SubscribeToSlotData<"warp_songs">(); -// SubscribeToSlotData<"shuffle_song_items">(); -// SubscribeToSlotData<"shuffle_medigoron_carpet_salesman">(); -// SubscribeToSlotData<"shuffle_frog_song_rupees">(); -// SubscribeToSlotData<"shuffle_scrubs">(); -// SubscribeToSlotData<"shuffle_child_trade">(); -// SubscribeToSlotData<"shuffle_freestanding_items">(); -// SubscribeToSlotData<"shuffle_pots">(); -// SubscribeToSlotData<"shuffle_crates">(); -// SubscribeToSlotData<"shuffle_cows">(); -// SubscribeToSlotData<"shuffle_beehives">(); -// SubscribeToSlotData<"shuffle_kokiri_sword">(); -// SubscribeToSlotData<"shuffle_ocarinas">(); -// SubscribeToSlotData<"shuffle_gerudo_card">(); -// SubscribeToSlotData<"shuffle_beans">(); - SubscribeToSlotData<"starting_age">(); -// SubscribeToSlotData<"bombchus_in_logic">(); -// SubscribeToSlotData<"spawn_positions">(); -// SubscribeToSlotData<"owl_drops">(); - SubscribeToSlotData<"no_epona_race">(); -// SubscribeToSlotData<"skip_some_minigame_phases">(); - SubscribeToSlotData<"complete_mask_quest">(); - SubscribeToSlotData<"free_scarecrow">(); -// SubscribeToSlotData<"plant_beans">(); - SubscribeToSlotData<"chicken_count">(); - SubscribeToSlotData<"big_poe_count">(); -// SubscribeToSlotData<"fae_torch_count">(); - SubscribeToSlotData<"blue_fire_arrows">(); - SubscribeToSlotData<"damage_multiplier">(); -// SubscribeToSlotData<"deadly_bonks">(); -// SubscribeToSlotData<"starting_tod">(); -// SubscribeToSlotData<"junk_ice_traps">(); - SubscribeToSlotData<"start_with_consumables">(); -// SubscribeToSlotData<"adult_trade_start">(); -} +//void registerSlotCallbacks() { +// SubscribeToSlotData<"open_forest">(); +// SubscribeToSlotData<"open_kakoriko">(); +// SubscribeToSlotData<"open_door_of_time">(); +// SubscribeToSlotData<"zora_fountain">(); +// SubscribeToSlotData<"gerudo_fortress">(); +// SubscribeToSlotData<"bridge">(); +// SubscribeToSlotData<"bridge_stones">(); +// SubscribeToSlotData<"bridge_medallions">(); +// SubscribeToSlotData<"bridge_rewards">(); +// SubscribeToSlotData<"bridge_tokens">(); +//// SubscribeToSlotData<"bridge_hearts">(); +// SubscribeToSlotData<"shuffle_ganon_bosskey">(); +// SubscribeToSlotData<"ganon_bosskey_medallions">(); +// SubscribeToSlotData<"ganon_bosskey_stones">(); +// SubscribeToSlotData<"ganon_bosskey_rewards">(); +// SubscribeToSlotData<"ganon_bosskey_tokens">(); +//// SubscribeToSlotData<"ganon_bosskey_hearts">(); +// SubscribeToSlotData<"trials">(); +// SubscribeToSlotData<"triforce_hunt">(); +// SubscribeToSlotData<"triforce_goal">(); +//// SubscribeToSlotData<"extra_triforce_percentage">(); +//// SubscribeToSlotData<"shopsanity">(); +//// SubscribeToSlotData<"shop_slots">(); +// SubscribeToSlotData<"shopsanity_prices">(); +//// SubscribeToSlotData<"tokensanity">(); +//// SubscribeToSlotData<"dungeon_shortcuts">(); +//// SubscribeToSlotData<"mq_dungeons_mode">(); +//// SubscribeToSlotData<"mq_dungeons_count">(); +//// SubscribeToSlotData<"shuffle_interior_entrances">(); +//// SubscribeToSlotData<"shuffle_grotto_entrances">(); +//// SubscribeToSlotData<"shuffle_dungeon_entrances">(); +//// SubscribeToSlotData<"shuffle_overworld_entrances">(); +//// SubscribeToSlotData<"shuffle_bosses">(); +//// SubscribeToSlotData<"key_rings">(); +//// SubscribeToSlotData<"enhance_map_compass">(); +//// SubscribeToSlotData<"shuffle_mapcompass">(); +//// SubscribeToSlotData<"shuffle_smallkeys">(); +//// SubscribeToSlotData<"shuffle_hideoutkeys">(); +//// SubscribeToSlotData<"shuffle_bosskeys">(); +//// SubscribeToSlotData<"logic_rules">(); +//// SubscribeToSlotData<"logic_no_night_tokens_without_suns_song">(); +//// SubscribeToSlotData<"warp_songs">(); +//// SubscribeToSlotData<"shuffle_song_items">(); +//// SubscribeToSlotData<"shuffle_medigoron_carpet_salesman">(); +//// SubscribeToSlotData<"shuffle_frog_song_rupees">(); +//// SubscribeToSlotData<"shuffle_scrubs">(); +//// SubscribeToSlotData<"shuffle_child_trade">(); +//// SubscribeToSlotData<"shuffle_freestanding_items">(); +//// SubscribeToSlotData<"shuffle_pots">(); +//// SubscribeToSlotData<"shuffle_crates">(); +//// SubscribeToSlotData<"shuffle_cows">(); +//// SubscribeToSlotData<"shuffle_beehives">(); +//// SubscribeToSlotData<"shuffle_kokiri_sword">(); +//// SubscribeToSlotData<"shuffle_ocarinas">(); +//// SubscribeToSlotData<"shuffle_gerudo_card">(); +//// SubscribeToSlotData<"shuffle_beans">(); +// SubscribeToSlotData<"starting_age">(); +//// SubscribeToSlotData<"bombchus_in_logic">(); +//// SubscribeToSlotData<"spawn_positions">(); +//// SubscribeToSlotData<"owl_drops">(); +// SubscribeToSlotData<"no_epona_race">(); +//// SubscribeToSlotData<"skip_some_minigame_phases">(); +// SubscribeToSlotData<"complete_mask_quest">(); +// SubscribeToSlotData<"free_scarecrow">(); +//// SubscribeToSlotData<"plant_beans">(); +// SubscribeToSlotData<"chicken_count">(); +// SubscribeToSlotData<"big_poe_count">(); +//// SubscribeToSlotData<"fae_torch_count">(); +// SubscribeToSlotData<"blue_fire_arrows">(); +// SubscribeToSlotData<"damage_multiplier">(); +//// SubscribeToSlotData<"deadly_bonks">(); +//// SubscribeToSlotData<"starting_tod">(); +//// SubscribeToSlotData<"junk_ice_traps">(); +// SubscribeToSlotData<"start_with_consumables">(); +//// SubscribeToSlotData<"adult_trade_start">(); +//} bool ArchipelagoClient::start_client() { - switch(AP_GetConnectionStatus()) { - case AP_ConnectionStatus::ConnectionRefused: - SPDLOG_TRACE("refused"); - break; - case AP_ConnectionStatus::Authenticated: - SPDLOG_TRACE("Authenticated"); - break; - case AP_ConnectionStatus::Connected: - SPDLOG_TRACE("Connected"); - break; - case AP_ConnectionStatus::Disconnected: - SPDLOG_TRACE("Disconnected"); - break; - } - - if(AP_GetConnectionStatus() != AP_ConnectionStatus::Disconnected) { - SPDLOG_TRACE("AP already connected, shutting it down"); - AP_Shutdown(); - } - - AP_Init(server_address, "Ocarina of Time", slot_name, password); - //AP_SetClientConnectedCallback(&ArchipelagoClient::on_connected); // currently broken :( - //AP_SetClientCouldntConnectCallback(5, &ArchipelagoClient::on_couldntConnect); - AP_SetItemClearCallback(&ArchipelagoClient::on_clear_items); - AP_SetItemRecvCallback(&ArchipelagoClient::on_item_recieved); - AP_SetLocationCheckedCallback(&ArchipelagoClient::on_location_checked); - AP_SetLocationInfoCallback(&ArchipelagoClient::on_location_scouted); - registerSlotCallbacks(); - AP_Start(); - AP_ConnectionStatus conn_status = AP_GetConnectionStatus(); - - //switch(conn_status) { + //switch(AP_GetConnectionStatus()) { + // case AP_ConnectionStatus::ConnectionRefused: + // SPDLOG_TRACE("refused"); + // break; // case AP_ConnectionStatus::Authenticated: // SPDLOG_TRACE("Authenticated"); // break; @@ -175,12 +151,71 @@ bool ArchipelagoClient::start_client() { // SPDLOG_TRACE("Disconnected"); // break; //} + + //if(AP_GetConnectionStatus() != AP_ConnectionStatus::Disconnected) { + // SPDLOG_TRACE("AP already connected, shutting it down"); + // AP_Shutdown(); + //} + + if(apclient != NULL) { + apclient.reset(); + } + + apclient = std::unique_ptr(new APClient(uuid, AP_Client_consts::AP_GAME_NAME, server_address)); + + apclient->set_room_info_handler([&]() { + std::list tags; + // tags.push_back("DeathLink"); // todo, implement deathlink + apclient->ConnectSlot(slot_name, password, 0b001, tags); + }); + + apclient->set_items_received_handler([&](const std::list& items) { + for(const APClient::NetworkItem& item : items) { + on_item_recieved(item.item, false); // todo get rid of notify, since it doesn't work for us right now anyway + } + }); + + apclient->set_location_info_handler([&](const std::list& items) { + scouted_items.clear(); + + for(const APClient::NetworkItem& item: items) { + ApItem apItem; + const std::string game = apclient->get_player_game(item.player); + apItem.itemName = apclient->get_item_name(item.item, game); + apItem.locationName = apclient->get_location_name(item.location, game); + apItem.playerName = apclient->get_player_alias(item.player); + apItem.flags = item.flags; + apItem.index = item.index; + scouted_items.push_back(apItem); + + const std::string itemName = apItem.itemName; + const std::string playerName = apItem.playerName; + const std::string locationName = apItem.locationName; + SPDLOG_TRACE("Location scouted: {} for {} in location {}", itemName, playerName, locationName); + } + + }); // todo maybe move these functions to a lambda, since they don't have to be static anymore + apclient->set_location_checked_handler([&](const std::list locations) { + // todo implement me + }); + + //apclient.set_slot_connected_handler() // todo rewrite the old slot callbacks when i'm ready to read slot data again + //registerSlotCallbacks(); + //AP_Start(); + //AP_ConnectionStatus conn_status = AP_GetConnectionStatus(); + save_data(); - return conn_status == AP_ConnectionStatus::Connected; + //return conn_status == AP_ConnectionStatus::Connected; + return true; } void ArchipelagoClient::start_location_scouts() { - AP_SendLocationScouts(AP_GetAllLocations(), false); + std::set location_set = apclient->get_missing_locations(); + std::list missing_location_list; + for(const int64_t loc_id : location_set) { + missing_location_list.emplace_back(loc_id); + } + apclient->LocationScouts(missing_location_list); } void ArchipelagoClient::save_data() { @@ -189,7 +224,7 @@ void ArchipelagoClient::save_data() { } bool ArchipelagoClient::isConnected() { - return AP_GetConnectionStatus() == AP_ConnectionStatus::Authenticated; + return apclient->get_state() == APClient::State::SLOT_CONNECTED; } void ArchipelagoClient::check_location(RandomizerCheck SoH_check_id) { @@ -197,14 +232,14 @@ void ArchipelagoClient::check_location(RandomizerCheck SoH_check_id) { if(ap_name.empty()) { return; } - int64_t ap_item_id = CheckNameToId(std::string(ap_name)); + int64_t ap_item_id = apclient->get_location_id(std::string(ap_name)); SPDLOG_TRACE("Checked: {}({}), sending to AP server", ap_name, ap_item_id); // currently not sending, because i only get so many real chances if(!isConnected()) { return; } - AP_SendItem(ap_item_id); + apclient->LocationChecks({ap_item_id}); } void ArchipelagoClient::addItemRecievedCallback(std::function callback) { @@ -219,18 +254,13 @@ void ArchipelagoClient::on_connected() { // todo implement me SPDLOG_TRACE("AP Connected!!"); } -void ArchipelagoClient::on_couldntConnect(AP_ConnectionStatus connection_status) { - // todo implement me -} - - -void ArchipelagoClient::on_clear_items() { - // todo implement me -} +//void ArchipelagoClient::on_couldntConnect(AP_ConnectionStatus connection_status) { +// // todo implement me +//} void ArchipelagoClient::on_item_recieved(int64_t recieved_item_id, bool notify_player) { // call each callback - std::string item_name = getAPitemName(recieved_item_id); + const std::string item_name = apclient->get_item_name(recieved_item_id, "Ocarina of Time"); ArchipelagoClient& ap_client = ArchipelagoClient::getInstance(); if(ap_client.ItemRecievedCallback) { SPDLOG_TRACE("item recieved: {}, notify: {}", item_name, notify_player); @@ -238,24 +268,21 @@ void ArchipelagoClient::on_item_recieved(int64_t recieved_item_id, bool notify_p } } -void ArchipelagoClient::on_location_checked(int64_t location_id) { - // todo implement me -} - -void ArchipelagoClient::on_location_scouted(std::vector network_items) { - for(const AP_NetworkItem& item: network_items) { - SPDLOG_TRACE("Location scouted: {} for {} in location {}", item.itemName, item.playerName, item.locationName); - } - getInstance().scouted_items = network_items; -} - void ArchipelagoClient::send_game_won() { if(!game_won) { - AP_StoryComplete(); + apclient->StatusUpdate(APClient::ClientStatus::GOAL); game_won = true; } } +const std::string& ArchipelagoClient::get_slot_name() const { + if(apclient == NULL) { + return; + } + + return apclient->get_slot(); +} + char* ArchipelagoClient::get_server_address_buff() { return server_address; } @@ -270,7 +297,7 @@ const std::map& ArchipelagoClient::get_slot_data() { return slot_data; } -const std::vector& ArchipelagoClient::get_scouted_items() { +const std::vector& ArchipelagoClient::get_scouted_items() { return scouted_items; } @@ -289,15 +316,15 @@ void ArchipelagoWindow::ArchipelagoDrawConnectPage() { ImGui::SameLine(); ImGui::Text(connected_text); - AP_ConnectionStatus con_status = AP_GetConnectionStatus(); - if(con_status == AP_ConnectionStatus::Connected) { - strncpy(connected_text, "Connected!", 25); - } else if(con_status == AP_ConnectionStatus::Authenticated) { - strncpy(connected_text, "Authenticated!", 25); - } - else { - strncpy(connected_text, "Not Connected", 25); - } + //ArchipelagoDrawConnectPageAP_ConnectionStatus con_status = AP_GetConnectionStatus(); + //if(con_status == AP_ConnectionStatus::Connected) { + // strncpy(connected_text, "Connected!", 25); + //} else if(con_status == AP_ConnectionStatus::Authenticated) { + // strncpy(connected_text, "Authenticated!", 25); + //} + //else { + // strncpy(connected_text, "Not Connected", 25); + //} if(ImGui::Button("scout")) { AP_client.start_location_scouts(); diff --git a/soh/soh/Enhancements/randomizer/archipelago.h b/soh/soh/Enhancements/randomizer/archipelago.h index 8f4487b9a..3164de576 100644 --- a/soh/soh/Enhancements/randomizer/archipelago.h +++ b/soh/soh/Enhancements/randomizer/archipelago.h @@ -1,5 +1,7 @@ +#pragma once #include "archipelago_settings_window.h" -#include "../../../../APCpp/Archipelago.h" + +#include #include "fixed_string.hpp" @@ -16,10 +18,20 @@ namespace AP_Client_consts { static constexpr char const* SETTING_ADDRESS = "AP_server_address"; static constexpr char const* SETTING_NAME = "AP_slot_name"; -}; -class ArchipelagoClient { + static constexpr char const* AP_GAME_NAME = "Ocarina of Time"; +} + +class ArchipelagoClient{ public: + struct ApItem { + std::string itemName; + std::string locationName; + std::string playerName; + unsigned int flags; + int index; + }; + static ArchipelagoClient& getInstance(); bool start_client(); @@ -28,11 +40,13 @@ class ArchipelagoClient { void start_location_scouts(); // getters + const std::string& get_slot_name() const; + char* get_server_address_buff(); char* get_slot_name_buff(); char* get_password_buff(); const std::map& get_slot_data(); - const std::vector& get_scouted_items(); + const std::vector& get_scouted_items(); void add_slot_data(std::string_view key, int id); @@ -47,7 +61,7 @@ class ArchipelagoClient { // todo move me back down when done testing - static void on_item_recieved(int64_t recieved_item_id, bool notify_player); + void on_item_recieved(int64_t recieved_item_id, bool notify_player); void send_game_won(); @@ -57,7 +71,10 @@ class ArchipelagoClient { private: ArchipelagoClient(ArchipelagoClient &) = delete; void operator=(const ArchipelagoClient &) = delete; - static std::shared_ptr instance; + std::string uuid; + std::unique_ptr apclient; + + static std::shared_ptr instance; // is this even used? static bool initialized; char server_address[AP_Client_consts::MAX_ADDRESS_LENGTH]; @@ -68,20 +85,19 @@ class ArchipelagoClient { std::map slot_data; std::set locations; - std::vector scouted_items; + std::vector scouted_items; //void registerSlotCallbacks(); void save_data(); // callback functions - static void on_connected(); - static void on_couldntConnect(AP_ConnectionStatus connection_status); - static void on_clear_items(); + void on_connected(); + //void on_couldntConnect(AP_ConnectionStatus connection_status); - static void on_location_checked(int64_t location_id); - static void on_deathlink_recieved() { }; // TODO: implement me - static void on_location_scouted(std::vector network_items); + void on_location_checked(int64_t location_id); + void on_deathlink_recieved() { }; // TODO: implement me + void on_location_scouted(const std::list& network_items); // callbacks std::function ItemRecievedCallback; diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index c72c9cfe6..2a5968ba4 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -13,7 +13,6 @@ #include "3drando/hints.hpp" #include "../kaleido.h" #include "archipelago.h" -#include "Archipelago.h" #include #include @@ -481,22 +480,22 @@ void Context::ParseItemLocationsJson(nlohmann::json spoilerFileJson) { } } -void Context::ParseArchipelagoItemsLocations(const std::vector& scouted_items) { - int playerId = AP_GetPlayerID(); // todo change me when the client is developed further +void Context::ParseArchipelagoItemsLocations(const std::vector& scouted_items) { + const std::string SlotName = ArchipelagoClient::getInstance().get_slot_name(); // init the item table with regular items first for(int rc = 1; rc <= RC_MAX; rc++) { itemLocationTable[rc].SetPlacedItem(StaticData::GetLocation(static_cast(rc))->GetVanillaItem()); } - for(const AP_NetworkItem& ap_item: scouted_items) { + for(const ArchipelagoClient::ApItem& ap_item: scouted_items) { const RandomizerCheck rc = StaticData::APcheckToSoh.find(ap_item.locationName)->second; if(rc == RC_KF_MIDOS_TOP_RIGHT_CHEST) { continue; } - if(playerId == ap_item.player) { + if(SlotName == ap_item.playerName) { // our item SPDLOG_TRACE("Populated item {} at location {}", ap_item.itemName, ap_item.locationName); const RandomizerGet item = StaticData::APitemToSoh.find(ap_item.itemName)->second; diff --git a/soh/soh/Enhancements/randomizer/context.h b/soh/soh/Enhancements/randomizer/context.h index 0840439d4..b347158ae 100644 --- a/soh/soh/Enhancements/randomizer/context.h +++ b/soh/soh/Enhancements/randomizer/context.h @@ -8,14 +8,13 @@ #include "hint.h" #include "fishsanity.h" #include "trial.h" +#include "archipelago.h" #include #include #include #include -// forward declarations -struct AP_NetworkItem; /** * @brief Singleton for storing and accessing dynamic Randomizer-related data @@ -128,7 +127,7 @@ class Context { void ParseArchipelago(); void ParseArchipelagoSettings(const std::map& slot_data); - void ParseArchipelagoItemsLocations(const std::vector& slot_data); + void ParseArchipelagoItemsLocations(const std::vector& slot_data); /** * @brief Get the hash for the current seed. diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 3f73ff602..ea8f8c327 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -222,10 +222,10 @@ static std::queue randomizerQueuedChecks; static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; static GetItemEntry randomizerQueuedItemEntry = GET_ITEM_NONE; -void ArchipelagoOnRecieveItem(const std::string& ap_item_id) { - SPDLOG_TRACE("Recieve item handler called! {}", ap_item_id); +void ArchipelagoOnRecieveItem(const std::string& ap_item_name) { + SPDLOG_TRACE("Recieve item handler called! {}", ap_item_name); randomizerQueuedChecks.push(RC_ARCHIPELAGO_RECIEVED_ITEM); - Rando::Context::GetInstance()->AddRecievedArchipelagoItem(ap_item_id); + Rando::Context::GetInstance()->AddRecievedArchipelagoItem(ap_item_name); } void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index 7eb3fc6c7..7be045873 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -94,6 +94,7 @@ std::shared_ptr mItemTrackerSettingsWindow; std::shared_ptr mItemTrackerWindow; std::shared_ptr mTimeSplitWindow; std::shared_ptr mPlandomizerWindow; +std::shared_ptr mArchipelagoWindow; std::shared_ptr mRandomizerSettingsWindow; std::shared_ptr mModalWindow; std::shared_ptr mNotificationWindow; @@ -195,6 +196,9 @@ void SetupGuiElements() { mPlandomizerWindow = std::make_shared(CVAR_WINDOW("PlandomizerEditor"), "Plandomizer Editor", ImVec2(850, 760)); gui->AddGuiWindow(mPlandomizerWindow); + mArchipelagoWindow = + std::make_shared(CVAR_WINDOW("ArchipelagoWindow"), "Archipelago", ImVec2(850, 760)); + gui->AddGuiWindow(mArchipelagoWindow); mModalWindow = std::make_shared(CVAR_WINDOW("ModalWindow"), "Modal Window"); gui->AddGuiWindow(mModalWindow); mModalWindow->Show(); @@ -237,6 +241,7 @@ void Destroy() { mInputViewerSettings = nullptr; mTimeSplitWindow = nullptr; mPlandomizerWindow = nullptr; + mArchipelagoWindow = nullptr; mTimeDisplayWindow = nullptr; } diff --git a/soh/soh/SohGui/SohGui.hpp b/soh/soh/SohGui/SohGui.hpp index d9b7bb644..7d5a37459 100644 --- a/soh/soh/SohGui/SohGui.hpp +++ b/soh/soh/SohGui/SohGui.hpp @@ -29,6 +29,7 @@ #include "soh/Enhancements/randomizer/randomizer_settings_window.h" #include "soh/Enhancements/timesplits/TimeSplits.h" #include "soh/Enhancements/randomizer/Plandomizer.h" +#include "soh/Enhancements/randomizer/archipelago.h" #include "SohModals.h" namespace SohGui { diff --git a/soh/soh/SohGui/SohMenuBar.cpp b/soh/soh/SohGui/SohMenuBar.cpp index aa747c168..577f33b14 100644 --- a/soh/soh/SohGui/SohMenuBar.cpp +++ b/soh/soh/SohGui/SohMenuBar.cpp @@ -41,6 +41,7 @@ #include "soh/Enhancements/enemyrandomizer.h" #include "soh/Enhancements/timesplits/TimeSplits.h" #include "soh/Enhancements/randomizer/Plandomizer.h" +#include "soh/Enhancements/randomizer/archipelago.h" #include "soh/Enhancements/TimeDisplay/TimeDisplay.h" // FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but diff --git a/soh/soh/SohGui/SohMenuRandomizer.cpp b/soh/soh/SohGui/SohMenuRandomizer.cpp index 8f4e6e43b..617990a42 100644 --- a/soh/soh/SohGui/SohMenuRandomizer.cpp +++ b/soh/soh/SohGui/SohMenuRandomizer.cpp @@ -100,6 +100,15 @@ void SohMenu::AddMenuRandomizer() { .WindowName("Plandomizer Editor") .Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window.")); + // Archipelago + path.sidebarName = "Archipelago"; + AddSidebarEntry("Randomizer", path.sidebarName, 1); + AddWidget(path, "Popout Archipelago Development Window", WIDGET_WINDOW_BUTTON) + .CVar(CVAR_WINDOW("ArchipelagoWindow")) + .RaceDisable(false) + .WindowName("Archipelago Development") + .Options(WindowButtonOptions().Tooltip("Enables the Archipelago development Window.")); + // Item Tracker path.sidebarName = "Item Tracker"; AddSidebarEntry("Randomizer", path.sidebarName, 1);