1
0
mirror of https://github.com/OpenTTD/OpenTTD.git synced 2025-08-19 12:39:11 +00:00

Compare commits

...

6 Commits

23 changed files with 175 additions and 141 deletions

View File

@@ -149,20 +149,14 @@ struct AIConfigWindow : public Window {
/**
* Can the AI config in the given company slot be edited?
* @param slot The slot to query.
* @return True if and only if the given AI Config slot can e edited.
* @return True if and only if the given AI Config slot can be edited.
*/
static bool IsEditable(CompanyID slot)
{
if (_game_mode != GM_NORMAL) {
return slot > 0 && slot <= GetGameSettings().difficulty.max_no_competitors;
return slot > 0 && slot < MAX_COMPANIES;
}
if (Company::IsValidID(slot)) return false;
int max_slot = GetGameSettings().difficulty.max_no_competitors;
for (CompanyID cid = COMPANY_FIRST; cid < (CompanyID)max_slot && cid < MAX_COMPANIES; cid++) {
if (Company::IsValidHumanID(cid)) max_slot++;
}
return slot < max_slot;
return slot < MAX_COMPANIES && !Company::IsValidID(slot);
}
void DrawWidget(const Rect &r, WidgetID widget) const override
@@ -186,7 +180,14 @@ struct AIConfigWindow : public Window {
if (this->selected_slot == i) {
tc = TC_WHITE;
} else if (IsEditable((CompanyID)i)) {
tc = TC_ORANGE;
int max_slot = GetGameSettings().difficulty.max_no_competitors;
for (const Company *c : Company::Iterate()) {
if (c->is_ai) max_slot--;
}
for (CompanyID cid = COMPANY_FIRST; cid < (CompanyID)max_slot && cid < MAX_COMPANIES; cid++) {
if (Company::IsValidHumanID(cid)) max_slot++;
}
if (i < max_slot) tc = TC_ORANGE;
} else if (Company::IsValidAiID(i)) {
tc = TC_GREEN;
}

View File

@@ -1217,17 +1217,13 @@ DEF_CONSOLE_CMD(ConRestart)
{
if (argc == 0) {
IConsolePrint(CC_HELP, "Restart game. Usage: 'restart'.");
IConsolePrint(CC_HELP, "Restarts a game. It tries to reproduce the exact same map as the game started with.");
IConsolePrint(CC_HELP, "However:");
IConsolePrint(CC_HELP, " * restarting games started in another version might create another map due to difference in map generation.");
IConsolePrint(CC_HELP, " * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame.");
IConsolePrint(CC_HELP, "Restarts a game, using the newgame settings.");
IConsolePrint(CC_HELP, " * if you started from a new game, and your newgame settings haven't changed, the game will be identical to when you started it.");
IConsolePrint(CC_HELP, " * if you started from a savegame / scenario / heightmap, the game might be different, because your settings might differ.");
return true;
}
/* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */
_settings_game.game_creation.map_x = Map::LogX();
_settings_game.game_creation.map_y = Map::LogY();
_switch_mode = SM_RESTARTGAME;
StartNewGameWithoutGUI(_settings_game.game_creation.generation_seed);
return true;
}
@@ -1236,12 +1232,12 @@ DEF_CONSOLE_CMD(ConReload)
if (argc == 0) {
IConsolePrint(CC_HELP, "Reload game. Usage: 'reload'.");
IConsolePrint(CC_HELP, "Reloads a game.");
IConsolePrint(CC_HELP, " * if you started from a savegame / scenario / heightmap, that exact same savegame / scenario / heightmap will be loaded.");
IConsolePrint(CC_HELP, " * if you started from a new game, this acts the same as 'restart'.");
IConsolePrint(CC_HELP, " * if you started from a new game, reload the game with the current active settings.");
IConsolePrint(CC_HELP, " * if you started from a savegame / scenario / heightmap, that same savegame / scenario / heightmap will be loaded again.");
return true;
}
/* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */
/* Use a switch-mode to prevent copying over newgame settings to active settings. */
_settings_game.game_creation.map_x = Map::LogX();
_settings_game.game_creation.map_y = Map::LogY();
_switch_mode = SM_RELOADGAME;

View File

@@ -65,7 +65,7 @@ void ShowGoalsList(CompanyID company);
void ShowGoalQuestion(uint16_t id, byte type, uint32_t button_mask, const std::string &question);
/* story_gui.cpp */
void ShowStoryBook(CompanyID company, uint16_t page_id = INVALID_STORY_PAGE);
void ShowStoryBook(CompanyID company, uint16_t page_id = INVALID_STORY_PAGE, bool centered = false);
/* viewport_gui.cpp */
void ShowExtraViewportWindow(TileIndex tile = INVALID_TILE);

View File

@@ -1812,13 +1812,6 @@ STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Enabling this s
STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Disable ships for computer: {STRING2}
STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Enabling this setting makes building ships impossible for a computer player
STR_CONFIG_SETTING_AI_PROFILE :Default settings profile: {STRING2}
STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Choose which settings profile to use for random AIs or for initial values when adding a new AI or Game Script
###length 3
STR_CONFIG_SETTING_AI_PROFILE_EASY :Easy
STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Medium
STR_CONFIG_SETTING_AI_PROFILE_HARD :Hard
STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Allow AIs in multiplayer: {STRING2}
STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Allow AI computer players to participate in multiplayer games

View File

@@ -171,6 +171,23 @@ uint32_t RoadStopScopeResolver::GetVariable(byte variable, [[maybe_unused]] uint
return ssl.grfid;
}
/* 16 bit road stop ID of nearby tiles */
case 0x6B: {
TileIndex nearby_tile = GetNearbyTile(parameter, this->tile);
if (!IsRoadStopTile(nearby_tile)) return 0xFFFFFFFF;
if (!IsCustomRoadStopSpecIndex(nearby_tile)) return 0xFFFE;
uint32_t grfid = this->st->roadstop_speclist[GetCustomRoadStopSpecIndex(this->tile)].grfid;
const RoadStopSpecList ssl = BaseStation::GetByTile(nearby_tile)->roadstop_speclist[GetCustomRoadStopSpecIndex(nearby_tile)];
if (ssl.grfid == grfid) {
return ssl.localidx;
}
return 0xFFFE;
}
case 0xF0: return this->st == nullptr ? 0 : this->st->facilities; // facilities
case 0xFA: return ClampTo<uint16_t>((this->st == nullptr ? TimerGameCalendar::date : this->st->build_date) - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR); // build date

View File

@@ -376,6 +376,22 @@ TownScopeResolver *StationResolverObject::GetTown()
return ssl.grfid;
}
case 0x6B: { // 16 bit Station ID of nearby tiles
TileIndex nearby_tile = GetNearbyTile(parameter, this->tile);
if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF;
if (!IsCustomStationSpecIndex(nearby_tile)) return 0xFFFE;
uint32_t grfid = this->st->speclist[GetCustomStationSpecIndex(this->tile)].grfid;
const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)];
if (ssl.grfid == grfid) {
return ssl.localidx;
}
return 0xFFFE;
}
/* General station variables */
case 0x82: return 50;
case 0x84: return this->st->string_id;

