Skip to content

Commit

Permalink
Feature: Import real-world town data via JSON file
Browse files Browse the repository at this point in the history
  • Loading branch information
2TallTyler committed Jan 23, 2024
1 parent 218d1db commit a353e5e
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/fileio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static const char * const _subdirs[] = {
"save" PATHSEP "autosave" PATHSEP,
"scenario" PATHSEP,
"scenario" PATHSEP "heightmap" PATHSEP,
"scenario" PATHSEP "towndata" PATHSEP,
"gm" PATHSEP,
"data" PATHSEP,
"baseset" PATHSEP,
Expand Down Expand Up @@ -1055,7 +1056,7 @@ void DeterminePaths(const char *exe, bool only_local_path)
Debug(misc, 1, "{} found as personal directory", _personal_dir);

static const Subdirectory default_subdirs[] = {
SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR, SCREENSHOT_DIR, SOCIAL_INTEGRATION_DIR
SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, TOWN_DATA_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR, SCREENSHOT_DIR, SOCIAL_INTEGRATION_DIR
};

for (uint i = 0; i < lengthof(default_subdirs); i++) {
Expand Down
6 changes: 6 additions & 0 deletions src/fileio_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum AbstractFileType {
FT_SAVEGAME, ///< old or new savegame
FT_SCENARIO, ///< old or new scenario
FT_HEIGHTMAP, ///< heightmap file
FT_TOWN_DATA, ///< town data file

FT_INVALID = 7, ///< Invalid or unknown file type.
FT_NUMBITS = 3, ///< Number of bits required for storing a #AbstractFileType value.
Expand All @@ -34,6 +35,9 @@ enum DetailedFileType {
DFT_HEIGHTMAP_BMP, ///< BMP file.
DFT_HEIGHTMAP_PNG, ///< PNG file.

/* Town data files. */
DFT_TOWN_DATA_JSON, ///< JSON file.

/* fios 'files' */
DFT_FIOS_DRIVE, ///< A drive (letter) entry.
DFT_FIOS_PARENT, ///< A parent directory entry.
Expand Down Expand Up @@ -76,6 +80,7 @@ enum FiosType {
FIOS_TYPE_OLD_SCENARIO = MAKE_FIOS_TYPE(FT_SCENARIO, DFT_OLD_GAME_FILE),
FIOS_TYPE_PNG = MAKE_FIOS_TYPE(FT_HEIGHTMAP, DFT_HEIGHTMAP_PNG),
FIOS_TYPE_BMP = MAKE_FIOS_TYPE(FT_HEIGHTMAP, DFT_HEIGHTMAP_BMP),
FIOS_TYPE_JSON = MAKE_FIOS_TYPE(FT_TOWN_DATA, DFT_TOWN_DATA_JSON),

FIOS_TYPE_INVALID = MAKE_FIOS_TYPE(FT_INVALID, DFT_INVALID),
};
Expand Down Expand Up @@ -111,6 +116,7 @@ enum Subdirectory {
AUTOSAVE_DIR, ///< Subdirectory of save for autosaves
SCENARIO_DIR, ///< Base directory for all scenarios
HEIGHTMAP_DIR, ///< Subdirectory of scenario for heightmaps
TOWN_DATA_DIR, ///< Subdirectory of scenario for town data
OLD_GM_DIR, ///< Old subdirectory for the music
OLD_DATA_DIR, ///< Old subdirectory for the data.
BASESET_DIR, ///< Subdirectory for all base data (base sets, intro game)
Expand Down
40 changes: 40 additions & 0 deletions src/fios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ void FileList::BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperati
FiosGetHeightmapList(fop, *this);
break;

case FT_TOWN_DATA:
FiosGetTownDataList(fop, *this);
break;

default:
NOT_REACHED();
}
Expand Down Expand Up @@ -183,6 +187,7 @@ bool FiosBrowseTo(const FiosItem *item)
case FIOS_TYPE_OLD_SCENARIO:
case FIOS_TYPE_PNG:
case FIOS_TYPE_BMP:
case FIOS_TYPE_JSON:
return false;
}

Expand Down Expand Up @@ -585,6 +590,41 @@ void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list)
FiosGetFileList(fop, &FiosGetHeightmapListCallback, subdir, file_list);
}

/**
* Callback for FiosGetTownDataList.
* @param fop Purpose of collecting the list.
* @param file Name of the file to check.
* @return a FIOS_TYPE_JSON type of the found file, FIOS_TYPE_INVALID if not a valid JSON file, and the title of the file (if any).
*/
static std::tuple<FiosType, std::string> FiosGetTownDataListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext)
{
if (fop == SLO_LOAD) {
if (StrEqualsIgnoreCase(ext, ".json")) {
return { FIOS_TYPE_JSON, GetFileTitle(file, SAVE_DIR) };
}
}

return { FIOS_TYPE_INVALID, {} };
}

/**
* Get a list of town data files.
* @param fop Purpose of collecting the list.
* @param file_list Destination of the found files.
*/
void FiosGetTownDataList(SaveLoadOperation fop, FileList &file_list)
{
static std::optional<std::string> fios_town_data_path;

if (!fios_town_data_path) fios_town_data_path = FioFindDirectory(TOWN_DATA_DIR);

_fios_path = &(*fios_town_data_path);

std::string base_path = FioFindDirectory(TOWN_DATA_DIR);
Subdirectory subdir = base_path == *_fios_path ? TOWN_DATA_DIR : NO_DIRECTORY;
FiosGetFileList(fop, &FiosGetTownDataListCallback, subdir, file_list);
}

