Merge tag '14.0-beta1' into jgrpp

# Conflicts:
#	src/3rdparty/squirrel/squirrel/sqcompiler.cpp
#	src/aircraft.h
#	src/animated_tile.h
#	src/base_consist.h
#	src/cargotype.h
#	src/company_gui.cpp
#	src/console_cmds.cpp
#	src/core/overflowsafe_type.hpp
#	src/engine_gui.cpp
#	src/industry_gui.cpp
#	src/lang/english.txt
#	src/music/extmidi.cpp
#	src/network/core/network_game_info.cpp
#	src/network/network_server.cpp
#	src/newgrf.cpp
#	src/newgrf_industries.cpp
#	src/order_base.h
#	src/order_cmd.cpp
#	src/order_gui.cpp
#	src/order_type.h
#	src/os/macosx/misc_osx.cpp
#	src/os/windows/crashlog_win.cpp
#	src/rail_gui.cpp
#	src/rail_gui.h
#	src/roadveh.h
#	src/roadveh_cmd.cpp
#	src/saveload/afterload.cpp
#	src/saveload/company_sl.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/saveload/saveload_error.hpp
#	src/script/api/script_town.cpp
#	src/settingsgen/settingsgen.cpp
#	src/ship.h
#	src/ship_cmd.cpp
#	src/smallmap_gui.cpp
#	src/spritecache.cpp
#	src/stdafx.h
#	src/strgen/strgen.cpp
#	src/strgen/strgen.h
#	src/table/settings/script_settings.ini
#	src/timetable_cmd.cpp
#	src/timetable_gui.cpp
#	src/town.h
#	src/town_cmd.cpp
#	src/town_cmd.h
#	src/town_gui.cpp
#	src/train.h
#	src/train_cmd.cpp
#	src/tree_cmd.cpp
#	src/vehicle.cpp
#	src/vehicle_base.h
#	src/vehicle_cmd.cpp
#	src/vehicle_gui.cpp
#	src/vehiclelist.cpp
#	src/waypoint_base.h
#	src/widget.cpp
This commit is contained in:
Jonathan G Rennison
2024-02-18 20:58:18 +00:00
140 changed files with 1265 additions and 582 deletions

View File

@@ -56,24 +56,26 @@ typedef sqvector<ExpState> ExpStateVec;
class SQCompiler
{
public:
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(nullptr), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(nullptr), _lex(_ss(v), rg, up), _debugline(0), _debugop(0)
{
_vm=v;
_sourcename = SQString::Create(_ss(v), sourcename);
_lineinfo = lineinfo;_raiseerror = raiseerror;
}
NORETURN static void ThrowError(void *ud, const SQChar *s) {
SQCompiler *c = (SQCompiler *)ud;
c->Error("%s", s);
}
NORETURN void Error(const SQChar *s, ...) WARN_FORMAT(2, 3)
[[noreturn]] void Error(const SQChar *s, ...) WARN_FORMAT(2, 3)
{
static SQChar temp[256];
va_list vl;
va_start(vl, s);
vseprintf(temp, lastof(temp), s, vl);
va_end(vl);
throw temp;
throw CompileException(temp);
}
[[noreturn]] void Error(const std::string &msg)
{
throw CompileException(msg);
}
void Lex(){ _token = _lex.Lex();}
void PushExpState(){ _expstates.push_back(ExpState()); }
@@ -163,7 +165,7 @@ public:
_debugline = 1;
_debugop = 0;
SQFuncState funcstate(_ss(_vm), nullptr,ThrowError,this);
SQFuncState funcstate(_ss(_vm), nullptr);
funcstate._name = SQString::Create(_ss(_vm), "main");
_fs = &funcstate;
_fs->AddParameter(_fs->CreateString("this"));
@@ -185,20 +187,12 @@ public:
#endif
return true;
}
catch (SQChar *compilererror) {
catch (const CompileException &compilererror) {
if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
_ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):"unknown",
_ss(_vm)->_compilererrorhandler(_vm, compilererror.what(), type(_sourcename) == OT_STRING ? _stringval(_sourcename) : "unknown",
_lex._currentline, _lex._currentcolumn);
}
_vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
return false;
}
catch (const std::string &compilererror) {
if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
_ss(_vm)->_compilererrorhandler(_vm, compilererror.c_str(), type(_sourcename) == OT_STRING ? _stringval(_sourcename) : "unknown",
_lex._currentline, _lex._currentcolumn);
}
_vm->_lasterror = SQString::Create(_ss(_vm), compilererror);
_vm->_lasterror = SQString::Create(_ss(_vm), compilererror.what());
return false;
}
}

View File

@@ -71,12 +71,7 @@ struct SQVM;
#define TK_ENUM 323
#define TK_CONST 324
/* MSVC doesn't like NORETURN for function prototypes, but we kinda need it for GCC. */
#if defined(_MSC_VER) && !defined(__clang__)
typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
#else
typedef NORETURN void(*CompilerErrorFunc)(void *ud, const SQChar *s);
#endif
using CompileException = std::runtime_error;
bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out, bool raiseerror, bool lineinfo);
#endif //_SQCOMPILER_H_

View File

@@ -92,7 +92,7 @@ void DumpLiteral(SQObjectPtr &o)
}
#endif
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent)
{
_nliterals = 0;
_literals = SQTable::Create(ss,0);
@@ -105,15 +105,13 @@ SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc
_traps = 0;
_returnexp = 0;
_varparams = false;
_errfunc = efunc;
_errtarget = ed;
_bgenerator = false;
}
void SQFuncState::Error(const SQChar *err)
{
_errfunc(_errtarget,err);
throw CompileException(err);
}
#ifdef _DEBUG_DUMP
@@ -549,7 +547,7 @@ SQFunctionProto *SQFuncState::BuildProto()
SQFuncState *SQFuncState::PushChildState(SQSharedState *ss)
{
SQFuncState *child = (SQFuncState *)sq_malloc(sizeof(SQFuncState));
new (child) SQFuncState(ss,this,_errfunc,_errtarget);
new (child) SQFuncState(ss,this);
_childstates.push_back(child);
return child;
}

View File

@@ -6,12 +6,12 @@
struct SQFuncState
{
SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed);
SQFuncState(SQSharedState *ss,SQFuncState *parent);
~SQFuncState();
#ifdef _DEBUG_DUMP
void Dump(SQFunctionProto *func);
#endif
void Error(const SQChar *err);
[[noreturn]] void Error(const SQChar *err);
SQFuncState *PushChildState(SQSharedState *ss);
void PopChildState();
void AddInstruction(SQOpcode _op,SQInteger arg0=0,SQInteger arg1=0,SQInteger arg2=0,SQInteger arg3=0){SQInstruction i(_op,arg0,arg1,arg2,arg3);AddInstruction(i);}
@@ -75,9 +75,6 @@ struct SQFuncState
SQSharedState *_sharedstate;
sqvector<SQFuncState*> _childstates;
SQInteger GetConstant(const SQObject &cons);
private:
CompilerErrorFunc _errfunc;
void *_errtarget;
};

View File

@@ -35,10 +35,8 @@ void SQLexer::APPEND_CHAR(char32_t c)
}
}
SQLexer::SQLexer(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
SQLexer::SQLexer(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up)
{
_errfunc = efunc;
_errtarget = ed;
_sharedstate = ss;
_keywords = SQTable::Create(ss, 26);
ADD_KEYWORD(while, TK_WHILE);
@@ -94,9 +92,9 @@ SQLexer::SQLexer(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerE
Next();
}
NORETURN void SQLexer::Error(const SQChar *err)
[[noreturn]] void SQLexer::Error(const SQChar *err)
{
_errfunc(_errtarget,err);
throw CompileException(err);
}
void SQLexer::Next()

View File

@@ -5,8 +5,8 @@
struct SQLexer
{
~SQLexer();
SQLexer(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
NORETURN void Error(const SQChar *err);
SQLexer(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up);
[[noreturn]] void Error(const SQChar *err);
SQInteger Lex();
const SQChar *Tok2Str(SQInteger tok);
private:
@@ -35,8 +35,6 @@ public:
char32_t _currdata;
SQSharedState *_sharedstate;
sqvector<SQChar> _longstr;
CompilerErrorFunc _errfunc;
void *_errtarget;
};
#endif

View File

@@ -216,7 +216,7 @@ bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
_RET_SUCCEED(_integer(res))
}
}
FALLTHROUGH;
[[fallthrough]];
default:
_RET_SUCCEED( _userpointer(o1) < _userpointer(o2)?-1:1 );
}
@@ -288,7 +288,7 @@ void SQVM::ToString(const SQObjectPtr &o,SQObjectPtr &res)
//else keeps going to the default
}
}
FALLTHROUGH;
[[fallthrough]];
default:
seprintf(buf, lastof(buf),"(%s : 0x%p)",GetTypeName(o),(void*)_rawval(o));
}
@@ -540,7 +540,7 @@ bool SQVM::FOREACH_OP(SQObjectPtr &o1,SQObjectPtr &o2,SQObjectPtr
_generator(o1)->Resume(this, arg_2+1);
_FINISH(0);
}
FALLTHROUGH;
[[fallthrough]];
default:
Raise_Error("cannot iterate %s", GetTypeName(o1));
}
@@ -775,7 +775,7 @@ exception_restore:
ct_stackbase = _stackbase;
goto common_call;
}
FALLTHROUGH;
[[fallthrough]];
case _OP_CALL: {
ct_tailcall = false;
ct_target = arg0;
@@ -1337,7 +1337,7 @@ bool SQVM::Set(const SQObjectPtr &self,const SQObjectPtr &key,const SQObjectPtr
return true;
}
}
FALLTHROUGH;
[[fallthrough]];
case OT_USERDATA:
if(_delegable(self)->_delegate) {
SQObjectPtr t;

View File

@@ -148,20 +148,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
@@ -185,7 +179,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

@@ -73,7 +73,7 @@ struct AircraftCache {
/**
* Aircraft, helicopters, rotors and their shadows belong to this class.
*/
struct Aircraft FINAL : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
uint16_t crashed_counter; ///< Timer for handling crash animations.
byte pos; ///< Next desired position of the aircraft.
byte previous_pos; ///< Previous desired position of the aircraft.

View File

@@ -1576,6 +1576,7 @@ void AircraftLeaveHangar(Aircraft *v, Direction exit_dir)
}
VehicleServiceInDepot(v);
v->LeaveUnbunchingDepot();
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
DirtyVehicleListWindowForVehicle(v);
@@ -1627,6 +1628,9 @@ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *ap
return;
}
/* Check if we should wait here for unbunching. */
if (v->IsWaitingForUnbunching()) return;
if (!v->current_order.IsType(OT_GOTO_STATION) &&
!v->current_order.IsType(OT_GOTO_DEPOT))
return;

View File