View File

@@ -1049,7 +1049,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_NEWGAME)) {
NetworkReboot();
} else {
NetworkDisconnect();
@@ -1113,7 +1113,6 @@ void SwitchToMode(SwitchMode new_mode)
UpdateSocialIntegration(GM_NORMAL);
break;
case SM_RESTARTGAME: // Restart --> 'Random game' with current settings
case SM_NEWGAME: // New Game --> 'Random game'
MakeNewGame(false, new_mode == SM_NEWGAME);
GenerateSavegameId();

View File

@@ -26,7 +26,6 @@ enum GameMode {
enum SwitchMode {
SM_NONE,
SM_NEWGAME, ///< New Game --> 'Random game'.
SM_RESTARTGAME, ///< Restart --> 'Random game' with current settings.
SM_RELOADGAME, ///< Reload the savegame / scenario / heightmap you started the game with.
SM_EDITOR, ///< Switch to scenario editor.
SM_LOAD_GAME, ///< Load game, Play Scenario.

View File

@@ -886,22 +886,32 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI
if (ret.Failed()) return ret;
bool had_success = false;
bool under_tunnelbridge = false;
CommandCost last_error = CMD_ERROR;
for (;;) {
ret = remove ? Command<CMD_REMOVE_SINGLE_RAIL>::Do(flags, tile, TrackdirToTrack(trackdir)) : Command<CMD_BUILD_SINGLE_RAIL>::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals);
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) {
if (fail_on_obstacle) return last_error;
if (had_success) break; // Keep going if we haven't constructed any rail yet, skipping the start of the drag
/* Don't try to place rail between tunnelbridge ends */
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
under_tunnelbridge = !under_tunnelbridge;
} else if (!under_tunnelbridge) {
if (remove) {
ret = Command<CMD_REMOVE_SINGLE_RAIL>::Do(flags, tile, TrackdirToTrack(trackdir));
} else {
ret = Command<CMD_BUILD_SINGLE_RAIL>::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals);
}
/* Ownership errors are more important. */
if (last_error.GetErrorMessage() == STR_ERROR_OWNED_BY && remove) break;
} else {
had_success = true;
total_cost.AddCost(ret);
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) {
if (fail_on_obstacle) return last_error;
if (had_success) break; // Keep going if we haven't constructed any rail yet, skipping the start of the drag
}
/* Ownership errors are more important. */
if (last_error.GetErrorMessage() == STR_ERROR_OWNED_BY && remove) break;
} else {
had_success = true;
total_cost.AddCost(ret);
}
}
if (tile == end_tile) break;

