From 940f480fb052ac406d7c4ef7c9a5014f4622c514 Mon Sep 17 00:00:00 2001 From: Berbe <4251220+Berbe@users.noreply.github.com> Date: Tue, 16 Mar 2021 03:22:37 +0100 Subject: [PATCH] Add: Improve heightmap support (dedicated) --- src/fios.cpp | 4 +- src/fios.h | 2 + src/genworld_gui.cpp | 17 +++++++- src/openttd.cpp | 88 +++++++++++++++++++++++++++++++++++---- src/video/dedicated_v.cpp | 2 +- 5 files changed, 100 insertions(+), 13 deletions(-) diff --git a/src/fios.cpp b/src/fios.cpp index 8e150daafd..19e41b73eb 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -490,7 +490,7 @@ void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list) * @see FiosGetFileList * @see FiosGetScenarioList */ -static std::tuple FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext) +std::tuple FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext) { /* Show scenario files * .SCN OpenTTD style scenario file @@ -530,7 +530,7 @@ void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list) FiosGetFileList(fop, &FiosGetScenarioListCallback, subdir, file_list); } -static std::tuple FiosGetHeightmapListCallback(SaveLoadOperation, const std::string &file, const std::string_view ext) +std::tuple FiosGetHeightmapListCallback(SaveLoadOperation, const std::string &file, const std::string_view ext) { /* Show heightmap files * .PNG PNG Based heightmap files diff --git a/src/fios.h b/src/fios.h index 8c727c2e32..fb4bcaf4b7 100644 --- a/src/fios.h +++ b/src/fios.h @@ -117,6 +117,8 @@ std::string FiosMakeHeightmapName(const char *name); std::string FiosMakeSavegameName(const char *name); std::tuple FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext); +std::tuple FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext); +std::tuple FiosGetHeightmapListCallback(SaveLoadOperation, const std::string &file, const std::string_view ext); void ScanScenarios(); const char *FindScenario(const ContentInfo *ci, bool md5sum); diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index d961b5d3df..da17636caa 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -1075,7 +1075,7 @@ void StartScenarioEditor() } /** - * Start a normal game without the GUI. + * Start a normal/heightmap game without the GUI. * @param seed The seed of the new game. */ void StartNewGameWithoutGUI(uint32_t seed) @@ -1083,7 +1083,20 @@ void StartNewGameWithoutGUI(uint32_t seed) /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */ _settings_newgame.game_creation.generation_seed = seed; - StartGeneratingLandscape(GLWM_GENERATE); + + GenerateLandscapeWindowMode mode = GLWM_GENERATE; + + if(_file_to_saveload.abstract_ftype == FT_HEIGHTMAP) { + uint x = 0; + uint y = 0; + + /* If the function returns false, it means there was a problem loading the heightmap */ + if (!GetHeightmapDimensions(_file_to_saveload.detail_ftype, _file_to_saveload.name.c_str(), &x, &y)) return; + + mode = GLWM_HEIGHTMAP; + } + + StartGeneratingLandscape(mode); } struct CreateScenarioWindow : public Window diff --git a/src/openttd.cpp b/src/openttd.cpp index 8b05cfe9af..c273ab3869 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -163,7 +163,7 @@ static void ShowHelp() " -t year = Set starting year\n" " -d [[fac=]lvl[,...]]= Debug mode\n" " -e = Start Editor\n" - " -g [savegame] = Start new/save game immediately\n" + " -g [file/name/title] = Load savegame/scenario/heightmap immediately\n" " -G seed = Set random seed\n" " -n host[:port][#company]= Join network game\n" " -p password = Password to join server\n" @@ -583,19 +583,79 @@ int openttd_main(int argc, char *argv[]) if (mgo.opt != nullptr) SetDebugString(mgo.opt, ShowInfoI); break; } - case 'e': _switch_mode = (_switch_mode == SM_LOAD_GAME || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : SM_EDITOR); break; + case 'e': + _switch_mode = (_switch_mode == SM_LOAD_GAME || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : ((_switch_mode == SM_LOAD_HEIGHTMAP || _switch_mode == SM_START_HEIGHTMAP) ? SM_LOAD_HEIGHTMAP : SM_EDITOR)); + break; case 'g': if (mgo.opt != nullptr) { _file_to_saveload.name = mgo.opt; - bool is_scenario = _switch_mode == SM_EDITOR || _switch_mode == SM_LOAD_SCENARIO; - _switch_mode = is_scenario ? SM_LOAD_SCENARIO : SM_LOAD_GAME; - _file_to_saveload.SetMode(SLO_LOAD, is_scenario ? FT_SCENARIO : FT_SAVEGAME, DFT_GAME_FILE); + bool is_editor = _switch_mode == SM_EDITOR || _switch_mode == SM_LOAD_SCENARIO || _switch_mode == SM_LOAD_HEIGHTMAP; + _switch_mode = is_editor ? (_switch_mode == SM_LOAD_HEIGHTMAP ? SM_LOAD_HEIGHTMAP : SM_LOAD_SCENARIO) : SM_LOAD_GAME; + _file_to_saveload.SetMode(SLO_LOAD, is_editor ? (_switch_mode == SM_LOAD_HEIGHTMAP ? FT_HEIGHTMAP : FT_SCENARIO) : FT_SAVEGAME, DFT_GAME_FILE); - /* if the file doesn't exist or it is not a valid savegame, let the saveload code show an error */ + /* If supplied file does not exist or is not a valid savegame/scenario/heightmap, let the saveload code show an error */ auto t = _file_to_saveload.name.find_last_of('.'); if (t != std::string::npos) { auto [ft, _] = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, _file_to_saveload.name.substr(t)); - if (ft != FIOS_TYPE_INVALID) _file_to_saveload.SetMode(ft); + if (ft != FIOS_TYPE_INVALID) { + _file_to_saveload.SetMode(ft); + _switch_mode = is_editor ? SM_LOAD_SCENARIO : SM_LOAD_GAME; + break; + } + std::tie(ft, _) = FiosGetScenarioListCallback(SLO_LOAD, _file_to_saveload.name, _file_to_saveload.name.substr(t)); + if (ft != FIOS_TYPE_INVALID) { + _file_to_saveload.SetMode(ft); + _switch_mode = is_editor ? SM_LOAD_SCENARIO : SM_LOAD_GAME; + break; + } + std::tie(ft, _) = FiosGetHeightmapListCallback(SLO_LOAD, _file_to_saveload.name, _file_to_saveload.name.substr(t)); + if (ft != FIOS_TYPE_INVALID) { + _file_to_saveload.SetMode(ft); + _switch_mode = is_editor ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; + break; + } + } + + /* If supplied value was not recognized as a valid resource, attempt to find a matching title */ + DeterminePaths(argv[0], only_local_path); + TarScanner::DoScan(TarScanner::SCENARIO); + FileList _my_file_list; + const FiosItem *item; + + _my_file_list.BuildFileList(FT_SAVEGAME, SLO_LOAD); + item = _my_file_list.FindItem(mgo.opt); + if (item != nullptr) { + if (GetAbstractFileType(item->type) == FT_SAVEGAME) { + _file_to_saveload.SetMode(item->type); + _file_to_saveload.name = FiosBrowseTo(item); + _file_to_saveload.title = item->title; + } + _switch_mode = is_editor ? SM_LOAD_SCENARIO : SM_LOAD_GAME; + break; + } + + _my_file_list.BuildFileList(FT_SCENARIO, SLO_LOAD); + item = _my_file_list.FindItem(mgo.opt); + if (item != nullptr) { + if (GetAbstractFileType(item->type) == FT_SCENARIO) { + _file_to_saveload.SetMode(item->type); + _file_to_saveload.name = FiosBrowseTo(item); + _file_to_saveload.title = item->title; + } + _switch_mode = is_editor ? SM_LOAD_SCENARIO : SM_LOAD_GAME; + break; + } + + _my_file_list.BuildFileList(FT_HEIGHTMAP, SLO_LOAD); + item = _my_file_list.FindItem(mgo.opt); + if (item != nullptr) { + if (GetAbstractFileType(item->type) == FT_HEIGHTMAP) { + _file_to_saveload.SetMode(item->type); + _file_to_saveload.name = FiosBrowseTo(item); + _file_to_saveload.title = item->title; + } + _switch_mode = is_editor ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; + break; } break; @@ -949,6 +1009,18 @@ bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileTy SaveOrLoadResult result = (lf == nullptr) ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf); if (result == SL_OK) return true; + if (_network_dedicated && _switch_mode == SM_START_HEIGHTMAP) { + auto t = _file_to_saveload.name.find_last_of('.'); + if (t != std::string::npos) { + auto [ft, _] = FiosGetHeightmapListCallback(SLO_LOAD, filename, filename.substr(t)); + (void)_; // Drop unused member of structured binding + if (ft != FIOS_TYPE_INVALID) { + _file_to_saveload.SetMode(ft); + return true; + } + } + } + if (_network_dedicated && ogm == GM_MENU) { /* * If we are a dedicated server *and* we just were in the menu, then we @@ -999,7 +1071,7 @@ void SwitchToMode(SwitchMode new_mode) if (new_mode != SM_SAVE_GAME) { /* If the network is active, make it not-active */ if (_networking) { - if (_network_server && (new_mode == SM_LOAD_GAME || new_mode == SM_NEWGAME || new_mode == SM_RESTARTGAME)) { + if (_network_server && (new_mode == SM_LOAD_GAME || new_mode == SM_START_HEIGHTMAP || new_mode == SM_NEWGAME || new_mode == SM_RESTARTGAME)) { NetworkReboot(); } else { NetworkDisconnect(); diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index f891be2402..87c2deda26 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.cpp @@ -205,7 +205,7 @@ void VideoDriver_Dedicated::MainLoop() _current_company = _local_company = COMPANY_SPECTATOR; /* If SwitchMode is SM_LOAD_GAME, it means that the user used the '-g' options */ - if (_switch_mode != SM_LOAD_GAME) { + if (_switch_mode != SM_LOAD_GAME && _switch_mode != SM_START_HEIGHTMAP) { StartNewGameWithoutGUI(GENERATE_NEW_SEED); }