diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index d99a12f474..72271c3945 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -13,6 +13,7 @@ #include "3drando/hints.hpp" #include "../kaleido.h" #include "soh/Network/Archipelago/Archipelago.h" +#include "soh/Network/Archipelago/ArchipelagoConsoleWindow.h" #include #include @@ -348,10 +349,12 @@ void Context::SetSpoilerLoaded(const bool spoilerLoaded) { void Context::AddRecievedArchipelagoItem(const std::string& ap_item_id) { mAPrecieveQueue.emplace(ap_item_id); SPDLOG_TRACE("Item Pushed {}", ap_item_id); + AddToArchipelagoConsole("Item Pushed"); } GetItemEntry Context::GetArchipelagoGIEntry() { SPDLOG_TRACE("Trying to get Item Entry"); + AddToArchipelagoConsole("Trying to get Item Entry"); if(mAPrecieveQueue.empty()) { // something must have gone wrong here, just give a rupee return ItemTableManager::Instance->RetrieveItemEntry(MOD_NONE, GI_HEART); diff --git a/soh/soh/Network/Archipelago/ArchipelagoConsoleWindow.cpp b/soh/soh/Network/Archipelago/ArchipelagoConsoleWindow.cpp new file mode 100644 index 0000000000..1e99e603c0 --- /dev/null +++ b/soh/soh/Network/Archipelago/ArchipelagoConsoleWindow.cpp @@ -0,0 +1,64 @@ +#include "ArchipelagoConsoleWindow.h" + +#include "soh/SohGui/UIWidgets.hpp" +#include "soh/SohGui/SohGui.hpp" + +ImVector Items; +bool autoScroll = true; +bool scrollToBottom = false; + +void AddToArchipelagoConsole(const char* fmt, ...) IM_FMTARGS(2) { + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf) - 1] = 0; + va_end(args); + Items.push_back(strdup(buf)); +} + +void ArchipelagoConsoleWindow::DrawElement() { + // Reserve enough left-over height for 1 separator + 1 input text + const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); + + if (ImGui::Button("Add line to log")) { + AddToArchipelagoConsole("Hello world"); + } + + if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, 400), false, + ImGuiWindowFlags_HorizontalScrollbar)) { + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing + + for (int i = 0; i < Items.Size; i++) { + const char* item = Items[i]; + + // Normally you would store more information in your item than just a string. + // (e.g. make Items[] an array of structure, store color/type etc.) + ImVec4 color; + bool has_color = false; + if (strstr(item, "[error]")) { + color = ImVec4(1.0f, 0.4f, 0.4f, 1.0f); + has_color = true; + } else if (strncmp(item, "# ", 2) == 0) { + color = ImVec4(1.0f, 0.8f, 0.6f, 1.0f); + has_color = true; + } + if (has_color) + ImGui::PushStyleColor(ImGuiCol_Text, color); + ImGui::TextUnformatted(item); + if (has_color) + ImGui::PopStyleColor(); + } + + // Keep up at the bottom of the scroll region if we were already at the bottom at the beginning of the frame. + // Using a scrollbar or mouse-wheel will take away from the bottom edge. + if (scrollToBottom || (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) { + ImGui::SetScrollHereY(1.0f); + } + scrollToBottom = false; + + ImGui::PopStyleVar(); + } + ImGui::EndChild(); +}; diff --git a/soh/soh/Network/Archipelago/ArchipelagoConsoleWindow.h b/soh/soh/Network/Archipelago/ArchipelagoConsoleWindow.h new file mode 100644 index 0000000000..c75a8bf3c2 --- /dev/null +++ b/soh/soh/Network/Archipelago/ArchipelagoConsoleWindow.h @@ -0,0 +1,20 @@ +#pragma once +#ifndef ARCHIPELAGO_CONSOLE_WINDOW_H +#define ARCHIPELAGO_CONSOLE_WINDOW_H + +#include + +class ArchipelagoConsoleWindow final : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + ~ArchipelagoConsoleWindow() {}; + + protected: + void InitElement() override {}; + void DrawElement() override; + void UpdateElement() override {}; +}; + +void AddToArchipelagoConsole(const char* fmt, ...); + +#endif // ARCHIPELAGO_CONSOLE_WINDOW_H \ No newline at end of file diff --git a/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.cpp b/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.cpp index fc8dd420df..e1f8d48198 100644 --- a/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.cpp +++ b/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.cpp @@ -3,6 +3,7 @@ #include "soh/SohGui/UIWidgets.hpp" #include "soh/SohGui/SohGui.hpp" +#include "soh/Network/Archipelago/ArchipelagoConsoleWindow.h" void ArchipelagoSettingsWindow::DrawElement() { ArchipelagoClient& AP_client = ArchipelagoClient::getInstance(); @@ -12,9 +13,9 @@ void ArchipelagoSettingsWindow::DrawElement() { ImGui::InputText("Password (leave blank for no password)", AP_client.get_password_buff(), AP_Client_consts::MAX_PASSWORD_LENGTH, ImGuiInputTextFlags_Password); - static char connected_text[25] = "Disconnected"; if (ImGui::Button("Connect")) { bool success = AP_client.start_client(); + AddToArchipelagoConsole("Trying to connect..."); } ImGui::SameLine(); diff --git a/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.h b/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.h index 08ce499ff0..22331e86f5 100644 --- a/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.h +++ b/soh/soh/Network/Archipelago/ArchipelagoSettingsWindow.h @@ -4,8 +4,6 @@ #include -class ArchipelagoClient; - class ArchipelagoSettingsWindow final : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index b152c43a31..ca258596b4 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -34,6 +34,7 @@ #include "soh/Notification/Notification.h" #include "soh/Enhancements/TimeDisplay/TimeDisplay.h" #include "soh/Network/Archipelago/ArchipelagoSettingsWindow.h" +#include "soh/Network/Archipelago/ArchipelagoConsoleWindow.h" namespace SohGui { @@ -95,6 +96,7 @@ std::shared_ptr mItemTrackerWindow; std::shared_ptr mTimeSplitWindow; std::shared_ptr mPlandomizerWindow; std::shared_ptr mArchipelagoSettingsWindow; +std::shared_ptr mArchipelagoConsoleWindow; std::shared_ptr mRandomizerSettingsWindow; std::shared_ptr mModalWindow; std::shared_ptr mNotificationWindow; @@ -199,6 +201,9 @@ void SetupGuiElements() { mArchipelagoSettingsWindow = std::make_shared(CVAR_WINDOW("ArchipelagoSettingsWindow"), "Archipelago Settings", ImVec2(850, 760)); gui->AddGuiWindow(mArchipelagoSettingsWindow); + mArchipelagoConsoleWindow = std::make_shared(CVAR_WINDOW("ArchipelagoConsoleWindow"), + "Archipelago Console", ImVec2(850, 760)); + gui->AddGuiWindow(mArchipelagoConsoleWindow); mModalWindow = std::make_shared(CVAR_WINDOW("ModalWindow"), "Modal Window"); gui->AddGuiWindow(mModalWindow); mModalWindow->Show(); @@ -242,6 +247,7 @@ void Destroy() { mTimeSplitWindow = nullptr; mPlandomizerWindow = nullptr; mArchipelagoSettingsWindow = nullptr; + mArchipelagoConsoleWindow = nullptr; mTimeDisplayWindow = nullptr; } diff --git a/soh/soh/SohGui/SohMenuNetwork.cpp b/soh/soh/SohGui/SohMenuNetwork.cpp index 6ab289e7db..cc3b0c1a4c 100644 --- a/soh/soh/SohGui/SohMenuNetwork.cpp +++ b/soh/soh/SohGui/SohMenuNetwork.cpp @@ -17,13 +17,20 @@ void SohMenu::AddMenuNetwork() { // Archipelago WidgetPath path = { "Network", "Archipelago", SECTION_COLUMN_1 }; - AddSidebarEntry("Network", path.sidebarName, 1); + AddSidebarEntry(path.sectionName, path.sidebarName, 2); AddWidget(path, "Popout Archipelago Settings Window", WIDGET_WINDOW_BUTTON) .CVar(CVAR_WINDOW("ArchipelagoSettings")) .RaceDisable(false) .WindowName("Archipelago Settings") .Options(WindowButtonOptions().Tooltip("Enables the Archipelago Settings Window.")); + path.column = SECTION_COLUMN_2; + AddWidget(path, "Popout Archipelago Console Window", WIDGET_WINDOW_BUTTON) + .CVar(CVAR_WINDOW("ArchipelagoConsole")) + .RaceDisable(false) + .WindowName("Archipelago Console") + .Options(WindowButtonOptions().Tooltip("Enables the Archipelago Console Window.")); + // Sail path.sidebarName = "Sail"; AddSidebarEntry("Network", path.sidebarName, 3);