View File

@@ -1007,49 +1007,55 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex
bool had_bridge = false;
bool had_tunnel = false;
bool had_success = false;
bool under_tunnelbridge = false;
/* Start tile is the first tile clicked by the user. */
for (;;) {
RoadBits bits = AxisToRoadBits(axis);
/* Don't try to place road between tunnelbridge ends */
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
under_tunnelbridge = !under_tunnelbridge;
} else if (!under_tunnelbridge) {
RoadBits bits = AxisToRoadBits(axis);
/* Determine which road parts should be built. */
if (!is_ai && start_tile != end_tile) {
/* Only build the first and last roadbit if they can connect to something. */
if (tile == end_tile && !CanConnectToRoad(tile, rt, dir)) {
bits = DiagDirToRoadBits(ReverseDiagDir(dir));
} else if (tile == start_tile && !CanConnectToRoad(tile, rt, ReverseDiagDir(dir))) {
bits = DiagDirToRoadBits(dir);
}
} else {
/* Road parts only have to be built at the start tile or at the end tile. */
if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir));
if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir);
}
CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, bits, rt, drd, 0);
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
if (is_ai) return last_error;
if (had_success) break; // Keep going if we haven't constructed any road yet, skipping the start of the drag
}
} else {
had_success = true;
/* Only pay for the upgrade on one side of the bridges and tunnels */
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
if (IsBridge(tile)) {
if (!had_bridge || GetTunnelBridgeDirection(tile) == dir) {
cost.AddCost(ret);
}
had_bridge = true;
} else { // IsTunnel(tile)
if (!had_tunnel || GetTunnelBridgeDirection(tile) == dir) {
cost.AddCost(ret);
}
had_tunnel = true;
/* Determine which road parts should be built. */
if (!is_ai && start_tile != end_tile) {
/* Only build the first and last roadbit if they can connect to something. */
if (tile == end_tile && !CanConnectToRoad(tile, rt, dir)) {
bits = DiagDirToRoadBits(ReverseDiagDir(dir));
} else if (tile == start_tile && !CanConnectToRoad(tile, rt, ReverseDiagDir(dir))) {
bits = DiagDirToRoadBits(dir);
}
} else {
cost.AddCost(ret);
/* Road parts only have to be built at the start tile or at the end tile. */
if (tile == end_tile && !end_half) bits &= DiagDirToRoadBits(ReverseDiagDir(dir));
if (tile == start_tile && start_half) bits &= DiagDirToRoadBits(dir);
}
CommandCost ret = Command<CMD_BUILD_ROAD>::Do(flags, tile, bits, rt, drd, 0);
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
if (is_ai) return last_error;
if (had_success) break; // Keep going if we haven't constructed any road yet, skipping the start of the drag
}
} else {
had_success = true;
/* Only pay for the upgrade on one side of the bridges and tunnels */
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
if (IsBridge(tile)) {
if (!had_bridge || GetTunnelBridgeDirection(tile) == dir) {
cost.AddCost(ret);
}
had_bridge = true;
} else { // IsTunnel(tile)
if (!had_tunnel || GetTunnelBridgeDirection(tile) == dir) {
cost.AddCost(ret);
}
had_tunnel = true;
}
} else {
cost.AddCost(ret);
}
}
}

