mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 06:13:45 -07:00
Proof of Concept
This commit is contained in:
parent
0ae7f626a1
commit
0683d965e9
5 changed files with 168 additions and 2 deletions
135
soh/soh/Enhancements/mod_menu.cpp
Normal file
135
soh/soh/Enhancements/mod_menu.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
#include "mod_menu.h"
|
||||
#include "utils/StringHelper.h"
|
||||
#include <libultraship/classes.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include <map>
|
||||
#include <ranges>
|
||||
|
||||
std::shared_ptr<Ship::ArchiveManager> GetArchiveManager() {
|
||||
return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager();
|
||||
}
|
||||
|
||||
std::map<std::string, bool> modFiles;
|
||||
|
||||
bool is_enabled(const std::pair<std::string, bool>& p) {
|
||||
return p.second;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetEnabledModFiles() {
|
||||
std::map<std::string, bool> enabledMods;
|
||||
|
||||
std::copy_if(modFiles.begin(), modFiles.end(), std::inserter(enabledMods, enabledMods.begin()), is_enabled);
|
||||
|
||||
auto ks = std::views::keys(enabledMods);
|
||||
std::vector<std::string> keys{ ks.begin(), ks.end() };
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
bool is_disabled(const std::pair<std::string, bool>& p) {
|
||||
return !p.second;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetDisabledModFiles() {
|
||||
std::map<std::string, bool> disabledMods;
|
||||
|
||||
std::copy_if(modFiles.begin(), modFiles.end(), std::inserter(disabledMods, disabledMods.begin()), is_disabled);
|
||||
|
||||
auto ks = std::views::keys(disabledMods);
|
||||
std::vector<std::string> keys{ ks.begin(), ks.end() };
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
void UpdateModFiles() {
|
||||
modFiles.clear();
|
||||
std::string modsPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName);
|
||||
if (modsPath.length() > 0 && std::filesystem::exists(modsPath)) {
|
||||
if (std::filesystem::is_directory(modsPath)) {
|
||||
for (const std::filesystem::directory_entry& p : std::filesystem::recursive_directory_iterator(modsPath, std::filesystem::directory_options::follow_directory_symlink)) {
|
||||
std::string extension = p.path().extension().string();
|
||||
if (
|
||||
StringHelper::IEquals(extension, ".otr") ||
|
||||
StringHelper::IEquals(extension, ".mpq") ||
|
||||
StringHelper::IEquals(extension, ".o2r") ||
|
||||
StringHelper::IEquals(extension, ".zip")
|
||||
) {
|
||||
modFiles.emplace(p.path().generic_string(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
std::sort(modFiles.begin(), modFiles.end(), [](const std::string& a, const std::string& b) {
|
||||
return std::lexicographical_compare(
|
||||
a.begin(), a.end(),
|
||||
b.begin(), b.end(),
|
||||
[](char c1, char c2) {
|
||||
return std::tolower(c1) < std::tolower(c2);
|
||||
}
|
||||
);
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
void ModMenuWindow::DrawElement() {
|
||||
if (ImGui::Button("Update")) {
|
||||
UpdateModFiles();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("tableMods", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("Enabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Disabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::TableNextRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGui::BeginChild("Enabled Mods", ImVec2(0, -8))) {
|
||||
std::vector<std::string> enabledMods = GetEnabledModFiles();
|
||||
if (!enabledMods.empty()) {
|
||||
for (std::string file : enabledMods) {
|
||||
if (ImGui::Button(("Disable##" + file).c_str())) {
|
||||
modFiles[file] = false;
|
||||
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->RemoveArchive(file);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(file.c_str());
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("<None>");
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGui::BeginChild("Disabled Mods", ImVec2(0, -8))) {
|
||||
std::vector<std::string> disabledMods = GetDisabledModFiles();
|
||||
if (!disabledMods.empty()) {
|
||||
for (std::string file : disabledMods) {
|
||||
if (ImGui::Button(("Enable##" + file).c_str())) {
|
||||
modFiles[file] = true;
|
||||
Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->AddArchive(file);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text(file.c_str());
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("<None>");
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
void ModMenuWindow::InitElement() {
|
||||
UpdateModFiles();
|
||||
}
|
14
soh/soh/Enhancements/mod_menu.h
Normal file
14
soh/soh/Enhancements/mod_menu.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
class ModMenuWindow : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
void InitElement() override;
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override {};
|
||||
};
|
||||
#endif
|
|
@ -265,7 +265,7 @@ OTRGlobals::OTRGlobals() {
|
|||
std::string mqPath = Ship::Context::LocateFileAcrossAppDirs("oot-mq.otr", appShortName);
|
||||
if (std::filesystem::exists(mqPath)) {
|
||||
OTRFiles.push_back(mqPath);
|
||||
}
|
||||
}
|
||||
std::string ootPath = Ship::Context::LocateFileAcrossAppDirs("oot.otr", appShortName);
|
||||
if (std::filesystem::exists(ootPath)) {
|
||||
OTRFiles.push_back(ootPath);
|
||||
|
@ -274,6 +274,7 @@ OTRGlobals::OTRGlobals() {
|
|||
if (std::filesystem::exists(sohOtrPath)) {
|
||||
OTRFiles.push_back(sohOtrPath);
|
||||
}
|
||||
/*
|
||||
std::string patchesPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName);
|
||||
std::vector<std::string> patchOTRs = {};
|
||||
if (patchesPath.length() > 0 && std::filesystem::exists(patchesPath)) {
|
||||
|
@ -297,7 +298,9 @@ OTRGlobals::OTRGlobals() {
|
|||
}
|
||||
);
|
||||
});
|
||||
|
||||
OTRFiles.insert(OTRFiles.end(), patchOTRs.begin(), patchOTRs.end());
|
||||
*/
|
||||
std::unordered_set<uint32_t> ValidHashes = {
|
||||
OOT_PAL_MQ,
|
||||
OOT_NTSC_JP_MQ,
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "Enhancements/debugger/MessageViewer.h"
|
||||
#include "soh/Notification/Notification.h"
|
||||
#include "soh/Enhancements/TimeDisplay/TimeDisplay.h"
|
||||
#include "soh/Enhancements/mod_menu.h"
|
||||
|
||||
bool isBetaQuestEnabled = false;
|
||||
|
||||
|
@ -110,6 +111,7 @@ namespace SohGui {
|
|||
std::shared_ptr<Ship::GuiWindow> mGfxDebuggerWindow;
|
||||
std::shared_ptr<Ship::GuiWindow> mInputEditorWindow;
|
||||
|
||||
std::shared_ptr<ModMenuWindow> mModMenuWindow;
|
||||
std::shared_ptr<AudioEditor> mAudioEditorWindow;
|
||||
std::shared_ptr<InputViewer> mInputViewer;
|
||||
std::shared_ptr<InputViewerSettingsWindow> mInputViewerSettings;
|
||||
|
@ -170,6 +172,8 @@ namespace SohGui {
|
|||
SPDLOG_ERROR("Could not find input editor window");
|
||||
}
|
||||
|
||||
mModMenuWindow = std::make_shared<ModMenuWindow>(CVAR_WINDOW("ModMenu"), "Mod Menu", ImVec2(820, 630));
|
||||
gui->AddGuiWindow(mModMenuWindow);
|
||||
mAudioEditorWindow = std::make_shared<AudioEditor>(CVAR_WINDOW("AudioEditor"), "Audio Editor", ImVec2(820, 630));
|
||||
gui->AddGuiWindow(mAudioEditorWindow);
|
||||
mInputViewer = std::make_shared<InputViewer>(CVAR_WINDOW("InputViewer"), "Input Viewer");
|
||||
|
@ -227,8 +231,9 @@ namespace SohGui {
|
|||
void Destroy() {
|
||||
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
|
||||
gui->RemoveAllGuiWindows();
|
||||
|
||||
|
||||
mNotificationWindow = nullptr;
|
||||
mModMenuWindow = nullptr;
|
||||
mModalWindow = nullptr;
|
||||
mAdvancedResolutionSettingsWindow = nullptr;
|
||||
mRandomizerSettingsWindow = nullptr;
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "Enhancements/timesplits/TimeSplits.h"
|
||||
#include "Enhancements/randomizer/Plandomizer.h"
|
||||
#include "Enhancements/TimeDisplay/TimeDisplay.h"
|
||||
#include "Enhancements/mod_menu.h"
|
||||
|
||||
// FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but
|
||||
// they don't work how I expect them to so I added that because it looked good when I eyeballed it
|
||||
|
@ -608,6 +609,7 @@ extern std::shared_ptr<CosmeticsEditorWindow> mCosmeticsEditorWindow;
|
|||
extern std::shared_ptr<GameplayStatsWindow> mGameplayStatsWindow;
|
||||
extern std::shared_ptr<TimeSplitWindow> mTimeSplitWindow;
|
||||
extern std::shared_ptr<TimeDisplayWindow> mTimeDisplayWindow;
|
||||
extern std::shared_ptr<ModMenuWindow> mModMenuWindow;
|
||||
|
||||
void DrawEnhancementsMenu() {
|
||||
if (ImGui::BeginMenu("Enhancements"))
|
||||
|
@ -1769,6 +1771,13 @@ void DrawEnhancementsMenu() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mModMenuWindow) {
|
||||
if (ImGui::Button(GetWindowButtonText("Mod Menu", CVarGetInteger(CVAR_WINDOW("ModMenu"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) {
|
||||
mModMenuWindow->ToggleVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(3);
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue