Fix multiple inconsistencies when saving (#550)
* debug_leave_town use same logic as normal town exit. fix #549 * Standardize all save party code paths Fix #480 Fix #204 Fix #267 * remove file_in_mem now that it is redundant * Print message when save file not chosen
This commit is contained in:
@@ -28,7 +28,7 @@ fs::path nav_get_or_decode_party();
|
||||
fs::path nav_put_or_temp_party(fs::path def = "");
|
||||
|
||||
bool load_party(fs::path file_to_load, cUniverse& univ);
|
||||
bool save_party(fs::path dest_file, const cUniverse& univ);
|
||||
bool save_party(cUniverse& univ, bool save_as = false);
|
||||
|
||||
void init_directories(const char* exec_path);
|
||||
|
||||
|
@@ -437,18 +437,17 @@ bool load_party_v2(fs::path file_to_load, cUniverse& real_univ){
|
||||
} else showWarning("There was an error loading the party custom graphics.");
|
||||
}
|
||||
|
||||
univ.file = file_to_load;
|
||||
real_univ = std::move(univ);
|
||||
return true;
|
||||
}
|
||||
|
||||
//mode; // 0 - normal 1 - save as
|
||||
bool save_party(fs::path dest_file, const cUniverse& univ) {
|
||||
static bool save_party_const(const cUniverse& univ, bool save_as) {
|
||||
// Make sure it has the proper file extension
|
||||
std::string fname = dest_file.filename().string();
|
||||
size_t dot = fname.find_last_of('.');
|
||||
if(dot == std::string::npos || fname.substr(dot) != ".exg")
|
||||
fname += ".exg";
|
||||
dest_file = dest_file.parent_path()/fname;
|
||||
fs::path dest_file = univ.file;
|
||||
if(dest_file.extension() != ".exg"){
|
||||
dest_file += ".exg";
|
||||
}
|
||||
|
||||
tarball partyOut;
|
||||
cTagFile file;
|
||||
@@ -543,3 +542,13 @@ bool save_party(fs::path dest_file, const cUniverse& univ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool save_party(cUniverse& univ, bool save_as) {
|
||||
// univ.file can be empty for prefab parties, so a file browser might be needed
|
||||
// even for a regular save.
|
||||
if(save_as || univ.file.empty()){
|
||||
univ.file = nav_put_or_temp_party();
|
||||
}
|
||||
// A file wasn't chosen
|
||||
if(univ.file.empty()) return false;
|
||||
return save_party_const(univ, save_as);
|
||||
}
|
||||
|
@@ -1252,9 +1252,7 @@ void handle_victory(bool force, bool record) {
|
||||
menu_activate();
|
||||
univ.party.scen_name = ""; // should be harmless...
|
||||
if(!force && cChoiceDlog("congrats-save",{"cancel","save"}).show() == "save"){
|
||||
// TODO: Wait, this shouldn't be a "save as" action, should it? It should save without asking for a location.
|
||||
fs::path file = nav_put_or_temp_party();
|
||||
if(!file.empty()) save_party(file, univ);
|
||||
do_save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1450,9 +1448,7 @@ bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter) {
|
||||
|
||||
case TOOLBAR_SAVE:
|
||||
if(overall_mode == MODE_OUTDOORS) {
|
||||
save_party(univ.file, univ);
|
||||
need_redraw = true;
|
||||
current_switch = 6;
|
||||
do_save();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -2023,14 +2019,10 @@ void debug_leave_town() {
|
||||
print_buf();
|
||||
return;
|
||||
}
|
||||
univ.party.end_split(0);
|
||||
overall_mode = MODE_OUTDOORS;
|
||||
position_party(univ.party.outdoor_corner.x,univ.party.outdoor_corner.y,univ.party.out_loc.x,univ.party.out_loc.y);
|
||||
clear_map();
|
||||
add_string_to_buf("Debug: Reunite party and leave town.");
|
||||
ASB("Debug: Reunite party and leave town.");
|
||||
print_buf();
|
||||
update_explored(univ.party.out_loc);
|
||||
redraw_screen(REFRESH_ALL);
|
||||
univ.party.end_split(0);
|
||||
end_town_mode(false, {0,0}, true);
|
||||
}
|
||||
|
||||
void debug_kill() {
|
||||
@@ -2777,25 +2769,24 @@ void post_load() {
|
||||
}
|
||||
|
||||
//mode; // 0 - normal 1 - save as
|
||||
void do_save(short mode) {
|
||||
void do_save(bool save_as) {
|
||||
if(overall_mode != MODE_TOWN && overall_mode != MODE_OUTDOORS && overall_mode != MODE_STARTUP) {
|
||||
add_string_to_buf("Save: Only while outdoors, or in town and not looking/casting.", 2);
|
||||
print_buf();
|
||||
return;
|
||||
}
|
||||
|
||||
if(univ.party.is_in_scenario()) save_outdoor_maps();
|
||||
fs::path file = univ.file;
|
||||
if(mode == 1 || file.empty())
|
||||
file = nav_put_or_temp_party(file);
|
||||
bool saved = false;
|
||||
if(!file.empty()) {
|
||||
univ.file = file;
|
||||
saved = save_party(univ.file, univ);
|
||||
}
|
||||
|
||||
if(saved)
|
||||
if(save_party(univ, save_as)){
|
||||
add_string_to_buf("Save: Game saved");
|
||||
|
||||
}else{
|
||||
add_string_to_buf("Save: Save not completed");
|
||||
}
|
||||
|
||||
// Cancel switching PC order
|
||||
current_switch = 6;
|
||||
|
||||
pause(6);
|
||||
redraw_screen(REFRESH_TEXT);
|
||||
}
|
||||
@@ -3307,9 +3298,7 @@ void start_new_game(bool force) {
|
||||
}
|
||||
party_in_memory = true;
|
||||
if(force) return;
|
||||
fs::path file = nav_put_or_temp_party();
|
||||
if(!file.empty()) save_party(file, univ);
|
||||
univ.file = file;
|
||||
do_save(true);
|
||||
}
|
||||
|
||||
void start_tutorial() {
|
||||
|
@@ -20,7 +20,7 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter);
|
||||
bool handle_scroll(const sf::Event& event);
|
||||
void do_load();
|
||||
void post_load();
|
||||
void do_save(short mode);
|
||||
void do_save(bool save_as = false);
|
||||
void do_abort();
|
||||
void increase_age();
|
||||
void handle_hunting();
|
||||
|
@@ -1140,9 +1140,7 @@ void handle_quit_event() {
|
||||
std::string choice = cChoiceDlog("quit-confirm-save", {"save","quit","cancel"}).show();
|
||||
if(choice == "cancel") return;
|
||||
if(choice == "save") {
|
||||
fs::path file = nav_put_or_temp_party();
|
||||
if(file.empty()) return;
|
||||
save_party(file, univ);
|
||||
do_save();
|
||||
}
|
||||
}
|
||||
All_Done = true;
|
||||
@@ -1151,7 +1149,7 @@ void handle_quit_event() {
|
||||
if(choice == "cancel")
|
||||
return;
|
||||
if(choice == "save")
|
||||
save_party(univ.file, univ);
|
||||
do_save();
|
||||
} else {
|
||||
std::string choice = cChoiceDlog("quit-confirm-nosave", {"quit", "cancel"}).show();
|
||||
if(choice == "cancel")
|
||||
@@ -1329,10 +1327,10 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
do_load();
|
||||
break;
|
||||
case eMenu::FILE_SAVE:
|
||||
do_save(0);
|
||||
do_save();
|
||||
break;
|
||||
case eMenu::FILE_SAVE_AS:
|
||||
do_save(1);
|
||||
do_save(true);
|
||||
break;
|
||||
case eMenu::FILE_NEW:
|
||||
new_party();
|
||||
|
@@ -513,7 +513,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
}
|
||||
|
||||
|
||||
location end_town_mode(short switching_level,location destination) { // returns new party location
|
||||
location end_town_mode(bool switching_level,location destination, bool debug_leave) { // returns new party location
|
||||
location to_return;
|
||||
bool data_saved = false,combat_end = false;
|
||||
|
||||
@@ -576,7 +576,7 @@ location end_town_mode(short switching_level,location destination) { // returns
|
||||
|
||||
|
||||
// Check for exit specials, if leaving town
|
||||
if(switching_level == 0) {
|
||||
if(!switching_level && !debug_leave) {
|
||||
to_return = univ.party.out_loc;
|
||||
|
||||
if(is_town()) {
|
||||
@@ -612,7 +612,7 @@ location end_town_mode(short switching_level,location destination) { // returns
|
||||
}
|
||||
}
|
||||
|
||||
if(switching_level == 0) {
|
||||
if(!switching_level) {
|
||||
overall_mode = MODE_OUTDOORS;
|
||||
|
||||
erase_out_specials();
|
||||
|
@@ -4,7 +4,7 @@
|
||||
|
||||
void force_town_enter(short which_town,location where_start);
|
||||
void start_town_mode(short which_town, short entry_dir);
|
||||
location end_town_mode(short switching_level,location destination); // returns new party location
|
||||
location end_town_mode(bool switching_level,location destination,bool debug_leave=false); // returns new party location
|
||||
void handle_leave_town_specials(short town_number, short which_spec,location start_loc) ;
|
||||
void handle_town_specials(short town_number, bool town_dead,location start_loc) ;
|
||||
bool abil_exists(eItemAbil abil);
|
||||
|
@@ -16,7 +16,6 @@
|
||||
|
||||
extern cUniverse univ;
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern fs::path file_in_mem;
|
||||
extern sf::Texture pc_gworld;
|
||||
|
||||
short which_pc_displayed,store_pc_trait_mode,store_which_to_edit;
|
||||
@@ -37,7 +36,7 @@ bool handle_action(const sf::Event & event) {
|
||||
|
||||
bool to_return = false;
|
||||
|
||||
if(file_in_mem.empty())
|
||||
if(univ.file.empty())
|
||||
return false;
|
||||
|
||||
for(short i = 0; i < 6; i++)
|
||||
|
@@ -16,7 +16,6 @@
|
||||
extern bool verify_restore_quit(std::string dlog);
|
||||
extern bool All_Done, party_in_scen, scen_items_loaded;
|
||||
extern cUniverse univ;
|
||||
extern fs::path file_in_mem;
|
||||
|
||||
@interface AppleEventHandler : NSObject<NSApplicationDelegate>
|
||||
-(BOOL)application:(NSApplication*) app openFile:(NSString*) file;
|
||||
@@ -41,7 +40,6 @@ void set_up_apple_events() {
|
||||
std::copy(msg.get(), msg.get() + len, std::inserter(fileName, fileName.begin()));
|
||||
|
||||
if(load_party(fileName, univ)) {
|
||||
file_in_mem = fileName;
|
||||
party_in_scen = !univ.party.scen_name.empty();
|
||||
if(!party_in_scen) load_base_item_defs();
|
||||
scen_items_loaded = true;
|
||||
|
@@ -24,7 +24,6 @@ extern cUniverse univ;
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern sf::View mainView;
|
||||
extern bool party_in_scen,scen_items_loaded;
|
||||
extern fs::path file_in_mem;
|
||||
|
||||
extern short store_flags[3];
|
||||
extern short current_active_pc;
|
||||
@@ -254,7 +253,7 @@ void draw_main_screen() {
|
||||
|
||||
TextStyle style;
|
||||
style.lineHeight = 10;
|
||||
if(!file_in_mem.empty()) {
|
||||
if(!univ.file.empty()) {
|
||||
dest_rect = dest_rec;
|
||||
dest_rect.left = 20;
|
||||
dest_rect.top = dest_rect.bottom - 10;
|
||||
@@ -273,21 +272,21 @@ void draw_main_screen() {
|
||||
dest_rect.right = whole_win_rect.right - 30; //What is this for? Commenting it out has no effect.
|
||||
dest_rect.left += 60;
|
||||
dest_rect.offset(0,21);
|
||||
if(!file_in_mem.empty())
|
||||
if(!univ.file.empty())
|
||||
win_draw_string(mainPtr,dest_rect,"Click on character to edit it.",eTextMode::WRAP,style);
|
||||
else
|
||||
win_draw_string(mainPtr,dest_rect,"Select Open from File menu.",eTextMode::WRAP,style);
|
||||
if(!file_in_mem.empty() && party_in_scen && !scen_items_loaded){
|
||||
if(!univ.file.empty() && party_in_scen && !scen_items_loaded){
|
||||
dest_rect.offset(200,0);
|
||||
win_draw_string(mainPtr,dest_rect,"Warning: Scenario item data could not be loaded.",eTextMode::WRAP,style);
|
||||
dest_rect.offset(-200,0);
|
||||
}
|
||||
dest_rect.offset(0,14);
|
||||
if(!file_in_mem.empty())
|
||||
if(!univ.file.empty())
|
||||
win_draw_string(mainPtr,dest_rect,"Press 'I' button to identify item, and 'D' button to drop item.",eTextMode::WRAP,style);
|
||||
style.pointSize = 12;
|
||||
dest_rect.offset(0,16);
|
||||
if(!file_in_mem.empty())
|
||||
if(!univ.file.empty())
|
||||
win_draw_string(mainPtr,dest_rect,"Back up save file before editing it!",eTextMode::WRAP,style);
|
||||
style.pointSize = 10;
|
||||
style.font = FONT_PLAIN;
|
||||
@@ -327,7 +326,7 @@ void do_button_action(short /*which_pc*/,short which_button) {
|
||||
void draw_items() {
|
||||
rectangle d_from = {12,28,24,42},i_from = {12,42,24,56},dest_rect;
|
||||
|
||||
if(file_in_mem.empty()) // save file loaded
|
||||
if(univ.file.empty()) // save file loaded
|
||||
return;
|
||||
|
||||
dest_rect = item_string_rects[0][0];
|
||||
@@ -380,7 +379,7 @@ void display_party() {
|
||||
|
||||
TextStyle style;
|
||||
style.lineHeight = 10;
|
||||
if(file_in_mem.empty()) { // what if no party loaded?
|
||||
if(univ.file.empty()) { // what if no party loaded?
|
||||
no_party_rect=pc_info_rect;
|
||||
no_party_rect.top+=5;
|
||||
no_party_rect.left+=5;
|
||||
|
@@ -57,7 +57,6 @@ bool All_Done = false;
|
||||
bool changed_display_mode = false;
|
||||
sf::RenderWindow mainPtr;
|
||||
sf::View mainView;
|
||||
fs::path file_in_mem;
|
||||
bool party_in_scen = false;
|
||||
bool scen_items_loaded = false;
|
||||
|
||||
@@ -100,7 +99,6 @@ static void process_args(int argc, char* argv[]) {
|
||||
}
|
||||
if(!file.empty()) {
|
||||
if(load_party(file, univ)) {
|
||||
file_in_mem = file;
|
||||
party_in_scen = !univ.party.scen_name.empty();
|
||||
if(!party_in_scen) load_base_item_defs();
|
||||
scen_items_loaded = true;
|
||||
@@ -277,11 +275,10 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
cChoiceDlog("about-pced").show();
|
||||
break;
|
||||
case eMenu::FILE_SAVE:
|
||||
save_party(file_in_mem, univ);
|
||||
save_party(univ);
|
||||
break;
|
||||
case eMenu::FILE_SAVE_AS:
|
||||
file = nav_put_party();
|
||||
if(!file.empty()) save_party(file, univ);
|
||||
save_party(univ, true);
|
||||
break;
|
||||
case eMenu::FILE_OPEN:
|
||||
result = verify_restore_quit("save-open");
|
||||
@@ -289,10 +286,9 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
case eMenu::FILE_REVERT:
|
||||
result = cChoiceDlog("save-revert", {"okay", "cancel"}).show() == "okay";
|
||||
if(result) {
|
||||
file = item_hit == eMenu::FILE_OPEN ? nav_get_party() : file_in_mem;
|
||||
file = item_hit == eMenu::FILE_OPEN ? nav_get_party() : univ.file;
|
||||
if(!file.empty()) {
|
||||
if(load_party(file, univ)) {
|
||||
file_in_mem = file;
|
||||
party_in_scen = !univ.party.scen_name.empty();
|
||||
if(!party_in_scen) load_base_item_defs();
|
||||
scen_items_loaded = true;
|
||||
@@ -303,7 +299,7 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
break;
|
||||
case eMenu::FILE_CLOSE:
|
||||
if(verify_restore_quit("save-close"))
|
||||
file_in_mem = "";
|
||||
univ = cUniverse();
|
||||
break;
|
||||
case eMenu::PREFS:
|
||||
pick_preferences();
|
||||
@@ -450,7 +446,7 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
bool verify_restore_quit(std::string dlog) {
|
||||
std::string choice;
|
||||
|
||||
if(file_in_mem.empty())
|
||||
if(univ.file.empty())
|
||||
return true;
|
||||
cChoiceDlog verify(dlog, {"save", "quit", "cancel"});
|
||||
choice = verify.show();
|
||||
@@ -458,7 +454,7 @@ bool verify_restore_quit(std::string dlog) {
|
||||
return false;
|
||||
if(choice == "quit")
|
||||
return true;
|
||||
save_party(file_in_mem, univ);
|
||||
save_party(univ);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1,13 +1,14 @@
|
||||
|
||||
#include <memory>
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include "tools/winutil.hpp"
|
||||
#include "universe/universe.hpp"
|
||||
#include "pc.menus.hpp"
|
||||
#include "pc.menu.hpp"
|
||||
#include "tools/winutil.hpp"
|
||||
#include <SFML/Graphics/RenderWindow.hpp>
|
||||
#include <memory>
|
||||
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern bool party_in_scen;
|
||||
extern fs::path file_in_mem;
|
||||
extern cUniverse univ;
|
||||
|
||||
std::shared_ptr<OpenBoEPCEditMenu> menu_ptr;
|
||||
|
||||
@@ -16,7 +17,7 @@ void init_menubar() {
|
||||
}
|
||||
|
||||
void menu_activate() {
|
||||
menu_ptr->update_for_editor_state(!file_in_mem.empty(), party_in_scen);
|
||||
menu_ptr->update_for_editor_state(!univ.file.empty(), party_in_scen);
|
||||
}
|
||||
|
||||
bool menuBarProcessEvent (sf::Event const & event) {
|
||||
|
@@ -20,7 +20,6 @@ extern short menuChoiceId;
|
||||
using MenuHandle = NSMenu*;
|
||||
|
||||
extern cUniverse univ;
|
||||
extern fs::path file_in_mem;
|
||||
extern bool scen_items_loaded, party_in_scen;
|
||||
MenuHandle menu_bar_handle;
|
||||
MenuHandle apple_menu, file_menu, reg_menu, extra_menu;
|
||||
@@ -83,7 +82,7 @@ void init_menubar() {
|
||||
}
|
||||
|
||||
void menu_activate() {
|
||||
if(file_in_mem.empty()) {
|
||||
if(univ.file.empty()) {
|
||||
for(int i = 3; i < [file_menu numberOfItems]; i++)
|
||||
[[file_menu itemAtIndex: i] setEnabled: NO];
|
||||
[[menu_bar_handle itemWithTitle: @"Edit Party"] setEnabled: NO];
|
||||
|
@@ -22,7 +22,6 @@ enum {
|
||||
extern sf::RenderWindow mainPtr;
|
||||
extern cUniverse univ;
|
||||
extern bool scen_items_loaded, party_in_scen;
|
||||
extern fs::path file_in_mem;
|
||||
LONG_PTR mainProc;
|
||||
HMENU menuHandle = NULL;
|
||||
accel_table_t accel;
|
||||
@@ -106,7 +105,7 @@ void init_menubar() {
|
||||
void menu_activate() {
|
||||
if(menuHandle == NULL) return;
|
||||
HMENU file_menu = GetSubMenu(menuHandle, FILE_MENU_POS);
|
||||
if(file_in_mem.empty()) {
|
||||
if(univ.file.empty()) {
|
||||
EnableMenuItem(menuHandle, PARTY_MENU_POS, MF_BYPOSITION | MF_GRAYED);
|
||||
EnableMenuItem(menuHandle, SCEN_MENU_POS, MF_BYPOSITION | MF_GRAYED);
|
||||
for(int i = 1; i < GetMenuItemCount(file_menu) - 1; i++)
|
||||
|
Reference in New Issue
Block a user