mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-07 12:03:24 -04:00
Add map loader to RmlUi (#1147)
* Add Warp to RmlUi * Remove ImGui map loader
This commit is contained in:
+2
-1
@@ -1458,7 +1458,6 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
src/dusk/imgui/ImGuiControllerOverlay.cpp
|
||||
src/dusk/imgui/ImGuiStubLog.cpp
|
||||
src/dusk/imgui/ImGuiMapLoader.cpp
|
||||
src/dusk/imgui/ImGuiSaveEditor.cpp
|
||||
src/dusk/imgui/ImGuiStateShare.hpp
|
||||
src/dusk/imgui/ImGuiStateShare.cpp
|
||||
@@ -1509,6 +1508,8 @@ set(DUSK_FILES
|
||||
src/dusk/ui/tab_bar.hpp
|
||||
src/dusk/ui/ui.cpp
|
||||
src/dusk/ui/ui.hpp
|
||||
src/dusk/ui/warp.cpp
|
||||
src/dusk/ui/warp.hpp
|
||||
src/dusk/ui/window.cpp
|
||||
src/dusk/ui/window.hpp
|
||||
src/dusk/achievements.cpp
|
||||
|
||||
@@ -14,7 +14,6 @@ constexpr const char* SHOW_DEBUG_OVERLAY = "F3";
|
||||
constexpr const char* SHOW_HEAP_VIEWER = "F4";
|
||||
constexpr const char* SHOW_PLAYER_INFO = "F5";
|
||||
constexpr const char* SHOW_SAVE_EDITOR = "F6";
|
||||
constexpr const char* SHOW_MAP_LOADER = "F7";
|
||||
constexpr const char* SHOW_STATE_SHARE = "F8";
|
||||
constexpr const char* SHOW_DEBUG_CAMERA = "F9";
|
||||
constexpr const char* SHOW_AUDIO_DEBUG = "F10";
|
||||
|
||||
@@ -368,7 +368,6 @@ namespace dusk {
|
||||
m_menuTools.ShowProcessManager();
|
||||
m_menuTools.ShowHeapOverlay();
|
||||
m_menuTools.ShowStubLog();
|
||||
m_menuTools.ShowMapLoader();
|
||||
m_menuTools.ShowBloomWindow();
|
||||
m_menuTools.ShowPlayerInfo();
|
||||
m_menuTools.ShowAudioDebug();
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
#include "d/d_com_inf_game.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include <imgui_internal.h>
|
||||
#include "ImGuiConsole.hpp"
|
||||
#include "ImGuiMenuTools.hpp"
|
||||
#include "dusk/map_loader_definitions.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace dusk {
|
||||
void ImGuiMenuTools::ShowMapLoader() {
|
||||
if (!getSettings().backend.enableAdvancedSettings ||
|
||||
!ImGuiConsole::CheckMenuViewToggle(ImGuiKey_F7, m_showMapLoader))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_AlwaysAutoResize |
|
||||
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
|
||||
|
||||
// ImGui::SetNextWindowBgAlpha(0.65f);
|
||||
|
||||
if (!ImGui::Begin("Map Loader", &m_showMapLoader, windowFlags)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Show Internal Names", &m_mapLoaderInfo.showInternalNames);
|
||||
|
||||
const char* previewRegion = "None";
|
||||
if (m_mapLoaderInfo.regionIdx != -1) {
|
||||
previewRegion = gameRegions[m_mapLoaderInfo.regionIdx].regionName;
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Select Region", previewRegion)) {
|
||||
int idx = 0;
|
||||
for (const auto& region : gameRegions) {
|
||||
if (ImGui::Selectable(region.regionName)) {
|
||||
if (m_mapLoaderInfo.regionIdx != idx) {
|
||||
m_mapLoaderInfo.mapIdx = 0;
|
||||
m_mapLoaderInfo.roomNoIdx = 0;
|
||||
m_mapLoaderInfo.pointNoIdx = 0;
|
||||
}
|
||||
m_mapLoaderInfo.regionIdx = idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (m_mapLoaderInfo.regionIdx != -1) {
|
||||
const auto& region = gameRegions[m_mapLoaderInfo.regionIdx];
|
||||
|
||||
std::string previewMap = "None";
|
||||
if (m_mapLoaderInfo.mapIdx != -1) {
|
||||
const auto& map = region.maps[m_mapLoaderInfo.mapIdx];
|
||||
previewMap = m_mapLoaderInfo.showInternalNames ? fmt::format("{} ({})", map.mapName, map.mapFile) : map.mapName;
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Select Map", previewMap.data())) {
|
||||
int prevMapIdx = m_mapLoaderInfo.mapIdx;
|
||||
for (int i = 0; i < region.maps.size(); ++i) {
|
||||
const auto& map = region.maps[i];
|
||||
std::string label = m_mapLoaderInfo.showInternalNames ? fmt::format("{} ({})", map.mapName, map.mapFile) : map.mapName;
|
||||
if (ImGui::Selectable(label.data())) {
|
||||
m_mapLoaderInfo.mapIdx = i;
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
if (m_mapLoaderInfo.mapIdx != prevMapIdx) {
|
||||
m_mapLoaderInfo.roomNoIdx = 0;
|
||||
m_mapLoaderInfo.pointNoIdx = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("No region selected.");
|
||||
}
|
||||
|
||||
if (m_mapLoaderInfo.regionIdx != -1 && m_mapLoaderInfo.mapIdx != -1) {
|
||||
const auto& region = gameRegions[m_mapLoaderInfo.regionIdx];
|
||||
const auto& map = region.maps[m_mapLoaderInfo.mapIdx];
|
||||
const auto& room = map.mapRooms[m_mapLoaderInfo.roomNoIdx];
|
||||
|
||||
if (map.mapRooms.size() > 1) {
|
||||
ImGui::Text("Selected Room: %2d", room.roomNo);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("-###RoomNoIdxDec")) {
|
||||
m_mapLoaderInfo.roomNoIdx--;
|
||||
if (m_mapLoaderInfo.roomNoIdx < 0) {
|
||||
m_mapLoaderInfo.roomNoIdx = map.mapRooms.size() - 1;
|
||||
}
|
||||
m_mapLoaderInfo.pointNoIdx = 0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("+###RoomNoIdxInc")) {
|
||||
m_mapLoaderInfo.roomNoIdx++;
|
||||
if (m_mapLoaderInfo.roomNoIdx >= map.mapRooms.size()) {
|
||||
m_mapLoaderInfo.roomNoIdx = 0;
|
||||
}
|
||||
m_mapLoaderInfo.pointNoIdx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr int MAX_LAYER = 14;
|
||||
|
||||
ImGui::Text("Selected Layer: %3d", m_mapLoaderInfo.layer);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("-###layerDec")) {
|
||||
m_mapLoaderInfo.layer--;
|
||||
if (m_mapLoaderInfo.layer < -1) {
|
||||
m_mapLoaderInfo.layer = MAX_LAYER;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("+###layerInc")) {
|
||||
m_mapLoaderInfo.layer++;
|
||||
if (m_mapLoaderInfo.layer > MAX_LAYER) {
|
||||
m_mapLoaderInfo.layer = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (room.roomPoints.size() > 1) {
|
||||
ImGui::Text("Selected Point: %3d", room.roomPoints[m_mapLoaderInfo.pointNoIdx]);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("-###PointNoIdxDec")) {
|
||||
m_mapLoaderInfo.pointNoIdx--;
|
||||
if (m_mapLoaderInfo.pointNoIdx < 0) {
|
||||
m_mapLoaderInfo.pointNoIdx = room.roomPoints.size() - 1;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("+###PointNoIdxInc")) {
|
||||
m_mapLoaderInfo.pointNoIdx++;
|
||||
if (m_mapLoaderInfo.pointNoIdx >= room.roomPoints.size()) {
|
||||
m_mapLoaderInfo.pointNoIdx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Button("Warp")) {
|
||||
dComIfGp_setNextStage(map.mapFile, room.roomPoints[m_mapLoaderInfo.pointNoIdx], room.roomNo, m_mapLoaderInfo.layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
} // namespace dusk
|
||||
@@ -40,7 +40,6 @@ namespace dusk {
|
||||
ImGui::BeginDisabled(getSettings().game.speedrunMode);
|
||||
|
||||
ImGui::MenuItem("Save Editor", hotkeys::SHOW_SAVE_EDITOR, &m_showSaveEditor);
|
||||
ImGui::MenuItem("Map Loader", hotkeys::SHOW_MAP_LOADER, &m_showMapLoader);
|
||||
ImGui::MenuItem("State Share", hotkeys::SHOW_STATE_SHARE, &m_showStateShare);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace dusk {
|
||||
void ShowProcessManager();
|
||||
void ShowHeapOverlay();
|
||||
void ShowStubLog();
|
||||
void ShowMapLoader();
|
||||
void ShowBloomWindow();
|
||||
void ShowPlayerInfo();
|
||||
void ShowAudioDebug();
|
||||
@@ -43,22 +42,9 @@ namespace dusk {
|
||||
|
||||
bool m_showStubLog = false;
|
||||
|
||||
bool m_showMapLoader = false;
|
||||
|
||||
bool m_showBloomWindow = false;
|
||||
|
||||
bool m_showAudioDebug = false;
|
||||
struct {
|
||||
int mapIdx = -1;
|
||||
int regionIdx = -1;
|
||||
int roomNoIdx = 0;
|
||||
int pointNoIdx = 0;
|
||||
int roomNo = -1;
|
||||
int pointNo = -1;
|
||||
int spawnId = 0;
|
||||
int layer = -1;
|
||||
bool showInternalNames = false;
|
||||
} m_mapLoaderInfo;
|
||||
|
||||
bool m_showPlayerInfo = false;
|
||||
int m_playerInfoOverlayCorner = 1; // top-right
|
||||
|
||||
+37
-38
@@ -26,6 +26,43 @@
|
||||
#include <vector>
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
Rml::String stage_option_label(const MapEntry& map, bool showInternalNames) {
|
||||
return showInternalNames ? fmt::format("{} ({})", map.mapName, map.mapFile) : map.mapName;
|
||||
}
|
||||
|
||||
Rml::String stage_label_for_file(const Rml::String& stageFile, bool showInternalNames) {
|
||||
for (const auto& region : gameRegions) {
|
||||
for (const auto& map : region.maps) {
|
||||
if (stageFile == map.mapFile) {
|
||||
return stage_option_label(map, showInternalNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stageFile;
|
||||
}
|
||||
|
||||
void populate_stage_picker(Pane& pane, std::function<Rml::String()> getStageFile,
|
||||
std::function<void(const char*)> setStageFile, bool showInternalNames) {
|
||||
pane.clear();
|
||||
for (const auto& region : gameRegions) {
|
||||
pane.add_section(region.regionName);
|
||||
for (const auto& map : region.maps) {
|
||||
pane.add_button({
|
||||
.text = stage_option_label(map, showInternalNames),
|
||||
.isSelected =
|
||||
[getStageFile, stageFile = map.mapFile] {
|
||||
return getStageFile() == stageFile;
|
||||
},
|
||||
})
|
||||
.on_pressed([setStageFile, stageFile = map.mapFile] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
setStageFile(stageFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool has_save_data() {
|
||||
@@ -155,44 +192,6 @@ bool parse_vec3(const Rml::String& value, float& x, float& y, float& z) {
|
||||
return *cursor == '\0';
|
||||
}
|
||||
|
||||
Rml::String stage_option_label(const MapEntry& map) {
|
||||
// TODO: option to show internal name?
|
||||
// return fmt::format("{} ({})", map.mapName, map.mapFile);
|
||||
return map.mapName;
|
||||
}
|
||||
|
||||
Rml::String stage_label_for_file(const Rml::String& stageFile) {
|
||||
for (const auto& region : gameRegions) {
|
||||
for (const auto& map : region.maps) {
|
||||
if (stageFile == map.mapFile) {
|
||||
return stage_option_label(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
return stageFile;
|
||||
}
|
||||
|
||||
void populate_stage_picker(Pane& pane, std::function<Rml::String()> getStageFile,
|
||||
std::function<void(const char*)> setStageFile) {
|
||||
pane.clear();
|
||||
for (const auto& region : gameRegions) {
|
||||
pane.add_section(region.regionName);
|
||||
for (const auto& map : region.maps) {
|
||||
pane.add_button({
|
||||
.text = stage_option_label(map),
|
||||
.isSelected =
|
||||
[getStageFile, stageFile = map.mapFile] {
|
||||
return getStageFile() == stageFile;
|
||||
},
|
||||
})
|
||||
.on_pressed([setStageFile, stageFile = map.mapFile] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
setStageFile(stageFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rml::String get_player_name() {
|
||||
if (!has_save_data()) {
|
||||
return "";
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
struct MapEntry;
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
class Pane;
|
||||
|
||||
Rml::String stage_option_label(const MapEntry& map, bool showInternalNames = false);
|
||||
Rml::String stage_label_for_file(const Rml::String& stageFile, bool showInternalNames = false);
|
||||
void populate_stage_picker(Pane& pane, std::function<Rml::String()> getStageFile,
|
||||
std::function<void(const char*)> setStageFile,
|
||||
bool showInternalNames = false);
|
||||
|
||||
class EditorWindow : public Window {
|
||||
public:
|
||||
EditorWindow();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "modal.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "ui.hpp"
|
||||
#include "warp.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
#include <chrono>
|
||||
@@ -51,11 +52,9 @@ MenuBar::MenuBar() : Document(kDocumentSource), mRoot(mDocument->GetElementById(
|
||||
.autoSelect = false,
|
||||
});
|
||||
mTabBar->add_tab("Settings", [this] { push(std::make_unique<SettingsWindow>()); });
|
||||
// mTabBar->add_tab("Warp", [] {
|
||||
// // TODO
|
||||
// });
|
||||
|
||||
if (getSettings().backend.enableAdvancedSettings) {
|
||||
mTabBar->add_tab("Warp", [this] { push(std::make_unique<WarpWindow>()); });
|
||||
mTabBar->add_tab("Editor", [this] { push(std::make_unique<EditorWindow>()); });
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
#include "warp.hpp"
|
||||
|
||||
#include "editor.hpp"
|
||||
#include "pane.hpp"
|
||||
|
||||
#include "dusk/map_loader_definitions.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace dusk::ui {
|
||||
namespace {
|
||||
|
||||
constexpr int kMinLayer = -1;
|
||||
constexpr int kMaxLayer = 14;
|
||||
|
||||
struct WarpSelectionState {
|
||||
int regionIdx = 0;
|
||||
int mapIdx = 0;
|
||||
int roomIdx = 0;
|
||||
int pointIdx = 0;
|
||||
int layer = -1;
|
||||
bool showInternalNames = false;
|
||||
};
|
||||
|
||||
WarpSelectionState& selection_state() {
|
||||
static WarpSelectionState state;
|
||||
return state;
|
||||
}
|
||||
|
||||
const RegionEntry* selected_region(const WarpSelectionState& state) {
|
||||
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
|
||||
return nullptr;
|
||||
}
|
||||
return &gameRegions[state.regionIdx];
|
||||
}
|
||||
|
||||
const MapEntry* selected_map(const WarpSelectionState& state) {
|
||||
const auto* region = selected_region(state);
|
||||
if (region == nullptr || state.mapIdx < 0 || state.mapIdx >= static_cast<int>(region->maps.size())) {
|
||||
return nullptr;
|
||||
}
|
||||
return ®ion->maps[state.mapIdx];
|
||||
}
|
||||
|
||||
const RoomEntry* selected_room(const WarpSelectionState& state) {
|
||||
const auto* map = selected_map(state);
|
||||
if (map == nullptr || state.roomIdx < 0 || state.roomIdx >= static_cast<int>(map->mapRooms.size())) {
|
||||
return nullptr;
|
||||
}
|
||||
return &map->mapRooms[state.roomIdx];
|
||||
}
|
||||
|
||||
const s16* selected_point(const WarpSelectionState& state) {
|
||||
const auto* room = selected_room(state);
|
||||
if (room == nullptr || state.pointIdx < 0 ||
|
||||
state.pointIdx >= static_cast<int>(room->roomPoints.size()))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return &room->roomPoints[state.pointIdx];
|
||||
}
|
||||
|
||||
void clamp_indices(WarpSelectionState& state) {
|
||||
if (gameRegions.empty()) {
|
||||
state.regionIdx = -1;
|
||||
state.mapIdx = -1;
|
||||
state.roomIdx = -1;
|
||||
state.pointIdx = -1;
|
||||
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
state.regionIdx = std::clamp(state.regionIdx, 0, static_cast<int>(gameRegions.size()) - 1);
|
||||
const auto& region = gameRegions[state.regionIdx];
|
||||
if (region.maps.empty()) {
|
||||
state.mapIdx = -1;
|
||||
state.roomIdx = -1;
|
||||
state.pointIdx = -1;
|
||||
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
state.mapIdx = std::clamp(state.mapIdx, 0, static_cast<int>(region.maps.size()) - 1);
|
||||
const auto& map = region.maps[state.mapIdx];
|
||||
if (map.mapRooms.empty()) {
|
||||
state.roomIdx = -1;
|
||||
state.pointIdx = -1;
|
||||
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
state.roomIdx = std::clamp(state.roomIdx, 0, static_cast<int>(map.mapRooms.size()) - 1);
|
||||
const auto& room = map.mapRooms[state.roomIdx];
|
||||
if (room.roomPoints.empty()) {
|
||||
state.pointIdx = -1;
|
||||
} else {
|
||||
state.pointIdx = std::clamp(state.pointIdx, 0, static_cast<int>(room.roomPoints.size()) - 1);
|
||||
}
|
||||
|
||||
state.layer = std::clamp(state.layer, kMinLayer, kMaxLayer);
|
||||
}
|
||||
|
||||
bool can_warp(const WarpSelectionState& state) {
|
||||
return selected_point(state) != nullptr;
|
||||
}
|
||||
|
||||
void reset_selection(WarpSelectionState& state) {
|
||||
state.roomIdx = 0;
|
||||
state.pointIdx = 0;
|
||||
state.layer = kMinLayer;
|
||||
clamp_indices(state);
|
||||
}
|
||||
|
||||
void populate_map_picker(Pane& pane, WarpSelectionState& state) {
|
||||
pane.clear();
|
||||
clamp_indices(state);
|
||||
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
|
||||
return;
|
||||
}
|
||||
|
||||
pane.add_button({
|
||||
.text = "Show Internal Names",
|
||||
.isSelected = [&state] { return state.showInternalNames; },
|
||||
})
|
||||
.on_pressed([&pane, &state] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
state.showInternalNames = !state.showInternalNames;
|
||||
populate_map_picker(pane, state);
|
||||
});
|
||||
|
||||
pane.add_section("Maps");
|
||||
const auto& region = gameRegions[state.regionIdx];
|
||||
for (int i = 0; i < static_cast<int>(region.maps.size()); ++i) {
|
||||
pane.add_button({
|
||||
.text = stage_option_label(region.maps[i], state.showInternalNames),
|
||||
.isSelected = [i, &state] { return state.mapIdx == i; },
|
||||
})
|
||||
.on_pressed([i, &state] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
if (state.mapIdx != i) {
|
||||
state.mapIdx = i;
|
||||
reset_selection(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WarpWindow::WarpWindow() {
|
||||
add_tab("Warp", [this](Rml::Element* content) {
|
||||
auto& leftPane = add_child<Pane>(content, Pane::Type::Controlled);
|
||||
auto& rightPane = add_child<Pane>(content, Pane::Type::Uncontrolled);
|
||||
auto& state = selection_state();
|
||||
clamp_indices(state);
|
||||
|
||||
leftPane.add_section("Destination");
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Region",
|
||||
.getValue =
|
||||
[&state] {
|
||||
clamp_indices(state);
|
||||
const auto* region = selected_region(state);
|
||||
return region == nullptr ? Rml::String{"None"} :
|
||||
Rml::String{region->regionName};
|
||||
},
|
||||
}),
|
||||
rightPane, [&state](Pane& pane) {
|
||||
pane.clear();
|
||||
for (int i = 0; i < static_cast<int>(gameRegions.size()); ++i) {
|
||||
pane.add_button({
|
||||
.text = gameRegions[i].regionName,
|
||||
.isSelected = [i, &state] { return state.regionIdx == i; },
|
||||
})
|
||||
.on_pressed([i, &state] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
if (state.regionIdx != i) {
|
||||
state.regionIdx = i;
|
||||
state.mapIdx = 0;
|
||||
reset_selection(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Map",
|
||||
.getValue =
|
||||
[&state] {
|
||||
clamp_indices(state);
|
||||
const auto* map = selected_map(state);
|
||||
return map == nullptr ? Rml::String{"None"} :
|
||||
stage_option_label(*map, state.showInternalNames);
|
||||
},
|
||||
}),
|
||||
rightPane, [&state](Pane& pane) { populate_map_picker(pane, state); });
|
||||
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Room",
|
||||
.getValue = [&state] {
|
||||
clamp_indices(state);
|
||||
const auto* room = selected_room(state);
|
||||
return room == nullptr ? Rml::String{"None"} :
|
||||
fmt::format("{}", room->roomNo);
|
||||
},
|
||||
.isDisabled = [&state] {
|
||||
clamp_indices(state);
|
||||
const auto* map = selected_map(state);
|
||||
return map == nullptr || map->mapRooms.size() <= 1;
|
||||
},
|
||||
}),
|
||||
rightPane, [&state](Pane& pane) {
|
||||
pane.clear();
|
||||
clamp_indices(state);
|
||||
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
|
||||
return;
|
||||
}
|
||||
const auto& region = gameRegions[state.regionIdx];
|
||||
if (state.mapIdx < 0 || state.mapIdx >= static_cast<int>(region.maps.size())) {
|
||||
return;
|
||||
}
|
||||
const auto& map = region.maps[state.mapIdx];
|
||||
for (int i = 0; i < static_cast<int>(map.mapRooms.size()); ++i) {
|
||||
pane.add_button({
|
||||
.text = fmt::format("{}", map.mapRooms[i].roomNo),
|
||||
.isSelected = [i, &state] { return state.roomIdx == i; },
|
||||
})
|
||||
.on_pressed([i, &state] {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
if (state.roomIdx != i) {
|
||||
state.roomIdx = i;
|
||||
state.pointIdx = 0;
|
||||
clamp_indices(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Point",
|
||||
.getValue = [&state] {
|
||||
clamp_indices(state);
|
||||
const auto* point = selected_point(state);
|
||||
return point == nullptr ? Rml::String{"None"} : fmt::format("{}", *point);
|
||||
},
|
||||
.isDisabled = [&state] {
|
||||
clamp_indices(state);
|
||||
const auto* room = selected_room(state);
|
||||
return room == nullptr || room->roomPoints.size() <= 1;
|
||||
},
|
||||
}),
|
||||
rightPane, [&state](Pane& pane) {
|
||||
pane.clear();
|
||||
clamp_indices(state);
|
||||
if (state.regionIdx < 0 || state.regionIdx >= static_cast<int>(gameRegions.size())) {
|
||||
return;
|
||||
}
|
||||
const auto& region = gameRegions[state.regionIdx];
|
||||
if (state.mapIdx < 0 || state.mapIdx >= static_cast<int>(region.maps.size())) {
|
||||
return;
|
||||
}
|
||||
const auto& map = region.maps[state.mapIdx];
|
||||
if (state.roomIdx < 0 || state.roomIdx >= static_cast<int>(map.mapRooms.size())) {
|
||||
return;
|
||||
}
|
||||
const auto& room = map.mapRooms[state.roomIdx];
|
||||
for (int i = 0; i < static_cast<int>(room.roomPoints.size()); ++i) {
|
||||
pane.add_button({
|
||||
.text = fmt::format("{}", room.roomPoints[i]),
|
||||
.isSelected = [i, &state] { return state.pointIdx == i; },
|
||||
})
|
||||
.on_pressed([i, &state] {
|
||||
if (state.pointIdx != i) {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
state.pointIdx = i;
|
||||
clamp_indices(state);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
leftPane.register_control(
|
||||
leftPane.add_select_button({
|
||||
.key = "Layer",
|
||||
.getValue = [&state] { return fmt::format("{}", state.layer); },
|
||||
}),
|
||||
rightPane, [&state](Pane& pane) {
|
||||
pane.clear();
|
||||
for (int layer = kMinLayer; layer <= kMaxLayer; ++layer) {
|
||||
pane.add_button({
|
||||
.text = fmt::format("{}", layer),
|
||||
.isSelected = [layer, &state] { return state.layer == layer; },
|
||||
})
|
||||
.on_pressed([layer, &state] {
|
||||
if (state.layer != layer) {
|
||||
mDoAud_seStartMenu(kSoundItemChange);
|
||||
state.layer = layer;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
leftPane.add_section("Action");
|
||||
leftPane.register_control(
|
||||
leftPane.add_button({
|
||||
.text = "Warp",
|
||||
.isDisabled = [&state] {
|
||||
clamp_indices(state);
|
||||
return !can_warp(state);
|
||||
},
|
||||
})
|
||||
.on_pressed([&state] {
|
||||
clamp_indices(state);
|
||||
if (!can_warp(state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDoAud_seStartMenu(kSoundClick);
|
||||
const auto& region = gameRegions[state.regionIdx];
|
||||
const auto& map = region.maps[state.mapIdx];
|
||||
const auto& room = map.mapRooms[state.roomIdx];
|
||||
dComIfGp_setNextStage( map.mapFile, room.roomPoints[state.pointIdx], room.roomNo, state.layer);
|
||||
}),
|
||||
rightPane, [](Pane& pane) {
|
||||
pane.clear();
|
||||
pane.add_text("Warp to the selected destination.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace dusk::ui
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "window.hpp"
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
class WarpWindow : public Window {
|
||||
public:
|
||||
WarpWindow();
|
||||
};
|
||||
|
||||
} // namespace dusk::ui
|
||||
Reference in New Issue
Block a user