@@ -581,6 +581,7 @@ CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, DoComma
if (cost.Succeeded() && old_head != new_head && (flags & DC_EXEC) != 0) {
/* Copy other things which cannot be copied by a command and which shall not stay resetted from the build vehicle command */
new_head->CopyVehicleConfigAndStatistics(old_head);
new_head->unbunch_state = std::move(old_head->unbunch_state);
GroupStatistics::AddProfitLastYear(new_head);
/* Switch vehicle windows/news to the new vehicle, so they are not closed/deleted when the old vehicle is sold */

View File

@@ -32,7 +32,7 @@
#define MARGIN_NORMAL_THRESHOLD 4
/** The SSE4 32 bpp blitter with palette animation. */
class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE4 {
class Blitter_32bppSSE4_Anim final : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE4 {
private:
public:

View File

@@ -14,7 +14,7 @@
#include "factory.hpp"
/** 8bpp blitter optimised for speed. */
class Blitter_8bppOptimized FINAL : public Blitter_8bppBase {
class Blitter_8bppOptimized final : public Blitter_8bppBase {
public:
/** Data stored about a (single) sprite. */
struct SpriteData {

View File

@@ -14,7 +14,7 @@
#include "factory.hpp"
/** Most trivial 8bpp blitter. */
class Blitter_8bppSimple FINAL : public Blitter_8bppBase {
class Blitter_8bppSimple final : public Blitter_8bppBase {
public:
using Blitter_8bppBase::Blitter_8bppBase;
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;

View File

@@ -23,6 +23,7 @@
#include "safeguards.h"
CargoSpec CargoSpec::array[NUM_CARGO];
std::array<std::vector<const CargoSpec *>, NUM_TPE> CargoSpec::town_production_cargoes{};
/**
* Bitmask of cargo types available. This includes phony cargoes like regearing cargoes.
@@ -193,6 +194,7 @@ static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * c
/** Initialize the list of sorted cargo specifications. */
void InitializeSortedCargoSpecs()
{
for (auto &tpc : CargoSpec::town_production_cargoes) tpc.clear();
_sorted_cargo_specs.clear();
/* Add each cargo spec to the list, and determine the largest cargo icon size. */
for (const CargoSpec *cargo : CargoSpec::Iterate()) {
@@ -211,6 +213,8 @@ void InitializeSortedCargoSpecs()
_standard_cargo_mask = 0;
uint8_t nb_standard_cargo = 0;
for (const auto &cargo : _sorted_cargo_specs) {
assert(cargo->town_production_effect != INVALID_TPE);
CargoSpec::town_production_cargoes[cargo->town_production_effect].push_back(cargo);
if (cargo->classes & CC_SPECIAL) break;
nb_standard_cargo++;
SetBit(_standard_cargo_mask, cargo->Index());

View File

@@ -22,16 +22,30 @@
typedef uint32_t CargoLabel;
/** Town growth effect when delivering cargo. */
enum TownEffect {
TE_BEGIN = 0,
TE_NONE = TE_BEGIN, ///< Cargo has no effect.
TE_PASSENGERS, ///< Cargo behaves passenger-like.
TE_MAIL, ///< Cargo behaves mail-like.
TE_GOODS, ///< Cargo behaves goods/candy-like.
TE_WATER, ///< Cargo behaves water-like.
TE_FOOD, ///< Cargo behaves food/fizzy-drinks-like.
TE_END, ///< End of town effects.
NUM_TE = TE_END, ///< Amount of town effects.
enum TownAcceptanceEffect : byte {
TAE_BEGIN = 0,
TAE_NONE = TAE_BEGIN, ///< Cargo has no effect.
TAE_PASSENGERS, ///< Cargo behaves passenger-like.
TAE_MAIL, ///< Cargo behaves mail-like.
TAE_GOODS, ///< Cargo behaves goods/candy-like.
TAE_WATER, ///< Cargo behaves water-like.
TAE_FOOD, ///< Cargo behaves food/fizzy-drinks-like.
TAE_END, ///< End of town effects.
NUM_TAE = TAE_END, ///< Amount of town effects.
};
/** Town effect when producing cargo. */
enum TownProductionEffect : byte {
TPE_NONE, ///< Town will not produce this cargo type.
TPE_PASSENGERS, ///< Cargo behaves passenger-like for production.
TPE_MAIL, ///< Cargo behaves mail-like for production.
NUM_TPE,
/**
* Invalid town production effect. Used as a sentinel to indicate if a NewGRF has explicitly set an effect.
* This does not 'exist' after cargo types are finalised.
*/
INVALID_TPE,
};
/** Cargo classes. */
@@ -52,6 +66,8 @@ enum CargoClass {
static const byte INVALID_CARGO_BITNUM = 0xFF; ///< Constant representing invalid cargo
static const uint TOWN_PRODUCTION_DIVISOR = 256;
/** Specification of a cargo type. */
struct CargoSpec {
CargoLabel label; ///< Unique label of the cargo type.
@@ -65,7 +81,9 @@ struct CargoSpec {
uint8_t transit_periods[2];
bool is_freight; ///< Cargo type is considered to be freight (affects train freight multiplier).
TownEffect town_effect; ///< The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
TownAcceptanceEffect town_acceptance_effect; ///< The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
TownProductionEffect town_production_effect{INVALID_TPE}; ///< The effect on town cargo production.
uint16_t town_production_multiplier{TOWN_PRODUCTION_DIVISOR}; ///< Town production multipler, if commanded by TownProductionEffect.
uint8_t callback_mask; ///< Bitmask of cargo callbacks that have to be called
StringID name; ///< Name of this type of cargo.
@@ -181,6 +199,9 @@ struct CargoSpec {
*/
static IterateWrapper Iterate(size_t from = 0) { return IterateWrapper(from); }
/** List of cargo specs for each Town Product Effect. */
static std::array<std::vector<const CargoSpec *>, NUM_TPE> town_production_cargoes;
private:
static CargoSpec array[NUM_CARGO]; ///< Array holding all CargoSpecs

View File

@@ -398,7 +398,7 @@ struct CompanyFinancesWindow : Window {
case WID_CF_EXPS_PRICE2:
case WID_CF_EXPS_PRICE3:
size->height = GetTotalCategoriesHeight();
FALLTHROUGH;
[[fallthrough]];
case WID_CF_BALANCE_VALUE:
case WID_CF_LOAN_VALUE:
@@ -840,7 +840,7 @@ public:
size->width = 0;
break;
}
FALLTHROUGH;
[[fallthrough]];
case WID_SCL_PRI_COL_DROPDOWN: {
this->square = GetSpriteSize(SPR_SQUARE);
@@ -1670,7 +1670,7 @@ public:
/* OK button */
case WID_SCMF_ACCEPT:
DoCommandP(0, 0, this->face, CMD_SET_COMPANY_MANAGER_FACE);
FALLTHROUGH;
[[fallthrough]];
/* Cancel button */
case WID_SCMF_CANCEL:

View File

@@ -394,7 +394,7 @@ void IConsoleCmdExec(const std::string &command_string, const uint recurse_count
tokenstream[tstream_i++] = *++cmdptr;
break;
}
FALLTHROUGH;
[[fallthrough]];
default: // Normal character
tokenstream[tstream_i++] = *cmdptr;

View File

@@ -1358,33 +1358,39 @@ DEF_CONSOLE_CMD(ConNewGame)
DEF_CONSOLE_CMD(ConRestart)
{
if (argc == 0) {
IConsoleHelp("Restart game. Usage: 'restart'");
IConsoleHelp("Restarts a game. It tries to reproduce the exact same map as the game started with.");
IConsoleHelp("However:");
IConsoleHelp(" * restarting games started in another version might create another map due to difference in map generation");
IConsoleHelp(" * restarting games based on scenarios, loaded games or heightmaps will start a new game based on the settings stored in the scenario/savegame");
if (argc == 0 || argc > 2) {
IConsoleHelp("Restart game. Usage: 'restart [current|newgame]'.");
IConsoleHelp("Restarts a game, using either the current or newgame (default) settings.");
IConsoleHelp(" * if you started from a new game, and your current/newgame settings haven't changed, the game will be identical to when you started it.");
IConsoleHelp(" * if you started from a savegame / scenario / heightmap, the game might be different, because the current/newgame 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 = MapLogX();
_settings_game.game_creation.map_y = MapLogY();
_switch_mode = SM_RESTARTGAME;
if (argc == 1 || std::string_view(argv[1]) == "newgame") {
StartNewGameWithoutGUI(_settings_game.game_creation.generation_seed);
} else {
_settings_game.game_creation.map_x = MapLogX();
_settings_game.game_creation.map_y = MapLogY();
_switch_mode = SM_RESTARTGAME;
}
return true;
}
DEF_CONSOLE_CMD(ConReload)
{
if (argc == 0) {
IConsoleHelp("Reload game. Usage: 'reload'");
IConsoleHelp("Reloads a game.");
IConsoleHelp(" * if you started from a savegame / scenario / heightmap, that exact same savegame / scenario / heightmap will be loaded.");
IConsoleHelp(" * if you started from a new game, this acts the same as 'restart'.");
IConsoleHelp("Reload game. Usage: 'reload'.");
IConsoleHelp("Reloads a game if loaded via savegame / scenario / heightmap.");
return true;
}
/* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */
if (_file_to_saveload.abstract_ftype == FT_NONE || _file_to_saveload.abstract_ftype == FT_INVALID) {
IConsolePrint(CC_ERROR, "No game loaded to reload.");
return true;
}
/* Use a switch-mode to prevent copying over newgame settings to active settings. */
_settings_game.game_creation.map_x = MapLogX();
_settings_game.game_creation.map_y = MapLogY();
_switch_mode = SM_RELOADGAME;

View File

@@ -15,7 +15,7 @@
* Function to exit with an error message after malloc() or calloc() have failed
* @param size number of bytes we tried to allocate
*/
void NORETURN MallocError(size_t size)
[[noreturn]] void MallocError(size_t size)
{
error("Out of memory. Cannot allocate " PRINTF_SIZE " bytes", size);
}
@@ -24,7 +24,7 @@ void NORETURN MallocError(size_t size)
* Function to exit with an error message after realloc() have failed
* @param size number of bytes we tried to allocate
*/
void NORETURN ReallocError(size_t size)
[[noreturn]] void ReallocError(size_t size)
{
error("Out of memory. Cannot reallocate " PRINTF_SIZE " bytes", size);
}

View File

@@ -17,8 +17,8 @@
* binary needlessly large.
*/
void NORETURN MallocError(size_t size);
void NORETURN ReallocError(size_t size);
[[noreturn]] void MallocError(size_t size);
[[noreturn]] void ReallocError(size_t size);
/**
* Checks whether allocating memory would overflow size_t.

View File

@@ -166,7 +166,7 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size)
*/
DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index)
{
extern void NORETURN SlErrorCorruptFmt(const char *format, ...);
[[noreturn]] extern void SlErrorCorruptFmt(const char *format, ...);
if (index >= Tmax_size) {
SlErrorCorruptFmt("%s index " PRINTF_SIZE " out of range (" PRINTF_SIZE ")", this->name, index, Tmax_size);

View File

@@ -385,4 +385,7 @@ static const int INDUSTRY_CUT_TREE_TICKS = INDUSTRY_PRODUCE_TICKS * 2; ///< cyc
/** An initial value for StateTicks when starting a new game */
static constexpr StateTicks INITIAL_STATE_TICKS_VALUE = 1 << 24;
/** Invalid state ticks value */
static constexpr StateTicks INVALID_STATE_TICKS = INT64_MIN;
#endif /* DATE_TYPE_H */

View File

@@ -23,8 +23,8 @@
*/
#define Debug(name, level, format_string, ...) do { if ((level) == 0 || _debug_ ## name ## _level >= (level)) debug_print(#name, level, fmt::format(FMT_STRING(format_string), ## __VA_ARGS__).c_str()); } while (false)
void NORETURN usererror_str(const char *msg);
void NORETURN fatalerror_str(const char *msg);
[[noreturn]] void usererror_str(const char *msg);
[[noreturn]] void fatalerror_str(const char *msg);
#define UserError(format_string, ...) usererror_str(fmt::format(FMT_STRING(format_string), ## __VA_ARGS__).c_str())
#define FatalError(format_string, ...) fatalerror_str(fmt::format(FMT_STRING(format_string), ## __VA_ARGS__).c_str())

View File

@@ -499,7 +499,7 @@ struct DepotWindow : Window {
switch (this->type) {
case VEH_TRAIN:
if (wagon) return MODE_ERROR;
FALLTHROUGH;
[[fallthrough]];
case VEH_ROAD:
if (xm <= this->flag_size.width) return MODE_START_STOP;

View File

@@ -34,7 +34,7 @@ enum DisasterSubType {
/**
* Disasters, like submarines, skyrangers and their shadows, belong to this class.
*/
struct DisasterVehicle FINAL : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
struct DisasterVehicle final : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
SpriteID image_override; ///< Override for the default disaster vehicle sprite.
VehicleID big_ufo_destroyer_target; ///< The big UFO that this destroyer is supposed to bomb.
byte flags; ///< Flags about the state of the vehicle, @see AirVehicleFlags

View File

@@ -1368,7 +1368,7 @@ static Money DeliverGoods(int num_pieces, CargoID cargo_type, StationID dest, ui
/* Increase town's counter for town effects */
const CargoSpec *cs = CargoSpec::Get(cargo_type);
st->town->received[cs->town_effect].new_act += accepted_total;
st->town->received[cs->town_acceptance_effect].new_act += accepted_total;
/* Determine profit */
Money profit = GetTransportedGoodsIncome(accepted_total, distance, periods_in_transit, cargo_type);

View File

@@ -21,7 +21,7 @@
* - bulldozer (road works)
* - bubbles (industry)
*/
struct EffectVehicle FINAL : public SpecializedVehicle<EffectVehicle, VEH_EFFECT> {
struct EffectVehicle final : public SpecializedVehicle<EffectVehicle, VEH_EFFECT> {
uint16_t animation_state; ///< State primarily used to change the graphics/behaviour.
byte animation_substate; ///< Sub state to time the change of the graphics/behaviour.

View File

@@ -156,7 +156,7 @@ static DualTrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
{
/* Single track bits are never masked out. */
if (likely(HasAtMostOneBit(tracks))) return tracks;
if (HasAtMostOneBit(tracks)) [[likely]] return tracks;
if (!IsPlainRailTile(t)) return tracks;

View File

@@ -127,7 +127,7 @@ struct EnginePreviewWindow : Window {
switch (widget) {
case WID_EP_YES:
DoCommandP(0, this->window_number, 0, CMD_WANT_ENGINE_PREVIEW);
FALLTHROUGH;
[[fallthrough]];
case WID_EP_NO:
if (!_shift_pressed) this->Close();
break;

View File

@@ -333,7 +333,7 @@ FILE *FioFOpenFile(const std::string &filename, const char *mode, Subdirectory s
case BASESET_DIR:
f = FioFOpenFile(filename, mode, OLD_GM_DIR, filesize, output_filename);
if (f != nullptr) break;
FALLTHROUGH;
[[fallthrough]];
case NEWGRF_DIR:
f = FioFOpenFile(filename, mode, OLD_DATA_DIR, filesize, output_filename);
break;
@@ -1264,7 +1264,7 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
switch (sd) {
case BASESET_DIR:
num += this->Scan(extension, OLD_GM_DIR, tars, recursive);
FALLTHROUGH;
[[fallthrough]];
case NEWGRF_DIR:
num += this->Scan(extension, OLD_DATA_DIR, tars, recursive);
break;

View File

@@ -886,7 +886,7 @@ public:
/* We reset the files filtered */
this->OnInvalidateData(SLIWD_FILTER_CHANGES);
FALLTHROUGH;
[[fallthrough]];
case SLIWD_SELECTION_CHANGES:
/* Selection changes */

View File

@@ -48,7 +48,7 @@ void CDECL strgen_error(const char *s, ...)
_errors++;
}
void NORETURN CDECL strgen_fatal(const char *s, ...)
[[noreturn]] void CDECL strgen_fatal(const char *s, ...)
{
char buf[1024];
va_list va;

View File

@@ -67,7 +67,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

@@ -915,14 +915,14 @@ public:
switch (cargo_suffix[j].display) {
case CSD_CARGO_AMOUNT_TEXT:
SetDParamStr(3, cargo_suffix[j].text);
FALLTHROUGH;
[[fallthrough]];
case CSD_CARGO_AMOUNT:
str = stockpiling ? STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT : STR_INDUSTRY_VIEW_ACCEPT_CARGO;
break;
case CSD_CARGO_TEXT:
SetDParamStr(3, cargo_suffix[j].text);
FALLTHROUGH;
[[fallthrough]];
case CSD_CARGO:
str = STR_INDUSTRY_VIEW_ACCEPT_CARGO;
break;
@@ -2469,10 +2469,11 @@ struct CargoesRow {
if (cargo_fld->u.cargo.supp_cargoes[i] == INVALID_CARGO) ind_fld->u.industry.other_produced[i] = others[--other_count];
}
} else {
/* Houses only display what is demanded. */
/* Houses only display cargo that towns produce. */
for (uint i = 0; i < cargo_fld->u.cargo.num_cargoes; i++) {
CargoID cid = cargo_fld->u.cargo.vertical_cargoes[i];
if (cid == CT_PASSENGERS || cid == CT_MAIL) cargo_fld->ConnectCargo(cid, true);
TownProductionEffect tpe = CargoSpec::Get(cid)->town_production_effect;
if (tpe == TPE_PASSENGERS || tpe == TPE_MAIL) cargo_fld->ConnectCargo(cid, true);
}
}
}
@@ -2724,8 +2725,10 @@ struct IndustryCargoesWindow : public Window {
static bool HousesCanSupply(const CargoID *cargoes, size_t length)
{
for (size_t i = 0; i < length; i++) {
if (cargoes[i] == INVALID_CARGO) continue;
if (cargoes[i] == CT_PASSENGERS || cargoes[i] == CT_MAIL) return true;
CargoID cid = cargoes[i];
if (!IsValidCargoID(cid)) continue;
TownProductionEffect tpe = CargoSpec::Get(cid)->town_production_effect;
if (tpe == TPE_PASSENGERS || tpe == TPE_MAIL) return true;
}
return false;
}

View File

@@ -2,7 +2,7 @@
STR_NEWS_VEHICLE_AUTORENEW_FAILED :{WHITE}Autorenew failed on {VEHICLE}{}{STRING1}
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}The NewGRF "{RAW_STRING}" has returned a fatal error: {}{STRING7}
STR_NEWGRF_ERROR_POPUP :{WHITE}The NewGRF "{RAW_STRING}" has returned an error: {}{STRING7}
STR_ORDER_TEXT :{STRING6} {STRING2} {STRING}
STR_ORDER_TEXT :{STRING6} {STRING2} {STRING} {STRING}
##override off
##no-translate on

View File

@@ -1100,11 +1100,11 @@ struct QueryStringWindow : public Window
switch (widget) {
case WID_QS_DEFAULT:
this->editbox.text.DeleteAll();
FALLTHROUGH;
[[fallthrough]];
case WID_QS_OK:
this->OnOk();
FALLTHROUGH;
[[fallthrough]];
case WID_QS_CANCEL:
this->Close();
@@ -1287,7 +1287,7 @@ struct QueryWindow : public Window {
this->proc(this->parent, true);
this->proc = nullptr;
}
FALLTHROUGH;
[[fallthrough]];
case WKC_ESC:
this->Close();

View File

@@ -126,7 +126,7 @@ void MusicDriver_ExtMidi::DoPlay()
case -1:
DEBUG(driver, 0, "extmidi: couldn't fork: %s", strerror(errno));
FALLTHROUGH;
[[fallthrough]];
default:
this->song.clear();

View File

@@ -352,17 +352,17 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo
switch (game_info_version) {
case 7:
info->ticks_playing = p->Recv_uint64();
FALLTHROUGH;
[[fallthrough]];
case 6:
newgrf_serialisation = (NewGRFSerializationType)p->Recv_uint8();
if (newgrf_serialisation >= NST_END) return;
FALLTHROUGH;
[[fallthrough]];
case 5: {
info->gamescript_version = (int)p->Recv_uint32();
info->gamescript_name = p->Recv_string(NETWORK_NAME_LENGTH);
FALLTHROUGH;
[[fallthrough]];
}
case 4: {
@@ -404,19 +404,19 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo
*dst = c;
dst = &c->next;
}
FALLTHROUGH;
[[fallthrough]];
}
case 3:
info->calendar_date = Clamp(p->Recv_uint32(), 0, MAX_DATE.base());
info->calendar_start = Clamp(p->Recv_uint32(), 0, MAX_DATE.base());
FALLTHROUGH;
[[fallthrough]];
case 2:
info->companies_max = p->Recv_uint8 ();
info->companies_on = p->Recv_uint8 ();
p->Recv_uint8(); // Used to contain max-spectators.
FALLTHROUGH;
[[fallthrough]];
case 1:
info->server_name = p->Recv_string(NETWORK_NAME_LENGTH);

View File

@@ -462,7 +462,7 @@ struct NetworkChatWindow : public Window {
switch (widget) {
case WID_NC_SENDBUTTON: /* Send */
SendChat(this->message_editbox.text.buf, this->dtype, this->dest);
FALLTHROUGH;
[[fallthrough]];
case WID_NC_CLOSE: /* Cancel */
this->Close();

View File

@@ -1183,7 +1183,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
/* For speaking to company or giving money, we need the company-name */
case NETWORK_ACTION_GIVE_MONEY:
if (!Company::IsValidID(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY;
FALLTHROUGH;
[[fallthrough]];
case NETWORK_ACTION_CHAT_COMPANY: {
StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;

View File

@@ -898,7 +898,7 @@ public:
return ES_HANDLED;
}
/* space is pressed and filter is focused. */
FALLTHROUGH;
[[fallthrough]];
default:
return ES_NOT_HANDLED;

View File

@@ -2145,7 +2145,7 @@ struct NetworkJoinStatusWindow : Window {
progress = 15; // We don't have the final size yet; the server is still compressing!
break;
}
FALLTHROUGH;
[[fallthrough]];
default: // Waiting is 15%, so the resting receivement of map is maximum 70%
progress = 15 + _network_join_bytes * (100 - 15) / _network_join_bytes_total;
@@ -2318,7 +2318,7 @@ struct NetworkCompanyPasswordWindow : public Window {
switch (widget) {
case WID_NCP_OK:
this->OnOk();
FALLTHROUGH;
[[fallthrough]];
case WID_NCP_CANCEL:
this->Close();

View File

@@ -1570,7 +1570,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
}
default:
DEBUG(net, 1, "Received unknown chat destination type %d; doing broadcast instead", desttype);
FALLTHROUGH;
[[fallthrough]];
case DESTTYPE_BROADCAST:
case DESTTYPE_BROADCAST_SS:
@@ -1623,7 +1623,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p)
switch (action) {
case NETWORK_ACTION_GIVE_MONEY:
if (!Company::IsValidID(ci->client_playas)) break;
FALLTHROUGH;
[[fallthrough]];
case NETWORK_ACTION_CHAT:
case NETWORK_ACTION_CHAT_CLIENT:
case NETWORK_ACTION_CHAT_COMPANY:

View File

@@ -2079,7 +2079,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, cons
case A0RPI_STATION_MIN_BRIDGE_HEIGHT:
if (MappedPropertyLengthMismatch(buf, 8, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x1B: // Minimum height for a bridge above
SetBit(statspec->internal_flags, SSIF_BRIDGE_HEIGHTS_SET);
for (uint i = 0; i < 8; i++) {
@@ -2257,7 +2257,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, const
case A0RPI_BRIDGE_MENU_ICON:
if (MappedPropertyLengthMismatch(buf, 4, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x14: // purchase sprite
bridge->sprite = buf->ReadWord();
bridge->pal = buf->ReadWord();
@@ -3104,15 +3104,15 @@ static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, const G
uint8_t substitute_type = buf->ReadByte();
switch (substitute_type) {
case 0x00: cs->town_effect = TE_PASSENGERS; break;
case 0x02: cs->town_effect = TE_MAIL; break;
case 0x05: cs->town_effect = TE_GOODS; break;
case 0x09: cs->town_effect = TE_WATER; break;
case 0x0B: cs->town_effect = TE_FOOD; break;
case 0x00: cs->town_acceptance_effect = TAE_PASSENGERS; break;
case 0x02: cs->town_acceptance_effect = TAE_MAIL; break;
case 0x05: cs->town_acceptance_effect = TAE_GOODS; break;
case 0x09: cs->town_acceptance_effect = TAE_WATER; break;
case 0x0B: cs->town_acceptance_effect = TAE_FOOD; break;
default:
grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
FALLTHROUGH;
case 0xFF: cs->town_effect = TE_NONE; break;
[[fallthrough]];
case 0xFF: cs->town_acceptance_effect = TAE_NONE; break;
}
break;
}
@@ -3129,6 +3129,24 @@ static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, const G
cs->multiplier = std::max<uint16_t>(1u, buf->ReadWord());
break;
case 0x1E: { // Town production substitute type
uint8_t substitute_type = buf->ReadByte();
switch (substitute_type) {
case 0x00: cs->town_production_effect = TPE_PASSENGERS; break;
case 0x02: cs->town_production_effect = TPE_MAIL; break;
default:
grfmsg(1, "CargoChangeInfo: Unknown town production substitute value %u, setting to none.", substitute_type);
[[fallthrough]];
case 0xFF: cs->town_production_effect = TPE_NONE; break;
}
break;
}
case 0x1F: // Town production multiplier
cs->town_production_multiplier = std::max<uint16_t>(1U, buf->ReadWord());
break;
default:
ret = HandleAction0PropertyDefault(buf, prop);
break;
@@ -4513,7 +4531,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, const
RailType resolved_rt = GetRailTypeByLabel(BSWAP32(label), false);
if (resolved_rt != INVALID_RAILTYPE) {
switch (prop) {
case 0x0F: SetBit(rti->powered_railtypes, resolved_rt); FALLTHROUGH; // Powered implies compatible.
case 0x0F: SetBit(rti->powered_railtypes, resolved_rt); [[fallthrough]]; // Powered implies compatible.
case 0x0E: SetBit(rti->compatible_railtypes, resolved_rt); break;
case 0x18: SetBit(rti->introduction_required_railtypes, resolved_rt); break;
case 0x19: SetBit(rti->introduces_railtypes, resolved_rt); break;
@@ -4660,7 +4678,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, cons
break;
}
grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
FALLTHROUGH;
[[fallthrough]];
case 0x0E: // Compatible railtype list
case 0x0F: // Powered railtype list
@@ -5097,7 +5115,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
switch (prop) {
case A0RPI_ROADSTOP_CLASS_ID:
if (MappedPropertyLengthMismatch(buf, 4, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x08: { // Road Stop Class ID
if (rs == nullptr) {
_cur.grffile->roadstops[id + i] = std::make_unique<RoadStopSpec>();
@@ -5112,42 +5130,42 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
case A0RPI_ROADSTOP_STOP_TYPE:
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x09: // Road stop type
rs->stop_type = (RoadStopAvailabilityType)buf->ReadByte();
break;
case A0RPI_ROADSTOP_STOP_NAME:
if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x0A: // Road Stop Name
AddStringForMapping(buf->ReadWord(), &rs->name);
break;
case A0RPI_ROADSTOP_CLASS_NAME:
if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x0B: // Road Stop Class name
AddStringForMapping(buf->ReadWord(), &RoadStopClass::Get(rs->cls_id)->name);
break;
case A0RPI_ROADSTOP_DRAW_MODE:
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x0C: // The draw mode
rs->draw_mode = (RoadStopDrawMode)buf->ReadByte();
break;
case A0RPI_ROADSTOP_TRIGGER_CARGOES:
if (MappedPropertyLengthMismatch(buf, 4, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x0D: // Cargo types for random triggers
rs->cargo_triggers = TranslateRefitMask(buf->ReadDWord());
break;
case A0RPI_ROADSTOP_ANIMATION_INFO:
if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x0E: // Animation info
rs->animation.frames = buf->ReadByte();
rs->animation.status = buf->ReadByte();
@@ -5155,35 +5173,35 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
case A0RPI_ROADSTOP_ANIMATION_SPEED:
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x0F: // Animation speed
rs->animation.speed = buf->ReadByte();
break;
case A0RPI_ROADSTOP_ANIMATION_TRIGGERS:
if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x10: // Animation triggers
rs->animation.triggers = buf->ReadWord();
break;
case A0RPI_ROADSTOP_CALLBACK_MASK:
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x11: // Callback mask
rs->callback_mask = buf->ReadByte();
break;
case A0RPI_ROADSTOP_GENERAL_FLAGS:
if (MappedPropertyLengthMismatch(buf, 4, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x12: // General flags
rs->flags = (uint16_t)buf->ReadDWord(); // Future-proofing, size this as 4 bytes, but we only need two bytes' worth of flags at present
break;
case A0RPI_ROADSTOP_MIN_BRIDGE_HEIGHT:
if (MappedPropertyLengthMismatch(buf, 6, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x13: // Minimum height for a bridge above
SetBit(rs->internal_flags, RSIF_BRIDGE_HEIGHTS_SET);
for (uint i = 0; i < 6; i++) {
@@ -5193,7 +5211,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
case A0RPI_ROADSTOP_DISALLOWED_BRIDGE_PILLARS:
if (MappedPropertyLengthMismatch(buf, 6, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x14: // Disallowed bridge pillars
SetBit(rs->internal_flags, RSIF_BRIDGE_DISALLOWED_PILLARS_SET);
for (uint i = 0; i < 6; i++) {
@@ -5203,7 +5221,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
case A0RPI_ROADSTOP_COST_MULTIPLIERS:
if (MappedPropertyLengthMismatch(buf, 2, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x15: // Cost multipliers
rs->build_cost_multiplier = buf->ReadByte();
rs->clear_cost_multiplier = buf->ReadByte();
@@ -5211,7 +5229,7 @@ static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, const
case A0RPI_ROADSTOP_HEIGHT:
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
FALLTHROUGH;
[[fallthrough]];
case 0x16: // Height
rs->height = buf->ReadByte();
break;
@@ -5284,7 +5302,7 @@ static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, Grf
case CIR_UNKNOWN:
grfmsg(0, "%s: Unknown property 0x%02X of feature %s, disabling", caller, property, GetFeatureString(feature));
FALLTHROUGH;
[[fallthrough]];
case CIR_INVALID_ID: {
/* No debug message for an invalid ID, as it has already been output */
@@ -10837,6 +10855,14 @@ static void FinaliseEngineArray()
void FinaliseCargoArray()
{
for (CargoSpec &cs : CargoSpec::array) {
if (cs.town_production_effect == INVALID_TPE) {
/* Set default town production effect by cargo label. */
switch (cs.label) {
case 'PASS': cs.town_production_effect = TPE_PASSENGERS; break;
case 'MAIL': cs.town_production_effect = TPE_MAIL; break;
default: cs.town_production_effect = TPE_NONE; break;
}
}
if (!cs.IsValid()) {
cs.name = cs.name_single = cs.units_volume = STR_NEWGRF_INVALID_CARGO;
cs.quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;

View File

@@ -189,7 +189,7 @@ struct AirportResolverObject : public ResolverObject {
{
TownScopeResolver *tsr = this->GetTown();
if (tsr != nullptr) return tsr;
FALLTHROUGH;
[[fallthrough]];
}
default: return ResolverObject::GetScope(scope, relative);
}

View File

@@ -1070,7 +1070,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
break;
}
/* With double click, continue */
FALLTHROUGH;
[[fallthrough]];
}
case WID_NS_REMOVE: { // Remove GRF
@@ -1128,7 +1128,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
break;
}
/* With double click, continue */
FALLTHROUGH;
[[fallthrough]];
}
case WID_NS_ADD:
@@ -1284,7 +1284,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
}
this->avails.ForceRebuild();
FALLTHROUGH;
[[fallthrough]];
case GOID_NEWGRF_CURRENT_LOADED:
this->modified = false;
@@ -1293,7 +1293,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
case GOID_NEWGRF_LIST_EDITED:
this->preset = -1;
FALLTHROUGH;
[[fallthrough]];
case GOID_NEWGRF_CHANGES_MADE:
UpdateScrollBars();

View File

@@ -129,7 +129,7 @@ uint32_t IndustriesScopeResolver::GetCountAndDistanceOfClosestInstance(byte para
case 0xFFFFFFFF: // current grf
GrfID = GetIndustrySpec(this->industry->type)->grf_prop.grffile->grfid;
FALLTHROUGH;
[[fallthrough]];
default: // use the grfid specified in register 100h
SetBit(param_setID, 7); // bit 7 means it is not an old type

View File

@@ -72,7 +72,7 @@ struct IndustriesResolverObject : public ResolverObject {
TownScopeResolver *tsr = this->GetTown();
if (tsr != nullptr) return tsr;
}
FALLTHROUGH;
[[fallthrough]];
default:
return ResolverObject::GetScope(scope, relative);

View File

@@ -243,7 +243,7 @@ static uint32_t GetCountAndDistanceOfClosestInstance(uint32_t local_id, uint32_t
case 0xFFFFFFFF: // current grf
grf_id = grfid;
FALLTHROUGH;
[[fallthrough]];
default: // use the grfid specified in register 100h
idx = _object_mngr.GetID(local_id, grf_id);

View File

@@ -184,7 +184,7 @@ struct ObjectResolverObject : public ResolverObject {
case VSG_SCOPE_PARENT: {
TownScopeResolver *tsr = this->GetTown();
if (tsr != nullptr) return tsr;
FALLTHROUGH;
[[fallthrough]];
}
default:

View File

@@ -124,7 +124,7 @@ struct RoadStopResolverObject : public ResolverObject {
case VSG_SCOPE_PARENT: {
TownScopeResolver *tsr = this->GetTown();
if (tsr != nullptr) return tsr;
FALLTHROUGH;
[[fallthrough]];
}
default: return ResolverObject::GetScope(scope, relative);
}

View File

@@ -76,7 +76,7 @@ struct StationResolverObject : public ResolverObject {
case VSG_SCOPE_PARENT: {
TownScopeResolver *tsr = this->GetTown();
if (tsr != nullptr) return tsr;
FALLTHROUGH;
[[fallthrough]];
}
default:

View File

@@ -99,14 +99,14 @@
case 0xC9: return GB(ClampTo<uint16_t>(this->t->supplied[CT_MAIL].old_act), 8, 8);
case 0xCA: return this->t->GetPercentTransported(CT_PASSENGERS);
case 0xCB: return this->t->GetPercentTransported(CT_MAIL);
case 0xCC: return this->t->received[TE_FOOD].new_act;
case 0xCD: return GB(this->t->received[TE_FOOD].new_act, 8, 8);
case 0xCE: return this->t->received[TE_WATER].new_act;
case 0xCF: return GB(this->t->received[TE_WATER].new_act, 8, 8);
case 0xD0: return this->t->received[TE_FOOD].old_act;
case 0xD1: return GB(this->t->received[TE_FOOD].old_act, 8, 8);
case 0xD2: return this->t->received[TE_WATER].old_act;
case 0xD3: return GB(this->t->received[TE_WATER].old_act, 8, 8);
case 0xCC: return this->t->received[TAE_FOOD].new_act;
case 0xCD: return GB(this->t->received[TAE_FOOD].new_act, 8, 8);
case 0xCE: return this->t->received[TAE_WATER].new_act;
case 0xCF: return GB(this->t->received[TAE_WATER].new_act, 8, 8);
case 0xD0: return this->t->received[TAE_FOOD].old_act;
case 0xD1: return GB(this->t->received[TAE_FOOD].old_act, 8, 8);
case 0xD2: return this->t->received[TAE_WATER].old_act;
case 0xD3: return GB(this->t->received[TAE_WATER].old_act, 8, 8);
case 0xD4: return this->t->road_build_months;
case 0xD5: return this->t->fund_buildings_months;
case A2VRI_TOWNS_HOUSE_COUNT: return this->t->cache.num_houses;

View File

@@ -129,7 +129,7 @@ extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMP
extern void OSOpenBrowser(const std::string &url);
extern void RebuildTownCaches(bool cargo_update_required, bool old_map_position);
extern void ShowOSErrorBox(const char *buf, bool system);
extern void NORETURN DoOSAbort();
[[noreturn]] extern void DoOSAbort();
extern std::string _config_file;
extern uint64_t _station_tile_cache_hash;
@@ -143,7 +143,7 @@ std::mutex _music_driver_mutex;
static std::string _music_driver_params;
static std::atomic<bool> _music_inited;
void NORETURN usererror_str(const char *msg)
[[noreturn]] void usererror_str(const char *msg)
{
ShowOSErrorBox(msg, false);
if (VideoDriver::GetInstance() != nullptr) VideoDriver::GetInstance()->Stop();
@@ -176,7 +176,7 @@ void CDECL usererror(const char *s, ...)
usererror_str(buf);
}
static void NORETURN fatalerror_common(const char *msg)
[[noreturn]] static void fatalerror_common(const char *msg)
{
if (VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) {
ShowOSErrorBox(msg, true);

View File

@@ -380,7 +380,7 @@ public:
/** What caused us going to the depot? */
inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 3); }
/** What are we going to do when in the depot. */
inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 3); }
inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 3, 4); }
/** Extra depot flags. */
inline OrderDepotExtraFlags GetDepotExtraFlags() const { return (OrderDepotExtraFlags)GB(this->flags, 8, 8); }
/** What waypoint flags? */
@@ -445,7 +445,7 @@ public:
/** Set the cause to go to the depot. */
inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 3, depot_order_type); }
/** Set what we are going to do in the depot. */
inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 3, depot_service_type); }
inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 3, 4, depot_service_type); }
/** Set what we are going to do in the depot. */
inline void SetDepotExtraFlags(OrderDepotExtraFlags depot_extra_flags) { SB(this->flags, 8, 8, depot_extra_flags); }
/** Set waypoint flags. */

View File

@@ -1083,11 +1083,21 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
/* Filter invalid load/unload types. */
switch (new_order.GetLoadType()) {
case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: case OLFB_NO_LOAD: break;
case OLFB_CARGO_TYPE_LOAD:
if (allow_load_by_cargo_type) break;
return CMD_ERROR;
default: return CMD_ERROR;
case OLF_LOAD_IF_POSSIBLE:
case OLFB_NO_LOAD:
break;
case OLFB_FULL_LOAD:
case OLF_FULL_LOAD_ANY:
if (v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_NO_FULL_LOAD);
break;
default:
return CMD_ERROR;
}
switch (new_order.GetUnloadType()) {
case OUF_UNLOAD_IF_POSSIBLE: case OUFB_UNLOAD: case OUFB_TRANSFER: case OUFB_NO_UNLOAD: break;
@@ -1103,7 +1113,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
case OSL_PLATFORM_MIDDLE:
case OSL_PLATFORM_THROUGH:
if (v->type != VEH_TRAIN) return CMD_ERROR;
FALLTHROUGH;
[[fallthrough]];
case OSL_PLATFORM_FAR_END:
break;
@@ -1207,6 +1217,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
VehicleOrderID skip_to = new_order.GetConditionSkipToOrder();
if (skip_to != 0 && skip_to >= v->GetNumOrders()) return CMD_ERROR; // Always allow jumping to the first (even when there is no order).
if (new_order.GetConditionVariable() >= OCV_END) return CMD_ERROR;
if (v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_NO_CONDITIONAL);
OrderConditionComparator occ = new_order.GetConditionComparator();
if (occ >= OCC_END) return CMD_ERROR;
@@ -1267,7 +1278,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
case OCV_LOAD_PERCENTAGE:
case OCV_RELIABILITY:
if (new_order.GetConditionValue() > 100) return CMD_ERROR;
FALLTHROUGH;
[[fallthrough]];
default:
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) return CMD_ERROR;
@@ -1389,6 +1400,7 @@ void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
u->cur_implicit_order_index = cur;
}
}
if (u->cur_timetable_order_index != INVALID_VEH_ORDER_ID && sel_ord <= u->cur_timetable_order_index) {
uint cur = u->cur_timetable_order_index + 1;
/* Check if we don't go out of bound */
@@ -1396,6 +1408,10 @@ void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
u->cur_timetable_order_index = cur;
}
}
/* Unbunching data is no longer valid. */
u->ResetDepotUnbunching();
/* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, INVALID_VEH_ORDER_ID | (sel_ord << 16));
}
@@ -1543,6 +1559,8 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
if (u->cur_implicit_order_index >= u->GetNumOrders()) u->cur_implicit_order_index = 0;
}
}
/* Unbunching data is no longer valid. */
u->ResetDepotUnbunching();
if (u->cur_timetable_order_index != INVALID_VEH_ORDER_ID) {
if (sel_ord < u->cur_timetable_order_index) {
@@ -1611,6 +1629,9 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
v->UpdateRealOrderIndex();
v->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
/* Unbunching data is no longer valid. */
v->ResetDepotUnbunching();
InvalidateVehicleOrder(v, VIWD_MODIFY_ORDERS);
v->ClearSeparation();
@@ -1696,6 +1717,9 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uint3
} else if (u->cur_implicit_order_index < moving_order && u->cur_implicit_order_index >= target_order) {
u->cur_implicit_order_index++;
}
/* Unbunching data is no longer valid. */
u->ResetDepotUnbunching();
u->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
@@ -1915,10 +1939,27 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return CMD_ERROR;
if ((data > OLFB_NO_LOAD && data != OLFB_CARGO_TYPE_LOAD) || data == 1) return CMD_ERROR;
if (data == order->GetLoadType()) return CMD_ERROR;
if ((data & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) && v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_NO_FULL_LOAD);
break;
case MOF_DEPOT_ACTION:
if (data >= DA_END) return CMD_ERROR;
/* Check if we are allowed to add unbunching. We are always allowed to remove it. */
if (data == DA_UNBUNCH) {
/* Only one unbunching order is allowed in a vehicle's orders. If this order already has an unbunching action, no error is needed. */
if (v->HasUnbunchingOrder() && !(order->GetDepotActionType() & ODATFB_UNBUNCH)) return_cmd_error(STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED);
for (Order *o : v->Orders()) {
/* We don't allow unbunching if the vehicle has a conditional order. */
if (o->IsType(OT_CONDITIONAL)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL);
/* We don't allow unbunching if the vehicle has a full load order. */
if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD);
if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() == OLFB_CARGO_TYPE_LOAD) {
}
}
}
break;
case MOF_COND_VARIABLE:
@@ -2153,7 +2194,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
break;
case MOF_DEPOT_ACTION: {
OrderDepotActionFlags base_order_action_type = order->GetDepotActionType() & ~(ODATFB_HALT | ODATFB_SELL);
OrderDepotActionFlags base_order_action_type = order->GetDepotActionType() & ~(ODATFB_HALT | ODATFB_SELL | ODATFB_UNBUNCH);
switch (data) {
case DA_ALWAYS_GO:
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
@@ -2178,6 +2219,11 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
order->SetRefit(CARGO_NO_REFIT);
break;
case DA_UNBUNCH:
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
order->SetDepotActionType((OrderDepotActionFlags)(base_order_action_type | ODATFB_UNBUNCH));
break;
default:
NOT_REACHED();
}
@@ -2261,7 +2307,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
case OCV_LOAD_PERCENTAGE:
case OCV_RELIABILITY:
if (order->GetConditionValue() > 100) order->SetConditionValue(100);
FALLTHROUGH;
[[fallthrough]];
default:
if (old_var_was_cargo || old_var_was_slot || old_var_was_counter || old_var_was_time || old_var_was_tt) order->SetConditionValue(0);
@@ -2421,6 +2467,10 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
(u->current_order.IsType(OT_GOTO_STATION) || u->current_order.IsType(OT_GOTO_WAYPOINT))) {
u->current_order.SetRoadVehTravelDirection((DiagDirection)data);
}
/* Unbunching data is no longer valid. */
u->ResetDepotUnbunching();
InvalidateVehicleOrder(u, VIWD_MODIFY_ORDERS);
}
CheckMarkDirtyViewportRoutePaths(v);
@@ -2951,6 +3001,9 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indic
}
}
/* Unbunching data is no longer valid. */
v->ResetDepotUnbunching();
if (reset_order_indices) {
v->cur_implicit_order_index = v->cur_real_order_index = 0;
v->cur_timetable_order_index = INVALID_VEH_ORDER_ID;

View File

@@ -775,6 +775,7 @@ static const StringID _order_depot_action_dropdown[] = {
STR_ORDER_DROP_GO_ALWAYS_DEPOT,
STR_ORDER_DROP_SERVICE_DEPOT,
STR_ORDER_DROP_HALT_DEPOT,
STR_ORDER_DROP_UNBUNCH,
STR_ORDER_DROP_SELL_DEPOT,
INVALID_STRING_ID
};
@@ -785,6 +786,8 @@ static int DepotActionStringIndex(const Order *order)
return DA_SELL;
} else if (order->GetDepotActionType() & ODATFB_HALT) {
return DA_STOP;
} else if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
return DA_SERVICE;
} else if (order->GetDepotOrderType() & ODTFB_SERVICE) {
return DA_SERVICE;
} else {
@@ -869,11 +872,12 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(7, STR_EMPTY);
SetDParam(10, STR_EMPTY);
SetDParam(11, STR_EMPTY);
/* Check range for aircraft. */
if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->GetRange() > 0 && order->IsGotoOrder()) {
const Order *next = order->next != nullptr ? order->next : v->GetFirstOrder();
if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) SetDParam(10, STR_ORDER_OUT_OF_RANGE);
if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) SetDParam(11, STR_ORDER_OUT_OF_RANGE);
}
bool timetable_wait_time_valid = false;
@@ -976,6 +980,12 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
}
timetable_wait_time_valid = !(order->GetDepotActionType() & ODATFB_HALT);
}
/* Do not show unbunching in the depot in the timetable window. */
if (!timetable && (order->GetDepotActionType() & ODATFB_UNBUNCH)) {
SetDParam(10, STR_ORDER_WAIT_TO_UNBUNCH);
}
break;
case OT_GOTO_WAYPOINT: {
@@ -1910,6 +1920,9 @@ public:
{
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_O_SCROLLBAR);
if (NWidgetCore *nwid = this->GetWidget<NWidgetCore>(WID_O_DEPOT_ACTION); nwid != nullptr) {
nwid->tool_tip = STR_ORDER_TRAIN_DEPOT_ACTION_TOOLTIP + v->type;
}
this->GetWidget<NWidgetStacked>(WID_O_SEL_OCCUPANCY)->SetDisplayedPlane(_settings_client.gui.show_order_occupancy_by_default ? 0 : SZSP_NONE);
this->SetWidgetLoweredState(WID_O_OCCUPANCY_TOGGLE, _settings_client.gui.show_order_occupancy_by_default);
this->current_aux_plane = SZSP_NONE;
@@ -2035,7 +2048,7 @@ public:
case VIWD_AUTOREPLACE:
/* Autoreplace replaced the vehicle */
this->vehicle = Vehicle::Get(this->window_number);
FALLTHROUGH;
[[fallthrough]];
case VIWD_CONSIST_CHANGED:
/* Vehicle composition was changed. */
@@ -2145,7 +2158,6 @@ public:
/* First row. */
this->RaiseWidget(WID_O_FULL_LOAD);
this->RaiseWidget(WID_O_UNLOAD);
this->RaiseWidget(WID_O_SERVICE);
/* Selection widgets. */
/* Train or road vehicle. */
@@ -2266,7 +2278,6 @@ public:
this->SetWidgetDisabledState(WID_O_REFIT,
(order->GetDepotOrderType() & ODTFB_SERVICE) || (order->GetDepotActionType() & ODATFB_HALT) ||
(!this->can_do_refit && !order->IsRefit()));
this->SetWidgetLoweredState(WID_O_SERVICE, order->GetDepotOrderType() & ODTFB_SERVICE);
break;
case OT_CONDITIONAL: {
@@ -2665,6 +2676,30 @@ public:
SetDParam(0, this->vehicle->index);
break;
case WID_O_DEPOT_ACTION: {
VehicleOrderID sel = this->OrderGetSel();
const Order *order = this->vehicle->GetOrder(sel);
if (order == nullptr || !order->IsType(OT_GOTO_DEPOT)) {
/* We can't leave this param unset or the undefined behavior can cause a crash. */
SetDParam(0, STR_EMPTY);
break;
};
/* Select the current action selected in the dropdown. The flags don't match the dropdown so we can't just use an index. */
if (order->GetDepotActionType() & ODATFB_SELL) {
SetDParam(0, STR_ORDER_DROP_SELL_DEPOT);
} else if (order->GetDepotOrderType() & ODTFB_SERVICE) {
SetDParam(0, STR_ORDER_DROP_SERVICE_DEPOT);
} else if (order->GetDepotActionType() & ODATFB_HALT) {
SetDParam(0, STR_ORDER_DROP_HALT_DEPOT);
} else if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
SetDParam(0, STR_ORDER_DROP_UNBUNCH);
} else {
SetDParam(0, STR_ORDER_DROP_GO_ALWAYS_DEPOT);
}
break;
}
case WID_O_OCCUPANCY_TOGGLE:
const_cast<Vehicle *>(this->vehicle)->RecalculateOrderOccupancyAverage();
if (this->vehicle->order_occupancy_average >= 16) {
@@ -2985,13 +3020,9 @@ public:
this->OrderClick_Refit(0, false);
break;
case WID_O_SERVICE:
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
this->OrderClick_Service(-1);
} else {
ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())),
WID_O_SERVICE, 0, _settings_client.gui.show_depot_sell_gui ? 0 : (1 << DA_SELL), 0, DDSF_LOST_FOCUS);
}
case WID_O_DEPOT_ACTION:
ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())),
WID_O_DEPOT_ACTION, 0, _settings_client.gui.show_depot_sell_gui ? 0 : (1 << DA_SELL), 0, DDSF_LOST_FOCUS);
break;
case WID_O_REFIT_DROPDOWN:
@@ -3375,7 +3406,7 @@ public:
}
break;
case WID_O_SERVICE:
case WID_O_DEPOT_ACTION:
this->OrderClick_Service(index);
break;
@@ -3785,8 +3816,8 @@ static constexpr NWidgetPart _nested_orders_train_widgets[] = {
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_MIDDLE),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_UNLOAD), SetMinimalSize(93, 12), SetFill(1, 0),
SetDataTip(STR_ORDER_TOGGLE_UNLOAD, STR_ORDER_TOOLTIP_UNLOAD), SetResize(1, 0),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_SERVICE), SetMinimalSize(93, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_NULL), SetResize(1, 0),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_DEPOT_ACTION), SetMinimalSize(93, 12), SetFill(1, 0),
SetDataTip(STR_JUST_STRING, STR_NULL), SetResize(1, 0),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_TOP_RIGHT),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(93, 12), SetFill(1, 0), SetResize(1, 0), EndContainer(),
@@ -3932,8 +3963,8 @@ static constexpr NWidgetPart _nested_orders_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_O_REFIT), SetMinimalSize(186, 12), SetFill(1, 0),
SetDataTip(STR_ORDER_REFIT, STR_ORDER_REFIT_TOOLTIP), SetResize(1, 0),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_SERVICE), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_NULL), SetResize(1, 0),
NWidget(NWID_BUTTON_DROPDOWN, COLOUR_GREY, WID_O_DEPOT_ACTION), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_JUST_STRING, STR_NULL), SetResize(1, 0),
EndContainer(),
/* Buttons for setting a condition. */

View File

@@ -140,6 +140,7 @@ enum OrderDepotActionFlags {
ODATFB_HALT = 1 << 0, ///< Service the vehicle and then halt it.
ODATFB_NEAREST_DEPOT = 1 << 1, ///< Send the vehicle to the nearest depot.
ODATFB_SELL = 1 << 2, ///< Sell the vehicle on arrival at the depot.
ODATFB_UNBUNCH = 1 << 3, ///< Service the vehicle and then unbunch it.
};
DECLARE_ENUM_AS_BIT_SET(OrderDepotActionFlags)
@@ -247,6 +248,7 @@ enum OrderDepotAction {
DA_ALWAYS_GO, ///< Always go to the depot
DA_SERVICE, ///< Service only if needed
DA_STOP, ///< Go to the depot and stop there
DA_UNBUNCH, ///< Go to the depot and unbunch
DA_SELL, ///< Go to the depot and sell vehicle
DA_END
};

View File

@@ -237,7 +237,7 @@ void ShowOSErrorBox(const char *buf, bool)
}
}
void NORETURN DoOSAbort()
[[noreturn]] void DoOSAbort()
{
abort();
}

View File

@@ -56,7 +56,7 @@
#pragma GCC diagnostic ignored "-Wclobbered"
#endif
static void NORETURN ImmediateExitProcess(uint exit_code)
static [[noreturn]] void ImmediateExitProcess(uint exit_code)
{
/* TerminateProcess may fail in some special edge cases, fall back to ExitProcess in this case */
TerminateProcess(GetCurrentProcess(), exit_code);

View File

@@ -64,7 +64,7 @@ void ShowOSErrorBox(const char *buf, bool system)
MessageBox(GetActiveWindow(), OTTD2FS(buf).c_str(), L"Error!", MB_ICONSTOP | MB_TASKMODAL);
}
void NORETURN DoOSAbort()
[[noreturn]] void DoOSAbort()
{
RaiseException(0xE1212012, 0, 0, nullptr);

View File

@@ -150,7 +150,7 @@ public:
* waypoint. */
Yapf().DisableCache(true);
}
FALLTHROUGH;
[[fallthrough]];
case OT_GOTO_STATION:
m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
@@ -162,7 +162,7 @@ public:
if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
m_any_depot = true;
}
FALLTHROUGH;
[[fallthrough]];
default:
m_destTile = v->dest_tile;

View File

@@ -876,7 +876,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32_t p1,
_rail_track_endtile = tile;
return_cmd_error(STR_ERROR_ALREADY_BUILT);
}
FALLTHROUGH;
[[fallthrough]];
}
default: {
@@ -1478,7 +1478,7 @@ static void ReReserveTrainPath(Train *v)
* - p1 = (bit 4) - 0 = signals, 1 = semaphores
* - p1 = (bit 5-7) - type of the signal, for valid values see enum SignalType in rail_map.h
* - p1 = (bit 8) - convert the present signal type and variant
* - p1 = (bit 9-14)- cycle through which signal set?
* - p1 = (bit 9-10)- cycle through which signal sets?
* - p1 = (bit 15-16)-cycle the signal direction this many times
* - p1 = (bit 17) - 1 = don't modify an existing signal but don't fail either, 0 = always set new signal type
* - p1 = (bit 18) - permit creation of/conversion to bidirectionally signalled bridges/tunnels
@@ -1498,7 +1498,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t p
bool convert_signal = HasBit(p1, 8); // convert button pressed
uint num_dir_cycle = GB(p1, 15, 2);
uint which_signals = GB(p1, 9, 6);
SignalCycleGroups which_signals = (SignalCycleGroups)GB(p1, 9, 2);
uint signal_style = GB(p1, 19, 4);
if (signal_style > _num_new_signal_styles || !HasBit(_enabled_new_signal_styles_mask, signal_style)) return CMD_ERROR;
@@ -1757,10 +1757,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t p
} else {
if (_ctrl_pressed && GetSignalStyle(tile, track) != 0) {
SignalType new_sigtype = GetSignalType(tile, track);
do {
new_sigtype = NextSignalType(new_sigtype, which_signals);
} while (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsSignalTypeUnsuitableForRealisticBraking(new_sigtype));
SignalType new_sigtype = NextSignalType(GetSignalType(tile, track), which_signals);
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsSignalTypeUnsuitableForRealisticBraking(new_sigtype)) return CMD_ERROR;
if (!is_style_usable(GetSignalVariant(tile, track), GetSignalStyle(tile, track), 1 << new_sigtype)) return_cmd_error(STR_ERROR_UNSUITABLE_SIGNAL_TYPE);
}
@@ -1842,9 +1840,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32_t p
if (sigtype == SIGTYPE_NO_ENTRY) CycleSignalSide(tile, track);
do {
sigtype = NextSignalType(sigtype, which_signals);
} while (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsSignalTypeUnsuitableForRealisticBraking(sigtype));
sigtype = NextSignalType(sigtype, which_signals);
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsSignalTypeUnsuitableForRealisticBraking(sigtype)) return CMD_ERROR;
SetSignalType(tile, track, sigtype);
if (IsPbsSignal(sigtype) && (GetPresentSignals(tile) & SignalOnTrack(track)) == SignalOnTrack(track)) {
@@ -4065,13 +4062,13 @@ static void DrawTile_Track(TileInfo *ti, DrawTileProcParams params)
switch (GetRailDepotDirection(ti->tile)) {
case DIAGDIR_NE:
if (!IsInvisibilitySet(TO_BUILDINGS)) break;
FALLTHROUGH;
[[fallthrough]];
case DIAGDIR_SW:
DrawGroundSprite(ground + RTO_X, PAL_NONE);
break;
case DIAGDIR_NW:
if (!IsInvisibilitySet(TO_BUILDINGS)) break;
FALLTHROUGH;
[[fallthrough]];
case DIAGDIR_SE:
DrawGroundSprite(ground + RTO_Y, PAL_NONE);
break;
@@ -4085,13 +4082,13 @@ static void DrawTile_Track(TileInfo *ti, DrawTileProcParams params)
switch (GetRailDepotDirection(ti->tile)) {
case DIAGDIR_NE:
if (!IsInvisibilitySet(TO_BUILDINGS)) break;
FALLTHROUGH;
[[fallthrough]];
case DIAGDIR_SW:
DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH);
break;
case DIAGDIR_NW:
if (!IsInvisibilitySet(TO_BUILDINGS)) break;
FALLTHROUGH;
[[fallthrough]];
case DIAGDIR_SE:
DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH);
break;
@@ -4105,13 +4102,13 @@ static void DrawTile_Track(TileInfo *ti, DrawTileProcParams params)
switch (GetRailDepotDirection(ti->tile)) {
case DIAGDIR_NE:
if (!IsInvisibilitySet(TO_BUILDINGS)) break;
FALLTHROUGH;
[[fallthrough]];
case DIAGDIR_SW:
DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH);
break;
case DIAGDIR_NW:
if (!IsInvisibilitySet(TO_BUILDINGS)) break;
FALLTHROUGH;
[[fallthrough]];
case DIAGDIR_SE:
DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH);
break;

View File

@@ -283,12 +283,14 @@ static void GenericPlaceSignals(TileIndex tile)
uint32_t p1 = track;
/* Which signals should we cycle through? */
uint8_t cycle_types;
if (_settings_client.gui.cycle_signal_types == SIGNAL_CYCLE_ALL && (_settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL || _settings_game.vehicle.train_braking_model == TBM_REALISTIC)) {
cycle_types = SIGNAL_CYCLE_ALL;
SignalCycleGroups cycle_types;
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
cycle_types = SCG_BLOCK | SCG_PBS;
} else if (_settings_client.gui.cycle_signal_types == SIGNAL_CYCLE_ALL) {
cycle_types = SCG_PBS;
if (_settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL) cycle_types |= SCG_BLOCK;
} else {
cycle_types = SIGNAL_CYCLE_PATH;
cycle_types = SCG_CURRENT_GROUP;
}
if (w != nullptr) {
@@ -297,7 +299,7 @@ static void GenericPlaceSignals(TileIndex tile)
SB(p1, 4, 1, _cur_signal_variant);
SB(p1, 5, 3, _cur_signal_type);
SB(p1, 8, 1, _convert_signal_button);
SB(p1, 9, 6, cycle_types);
SB(p1, 9, 2, cycle_types);
SB(p1, 19, 4, _cur_signal_style);
if (_cur_signal_type == SIGTYPE_NO_ENTRY) SB(p1, 15, 2, 1); // reverse default signal direction
} else {
@@ -305,7 +307,7 @@ static void GenericPlaceSignals(TileIndex tile)
SB(p1, 4, 1, (CalTime::CurYear() < _settings_client.gui.semaphore_build_before ? SIG_SEMAPHORE : SIG_ELECTRIC));
SB(p1, 5, 3, GetDefaultSignalType());
SB(p1, 8, 1, 0);
SB(p1, 9, 6, cycle_types);
SB(p1, 9, 2, cycle_types);
}
SB(p1, 18, 1, _settings_client.gui.adv_sig_bridge_tun_modes);
SB(p1, 23, 5, Clamp<int>(_settings_client.gui.drag_signals_density, 1, 16));
@@ -2757,7 +2759,7 @@ static void SetDefaultRailGui()
if (count[rt] > 0) break;
/* No rail, just get the first available one */
FALLTHROUGH;
[[fallthrough]];
}
case 0: {
/* Use first available type */

View File

@@ -18,8 +18,8 @@ enum SignalGUISettings : uint8_t {
/** Settings for which signals are cycled through by control-clicking on the signal with the signal tool. */
enum SignalCycleSettings : uint8_t {
SIGNAL_CYCLE_PATH = 0, ///< Cycle through path signals only.
SIGNAL_CYCLE_ALL = 1, ///< Cycle through all signals visible.
SIGNAL_CYCLE_GROUP = 0, ///< Cycle through current signal group (block or path) only.
SIGNAL_CYCLE_ALL = 1, ///< Cycle through all signals visible to the player.
};
#endif /* RAIL_GUI_TYPE_H */

View File

@@ -139,7 +139,7 @@ enum RoadVehicleFlags {
/**
* Buses, trucks and trams belong to this class.
*/
struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
struct RoadVehicle final : public GroundVehicle<RoadVehicle, VEH_ROAD> {
byte state; ///< @see RoadVehicleStates
byte frame;
uint16_t blocked_ctr;

View File

@@ -427,7 +427,12 @@ CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin
if (IsTileType(v->tile, MP_TUNNELBRIDGE) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
if (flags & DC_EXEC) v->reverse_ctr = 180;
if (flags & DC_EXEC) {
v->reverse_ctr = 180;
/* Unbunching data is no longer valid. */
v->ResetDepotUnbunching();
}
return CommandCost();
}
@@ -1338,6 +1343,7 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
if (RoadVehFindCloseTo(v, x, y, v->direction, false) != nullptr) return true;
VehicleServiceInDepot(v);
v->LeaveUnbunchingDepot();
StartRoadVehSound(v);
@@ -2154,7 +2160,11 @@ static bool RoadVehController(RoadVehicle *v)
v->HandleWaiting(false, true);
if (v->current_order.IsType(OT_WAITING)) return true;
if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return true;
if (v->IsInDepot()) {
/* Check if we should wait here for unbunching. */
if (v->IsWaitingForUnbunching()) return true;
if (RoadVehLeaveDepot(v, true)) return true;
}
int j;
{

View File

@@ -175,7 +175,7 @@ static void ConvertTownOwner()
if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HasBit(_m[tile].m3, 7)) {
_m[tile].m3 = OWNER_TOWN;
}
FALLTHROUGH;
[[fallthrough]];
case MP_TUNNELBRIDGE:
if (_m[tile].m1 & 0x80) SetTileOwner(tile, OWNER_TOWN);
@@ -2150,7 +2150,21 @@ bool AfterLoadGame()
v->current_order.SetLoadType(OLFB_NO_LOAD);
}
}
} else if (SlXvIsFeaturePresent(XSLFI_JOKERPP, 1, SL_JOKER_1_23)) {
}
if (IsSavegameVersionBefore(SLV_DEPOT_UNBUNCHING) && SlXvIsFeatureMissing(XSLFI_DEPOT_UNBUNCHING)) {
/* OrderDepotActionFlags were moved, instead of starting at bit 4 they now start at bit 3. */
for (Order *order : Order::Iterate()) {
if (!order->IsType(OT_GOTO_DEPOT)) continue;
OrderDepotActionFlags flags = (OrderDepotActionFlags)(order->GetDepotActionType() >> 1);
if (((flags & (1 << 2)) != 0) && SlXvIsFeatureMissing(XSLFI_DEPOT_UNBUNCHING)) {
flags ^= (ODATFB_SELL | ODATFB_UNBUNCH); // Unbunch moved from bit 2 to bit 3
}
order->SetDepotActionType(flags);
}
}
if (SlXvIsFeaturePresent(XSLFI_JOKERPP, 1, SL_JOKER_1_23)) {
for (Order *order : Order::Iterate()) {
if (order->IsType(OT_CONDITIONAL) && order->GetConditionVariable() == OCV_SLOT_OCCUPANCY) {
order->GetXDataRef() = order->GetConditionValue();
@@ -2656,15 +2670,15 @@ bool AfterLoadGame()
s->remaining = 12 - s->remaining; // convert "age" to "remaining"
s->awarded = INVALID_COMPANY; // not awarded to anyone
const CargoSpec *cs = CargoSpec::Get(s->cargo_type);
switch (cs->town_effect) {
case TE_PASSENGERS:
case TE_MAIL:
switch (cs->town_acceptance_effect) {
case TAE_PASSENGERS:
case TAE_MAIL:
/* Town -> Town */
s->src_type = s->dst_type = SourceType::Town;
if (Town::IsValidID(s->src) && Town::IsValidID(s->dst)) continue;
break;
case TE_GOODS:
case TE_FOOD:
case TAE_GOODS:
case TAE_FOOD:
/* Industry -> Town */
s->src_type = SourceType::Industry;
s->dst_type = SourceType::Town;
@@ -2682,9 +2696,9 @@ bool AfterLoadGame()
* Town -> Town subsidies are converted using simple heuristic */
s->remaining = 24 - s->remaining; // convert "age of awarded subsidy" to "remaining"
const CargoSpec *cs = CargoSpec::Get(s->cargo_type);
switch (cs->town_effect) {
case TE_PASSENGERS:
case TE_MAIL: {
switch (cs->town_acceptance_effect) {
case TAE_PASSENGERS:
case TAE_MAIL: {
/* Town -> Town */
const Station *ss = Station::GetIfValid(s->src);
const Station *sd = Station::GetIfValid(s->dst);
@@ -3258,12 +3272,12 @@ bool AfterLoadGame()
/* Set the default cargo requirement for town growth */
switch (_settings_game.game_creation.landscape) {
case LT_ARCTIC:
if (FindFirstCargoWithTownEffect(TE_FOOD) != nullptr) t->goal[TE_FOOD] = TOWN_GROWTH_WINTER;
if (FindFirstCargoWithTownAcceptanceEffect(TAE_FOOD) != nullptr) t->goal[TAE_FOOD] = TOWN_GROWTH_WINTER;
break;
case LT_TROPIC:
if (FindFirstCargoWithTownEffect(TE_FOOD) != nullptr) t->goal[TE_FOOD] = TOWN_GROWTH_DESERT;
if (FindFirstCargoWithTownEffect(TE_WATER) != nullptr) t->goal[TE_WATER] = TOWN_GROWTH_DESERT;
if (FindFirstCargoWithTownAcceptanceEffect(TAE_FOOD) != nullptr) t->goal[TAE_FOOD] = TOWN_GROWTH_DESERT;
if (FindFirstCargoWithTownAcceptanceEffect(TAE_WATER) != nullptr) t->goal[TAE_WATER] = TOWN_GROWTH_DESERT;
break;
}
}
@@ -3366,12 +3380,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 done here as the SLV_182 check below needs the blocked status. */
UpdateStationTileCacheFlags(SlXvIsFeatureMissing(XSLFI_STATION_TILE_CACHE_FLAGS));
@@ -3657,6 +3665,23 @@ bool AfterLoadGame()
_old_timetable_start_subticks_map.clear();
}
if (!IsSavegameVersionBefore(SLV_DEPOT_UNBUNCHING)) {
for (Vehicle *v : Vehicle::Iterate()) {
if (v->unbunch_state != nullptr) {
if (v->unbunch_state->depot_unbunching_last_departure > 0) {
v->unbunch_state->depot_unbunching_last_departure += _state_ticks.base() - _tick_counter;
} else {
v->unbunch_state->depot_unbunching_last_departure = INVALID_STATE_TICKS;
}
if (v->unbunch_state->depot_unbunching_next_departure > 0) {
v->unbunch_state->depot_unbunching_next_departure += _state_ticks.base() - _tick_counter;
} else {
v->unbunch_state->depot_unbunching_next_departure = INVALID_STATE_TICKS;
}
}
}
}
if (SlXvIsFeaturePresent(XSLFI_SPRINGPP, 1, 1)) {
/*
* Cost scaling changes:

View File

@@ -164,7 +164,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

@@ -1830,7 +1830,7 @@ void ChunkHandler::LoadCheck(size_t len) const
case CH_TABLE:
case CH_SPARSE_TABLE:
SlTableHeader({});
FALLTHROUGH;
[[fallthrough]];
case CH_ARRAY:
case CH_SPARSE_ARRAY:
SlSkipArray();

View File

@@ -85,7 +85,7 @@ public:
void Load(Town *t) const override
{
size_t length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? (size_t)TE_END : SlGetStructListLength(TE_END);
size_t length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? (size_t)TAE_END : SlGetStructListLength(TAE_END);
for (size_t i = 0; i < length; i++) {
SlObject(&t->received[i], this->GetLoadDescription());
}
@@ -150,12 +150,12 @@ static const SaveLoad _town_desc[] = {
SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_9),
SLE_CONDVAR(Town, supplied[CT_MAIL].new_act, SLE_UINT32, SLV_9, SLV_165),
SLE_CONDVAR(Town, received[TE_FOOD].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVAR(Town, received[TE_WATER].old_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVAR(Town, received[TE_FOOD].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVAR(Town, received[TE_WATER].new_act, SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVARNAME(Town, received[TAE_FOOD].old_act, "received[TE_FOOD].old_act", SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVARNAME(Town, received[TAE_WATER].old_act, "received[TE_WATER].old_act", SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVARNAME(Town, received[TAE_FOOD].new_act, "received[TE_FOOD].new_act", SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDVARNAME(Town, received[TAE_WATER].new_act, "received[TE_WATER].new_act", SLE_UINT16, SL_MIN_VERSION, SLV_165),
SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TE, SLV_165, SL_MAX_VERSION),
SLE_CONDARR(Town, goal, SLE_UINT32, NUM_TAE, SLV_165, SL_MAX_VERSION),
SLE_CONDSSTR(Town, text, SLE_STR | SLF_ALLOW_CONTROL, SLV_168, SL_MAX_VERSION),

View File

@@ -44,6 +44,7 @@ static uint32_t _cargo_source_xy;
static uint16_t _cargo_count;
static uint16_t _cargo_paid_for;
static Money _cargo_feeder_share;
static VehicleUnbunchState _unbunch_state;
class SlVehicleCommon : public DefaultSaveLoadHandler<SlVehicleCommon, Vehicle> {
public:
@@ -180,6 +181,10 @@ public:
SLE_CONDVAR(Vehicle, current_order_time, SLE_FILE_I32 | SLE_VAR_U32, SLV_TIMETABLE_TICKS_TYPE, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, last_loading_tick, SLE_FILE_U64 | SLE_VAR_I64, SLV_LAST_LOADING_TICK, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION),
SLEG_CONDVAR("depot_unbunching_last_departure", _unbunch_state.depot_unbunching_last_departure, SLE_UINT64, SLV_DEPOT_UNBUNCHING, SL_MAX_VERSION),
SLEG_CONDVAR("depot_unbunching_next_departure", _unbunch_state.depot_unbunching_next_departure, SLE_UINT64, SLV_DEPOT_UNBUNCHING, SL_MAX_VERSION),
SLEG_CONDVAR("round_trip_time", _unbunch_state.round_trip_time, SLE_INT32, SLV_DEPOT_UNBUNCHING, SL_MAX_VERSION),
};
#if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916)
return description;
@@ -535,6 +540,11 @@ struct VEHSChunkHandler : ChunkHandler {
v->cargo.Append(cp);
}
if (!IsSavegameVersionBefore(SLV_DEPOT_UNBUNCHING) && _unbunch_state.depot_unbunching_last_departure > 0) {
v->unbunch_state.reset(new VehicleUnbunchState(_unbunch_state));
_unbunch_state = {};
}
#if 0
/* Old savegames used 'last_station_visited = 0xFF' */
if (IsSavegameVersionBefore(SLV_5) && v->last_station_visited == 0xFF) {

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

@@ -24,7 +24,7 @@
/* static */ bool ScriptCargo::IsValidTownEffect(TownEffect towneffect_type)
{
return (towneffect_type >= (TownEffect)TE_BEGIN && towneffect_type < (TownEffect)TE_END);
return (towneffect_type >= (TownEffect)TAE_BEGIN && towneffect_type < (TownEffect)TAE_END);
}
/* static */ std::optional<std::string> ScriptCargo::GetName(CargoID cargo_type)
@@ -66,7 +66,7 @@
{
if (!IsValidCargo(cargo_type)) return TE_NONE;
return (ScriptCargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect;
return (ScriptCargo::TownEffect)::CargoSpec::Get(cargo_type)->town_acceptance_effect;
}
/* static */ Money ScriptCargo::GetCargoIncome(CargoID cargo_type, SQInteger distance, SQInteger days_in_transit)

View File

@@ -43,12 +43,12 @@ public:
*/
enum TownEffect {
/* Note: these values represent part of the in-game TownEffect enum */
TE_NONE = ::TE_NONE, ///< This cargo has no effect on a town
TE_PASSENGERS = ::TE_PASSENGERS, ///< This cargo supplies passengers to a town
TE_MAIL = ::TE_MAIL, ///< This cargo supplies mail to a town
TE_GOODS = ::TE_GOODS, ///< This cargo supplies goods to a town
TE_WATER = ::TE_WATER, ///< This cargo supplies water to a town
TE_FOOD = ::TE_FOOD, ///< This cargo supplies food to a town
TE_NONE = ::TAE_NONE, ///< This cargo has no effect on a town
TE_PASSENGERS = ::TAE_PASSENGERS, ///< This cargo supplies passengers to a town
TE_MAIL = ::TAE_MAIL, ///< This cargo supplies mail to a town
TE_GOODS = ::TAE_GOODS, ///< This cargo supplies goods to a town
TE_WATER = ::TAE_WATER, ///< This cargo supplies water to a town
TE_FOOD = ::TAE_FOOD, ///< This cargo supplies food to a town
};
/**

View File

@@ -38,7 +38,7 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S
case TEXT_TAB_SPECIAL:
if (index < 0xE4) break; // Player name
FALLTHROUGH;
[[fallthrough]];
case TEXT_TAB_TOWN:
if (index < 0xC0) break; // Town name

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

@@ -148,13 +148,13 @@ void CargoCollector::Update(StationID from, StationID via, uint amount)
switch (Tselector) {
case ScriptStationList_Cargo::CS_VIA_BY_FROM:
if (via != this->other_station) return;
FALLTHROUGH;
[[fallthrough]];
case ScriptStationList_Cargo::CS_BY_FROM:
key = from;
break;
case ScriptStationList_Cargo::CS_FROM_BY_VIA:
if (from != this->other_station) return;
FALLTHROUGH;
[[fallthrough]];
case ScriptStationList_Cargo::CS_BY_VIA:
key = via;
break;

View File

@@ -20,7 +20,7 @@ ScriptTownList::ScriptTownList(HSQUIRRELVM vm)
ScriptTownEffectList::ScriptTownEffectList()
{
for (int i = TE_BEGIN; i < TE_END; i++) {
for (int i = TAE_BEGIN; i < TAE_END; i++) {
this->AddItem(i);
}
}

View File

@@ -37,10 +37,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

@@ -315,7 +315,7 @@ static int ParseIntList(const char *p, T *items, size_t maxitems)
/* Do not accept multiple commas between numbers */
if (!comma) return -1;
comma = false;
FALLTHROUGH;
[[fallthrough]];
case ' ':
p++;

View File

@@ -2695,7 +2695,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

@@ -565,7 +565,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

@@ -28,7 +28,7 @@
* @param s Format string.
* @note Function does not return.
*/
void NORETURN CDECL error(const char *s, ...)
[[noreturn]] void CDECL error(const char *s, ...)
{
char buf[1024];
va_list va;

View File

@@ -31,7 +31,7 @@ static_assert((SHIP_PATH_CACHE_LENGTH & SHIP_PATH_CACHE_MASK) == 0, ""); // Must
/**
* All ships have this type.
*/
struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
struct Ship final : public SpecializedVehicle<Ship, VEH_SHIP> {
TrackBits state; ///< The "track" the ship is following.
ShipPathCache cached_path; ///< Cached path.
Direction rotation; ///< Visible direction.

View File

@@ -451,6 +451,9 @@ static bool CheckShipLeaveDepot(Ship *v)
return true;
}
/* Check if we should wait here for unbunching. */
if (v->IsWaitingForUnbunching()) return true;
/* We are leaving a depot, but have to go to the exact same one; re-enter */
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
IsShipDepotTile(v->tile) && GetDepotIndex(v->tile) == v->current_order.GetDestination()) {
@@ -498,8 +501,9 @@ static bool CheckShipLeaveDepot(Ship *v)
v->UpdateViewport(true, true);
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
v->PlayLeaveStationSound();
VehicleServiceInDepot(v);
v->LeaveUnbunchingDepot();
v->PlayLeaveStationSound();
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
DirtyVehicleListWindowForVehicle(v);

View File

@@ -68,6 +68,35 @@ static const TrackdirBits _enterdir_to_trackdirbits[DIAGDIR_END] = {
TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LEFT_S
};
SignalType NextSignalType(SignalType cur, SignalCycleGroups which_signals)
{
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
switch (cur) {
case SIGTYPE_PBS: return SIGTYPE_PBS_ONEWAY;
case SIGTYPE_PBS_ONEWAY: return SIGTYPE_BLOCK;
default: return SIGTYPE_PBS;
}
}
if (which_signals == SCG_CURRENT_GROUP) which_signals = IsPbsSignal(cur) ? SCG_PBS : SCG_BLOCK;
bool pbs = which_signals & SCG_PBS;
bool block = which_signals & SCG_BLOCK;
switch(cur) {
case SIGTYPE_BLOCK: return block ? SIGTYPE_ENTRY : SIGTYPE_PBS;
case SIGTYPE_ENTRY: return block ? SIGTYPE_EXIT : SIGTYPE_PBS;
case SIGTYPE_EXIT: return block ? SIGTYPE_COMBO : SIGTYPE_PBS;
case SIGTYPE_COMBO: return pbs ? SIGTYPE_PBS : SIGTYPE_BLOCK;
case SIGTYPE_PROG: return pbs ? SIGTYPE_PBS : SIGTYPE_BLOCK;
case SIGTYPE_PBS: return pbs ? SIGTYPE_PBS_ONEWAY : SIGTYPE_BLOCK;
case SIGTYPE_PBS_ONEWAY: return block ? SIGTYPE_BLOCK : SIGTYPE_PBS;
case SIGTYPE_NO_ENTRY: return pbs ? SIGTYPE_PBS : SIGTYPE_BLOCK;
default:
DEBUG(map, 0, "Attempt to cycle from signal type %d", cur);
return SIGTYPE_BLOCK; // Fortunately mostly harmless
}
}
/**
* Set containing 'items' items of 'tile and Tdir'
* No tree structure is used because it would cause
@@ -956,7 +985,7 @@ static SigSegState UpdateSignalsInBuffer(Owner owner)
break;
}
}
FALLTHROUGH;
[[fallthrough]];
case MP_RAILWAY:
if (IsRailDepotTile(tile)) {
@@ -965,7 +994,7 @@ static SigSegState UpdateSignalsInBuffer(Owner owner)
_tbdset.Add(tile, INVALID_DIAGDIR); // start from depot inside
break;
}
FALLTHROUGH;
[[fallthrough]];
case MP_STATION:
case MP_ROAD:
@@ -975,7 +1004,7 @@ static SigSegState UpdateSignalsInBuffer(Owner owner)
_tbdset.Add(tile + TileOffsByDiagDir(dir), ReverseDiagDir(dir));
break;
}
FALLTHROUGH;
[[fallthrough]];
default:
/* jump to next tile */

View File

@@ -129,25 +129,7 @@ inline bool IsSignalSpritePBS(SignalType type)
return type >= SIGTYPE_FIRST_PBS_SPRITE;
}
inline SignalType NextSignalType(SignalType cur, uint which_signals)
{
bool pbs = true;
bool block = (which_signals == SIGNAL_CYCLE_ALL);
switch(cur) {
case SIGTYPE_BLOCK: return block ? SIGTYPE_ENTRY : SIGTYPE_PBS;
case SIGTYPE_ENTRY: return block ? SIGTYPE_EXIT : SIGTYPE_PBS;
case SIGTYPE_EXIT: return block ? SIGTYPE_COMBO : SIGTYPE_PBS;
case SIGTYPE_COMBO: return pbs ? SIGTYPE_PBS : SIGTYPE_BLOCK;
case SIGTYPE_PROG: return pbs ? SIGTYPE_PBS : SIGTYPE_BLOCK;
case SIGTYPE_PBS: return pbs ? SIGTYPE_PBS_ONEWAY : SIGTYPE_BLOCK;
case SIGTYPE_PBS_ONEWAY: return block ? SIGTYPE_BLOCK : SIGTYPE_PBS;
case SIGTYPE_NO_ENTRY: return pbs ? SIGTYPE_PBS : SIGTYPE_BLOCK;
default:
DEBUG(map, 0, "Attempt to cycle from signal type %d", cur);
return SIGTYPE_BLOCK; // Fortunately mostly harmless
}
}
SignalType NextSignalType(SignalType cur, SignalCycleGroups which_signals);
/** State of the signal segment */
enum SigSegState {

View File

@@ -66,6 +66,14 @@ enum SignalState {
SIGNAL_STATE_MAX = SIGNAL_STATE_GREEN,
};
/** Signal groups to cycle through. */
enum SignalCycleGroups : uint8_t {
SCG_CURRENT_GROUP = 0,
SCG_BLOCK = 1 << 0,
SCG_PBS = 1 << 1,
};
DECLARE_ENUM_AS_BIT_SET(SignalCycleGroups)
static const int SIGNAL_DIRTY_LEFT = 14 * ZOOM_LVL_BASE;
static const int SIGNAL_DIRTY_RIGHT = 14 * ZOOM_LVL_BASE;
static const int SIGNAL_DIRTY_TOP = 30 * ZOOM_LVL_BASE;

View File

@@ -522,7 +522,7 @@ struct SignWindow : Window, SignList {
case WID_QES_OK:
if (RenameSign(this->cur_sign, this->name_editbox.text.buf)) break;
FALLTHROUGH;
[[fallthrough]];
case WID_QES_CANCEL:
this->Close();

View File

@@ -196,7 +196,7 @@ void AfterLoadCompanyStats()
}
}
}
FALLTHROUGH;
[[fallthrough]];
case MP_OBJECT:
if (GetWaterClass(tile) == WATER_CLASS_CANAL) {

View File

@@ -209,6 +209,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_NEWGRF_LAST_SERVICE, XSCF_NULL, 1, 1, "slv_newgrf_last_service", nullptr, nullptr, nullptr },
{ XSLFI_CARGO_TRAVELLED, XSCF_NULL, 1, 1, "slv_cargo_travelled", nullptr, nullptr, nullptr },
{ XSLFI_SHIP_ACCELERATION, XSCF_NULL, 1, 1, "slv_ship_acceleration", nullptr, nullptr, nullptr },
{ XSLFI_DEPOT_UNBUNCHING, XSCF_NULL, 1, 1, "slv_depot_unbunching", nullptr, nullptr, "VUBS" },
{ XSLFI_TABLE_PATS, XSCF_NULL, 1, 1, "table_pats", nullptr, nullptr, nullptr },
{ XSLFI_TABLE_MISC_SL, XSCF_NULL, 1, 1, "table_misc_sl", nullptr, nullptr, nullptr },

View File

@@ -158,6 +158,7 @@ enum SlXvFeatureIndex {
XSLFI_NEWGRF_LAST_SERVICE, ///< See: SLV_NEWGRF_LAST_SERVICE (PR #11124)
XSLFI_CARGO_TRAVELLED, ///< See: SLV_CARGO_TRAVELLED (PR #11283)
XSLFI_SHIP_ACCELERATION, ///< See: SLV_SHIP_ACCELERATION (PR #10734)
XSLFI_DEPOT_UNBUNCHING, ///< See: SLV_DEPOT_UNBUNCHING (PR #11945)
XSLFI_TABLE_PATS, ///< Use upstream table format for PATS
XSLFI_TABLE_MISC_SL, ///< Use upstream table format for miscellaneous chunks, so far: DATE, VIEW, MAPS

View File

@@ -600,10 +600,10 @@ static const OldChunks town_chunk[] = {
OCL_NULL( 2 ), ///< pct_pass_transported / pct_mail_transported, now computed on the fly
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].new_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].new_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_FOOD].old_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TE_WATER].old_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_FOOD].new_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_WATER].new_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_FOOD].old_act ),
OCL_SVAR( OC_TTD | OC_UINT16, Town, received[TAE_WATER].old_act ),
OCL_SVAR( OC_UINT8, Town, road_build_months ),
OCL_SVAR( OC_UINT8, Town, fund_buildings_months ),

View File

@@ -412,7 +412,7 @@ struct ThreadSlErrorException {
* @note This function does never return as it throws an exception to
* break out of all the saveload code.
*/
void NORETURN SlError(StringID string, std::string extra_msg)
[[noreturn]] void SlError(StringID string, std::string extra_msg)
{
if (IsNonMainThread() && IsNonGameThread() && _sl.action != SLA_SAVE) {
throw ThreadSlErrorException{ string, std::move(extra_msg) };
@@ -442,7 +442,7 @@ void NORETURN SlError(StringID string, std::string extra_msg)
/**
* As SlError, except that it takes a format string and additional parameters
*/
void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...)
[[noreturn]] void CDECL SlErrorFmt(StringID string, const char *msg, ...)
{
va_list va;
va_start(va, msg);
@@ -458,7 +458,7 @@ void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...)
* @note This function does never return as it throws an exception to
* break out of all the saveload code.
*/
void NORETURN SlErrorCorrupt(std::string msg)
[[noreturn]] void SlErrorCorrupt(std::string msg)
{
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, std::move(msg));
}
@@ -470,7 +470,7 @@ void NORETURN SlErrorCorrupt(std::string msg)
* @note This function does never return as it throws an exception to
* break out of all the saveload code.
*/
void NORETURN CDECL SlErrorCorruptFmt(const char *format, ...)
[[noreturn]] void CDECL SlErrorCorruptFmt(const char *format, ...)
{
va_list va;
va_start(va, format);

View File

@@ -1067,7 +1067,7 @@ inline void SlLoadTableOrRiffFiltered(const NamedSaveLoadTable &slt)
SlLoadTableOrRiffFiltered(SlTableHeaderOrRiff(slt));
}
void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3);
[[noreturn]] void CDECL SlErrorFmt(StringID string, const char *msg, ...) WARN_FORMAT(2, 3);
bool SaveloadCrashWithMissingNewGRFs();

View File

@@ -385,6 +385,7 @@ enum SaveLoadVersion : uint16_t {
SLV_CALENDAR_SUB_DATE_FRACT, ///< 328 PR#11428 Add sub_date_fract to measure calendar days.
SLV_SHIP_ACCELERATION, ///< 329 PR#10734 Start using Vehicle's acceleration field for ships too.
SLV_MAX_LOAN_FOR_COMPANY, ///< 330 PR#11224 Separate max loan for each company.
SLV_DEPOT_UNBUNCHING, ///< 331 PR#11945 Allow unbunching shared order vehicles at a depot.
SL_MAX_VERSION, ///< Highest possible saveload version
@@ -429,9 +430,9 @@ void SlSkipBytes(size_t length);
size_t SlGetBytesRead();
size_t SlGetBytesWritten();
void NORETURN SlError(StringID string, std::string extra_msg = {});
void NORETURN SlErrorCorrupt(std::string msg);
void NORETURN CDECL SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2);
[[noreturn]] void SlError(StringID string, std::string extra_msg = {});
[[noreturn]] void SlErrorCorrupt(std::string msg);
[[noreturn]] void CDECL SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2);
bool SaveLoadFileTypeIsScenario();

Some files were not shown because too many files have changed in this diff Show More