Escape: open a 'pause' menu

This commit is contained in:
2025-08-28 21:18:54 -05:00
parent 3af458eec8
commit 42000f1094
6 changed files with 88 additions and 23 deletions

View File

@@ -30,6 +30,7 @@
#include "mathutil.hpp"
#include "fileio/fileio.hpp"
#include "fileio/resmgr/res_dialog.hpp"
#include "dialogxml/dialogs/btnpanel.hpp"
#include "dialogxml/dialogs/choicedlog.hpp"
#include "dialogxml/dialogs/pictchoice.hpp"
#include "dialogxml/dialogs/dialog.hpp"
@@ -275,12 +276,12 @@ void init_screen_locs() {
}
// Some actions directly show a dialog. This handles that, and records it.
void show_dialog_action(std::string xml_file) {
if(recording){
void show_dialog_action(std::string xml_file, bool record, cDialog* parent) {
if(recording && record){
record_action("show_dialog_action", xml_file);
}
cChoiceDlog(xml_file).show();
cChoiceDlog(xml_file, parent).show();
}
bool prime_time() {
@@ -2766,6 +2767,62 @@ static bool handle_debug_key(char key) {
extern std::vector<std::string> preset_words;
void run_quick_menu() {
if(!replaying){
record_action("quick_menu", "");
}
// "Pause" menu
std::vector<std::string> choices;
std::vector<std::function<void(cButtonPanel&)>> handlers;
choices.push_back("Save");
handlers.push_back([](cButtonPanel&) -> void {
do_save(true); // "Save" is always a "Save As" in modern Spiderweb pause menus
});
choices.push_back("Load");
handlers.push_back([](cButtonPanel& me) -> void {
if(do_load())
me->toast(true);
});
choices.push_back("Settings");
handlers.push_back([](cButtonPanel& me) -> void {
pick_preferences(me.operator->());
});
choices.push_back("Help");
handlers.push_back([](cButtonPanel& me) -> void {
// passing false = don't record these - because the recorded menu button press will handle it
if(is_out()) show_dialog_action("help-outdoor", false, me.operator->());
else if(is_town()) show_dialog_action("help-town", false, me.operator->());
else if(is_combat()) show_dialog_action("help-combat", false, me.operator->());
// TODO is this possible? Should it be added to the '?' key handler?
else show_dialog_action("help-hints", false, me.operator->());
});
choices.push_back("Main Menu");
handlers.push_back([](cButtonPanel& me) -> void {
if(!replaying){ // do_abort is recorded as an action
if(do_abort()){
me->toast(true);
}
}
});
choices.push_back("Quit to Desktop");
handlers.push_back([](cButtonPanel& me) -> void {
if(!replaying){ // close_window is recorded as an action
extern bool handle_quit_event();
if(handle_quit_event()){
me->toast(true);
}
}
});
cButtonPanel panel(choices, handlers, "Quick Menu");
panel->getControl("cancel").setText("Resume");
panel->getControl("done").hide();
dynamic_cast<cPict&>(panel->getControl("pic")).setPict(23,PIC_DLOG);
panel.show();
}
bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
bool are_done = false;
location pass_point; // TODO: This isn't needed
@@ -2838,8 +2895,8 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
handled = false;
break;
}
if(!handled && map_visible){
close_map();
if(!handled && univ.party.is_in_scenario()){
run_quick_menu();
return false;
}
}
@@ -3162,18 +3219,18 @@ bool handle_scroll(const sf::Event& event) {
return true;
}
void do_load() {
bool do_load() {
// Edge case: Replay can be cut off before a file is chosen,
// or party selection can be canceled, and this will cause
// a crash trying to decode a party
if(replaying && !has_next_action("load_party")){
return;
return false;
}
fs::path file_to_load = run_file_picker(false);
if(file_to_load.empty()) return;
if(file_to_load.empty()) return false;
set_cursor(watch_curs);
if(!load_party(file_to_load, univ, spec_scen_g))
return;
return false;
finish_load_party();
if(overall_mode != MODE_STARTUP)
post_load();
@@ -3186,6 +3243,7 @@ void do_load() {
}
menu_activate();
restore_cursor();
return true;
}
void post_load() {
@@ -3247,19 +3305,20 @@ void do_save(bool save_as) {
redraw_screen(REFRESH_TEXT);
}
void do_abort() {
bool do_abort() {
if(recording){
record_action("do_abort", "");
}
if(party_in_memory) {
std::string choice = cChoiceDlog("abort-game",{"okay","cancel"}).show();
if (choice=="cancel") return;
if (choice=="cancel") return false;
reload_startup();
overall_mode = MODE_STARTUP;
}
party_in_memory = false;
draw_startup(0);
menu_activate();
return true;
}
void do_rest(long length, int hp_restore, int mp_restore) {

View File

@@ -8,6 +8,8 @@
#include "dialogxml/keycodes.hpp"
#include "tools/framerate_limiter.hpp"
class cDialog;
struct key_action_t {
std::vector<char> keys;
std::string name;
@@ -31,10 +33,10 @@ void handle_menu_spell(short spell_picked,short spell_type) ;
void initiate_outdoor_combat(short i);
bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter);
bool handle_scroll(const sf::Event& event);
void do_load();
bool do_load();
void post_load();
void do_save(bool save_as = false);
void do_abort();
bool do_abort();
void increase_age(bool eating_trigger_autosave = true);
void handle_hunting();
void switch_pc(short which);
@@ -72,7 +74,7 @@ void handle_drop_item(location destination, bool& need_redraw);
void handle_give_item(short item_hit, bool& did_something, bool& need_redraw);
void handle_toggle_active(bool& need_reprint);
void handle_parry(bool& did_something, bool& need_redraw, bool& need_reprint);
void show_dialog_action(std::string xml_file);
void show_dialog_action(std::string xml_file, bool record = true, cDialog* parent = nullptr);
void handle_new_pc_graphic();
void handle_rename_pc();
void handle_begin_look(bool right_button, bool& need_redraw, bool& need_reprint);

View File

@@ -1462,14 +1462,14 @@ static bool reset_help(cDialog& me, std::string, eKeyMod) {
return true;
}
void pick_preferences(bool record) {
void pick_preferences(bool record, cDialog* parent) {
if(record && recording){
record_action("pick_preferences", "");
}
set_cursor(sword_curs);
cDialog prefsDlog(*ResMgr::dialogs.get("preferences"));
cDialog prefsDlog(*ResMgr::dialogs.get("preferences"), parent);
prefsDlog.attachClickHandlers(&prefs_autosave_event_filter, {"autosave-toggle", "autosave-details"});
prefsDlog.attachClickHandlers(&prefs_event_filter, {"okay", "cancel"});
prefsDlog.attachClickHandlers(&reset_help, {"resethelp"});

View File

@@ -21,7 +21,7 @@ void do_sign(short town_num, short which_sign, short sign_type);
void do_talk(short personality, unsigned short m_num);
void put_party_stats();
void edit_party();
void pick_preferences(bool record = true);
void pick_preferences(bool record = true, cDialog* parent = nullptr);
void save_prefs();
void tip_of_day();
struct scen_header_type pick_a_scen();

View File

@@ -227,7 +227,7 @@ static void showWelcome();
static void replay_next_action();
void handle_quit_event();
bool handle_quit_event();
void handle_help_toc();
void menu_give_help(short help1);
@@ -633,6 +633,9 @@ static void replay_action(Element& action) {
eKeyMod mods = static_cast<eKeyMod>(std::stoi(info["mods"]));
handle_startup_button_click(btn, mods);
return;
}else if(t == "quick_menu"){
extern void run_quick_menu();
run_quick_menu();
}else if(t == "change_fps"){
extern boost::optional<cFramerateLimiter> replay_fps_limit;
// default new fps: slow the replay down substantially
@@ -1344,14 +1347,14 @@ void handle_events() {
}
}
void handle_quit_event() {
bool handle_quit_event() {
if(recording){
record_action("close_window", "");
}
if(overall_mode == MODE_STARTUP) {
if(party_in_memory) {
std::string choice = cChoiceDlog("quit-confirm-save", {"save","quit","cancel"}).show();
if(choice == "cancel") return;
if(choice == "cancel") return false;
if(choice == "save") {
do_save();
}
@@ -1360,15 +1363,16 @@ void handle_quit_event() {
}else if(overall_mode == MODE_TOWN || overall_mode == MODE_OUTDOORS){
std::string choice = cChoiceDlog("quit-confirm-save", {"save", "quit", "cancel"}).show();
if(choice == "cancel")
return;
return false;
if(choice == "save")
do_save();
} else {
std::string choice = cChoiceDlog("quit-confirm-nosave", {"quit", "cancel"}).show();
if(choice == "cancel")
return;
return false;
}
All_Done = true;
return true;
}
int last_window_x = 0;

View File

@@ -1513,7 +1513,7 @@ void draw_map(bool need_refresh, std::string tooltip_text) {
style.colour = sf::Color::White;
style.lineHeight = 12;
win_draw_string(mini_map(), map_title_rect,title_string,eTextMode::WRAP,style);
win_draw_string(mini_map(), map_bar_rect,"(Hit Escape to close.)",eTextMode::WRAP,style);
win_draw_string(mini_map(), map_bar_rect,"(Hit 'a' to close.)",eTextMode::WRAP,style);
if(canMap) {
rect_draw_some_item(map_gworld().getTexture(),the_rect,mini_map(),area_to_draw_on);