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:
282
changelog.txt
282
changelog.txt
@@ -1,3 +1,285 @@
|
||||
14.0-beta1 (2023-02-03)
|
||||
------------------------------------------------------------------------
|
||||
Feature: Order option to unbunch vehicles at depot (#11945)
|
||||
Feature: Infinite money mode (#11902)
|
||||
Feature: Setting to disable the loading speed penalty for trains longer than the station (#11682)
|
||||
Feature: Plugin framework for Social Integration with Steam, Discord, GOG, etc (#11628)
|
||||
Feature: Scalable OpenTTD TrueType font made by Zephyris (#11593)
|
||||
Feature: Toyland-specific river graphics (#11523)
|
||||
Feature: Add zoom level buttons to sprite aligner (#11518)
|
||||
Feature: Add shading to river slopes (#11491)
|
||||
Feature: Place cargo icon on cargo filter dropdowns (#11487)
|
||||
Feature: Mode to display timetable in seconds (#11435)
|
||||
Feature: Setting to influence how many minutes a calendar year takes (#11428)
|
||||
Feature: Base graphics can offer parameters for additional settings (#11347)
|
||||
Feature: Sandbox option to lock station ratings at 100% (#11346)
|
||||
Feature: Setting to use real-time "wallclock" as timekeeping units (#11341)
|
||||
Feature: Setting to automatically restart server based on hours played (#11142)
|
||||
Feature: Add config option to set default company secondary colour for new games (#11068)
|
||||
Feature: Transparency option for cost and income indicators (#11001)
|
||||
Feature: Create group of vehicles from manage vehicle list button (#10890)
|
||||
Feature: Show coverage highlight the same as stations when adding waypoints (#10875)
|
||||
Feature: Show the number of industries already built in the Fund New Industry window (#10806)
|
||||
Feature: Add search filter and name text to build waypoint window (#10786)
|
||||
Feature: Setting to disallow level crossings with competitors (#10755)
|
||||
Feature: Opt-in survey when leaving a game (#10719)
|
||||
Feature: Replace buying/selling company shares with hostile takeovers of AI companies (#10709, #10914)
|
||||
Feature: Settings to scale cargo production of towns and industries (#10606)
|
||||
Feature: Separate rail/road and sea/air velocity units, and add knots (#10594)
|
||||
Feature: Region-based pathfinder for ships (#10543)
|
||||
Feature: Filter engine build menu by name and NewGRF extra text (#10519)
|
||||
Feature: Industry directory text filter (#10518)
|
||||
Feature: Ctrl+Click to reset late counter for the entire vehicle group (#10464)
|
||||
Feature: Orientation of rail and road depots can be changed (#9642)
|
||||
Feature: Display help and manuals in-game (#7786)
|
||||
Feature: [NewGRF] Town production effect and multiplier (#11947)
|
||||
Feature: [NewGRF] Randomize direction of rail vehicle on build based on probability callback (#11489)
|
||||
Feature: [NewGRF] Related Act2 objects for airports and airport tiles (#11282)
|
||||
Feature: [NewGRF] Allow higher max speeds for ships (#10734)
|
||||
Feature: [NewGRF] Increase limit of objects/stations/roadstops per NewGRF (#10672)
|
||||
Feature: [NewGRF] Road stops (#10144)
|
||||
Feature: [Script] Goal destination can be updated (#10817)
|
||||
Add: Argument for console command "restart" to use either current or newgame settings (#11962, #11963)
|
||||
Add: {CURRENCY_SHORT} only did k / m suffix. Add bn / tn and make translatable (#11921)
|
||||
Add: Show in multiplayer the amount of hours a game has been unpaused (#11886)
|
||||
Add: Allow loading heightmaps from command-line (#11870)
|
||||
Add: List_[scenario|heightmap] and load_[scenario|height] console commands (#11867)
|
||||
Add: Latvian Lats currency (#11691)
|
||||
Add: Horizontal scroll for script debug log (#11597)
|
||||
Add: GUI options to select sprite font and AA mode for all fonts (#11593)
|
||||
Add: Website button for basesets in Game Options window, the Game Script settings window and AI settings window (#11512)
|
||||
Add: [Emscripten] Support for bootstrapping (#11109)
|
||||
Add: Hotkey to focus town / industry directory filter box (#11030)
|
||||
Add: Maximum number of companies allowed to the client list (#10523)
|
||||
Add: Use specific error message when vehicle cannot go to station/waypoint (#10494)
|
||||
Add: Show NewGRF name in NewGRF-created errors (#10457)
|
||||
Add: Alternative setting for right-click close window option to exclude pinned windows (#10204)
|
||||
Add: Allow autoreplace with same model vehicle (#7729)
|
||||
Add: [NewGRF] Allow inspection of road tiles and airports (#11282, #11323)
|
||||
Add: [NewGRF] Station variable 6B to get extended station id of nearby tiles (#10953)
|
||||
Add: [NewGRF] String code "9A 21" to display force from textstack (#10782)
|
||||
Add: [NewGRF] Station property 1C/1D to set name/classname (#10672)
|
||||
Add: [Script] Optional filter parameter to ScriptXXXList constructors (#11698,#11663)
|
||||
Add: [Script] AI/GS Time Mode to choose between economy (default) and calendar time (#11603)
|
||||
Add: [Script] Allow to set max loan for each company separately (#11224)
|
||||
Add: [Script] GSIndustry.GetConstructionDate() method (#11145)
|
||||
Add: [Script] Game script control of industry production level and news messages (#11141)
|
||||
Add: [Script] GSAsyncMode to set async mode of gamescript commands (#10913)
|
||||
Add: [Script] GSCompanyMode::IsValid and IsDeity, and enforce valid company/deity mode where applicable (#10536, #10529)
|
||||
Add: [Script] Allow GS to found town with random road layout (#10442)
|
||||
Add: [Script] Create own Randomizer per instance (#10349)
|
||||
Change: Better handle different GUI sizes for most windows, and squash inconsistencies between windows
|
||||
Change: Allow configuring AI slots above the current maximum number of competitors (#11961)
|
||||
Change: Forcefully enable prefixing logs with date (#11930)
|
||||
Change: Position error window closer to cursor on large screens (#11923)
|
||||
Change: Only open story-book in center when a GS does it (#11916)
|
||||
Change: Rebrand Cheats as Sandbox Options (#11874)
|
||||
Change: Make smooth-scrolling based on actual time (#11865)
|
||||
Change: Set smooth-scrolling on by default (#11860)
|
||||
Change: Disable building rail infrastructure if train build limit is zero (#11847)
|
||||
Change: Invalidate music volume when restarting music playback on Windows (#11836)
|
||||
Change: Make street lights transparent with houses (#11828)
|
||||
Change: Redesign script debug window (#11782)
|
||||
Change: Reorganize Settings menu items (#11683)
|
||||
Change: Set amount of smoke/sparks to "realistic" by default (#11624)
|
||||
Change: Show a message in livery window if vehicle type has no groups (#11617)
|
||||
Change: Add distinct tooltips for vehicle group colour schemes (#11617)
|
||||
Change: Move colour selection dropdowns to bottom of window (#11617)
|
||||
Change: Support custom transparency remaps with 32bpp blitters (#11616)
|
||||
Change: Make "middle" the default stopping location for trains in platforms (#11605)
|
||||
Change: Scale sprites to requested highest resolution level (#11600)
|
||||
Change: Allow opening multiple script debug windows by holding Ctrl (#11592)
|
||||
Change: Don't show scoring year in high score table (#11546)
|
||||
Change: Revert pressed-button content shifting introduced in r2161 (#11542)
|
||||
Change: Show rating in station list even with no cargo waiting (#11540)
|
||||
Change: Hide unused cargos from vehicle cargo filter (#11533)
|
||||
Change: Don't restart playback when toggling playlist shuffle (#11504)
|
||||
Change: Increase finance window lines (and underlines) with interface scale (#11459)
|
||||
Change: Move baseset missing/corrupted files label to list item (#11455)
|
||||
Change: Add horizontal scrollbar to Industry Directory window (#11434)
|
||||
Change: Improve layout of airport, dock, object, road/tram stop, train station pickers (#11430)
|
||||
Change: Display cargo lists in sorted cargo order (#11383)
|
||||
Change: Link houses production on industry chain graph by TPE_PASSENGERS or TPE_MAIL cargo (#11378)
|
||||
Change: Passenger subsidies are generated for any TPE_PASSENGER cargo type (#11378)
|
||||
Change: Towns generate cargo based on town production effect (#11378)
|
||||
Change: Always allow expanding towns in Scenario Editor to build new roads (#11377)
|
||||
Change: Don't set vehicle on time if timetable not started (#11359)
|
||||
Change: Store station blocked/wires/pylons flags in map (#11337)
|
||||
Change: Recover when possible from crashes during a crash (#11238)
|
||||
Change: Store crash logs in JSON format (#11232)
|
||||
Change: Remove autosave from settings window; it is already in the Game Options (#11218)
|
||||
Change: Enable "Forbid 90 degree turns" setting by default (#11160)
|
||||
Change: Do not allow mixing road/tram types in powered road type list (#11148)
|
||||
Change: Only show platform stopping location in orders when other than default (#11102)
|
||||
Change: Autorail / autoroad tools can start dragging from invalid tiles (#11089)
|
||||
Change: Only allow buying Exclusive Transport Rights when no one has them (#11076)
|
||||
Change: Remove currency code/symbol suffix from language files (#11061)
|
||||
Change: Add separate setting for server sent commands per frame limit (#11023)
|
||||
Change: Cargo flow legend only shows defined cargo (#10872)
|
||||
Change: Use "Via-Destination-Source" as default station cargodist display (#10851)
|
||||
Change: Preserve orders and related settings where possible when moving engines around in a train (#10799)
|
||||
Change: Standardise unit conversions and allow decimal places (#10795)
|
||||
Change: Use separate names for default stations/roadstops (#10786)
|
||||
Change: [MacOS] Require at least 10.15 to run the game (#10745)
|
||||
Change: Hide all variants from UI when (display) parent is hidden (#10708)
|
||||
Change: Split Game options into General, Graphics and Sound tabs (#10674)
|
||||
Change: Extend entity override manager and station spec lists to support 16 bit IDs (#10672)
|
||||
Change: Base autosaves intervals on real time (instead of game time) (#10655)
|
||||
Change: Allow overbuilding station and waypoint tiles (#10618)
|
||||
Change: Use realtime for Linkgraph update settings (#10610)
|
||||
Change: Make tick length 27 milliseconds (#10607)
|
||||
Change: Increase max cargo age and let min cargo payment approach zero (#10596)
|
||||
Change: Show buy company dialog window even when playing in the AI company (#10459)
|
||||
Change: Use HTTPS for content-service connections (#10448)
|
||||
Change: Big UFO disaster targets current location of a random train (#10290)
|
||||
Change: Remove land generator setting from World Generation GUI (#10093)
|
||||
Change: Build signals to the next junction when dragging regardless of the Ctrl state (#9637)
|
||||
Change: Allow dedicated server to use threaded saves (#10787)
|
||||
Change: [NewGRF] Increase vehicle random data from 8 to 16 bits (#10701)
|
||||
Change: [NewGRF] Read Action 3 IDs as extended-bytes for all features (#10672)
|
||||
Change: [NewGRF] Make Action 3 debug messages more consistent (#10672)
|
||||
Change: [NewGRF] Extend callback 161 (engine name) with bit 0x22 for context 'Autoreplace - Vehicles in use' (#10666)
|
||||
Change: [Script] Replace easy/medium/hard values with default value (#11959)
|
||||
Change: [Script] Limit total script ops that can be consumed by a list valuate (#11670)
|
||||
Change: [Script] Allow GS access to ScriptGroup, ScriptGameSettings.IsDisabledVehicleType, more ScriptCompany and more ScriptOrder functions (#10642)
|
||||
Change: [Script] Improve ScriptText validation error messages (#10545)
|
||||
Change: [Script] Restore support of {RAW_STRING} in ScriptText (#10492)
|
||||
Change: [Script] Validate ScriptText parameters type and amount (#10492)
|
||||
Change: [Script] Automate the ScriptObject reference counting (#10492)
|
||||
Change: [Script] Extract params info from GS strings (#10492)
|
||||
Change: [Script] A ScriptText with too many parameters is now a fatal error (#10483)
|
||||
Change: [Script] Log AI/GS Squirrel crashes in white text for readability (#10375)
|
||||
Fix #11918: Houses should only build next to road stops, not any station type (#11919)
|
||||
Fix #11827: Make text layouter aware of ligatures (#11831)
|
||||
Fix #11752: Characters could be repeated when wrapping multi-line text (#11761)
|
||||
Fix #11748: Decreasing service interval value sufficiently would result in it wrapping around (#11749)
|
||||
Fix #11629: Crash when getting the nearest town for rotated airports (#11631)
|
||||
Fix #11516: Adjust window size by interface scale during ReInit (#11517)
|
||||
Fix #11515: Changing interface scale could have unintended effects on zoom level (#11615)
|
||||
Fix #11442: "Default" colour in group colour window is not updated when changing master colour (#11614)
|
||||
Fix #11437: Flipped shorter rail vehicles disappear in windows (#11446)
|
||||
Fix #11413: Incorrect sorting by industry production (#11414)
|
||||
Fix #11407: Don't steal focus from dropdown menus (#11484)
|
||||
Fix #11402: Make string filter locale-aware (#11426)
|
||||
Fix #11329: Don't assert vehicle list length is non-zero when only asked to set string parameter (#11330)
|
||||
Fix #11315: Sort industries and cargoes by name in industry chain window (#11317)
|
||||
Fix #11307: Incorrect GroupStatistics after selling leading wagon (#11311)
|
||||
Fix #11261: Airport menu selectability after closing window on a class with no available airports (#11344)
|
||||
Fix #11230: Sort by button in group list window could be misaligned (#11231)
|
||||
Fix #11215: Assert in NewGRF parameters window (manual parameter mode) (#11217)
|
||||
Fix #11203: [Linux] Crash when editing CJK characters in edit box (#11204)
|
||||
Fix #11180: Aircraft crashes could point to the wrong tile (#11184)
|
||||
Fix #11164: Don't create duplicate town names when using 'Many random towns' in the scenario editor (#11165)
|
||||
Fix #11162: Second company colour was not consistently applied to articulated vehicles (#11163)
|
||||
Fix #11115: Focus the abandon game/exit game windows (#11125)
|
||||
Fix #11096: Increase priority of error and confirmation windows (#11104)
|
||||
Fix #11087: Disable base graphics/sound dropdown outside main menu (#11091)
|
||||
Fix #11054: Prevent translation of currency codes (#11061)
|
||||
Fix #11026: Use real engine name instead of default name for filtering (#11033)
|
||||
Fix #10982: No help text for gamelog command (#10984)
|
||||
Fix #10880: Crash in object window due to incorrect parameter order (#10881)
|
||||
Fix #10868: Crash when Script tries to load large savegame data (#11029)
|
||||
Fix #10811: Allow dragging vehicle in depot to any free row (#11508)
|
||||
Fix #10660: Sprite Font scale affected by viewport zoom level limits (#10668)
|
||||
Fix #10619: Crash loading linkgraph for older savegames (#10620)
|
||||
Fix #10600: 'Replace Vehicles' didn't show numbers >999 (#10680)
|
||||
Fix #10578: Allow to select any version of AI/GS from GUI (#10604)
|
||||
Fix #10522: Link graph tooltip vertical lines were not handled correctly (#10524)
|
||||
Fix #10511: Don't search for depot every tick if one cannot be found (#11548)
|
||||
Fix #10478: Clarify airport noise control setting texts (#11169)
|
||||
Fix #10452: Prevent long stalls during river generation (#11544)
|
||||
Fix #10430: Display chain window causing assert (#10431)
|
||||
Fix #10343: Don't extend town-disallowed roadtypes (#10347)
|
||||
Fix #10251: [MacOS] Screen looks blue-ish when using newer SDKs (#11207)
|
||||
Fix #10222: Adjust line drawing algorithm (#10491)
|
||||
Fix #10131: Actually cancel downloads when pressing cancel (#10485)
|
||||
Fix #10118: Cycle through current signal group, not just path signals (#11798)
|
||||
Fix #10439: [Script] Validate story page button colour, flags, cursor and vehicle type (#11892)
|
||||
Fix #10438: [Script] Validate story page element type for ScriptStoryPage::NewElement (#11888)
|
||||
Fix #9865: Removing files with the console always failed
|
||||
Fix #9810: Rebuilding a through road stop costs money (#9852)
|
||||
Fix #9722: Crash when pressing hotkeys early in world generation (#11858)
|
||||
Fix #9697: Limit the default width of the Online Players window (#11936)
|
||||
Fix #9642: Keep infrastructure totals when overbuilding road depots (#11229)
|
||||
Fix #9545: Crash when all cargo types are disabled (#11432)
|
||||
Fix #8846: When upgrading NewGRF presets, copy NewGRF parameters only if the NewGRF are compatible (#11348)
|
||||
Fix #8253: Improve profit graph when having lots of money (#11915)
|
||||
Fix #6377: Two tarballs with the same folder in them were considered as one (#11855)
|
||||
Fix #5713: Ships could be sent to unreachable depots (#11768)
|
||||
Fix #4575: Use Latin 'l' in English translation of zloty (#11090)
|
||||
Fix #4415: Land info build date is also renovation date (#11759)
|
||||
Fix: Display rank correctly with more than 15 companies in a league table (#11940)
|
||||
Fix: Extra refit button when train/RV is in a depot (#11904)
|
||||
Fix: Update server listing as offline when unexpected disconnect during refresh (#11891)
|
||||
Fix: Horizontal scale of framerate window switched excessively (#11813)
|
||||
Fix: [Linux] Various issues with resolutions and fullscreen in multi-display setups (#11778, #11779)
|
||||
Fix: Build button text when train purchase window using "Engines" filter (#11755)
|
||||
Fix: One-way state remained after removing road from road and tram tile (#11745)
|
||||
Fix: Draw video driver info at the correct size and text wrap (#10716)
|
||||
Fix: Language genders could not be applied to SCC_INDUSTRY_NAME (#11697)
|
||||
Fix: Spurious cancellations of HTTP content downloads (#11668)
|
||||
Fix: Calculation of initial engine age was inaccurate (#11660)
|
||||
Fix: Prevent underflow if engine base life is less than 8 years (#11635)
|
||||
Fix: Changing default livery did not propagate to group liveries (#11633)
|
||||
Fix: Window width/height was doubly-scaled with automatic DPI switch (#11598)
|
||||
Fix: Don't crash when saving a crashlog save with no main window open (#11586)
|
||||
Fix: Prevent overflow when calculating max town noise (#11564)
|
||||
Fix: Deleting towns did not check for waypoints referencing the town (#11513)
|
||||
Fix: Invalidate playlist window when (un)shuffling playlist (#11504)
|
||||
Fix: Restore original cargo legend 'blob' dimensions (#11480)
|
||||
Fix: Extmidi did not move on to next song after playing ends (#11469)
|
||||
Fix: Server password length in the UI was unnecessarily limited (#11408)
|
||||
Fix: OpenTTD can fail to exit on an error due to mutex locks in threads (#11398)
|
||||
Fix: Scale minimum width for server name by interface scale (#11381)
|
||||
Fix: Server connection was not closed when relay window was closed (#11366)
|
||||
Fix: Upgrading NewGRF presets could result in incomplete display of NewGRF parameters until restart (#11348)
|
||||
Fix: Check for engine variant loops during NewGRF initialization (#11343)
|
||||
Fix: Don't allow industries to produce invalid cargo (#11314)
|
||||
Fix: Also apply cargo filters on shared groups in vehicle listing (#11294)
|
||||
Fix: Only count distance traveled in vehicles for cargo payment (#11283)
|
||||
Fix: Base cargo payment on load/unload tile, instead of station sign location (#11281)
|
||||
Fix: Crash when opening a damaged base-graphics (#11275)
|
||||
Fix: Trivial autoreplace of mixed cargo articulated engines (#11253)
|
||||
Fix: [Emscripten] Config not saved on exit (#11248)
|
||||
Fix: Inaccurate waiting cargo total in station window when using cargodist (#11213)
|
||||
Fix: No fast forward in network was ensured only from GUI side (#11206)
|
||||
Fix: Crash when not passing command-line parameter for -n (#11153)
|
||||
Fix: [Bootstrap] Don't crash when failing to connect to content server (#11122)
|
||||
Fix: Crash when failing to load a game into a dedicated server at startup (#11021)
|
||||
Fix: Don't allow changing settings over the network that are marked as local settings (#11009)
|
||||
Fix: Move no_http_content_downloads and use_relay_service to private settings (#10762)
|
||||
Fix: Extra viewport could not be scrolled with right-click-close (#10644)
|
||||
Fix: Specify units for value of share trading age setting (#10612)
|
||||
Fix: Road type is not available before its introduction date (#10585)
|
||||
Fix: Do not update a RV's Z-position when stationary while turning (#10570)
|
||||
Fix: Don't (briefly) switch from title-only playlist on menu screen (#10553)
|
||||
Fix: Reset content download progress to zero if falling back to TCP (#10485)
|
||||
Fix: Make script goals work with the whole range of ClientIDs (#10435)
|
||||
Fix: [NewGRF] Tile slope missing from road stops varact2 variable 0x42 (#11373)
|
||||
Fix: [NewGRF] House class mappings were not reset between games (#11279)
|
||||
Fix: [NewGRF] Profile didn't stop if there were no events yet (#10816)
|
||||
Fix: [NewGRF] Support more than 256 stations/waypoints/roadstops per class (#10793)
|
||||
Fix: [NewGRF] Var68 for station and roadstop was broken (#10784)
|
||||
Fix: [NewGRF] Object and road stop ignore property handlers (#10525)
|
||||
Fix: [Script] Apply random deviation to settings only at script start (#11944)
|
||||
Fix: [Script] Improve ScriptText validation (#11721)
|
||||
Fix: [Script] GSAdmin.Send() could generate invalid JSON (#11250)
|
||||
Fix: [Script] Crash if squirrel compatibility scripts cannot be parsed (#11589)
|
||||
Fix: [Script] Don't list unavailable road types for game scripts (#10585)
|
||||
Fix: [Script] Game scripts were able to build with non-existing road types (#10539)
|
||||
Fix: [Script] Inconsistent precondition failure return values (#10533)
|
||||
Fix: [Script] Crash when companies disappear (#10529)
|
||||
Fix: [Script] ScriptBase::Rand() return value could return negative values (#10443)
|
||||
Fix: [Script] Incorrect value for GOAL_INVALID (#10436)
|
||||
Fix: [Script] Extend Script::IsValidVehicle to check for primary vehicles (#10386)
|
||||
Remove: "generation_seed" from config, as it was a write-only value (#11927)
|
||||
Remove: Debug redirect over network (#11776)
|
||||
Remove: Officially mark Vista as no longer supported (#11531)
|
||||
Remove: OS/2 and SunOS ports (#11018, #11210)
|
||||
Remove: Obsolete NewGRF text unprinting (#10884)
|
||||
Remove: [Script] CONFIG_RANDOM from AddSetting flags (#11942)
|
||||
|
||||
|
||||
13.4 (2023-07-29)
|
||||
------------------------------------------------------------------------
|
||||
Fix: Setting tree lines drawn incorrectly for RTL languages (#11070)
|
||||
|
32
src/3rdparty/squirrel/squirrel/sqcompiler.cpp
vendored
32
src/3rdparty/squirrel/squirrel/sqcompiler.cpp
vendored
@@ -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;
|
||||
}
|
||||
}
|
||||
|
7
src/3rdparty/squirrel/squirrel/sqcompiler.h
vendored
7
src/3rdparty/squirrel/squirrel/sqcompiler.h
vendored
@@ -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_
|
||||
|
@@ -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;
|
||||
}
|
||||
|
7
src/3rdparty/squirrel/squirrel/sqfuncstate.h
vendored
7
src/3rdparty/squirrel/squirrel/sqfuncstate.h
vendored
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
8
src/3rdparty/squirrel/squirrel/sqlexer.cpp
vendored
8
src/3rdparty/squirrel/squirrel/sqlexer.cpp
vendored
@@ -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()
|
||||
|
6
src/3rdparty/squirrel/squirrel/sqlexer.h
vendored
6
src/3rdparty/squirrel/squirrel/sqlexer.h
vendored
@@ -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
|
||||
|
10
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
10
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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:
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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());
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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())
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -886,7 +886,7 @@ public:
|
||||
/* We reset the files filtered */
|
||||
this->OnInvalidateData(SLIWD_FILTER_CHANGES);
|
||||
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
case SLIWD_SELECTION_CHANGES:
|
||||
/* Selection changes */
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
|
@@ -898,7 +898,7 @@ public:
|
||||
return ES_HANDLED;
|
||||
}
|
||||
/* space is pressed and filter is focused. */
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
default:
|
||||
return ES_NOT_HANDLED;
|
||||
|
@@ -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();
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -184,7 +184,7 @@ struct ObjectResolverObject : public ResolverObject {
|
||||
case VSG_SCOPE_PARENT: {
|
||||
TownScopeResolver *tsr = this->GetTown();
|
||||
if (tsr != nullptr) return tsr;
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
default:
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ struct StationResolverObject : public ResolverObject {
|
||||
case VSG_SCOPE_PARENT: {
|
||||
TownScopeResolver *tsr = this->GetTown();
|
||||
if (tsr != nullptr) return tsr;
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
||||
default:
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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. */
|
||||
|
@@ -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;
|
||||
|
@@ -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. */
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -237,7 +237,7 @@ void ShowOSErrorBox(const char *buf, bool)
|
||||
}
|
||||
}
|
||||
|
||||
void NORETURN DoOSAbort()
|
||||
[[noreturn]] void DoOSAbort()
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
{
|
||||
|
@@ -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:
|
||||
|
@@ -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"),
|
||||
|
@@ -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();
|
||||
|
@@ -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),
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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
|
||||
|
@@ -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).
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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 */
|
||||
|
@@ -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++;
|
||||
|
@@ -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"));
|
||||
|
@@ -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
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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();
|
||||
|
@@ -196,7 +196,7 @@ void AfterLoadCompanyStats()
|
||||
}
|
||||
}
|
||||
}
|
||||
FALLTHROUGH;
|
||||
[[fallthrough]];
|
||||
|
||||
case MP_OBJECT:
|
||||
if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
|
||||
|
@@ -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 },
|
||||
|
@@ -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
|
||||
|
@@ -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 ),
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user