/**
* Get the directory for screenshots.
* @return path to screenshots
Expand Down
1 change: 1 addition & 0 deletions src/fios.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fo
void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list);
void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list);
void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list);
void FiosGetTownDataList(SaveLoadOperation fop, FileList &file_list);

bool FiosBrowseTo(const FiosItem *item);

Expand Down
79 changes: 77 additions & 2 deletions src/fios_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "querystring_gui.h"
#include "engine_func.h"
#include "landscape_type.h"
#include "genworld.h"
#include "timer/timer_game_calendar.h"
#include "core/geometry_func.hpp"
#include "gamelog.h"
Expand Down Expand Up @@ -168,6 +169,49 @@ static constexpr NWidgetPart _nested_load_heightmap_dialog_widgets[] = {
EndContainer(),
};

/** Load town data */
static constexpr NWidgetPart _nested_load_town_data_dialog_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
EndContainer(),
/* Current directory and free space */
NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(),

/* Filter box with label */
NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0),
SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
EndContainer(),
EndContainer(),
/* Sort Buttons */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0),
EndContainer(),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON),
EndContainer(),
/* Files */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND),
NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2),
SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(),
EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR),
EndContainer(),
/* Load button */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetResize(1, 0), SetFill(1, 0),
SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_TOWN_DATA_TOOLTIP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
EndContainer(),
};

/** Save game/scenario */
static constexpr NWidgetPart _nested_save_dialog_widgets[] = {
NWidget(NWID_HORIZONTAL),
Expand Down Expand Up @@ -233,6 +277,7 @@ static const TextColour _fios_colours[] = {
TC_ORANGE, // DFT_GAME_FILE
TC_YELLOW, // DFT_HEIGHTMAP_BMP
TC_ORANGE, // DFT_HEIGHTMAP_PNG
TC_LIGHT_BROWN, // DFT_TOWN_DATA_JSON
TC_LIGHT_BLUE, // DFT_FIOS_DRIVE
TC_DARK_GREEN, // DFT_FIOS_PARENT
TC_DARK_GREEN, // DFT_FIOS_DIR
Expand Down Expand Up @@ -320,6 +365,7 @@ struct SaveLoadWindow : public Window {
break;

default:
/* It's not currently possible to save town data. */
NOT_REACHED();
}
}
Expand All @@ -346,6 +392,10 @@ struct SaveLoadWindow : public Window {
caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_HEIGHTMAP : STR_SAVELOAD_LOAD_HEIGHTMAP;
break;

case FT_TOWN_DATA:
caption_string = STR_SAVELOAD_LOAD_TOWN_DATA; // It's not currently possible to save town data.
break;

default:
NOT_REACHED();
}
Expand Down Expand Up @@ -384,6 +434,10 @@ struct SaveLoadWindow : public Window {
o_dir.name = FioFindDirectory(HEIGHTMAP_DIR);
break;

case FT_TOWN_DATA:
o_dir.name = FioFindDirectory(TOWN_DATA_DIR);
break;

default:
o_dir.name = _personal_dir;
}
Expand Down Expand Up @@ -624,6 +678,9 @@ struct SaveLoadWindow : public Window {
if (this->abstract_filetype == FT_HEIGHTMAP) {
this->Close();
ShowHeightmapLoad();
} else if (this->abstract_filetype == FT_TOWN_DATA) {
this->Close();
LoadTownData();
} else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
_switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
ClearErrorMessages();
Expand Down Expand Up @@ -679,7 +736,7 @@ struct SaveLoadWindow : public Window {
} else if (!_load_check_data.HasErrors()) {
this->selected = file;
if (this->fop == SLO_LOAD) {
if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) {
if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO || this->abstract_filetype == FT_TOWN_DATA) {
this->OnClick(pt, WID_SL_LOAD_BUTTON, 1);
} else {
assert(this->abstract_filetype == FT_HEIGHTMAP);
Expand Down Expand Up @@ -846,6 +903,7 @@ struct SaveLoadWindow : public Window {

switch (this->abstract_filetype) {
case FT_HEIGHTMAP:
case FT_TOWN_DATA:
this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, this->selected == nullptr || _load_check_data.HasErrors());
break;

Expand Down Expand Up @@ -898,6 +956,14 @@ static WindowDesc _load_heightmap_dialog_desc(__FILE__, __LINE__,
std::begin(_nested_load_heightmap_dialog_widgets), std::end(_nested_load_heightmap_dialog_widgets)
);

/** Load town data */
static WindowDesc _load_town_data_dialog_desc(__FILE__, __LINE__,
WDP_CENTER, "load_town_data", 257, 320,
WC_SAVELOAD, WC_NONE,
0,
std::begin(_nested_load_town_data_dialog_widgets), std::end(_nested_load_town_data_dialog_widgets)
);

/** Save game/scenario */
static WindowDesc _save_dialog_desc(__FILE__, __LINE__,
WDP_CENTER, "save_game", 500, 294,
Expand All @@ -920,7 +986,16 @@ void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fo
sld = &_save_dialog_desc;
} else {
/* Dialogue for loading a file. */
sld = (abstract_filetype == FT_HEIGHTMAP) ? &_load_heightmap_dialog_desc : &_load_dialog_desc;
switch (abstract_filetype) {
case FT_HEIGHTMAP:
sld = &_load_heightmap_dialog_desc;
break;
case FT_TOWN_DATA:
sld = &_load_town_data_dialog_desc;
break;
default:
sld = &_load_dialog_desc;
}
}

new SaveLoadWindow(sld, abstract_filetype, fop);
Expand Down

0 comments on commit a353e5e

Please sign in to comment.