mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-24 22:56:17 +02:00
The ReSkate menu now has two styles, switched with View / F11 or the buttons in its top bar and saved with the profile (`ui fullscreen`): - Window: the mouse menu as before, with a side rail of pages in groups. - Full screen: made for a controller, in the pause menu's look. Pages across the top (LB / RB), each page's sections as the ONLINE page's tabs (LT / RT), button prompts at the bottom, the pause menu's sounds, and the pause menu's own Multiplayer pages as ONLINE. The pages are regrouped: HOME (quick switches and a tile for each page), MAP, BUILD, SKATER (freecam, first person, cheats), SANDBOX (once Trainer), ADDONS (drone, Board Break, Road Rash, Hall of Meat, grind exits, music), ONLINE, PROGRESS, MODS, SETTINGS, DEVELOPER. Full screen, every shared control is drawn for a pad: switches and option rows changed with left / right one step a press, sliders as steppers that repeat when held, rows of buttons, and pages that scroll with the right stick. Search boxes and typed values stay in the window. A pad press takes the menu's focus back and hides the pointer until the mouse moves. Also: map pictures in the map picker (official loading screens, a mod's icon) with a search box in the window, Splash and Tutorial Island left out of it; number boxes beside the window's sliders; the binds in groups, with an action bind to open the menu (`menu`); a menu size for each style (`ui scalefull`); the time of day stepping from the one last asked for.
128 lines
6.1 KiB
C++
128 lines
6.1 KiB
C++
#pragma once
|
|
|
|
#include "overlay.h"
|
|
#include "park_editor.h"
|
|
#include "Engine/Scripting/custom_scripts.h"
|
|
#include <imgui.h>
|
|
#include <optional>
|
|
#include <map>
|
|
|
|
namespace dingosdk::overlay {
|
|
struct AtmosphereEdit {
|
|
AtmosphereValue value;
|
|
std::optional<AtmosphereValue> pending;
|
|
bool waiting{}, editing{}, dirty{};
|
|
double deadline{};
|
|
};
|
|
struct SkateMenu {
|
|
int page = 0;
|
|
int multiplayer_tab = 0;
|
|
bool multiplayer_session_seen{};
|
|
bool multiplayer_host_seeded{}; // host drafts filled from the saved host settings
|
|
int multiplayer_capacity = multiplayer_lobby_player_limit;
|
|
unsigned multiplayer_tps = multiplayer_default_tps;
|
|
int multiplayer_visibility = 1;
|
|
int multiplayer_lobbies_frame = -2; // last frame the Lobbies tab drew
|
|
bool multiplayer_password_enabled = false;
|
|
bool multiplayer_same_map_only = false;
|
|
bool multiplayer_dedicated_only = false;
|
|
std::array<char, 321> server_command{}; // an admin's command for the dedicated server
|
|
std::map<std::string, std::pair<bool, double>> map_pool_pending; // asset -> {ticked, until}, until the server agrees
|
|
std::optional<int> map_rotation_pending; // the rotation slider, likewise
|
|
double map_rotation_until{};
|
|
bool ban_confirm_on_server{}; // the Ban popup bans from a dedicated server
|
|
int multiplayer_lobby_sort = 1; // most players first
|
|
float multiplayer_code_height = 0; // what the join-by-code card took last frame
|
|
// Bans: the manual add form, and the player a Ban button is asking about.
|
|
std::array<char, 24> ban_id{};
|
|
std::array<char, 65> ban_name{};
|
|
std::uint64_t ban_confirm_id{};
|
|
std::string ban_confirm_name;
|
|
bool ban_confirm_requested{};
|
|
bool multiplayer_password_popup_requested = false, multiplayer_password_show = false;
|
|
std::optional<MultiplayerLobby> multiplayer_password_lobby;
|
|
std::string multiplayer_password_code, multiplayer_password_error;
|
|
std::array<char,65> multiplayer_host_password{}, multiplayer_join_password{};
|
|
std::array<char,96> multiplayer_join_code{};
|
|
std::array<char,128> multiplayer_lobby_search{};
|
|
std::array<char,129> multiplayer_lobby_name{};
|
|
MultiplayerDistances multiplayer_distance_draft, multiplayer_distance_applied;
|
|
bool multiplayer_distance_initialized{}, multiplayer_distance_hosting{};
|
|
int voice_bind_capture{};
|
|
ControllerComboCapture voice_controller_capture;
|
|
double voice_capture_until{}, voice_pending_until{};
|
|
std::optional<VoiceSettings> voice_pending;
|
|
std::optional<float> voice_range_pending; // the host's range slider while dragged / until the model agrees
|
|
double voice_range_until{};
|
|
// Chat bubble distance/duration/history sliders, likewise held while dragged.
|
|
std::optional<float> chat_bubbles_distance_pending, chat_bubbles_duration_pending, nametag_distance_pending;
|
|
double nametag_distance_until{};
|
|
std::optional<float> player_distance_pending;
|
|
double player_distance_until{};
|
|
std::optional<int> chat_bubbles_history_pending;
|
|
double chat_bubbles_distance_until{}, chat_bubbles_duration_until{}, chat_bubbles_history_until{};
|
|
std::map<std::uint64_t, std::pair<float, double>> voice_volume_pending;
|
|
std::array<bool, 256> voice_keys_down{};
|
|
std::string multiplayer_distance_lobby;
|
|
int recording_bind = 0;
|
|
ControllerComboCapture bind_capture;
|
|
double bind_capture_until = 0;
|
|
int last_menu_frame = -1;
|
|
// Live while the scale slider is held; the saved value is authoritative otherwise.
|
|
float scale = default_menu_scale;
|
|
bool scale_editing{};
|
|
// Selected tab on each page; see the Page list in skate_menu_internal.h.
|
|
int map_tab = 0, build_tab = 0, skater_tab = 0, settings_tab = 0, mods_tab = 0;
|
|
int addon = 0; // the ADDONS page's addon (menu::Addon)
|
|
// Window or full screen, as just chosen, until the saved setting comes back through the model.
|
|
std::optional<bool> fullscreen_pending;
|
|
double fullscreen_until = 0;
|
|
bool fullscreen_drawn = false; // the last frame was drawn full screen
|
|
bool loose_files_settings_loaded{}, loose_files_saved{true};
|
|
bool custom_scripts_scanned{};
|
|
std::vector<custom_scripts::Script> custom_script_rows;
|
|
std::string custom_script_error;
|
|
std::array<std::optional<int>, 3> graphics_pending{};
|
|
std::array<double, 3> graphics_pending_until{};
|
|
std::array<char, 128> object_search{};
|
|
int world_layer_category = 0;
|
|
std::array<char, 128> world_layer_search{};
|
|
int progression_tab = 0;
|
|
int drone_tab = 0; // the DRONE page (drone_page.cpp)
|
|
int bus_stop_map = 0;
|
|
int challenge_type = 0;
|
|
std::array<char, 128> challenge_search{};
|
|
bool score_dirty = false;
|
|
std::int64_t score_edit = 0, score_cap_edit = 1;
|
|
int score_level_edit = 1;
|
|
std::array<int, 4> district_edit{};
|
|
std::array<bool, 4> district_dirty{};
|
|
std::string destination = "levels/game/BAM_LevelRoot/BAM_LevelRoot";
|
|
std::string feedback;
|
|
std::array<char, 128> mission_search{};
|
|
int mission_group = 0;
|
|
ParkChoices park_edit, park_seen;
|
|
std::array<char,128> atmosphere_search{};
|
|
std::array<AtmosphereEdit, dingosdk::atmosphere_controls.size()> atmosphere_edit{};
|
|
double feedback_until = 0;
|
|
ImFont* body = nullptr;
|
|
ImFont* bold = nullptr;
|
|
ImFont* title = nullptr; // brushed page titles
|
|
ImFont* heading = nullptr; // tile and section headers
|
|
ImFont* mono = nullptr;
|
|
// The same faces drawn larger (large_font_ratio times), swapped in while the menu is full
|
|
// screen, where everything is scaled up: text stays sharp instead of stretched.
|
|
ImFont* body_large = nullptr;
|
|
ImFont* bold_large = nullptr;
|
|
ImFont* heading_large = nullptr;
|
|
ImFont* title_large = nullptr;
|
|
// Full screen: the page's section rail (its first row of tabs, drawn down the left), indenting
|
|
// what follows it until the page is done.
|
|
float rail_indent = 0;
|
|
};
|
|
inline constexpr float large_font_ratio = 30.0f / 17.0f;
|
|
void load_skate_fonts(SkateMenu& menu);
|
|
void draw_skate_menu(SkateMenu& menu, const Model& model, const CallbacksV3& callbacks,
|
|
bool& visible);
|
|
}
|