View File

@@ -2862,12 +2862,6 @@ bool AfterLoadGame()
}
}
if (IsSavegameVersionBefore(SLV_178)) {
extern uint8_t _old_diff_level;
/* Initialise script settings profile */
_settings_game.script.settings_profile = IsInsideMM(_old_diff_level, SP_BEGIN, SP_END) ? _old_diff_level : (uint)SP_MEDIUM;
}
{
/* Station blocked, wires and pylon flags need to be stored in the map. This is effectively cached data, so no
* version check is necessary. This is done here as the SLV_182 check below needs the blocked status. */

View File

@@ -162,7 +162,7 @@ const SaveLoadCompat _settings_sl_compat[] = {
SLC_VAR("economy.initial_city_size"),
SLC_VAR("economy.mod_road_rebuild"),
SLC_NULL(1, SL_MIN_VERSION, SLV_107),
SLC_VAR("script.settings_profile"),
SLC_NULL(1, SLV_178, SLV_TABLE_CHUNKS),
SLC_VAR("ai.ai_in_multiplayer"),
SLC_VAR("ai.ai_disable_veh_train"),
SLC_VAR("ai.ai_disable_veh_roadveh"),

View File

@@ -33,6 +33,7 @@
* \li AISubsidyList accepts an optional filter function
* \li AITownList accepts an optional filter function
* \li AIVehicleList accepts an optional filter function
* \li AIInfo::AddSettings easy_value / medium_value / hard_value are replaced with default_value
*
* \b 13.0
*

View File

@@ -99,6 +99,7 @@
* \li GSSubsidyList accepts an optional filter function
* \li GSTownList accepts an optional filter function
* \li GSVehicleList accepts an optional filter function
* \li GSInfo::AddSettings easy_value / medium_value / hard_value are replaced with default_value
*
* \b 13.0
*

View File

@@ -222,18 +222,8 @@ public:
* - max_value The maximum value of this setting. Required for integer
* settings and not allowed for boolean settings. The value will be
* clamped in the range [MIN(int32_t), MAX(int32_t)] (inclusive).
* - easy_value The default value if the easy difficulty level
* is selected. Required. The value will be clamped in the range
* [MIN(int32_t), MAX(int32_t)] (inclusive).
* - medium_value The default value if the medium difficulty level
* is selected. Required. The value will be clamped in the range
* [MIN(int32_t), MAX(int32_t)] (inclusive).
* - hard_value The default value if the hard difficulty level
* is selected. Required. The value will be clamped in the range
* [MIN(int32_t), MAX(int32_t)] (inclusive).
* - custom_value The default value if the custom difficulty level
* is selected. Required. The value will be clamped in the range
* [MIN(int32_t), MAX(int32_t)] (inclusive).
* - default_value The default value. Required. The value will be
* clamped in the range [MIN(int32_t), MAX(int32_t)] (inclusive).
* - random_deviation If this property has a nonzero value, then the
* actual value of the setting in game will be randomised in the range
* [user_configured_value - random_deviation, user_configured_value + random_deviation] (inclusive).

View File

@@ -34,10 +34,7 @@ struct ScriptConfigItem {
std::string description; ///< The description of the configuration setting.
int min_value = 0; ///< The minimal value this configuration setting can have.
int max_value = 1; ///< The maximal value this configuration setting can have.
int custom_value = 0; ///< The default value on custom difficulty setting.
int easy_value = 0; ///< The default value on easy difficulty setting.
int medium_value = 0; ///< The default value on medium difficulty setting.
int hard_value = 0; ///< The default value on hard difficulty setting.
int default_value = 0; ///< The default value of this configuration setting.
int random_deviation = 0; ///< The maximum random deviation from the default value.
int step_size = 1; ///< The step size in the gui.
ScriptConfigFlags flags = SCRIPTCONFIG_NONE; ///< Flags for the configuration setting.

View File

@@ -87,6 +87,10 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
ScriptConfigItem config;
uint items = 0;
int easy_value = INT32_MIN;
int medium_value = INT32_MIN;
int hard_value = INT32_MIN;
/* Read the table, and find all properties we care about */
sq_pushnull(vm);
while (SQ_SUCCEEDED(sq_next(vm, -2))) {
@@ -122,28 +126,30 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
} else if (key == "easy_value") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
config.easy_value = ClampTo<int32_t>(res);
easy_value = ClampTo<int32_t>(res);
items |= 0x010;
} else if (key == "medium_value") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
config.medium_value = ClampTo<int32_t>(res);
medium_value = ClampTo<int32_t>(res);
items |= 0x020;
} else if (key == "hard_value") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
config.hard_value = ClampTo<int32_t>(res);
hard_value = ClampTo<int32_t>(res);
items |= 0x040;
} else if (key == "custom_value") {
// No longer parsed.
} else if (key == "default_value") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
config.default_value = ClampTo<int32_t>(res);
items |= 0x080;
} else if (key == "random_deviation") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
config.random_deviation = ClampTo<int32_t>(abs(res));
items |= 0x200;
} else if (key == "custom_value") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
config.custom_value = ClampTo<int32_t>(res);
items |= 0x080;
} else if (key == "step_size") {
SQInteger res;
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
@@ -162,6 +168,28 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
}
sq_pop(vm, 1);
/* Check if default_value is set. Although required, this was changed with
* 14.0, and as such, older AIs don't use it yet. So we convert the older
* values into a default_value. */
if ((items & 0x080) == 0) {
/* Easy/medium/hard should all three be defined. */
if ((items & 0x010) == 0 || (items & 0x020) == 0 || (items & 0x040) == 0) {
this->engine->ThrowError("please define all properties of a setting (min/max not allowed for booleans)");
return SQ_ERROR;
}
config.default_value = medium_value;
/* If not boolean and no random deviation set, calculate it based on easy/hard difference. */
if ((config.flags & SCRIPTCONFIG_BOOLEAN) == 0 && (items & 0x200) == 0) {
config.random_deviation = abs(hard_value - easy_value) / 2;
items |= 0x200;
}
items |= 0x080;
} else {
/* For compatibility, also act like the default sets the easy/medium/hard. */
items |= 0x010 | 0x020 | 0x040;
}
/* Don't allow both random_deviation and SCRIPTCONFIG_BOOLEAN to
* be set for the same config item. */
if ((items & 0x200) != 0 && (config.flags & SCRIPTCONFIG_BOOLEAN) != 0) {
@@ -252,14 +280,7 @@ int ScriptInfo::GetSettingDefaultValue(const std::string &name) const
{
for (const auto &item : this->config_list) {
if (item.name != name) continue;
/* The default value depends on the difficulty level */
switch (GetGameSettings().script.settings_profile) {
case SP_EASY: return item.easy_value;
case SP_MEDIUM: return item.medium_value;
case SP_HARD: return item.hard_value;
case SP_CUSTOM: return item.custom_value;
default: NOT_REACHED();
}
return item.default_value;
}
/* There is no such setting */

View File

@@ -2249,7 +2249,6 @@ static SettingsContainer &GetSettingsTree()
{
SettingsPage *npc = ai->Add(new SettingsPage(STR_CONFIG_SETTING_AI_NPC));
{
npc->Add(new SettingEntry("script.settings_profile"));
npc->Add(new SettingEntry("script.script_max_opcode_till_suspend"));
npc->Add(new SettingEntry("script.script_max_memory_megabytes"));
npc->Add(new SettingEntry("difficulty.competitor_speed"));

View File

@@ -405,7 +405,6 @@ struct AISettings {
/** Settings related to scripts. */
struct ScriptSettings {
uint8_t settings_profile; ///< difficulty profile to set initial settings of scripts, esp. random AIs
uint32_t script_max_opcode_till_suspend; ///< max opcode calls till scripts will suspend
uint32_t script_max_memory_megabytes; ///< limit on memory a single script instance may have allocated
};

View File

@@ -368,7 +368,7 @@ CommandCost CmdShowStoryPage(DoCommandFlag flags, StoryPageID page_id)
if (flags & DC_EXEC) {
StoryPage *g = StoryPage::Get(page_id);
if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, page_id);
if ((g->company != INVALID_COMPANY && g->company == _local_company) || (g->company == INVALID_COMPANY && Company::IsValidID(_local_company))) ShowStoryBook(_local_company, page_id, true);
}
return CommandCost();

View File

@@ -969,7 +969,14 @@ static constexpr NWidgetPart _nested_story_book_widgets[] = {
};
static WindowDesc _story_book_desc(__FILE__, __LINE__,
WDP_CENTER, "view_story", 400, 300,
WDP_AUTO, "view_story", 400, 300,
WC_STORY_BOOK, WC_NONE,
0,
std::begin(_nested_story_book_widgets), std::end(_nested_story_book_widgets)
);
static WindowDesc _story_book_gs_desc(__FILE__, __LINE__,
WDP_CENTER, "view_story_gs", 400, 300,
WC_STORY_BOOK, WC_NONE,
0,
std::begin(_nested_story_book_widgets), std::end(_nested_story_book_widgets)
@@ -1041,11 +1048,12 @@ static CursorID TranslateStoryPageButtonCursor(StoryPageButtonCursor cursor)
* Raise or create the story book window for \a company, at page \a page_id.
* @param company 'Owner' of the story book, may be #INVALID_COMPANY.
* @param page_id Page to open, may be #INVALID_STORY_PAGE.
* @param centered Whether to open the window centered.
*/
void ShowStoryBook(CompanyID company, uint16_t page_id)
void ShowStoryBook(CompanyID company, uint16_t page_id, bool centered)
{
if (!Company::IsValidID(company)) company = (CompanyID)INVALID_COMPANY;
StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(&_story_book_desc, company, true);
StoryBookWindow *w = AllocateWindowDescFront<StoryBookWindow>(centered ? &_story_book_gs_desc : &_story_book_desc, company, true);
if (page_id != INVALID_STORY_PAGE) w->SetSelectedPage(page_id);
}

View File

@@ -131,6 +131,7 @@ static const NIVariable _niv_stations[] = {
NIV(0x68, "station info of nearby tiles"),
NIV(0x69, "information about cargo accepted in the past"),
NIV(0x6A, "GRFID of nearby station tiles"),
NIV(0x6B, "station ID of nearby tiles"),
NIV_END()
};
@@ -689,6 +690,7 @@ static const NIVariable _nif_roadstops[] = {
NIV(0x68, "road stop info of nearby tiles"),
NIV(0x69, "information about cargo accepted in the past"),
NIV(0x6A, "GRFID of nearby road stop tiles"),
NIV(0x6B, "road stop ID of nearby tiles"),
NIV_END(),
};

View File

@@ -8,7 +8,6 @@
; and in the savegame PATS chunk.
[pre-amble]
static constexpr std::initializer_list<const char*> _settings_profiles{"easy", "medium", "hard"};
static const SettingVariant _script_settings_table[] = {
[post-amble]
@@ -41,20 +40,6 @@ extra = 0
startup = false
[SDT_OMANY]
var = script.settings_profile
type = SLE_UINT8
from = SLV_178
flags = SF_GUI_DROPDOWN
def = SP_EASY
min = SP_EASY
max = SP_HARD
full = _settings_profiles
str = STR_CONFIG_SETTING_AI_PROFILE
strhelp = STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT
strval = STR_CONFIG_SETTING_AI_PROFILE_EASY
cat = SC_BASIC
[SDT_VAR]
var = script.script_max_opcode_till_suspend
type = SLE_UINT32