Merge branch 'master' into jgrpp
# Conflicts: # CMakeLists.txt # cmake/CompileFlags.cmake # src/bridge_gui.cpp # src/saveload/afterload.cpp # src/saveload/saveload.cpp # src/saveload/saveload.h # src/saveload/town_sl.cpp # src/screenshot.cpp # src/screenshot.h # src/toolbar_gui.cpp # src/town.h # src/town_cmd.cpp
This commit is contained in:
@@ -7,6 +7,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
endif (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9)
|
||||
|
||||
# Use GNUInstallDirs to allow customisation
|
||||
# but set our own default data dir
|
||||
@@ -31,19 +32,20 @@ find_package(ZLIB)
|
||||
find_package(LibLZMA)
|
||||
find_package(LZO)
|
||||
find_package(PNG)
|
||||
|
||||
if (NOT WIN32)
|
||||
find_package(Allegro)
|
||||
if (NOT APPLE)
|
||||
find_package(SDL2)
|
||||
if (NOT SDL2_FOUND)
|
||||
find_package(SDL)
|
||||
endif( NOT SDL2_FOUND)
|
||||
find_package(Allegro)
|
||||
find_package(Fluidsynth)
|
||||
find_package(Freetype)
|
||||
find_package(Fontconfig)
|
||||
find_package(ICU OPTIONAL_COMPONENTS i18n lx)
|
||||
find_package(XDG_basedir)
|
||||
endif (NOT WIN32)
|
||||
if (APPLE)
|
||||
else (NOT APPLE)
|
||||
find_package(Iconv)
|
||||
|
||||
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
|
||||
@@ -51,7 +53,8 @@ if (APPLE)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
|
||||
find_package(MacUcontext)
|
||||
endif (APPLE)
|
||||
endif (NOT APPLE)
|
||||
endif (NOT WIN32)
|
||||
|
||||
if (MSVC)
|
||||
find_package(Editbin REQUIRED)
|
||||
|
@@ -31,8 +31,13 @@ macro(compile_flags)
|
||||
# it does not appear to support the $<> tags.
|
||||
add_compile_options(
|
||||
"$<$<CONFIG:Debug>:-D_DEBUG>"
|
||||
"$<$<CONFIG:Debug>:-D_FORTIFY_SOURCE=2>"
|
||||
"$<$<NOT:$<CONFIG:Debug>>:-D_FORTIFY_SOURCE=2>" # FORTIFY_SOURCE should only be used in non-debug builds (requires -O1+)
|
||||
)
|
||||
if (MINGW)
|
||||
add_link_options(
|
||||
"$<$<NOT:$<CONFIG:Debug>>:-fstack-protector>" # Prevent undefined references when _FORTIFY_SOURCE > 0
|
||||
)
|
||||
endif (MINGW)
|
||||
|
||||
# Prepare a generator that checks if we are not a debug, and don't have asserts
|
||||
# on. We need this later on to set some compile options for stable releases.
|
||||
@@ -73,14 +78,34 @@ macro(compile_flags)
|
||||
add_compile_options(-O2 -DNDEBUG)
|
||||
endif(NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
#add_compile_options(
|
||||
# When we are a stable release (Release build + USE_ASSERTS not set),
|
||||
# assertations are off, which trigger a lot of warnings. We disable
|
||||
# these warnings for these releases.
|
||||
#"$<${IS_STABLE_RELEASE}:-Wno-unused-variable>"
|
||||
#"$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-parameter>"
|
||||
#"$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-variable>"
|
||||
#)
|
||||
#if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# add_compile_options(
|
||||
# "$<${IS_STABLE_RELEASE}:-Wno-unused-variable>"
|
||||
# "$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-parameter>"
|
||||
# "$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-variable>"
|
||||
# )
|
||||
#else (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# add_compile_options(
|
||||
# "$<${IS_STABLE_RELEASE}:-Wno-unused-variable>"
|
||||
# "$<${IS_STABLE_RELEASE}:-Wno-unused-parameter>"
|
||||
# )
|
||||
#endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
|
||||
# Ninja processes the output so the output from the compiler
|
||||
# isn't directly to a terminal; hence, the default is
|
||||
# non-coloured output. We can override this to get nicely
|
||||
# coloured output, but since that might yield odd results with
|
||||
# IDEs, we extract it to an option.
|
||||
if (OPTION_FORCE_COLORED_OUTPUT)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
add_compile_options (-fdiagnostics-color=always)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
add_compile_options (-fcolor-diagnostics)
|
||||
endif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
endif (OPTION_FORCE_COLORED_OUTPUT)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
@@ -58,7 +58,7 @@ elseif(CMAKE_CXX_COMPILER_LOADED)
|
||||
include(CheckCXXSourceCompiles)
|
||||
else()
|
||||
# If neither C nor CXX are loaded, implicit iconv makes no sense.
|
||||
set(Iconv_IS_BUILT_IN FALSE)
|
||||
set(Iconv_IS_BUILT_IN NO)
|
||||
endif()
|
||||
|
||||
# iconv can only be provided in libc on a POSIX system.
|
||||
@@ -94,7 +94,7 @@ if(NOT DEFINED Iconv_IS_BUILT_IN)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
else()
|
||||
set(Iconv_IS_BUILT_IN FALSE)
|
||||
set(Iconv_IS_BUILT_IN NO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@@ -48,6 +48,8 @@ function(set_options)
|
||||
set(DEFAULT_OPTION_INSTALL_FHS OFF)
|
||||
endif (UNIX AND NOT APPLE)
|
||||
|
||||
option(OPTION_FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." OFF)
|
||||
|
||||
option(OPTION_DEDICATED "Build dedicated server only (no GUI)" OFF)
|
||||
option(OPTION_INSTALL_FHS "Install with Filesstem Hierarchy Standard folders" ${DEFAULT_OPTION_INSTALL_FHS})
|
||||
option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" ON)
|
||||
|
@@ -82,7 +82,7 @@ if (GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
set(REV_VERSION "${TAG}")
|
||||
set(REV_ISTAG 1)
|
||||
|
||||
string(REGEX REPLACE "^[0-9.]*$" "" STABLETAG "${TAG}")
|
||||
string(REGEX REPLACE "^[0-9.]+$" "" STABLETAG "${TAG}")
|
||||
if (NOT STABLETAG STREQUAL "")
|
||||
set(REV_ISSTABLETAG 1)
|
||||
else ()
|
||||
|
@@ -86,6 +86,9 @@ Last updated: 2011-01-20
|
||||
Note: not every update type supports every frequency. If in doubt, you can
|
||||
verify against the data received in `ADMIN_PACKET_SERVER_PROTOCOL`.
|
||||
|
||||
Please note the potential gotcha in the "Certain packet information" section below
|
||||
when using the `ADMIN_UPDATE_FREQUENCY` packet.
|
||||
|
||||
The server will not confirm your registered update. However, asking for an
|
||||
invalid `AdminUpdateType` or a not supported `AdminUpdateFrequency` you will be
|
||||
disconnected from the server with `NETWORK_ERROR_ILLEGAL_PACKET`.
|
||||
@@ -143,6 +146,9 @@ Last updated: 2011-01-20
|
||||
- ADMIN_UPDATE_COMPANY_STATS
|
||||
- ADMIN_UPDATE_CMD_NAMES
|
||||
|
||||
Please note the potential gotcha in the "Certain packet information" section below
|
||||
when using the `ADMIN_POLL` packet.
|
||||
|
||||
`ADMIN_UPDATE_CLIENT_INFO` and `ADMIN_UPDATE_COMPANY_INFO` accept an additional
|
||||
parameter. This parameter is used to specify a certain client or company.
|
||||
Setting this parameter to `UINT32_MAX (0xFFFFFFFF)` will tell the server you
|
||||
@@ -213,6 +219,14 @@ Last updated: 2011-01-20
|
||||
|
||||
## 7.0) Certain packet information
|
||||
|
||||
`ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY` and `ADMIN_PACKET_ADMIN_POLL`
|
||||
|
||||
Potential gotcha: the AdminUpdateType integer type used is a
|
||||
uint16 for `UPDATE_FREQUENCY`, and a uint8 for `POLL`.
|
||||
This is due to boring legacy reasons.
|
||||
It is safe to cast between the two when sending
|
||||
(i.e cast from a uint8 to a uint16).
|
||||
|
||||
All `ADMIN_PACKET_SERVER_*` packets have an enum value greater 100.
|
||||
|
||||
`ADMIN_PACKET_SERVER_WELCOME`
|
||||
|
@@ -65,9 +65,9 @@ public:
|
||||
}
|
||||
NORETURN static void ThrowError(void *ud, const SQChar *s) {
|
||||
SQCompiler *c = (SQCompiler *)ud;
|
||||
c->Error(s);
|
||||
c->Error("%s", s);
|
||||
}
|
||||
NORETURN void Error(const SQChar *s, ...)
|
||||
NORETURN void Error(const SQChar *s, ...) WARN_FORMAT(2, 3)
|
||||
{
|
||||
static SQChar temp[256];
|
||||
va_list vl;
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
}
|
||||
Error("expected '%s'", etypename);
|
||||
}
|
||||
Error("expected '%c'", tok);
|
||||
Error("expected '%c'", (char)tok);
|
||||
}
|
||||
}
|
||||
SQObjectPtr ret;
|
||||
|
2
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
2
src/3rdparty/squirrel/squirrel/sqvm.cpp
vendored
@@ -94,7 +94,7 @@ bool SQVM::ARITH_OP(SQUnsignedInteger op,SQObjectPtr &trg,const SQObjectPtr &o1,
|
||||
if(!StringCat(o1, o2, trg)) return false;
|
||||
}
|
||||
else if(!ArithMetaMethod(op,o1,o2,trg)) {
|
||||
Raise_Error("arith op %c on between '%s' and '%s'",op,GetTypeName(o1),GetTypeName(o2)); return false;
|
||||
Raise_Error("arith op %c on between '%s' and '%s'",(char)op,GetTypeName(o1),GetTypeName(o2)); return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
2
src/3rdparty/squirrel/squirrel/sqvm.h
vendored
2
src/3rdparty/squirrel/squirrel/sqvm.h
vendored
@@ -81,7 +81,7 @@ public:
|
||||
SQString *PrintObjVal(const SQObject &o);
|
||||
|
||||
|
||||
void Raise_Error(const SQChar *s, ...);
|
||||
void Raise_Error(const SQChar *s, ...) WARN_FORMAT(2, 3);
|
||||
void Raise_Error(SQObjectPtr &desc);
|
||||
void Raise_IdxError(const SQObject &o);
|
||||
void Raise_CompareError(const SQObject &o1, const SQObject &o2);
|
||||
|
@@ -433,9 +433,12 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
||||
default: break;
|
||||
}
|
||||
|
||||
bool any_available = false;
|
||||
CommandCost type_check;
|
||||
/* loop for all bridgetypes */
|
||||
for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
|
||||
if (CheckBridgeAvailability(brd_type, bridge_len).Succeeded()) {
|
||||
type_check = CheckBridgeAvailability(brd_type, bridge_len);
|
||||
if (type_check.Succeeded()) {
|
||||
/* Re-check bridge building possibility is initial bridge builindg query indicated a bridge type dependent failure */
|
||||
if (query_per_bridge_type && DoCommand(end, start, type | brd_type, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)) | DC_QUERY_COST, CMD_BUILD_BRIDGE).Failed()) continue;
|
||||
/* bridge is accepted, add to list */
|
||||
@@ -446,8 +449,14 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
||||
/* Add to terraforming & bulldozing costs the cost of the
|
||||
* bridge itself (not computed with DC_QUERY_COST) */
|
||||
item.cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item.spec->price) >> 8) + infra_cost;
|
||||
any_available = true;
|
||||
}
|
||||
}
|
||||
/* give error cause if no bridges available here*/
|
||||
if (!any_available)
|
||||
{
|
||||
errmsg = type_check.GetErrorMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if (bl != nullptr && bl->size() != 0) {
|
||||
|
@@ -42,8 +42,8 @@ void SetupCargoForClimate(LandscapeID l)
|
||||
assert(l < lengthof(_default_climate_cargo));
|
||||
|
||||
/* Reset and disable all cargo types */
|
||||
memset(CargoSpec::array, 0, sizeof(CargoSpec::array));
|
||||
for (CargoID i = 0; i < lengthof(CargoSpec::array); i++) {
|
||||
*CargoSpec::Get(i) = {};
|
||||
CargoSpec::Get(i)->bitnum = INVALID_CARGO;
|
||||
|
||||
/* Set defaults for newer properties, which old GRFs do not know */
|
||||
|
@@ -151,7 +151,6 @@ static void _GenerateWorld()
|
||||
}
|
||||
return;
|
||||
}
|
||||
UpdateTownCargoBitmap();
|
||||
GenerateIndustries();
|
||||
GenerateObjects();
|
||||
GenerateTrees();
|
||||
|
@@ -2688,7 +2688,7 @@ static void ChangeIndustryProduction(Industry *i, bool monthly)
|
||||
/* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
|
||||
new_prod = Clamp(new_prod, 1, 255);
|
||||
|
||||
if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
|
||||
if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1 && !(indspec->behaviour & INDUSTRYBEH_WATER_NO_CLAMP_PROD)) {
|
||||
new_prod = Clamp(new_prod, 0, 16);
|
||||
}
|
||||
|
||||
|
@@ -80,6 +80,7 @@ enum IndustryBehaviour {
|
||||
INDUSTRYBEH_NOBUILT_MAPCREATION = 1 << 16, ///< Do not force one instance of this type to appear on map generation
|
||||
INDUSTRYBEH_CANCLOSE_LASTINSTANCE = 1 << 17, ///< Allow closing down the last instance of this type
|
||||
INDUSTRYBEH_CARGOTYPES_UNLIMITED = 1 << 18, ///< Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types
|
||||
INDUSTRYBEH_WATER_NO_CLAMP_PROD = 1 << 19, ///< Do not clamp production of second cargo for water industries
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(IndustryBehaviour)
|
||||
|
||||
|
@@ -109,8 +109,6 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
||||
RebuildTownKdtree();
|
||||
RebuildViewportKdtree();
|
||||
|
||||
UpdateTownCargoBitmap();
|
||||
|
||||
FreeSignalPrograms();
|
||||
FreeSignalDependencies();
|
||||
|
||||
|
@@ -90,7 +90,7 @@ struct CStrA : public CBlobT<char>
|
||||
}
|
||||
|
||||
/** Add formatted string (like vsprintf) at the end of existing contents. */
|
||||
int AddFormatL(const char *format, va_list args)
|
||||
int AddFormatL(const char *format, va_list args) WARN_FORMAT(2, 0)
|
||||
{
|
||||
size_t addSize = max<size_t>(strlen(format), 16);
|
||||
addSize += addSize / 2;
|
||||
|
@@ -134,7 +134,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Register updates to be sent at certain frequencies (as announced in the PROTOCOL packet):
|
||||
* uint16 Update type (see #AdminUpdateType).
|
||||
* uint16 Update type (see #AdminUpdateType). Note integer type - see "Certain Packet Information" in docs/admin_network.md.
|
||||
* uint16 Update frequency (see #AdminUpdateFrequency), setting #ADMIN_FREQUENCY_POLL is always ignored.
|
||||
* @param p The packet that was just received.
|
||||
* @return The state the network should have.
|
||||
@@ -143,7 +143,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Poll the server for certain updates, an invalid poll (e.g. not existent id) gets silently dropped:
|
||||
* uint8 #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet.
|
||||
* uint8 #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet. Note integer type - see "Certain Packet Information" in docs/admin_network.md.
|
||||
* uint32 ID relevant to the packet type, e.g.
|
||||
* - the client ID for #ADMIN_UPDATE_CLIENT_INFO. Use UINT32_MAX to show all clients.
|
||||
* - the company ID for #ADMIN_UPDATE_COMPANY_INFO. Use UINT32_MAX to show all companies.
|
||||
|
@@ -1595,7 +1595,7 @@ struct NetworkLobbyWindow : public Window {
|
||||
NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // company info
|
||||
NetworkUDPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // general data
|
||||
/* Clear the information so removed companies don't remain */
|
||||
memset(this->company_info, 0, sizeof(this->company_info));
|
||||
for (auto &company : this->company_info) company = {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -671,6 +671,11 @@ static bool ReadyForNextNewsItem()
|
||||
/** Move to the next ticker item */
|
||||
static void MoveToNextTickerItem()
|
||||
{
|
||||
/* There is no status bar, so no reason to show news;
|
||||
* especially important with the end game screen when
|
||||
* there is no status bar but possible news. */
|
||||
if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
|
||||
|
||||
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar
|
||||
|
||||
/* if we're not at the last item, then move on */
|
||||
@@ -702,6 +707,11 @@ static void MoveToNextTickerItem()
|
||||
/** Move to the next news item */
|
||||
static void MoveToNextNewsItem()
|
||||
{
|
||||
/* There is no status bar, so no reason to show news;
|
||||
* especially important with the end game screen when
|
||||
* there is no status bar but possible news. */
|
||||
if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
|
||||
|
||||
DeleteWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown
|
||||
_forced_news = nullptr;
|
||||
|
||||
@@ -995,11 +1005,6 @@ void NewsLoop()
|
||||
/* no news item yet */
|
||||
if (_total_news == 0) return;
|
||||
|
||||
/* There is no status bar, so no reason to show news;
|
||||
* especially important with the end game screen when
|
||||
* there is no status bar but possible news. */
|
||||
if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return;
|
||||
|
||||
static byte _last_clean_month = 0;
|
||||
|
||||
if (_last_clean_month != _cur_month) {
|
||||
|
@@ -1368,13 +1368,9 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
|
||||
|
||||
/* Check the town caches. */
|
||||
std::vector<TownCache> old_town_caches;
|
||||
std::vector<CargoTypes> old_town_cargo_accepted_totals;
|
||||
std::vector<CargoTypes> old_town_cargo_produced;
|
||||
std::vector<StationList> old_town_stations_nears;
|
||||
for (const Town *t : Town::Iterate()) {
|
||||
old_town_caches.push_back(t->cache);
|
||||
old_town_cargo_accepted_totals.push_back(t->cargo_accepted_total);
|
||||
old_town_cargo_produced.push_back(t->cargo_produced);
|
||||
old_town_stations_nears.push_back(t->stations_near);
|
||||
}
|
||||
|
||||
@@ -1392,8 +1388,6 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
|
||||
old_industry_stations_nears.push_back(ind->stations_near);
|
||||
}
|
||||
|
||||
const CargoTypes old_town_cargoes_accepted = _town_cargoes_accepted;
|
||||
|
||||
extern void RebuildTownCaches(bool cargo_update_required);
|
||||
RebuildTownCaches(false);
|
||||
RebuildSubsidisedSourceAndDestinationCache();
|
||||
@@ -1405,20 +1399,11 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log)
|
||||
if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) {
|
||||
CCLOG("town cache mismatch: town %i", (int)t->index);
|
||||
}
|
||||
if (old_town_cargo_accepted_totals[i] != t->cargo_accepted_total) {
|
||||
CCLOG("town cargo_accepted_total mismatch: town %i, old: " OTTD_PRINTFHEX64 ". new: " OTTD_PRINTFHEX64, (int)t->index, old_town_cargo_accepted_totals[i], t->cargo_accepted_total);
|
||||
}
|
||||
if (old_town_cargo_produced[i] != t->cargo_produced) {
|
||||
CCLOG("town cargo_produced mismatch: town %i, old: " OTTD_PRINTFHEX64 ". new: " OTTD_PRINTFHEX64, (int)t->index, old_town_cargo_produced[i], t->cargo_produced);
|
||||
}
|
||||
if (old_town_stations_nears[i] != t->stations_near) {
|
||||
CCLOG("town stations_near mismatch: town %i, (old size: %u, new size: %u)", (int)t->index, (uint)old_town_stations_nears[i].size(), (uint)t->stations_near.size());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (old_town_cargoes_accepted != _town_cargoes_accepted) {
|
||||
CCLOG("_town_cargoes_accepted mismatch: old: " OTTD_PRINTFHEX64 ". new: " OTTD_PRINTFHEX64, old_town_cargoes_accepted, _town_cargoes_accepted);
|
||||
}
|
||||
i = 0;
|
||||
for (Station *st : Station::Iterate()) {
|
||||
if (old_station_industries_nears[i] != st->industries_near) {
|
||||
|
@@ -1671,14 +1671,15 @@ void DrawRoadCatenary(const TileInfo *ti)
|
||||
* @param dx the offset from the top of the BB of the tile
|
||||
* @param dy the offset from the top of the BB of the tile
|
||||
* @param h the height of the sprite to draw
|
||||
* @param transparent whether the sprite should be transparent (used for roadside trees)
|
||||
*/
|
||||
static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int h)
|
||||
static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int h, bool transparent)
|
||||
{
|
||||
int x = ti->x | dx;
|
||||
int y = ti->y | dy;
|
||||
int z = ti->z;
|
||||
if (ti->tileh != SLOPE_FLAT) z = GetSlopePixelZ(x, y);
|
||||
AddSortableSpriteToDraw(img, PAL_NONE, x, y, 2, 2, h, z);
|
||||
AddSortableSpriteToDraw(img, PAL_NONE, x, y, 2, 2, h, z, transparent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1831,9 +1832,12 @@ void DrawRoadBits(TileInfo *ti)
|
||||
/* If there are no road bits, return, as there is nothing left to do */
|
||||
if (HasAtMostOneBit(road)) return;
|
||||
|
||||
if (roadside == ROADSIDE_TREES && IsInvisibilitySet(TO_TREES)) return;
|
||||
bool is_transparent = roadside == ROADSIDE_TREES && IsTransparencySet(TO_TREES);
|
||||
|
||||
/* Draw extra details. */
|
||||
for (const DrawRoadTileStruct *drts = _road_display_table[roadside][road | tram]; drts->image != 0; drts++) {
|
||||
DrawRoadDetail(drts->image, ti, drts->subcoord_x, drts->subcoord_y, 0x10);
|
||||
DrawRoadDetail(drts->image, ti, drts->subcoord_x, drts->subcoord_y, 0x10, is_transparent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3113,22 +3113,6 @@ bool AfterLoadGame()
|
||||
* which is done by StartupEngines(). */
|
||||
if (gcf_res != GLC_ALL_GOOD) StartupEngines();
|
||||
|
||||
if (SlXvIsFeatureMissing(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||
/* Update cargo acceptance map of towns. */
|
||||
for (Town *town : Town::Iterate()) {
|
||||
town->cargo_accepted.Clear();
|
||||
}
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||
Town::Get(GetTownIndex(t))->cargo_accepted.Add(t);
|
||||
}
|
||||
|
||||
for (Town *town : Town::Iterate()) {
|
||||
UpdateTownCargoes(town);
|
||||
}
|
||||
UpdateTownCargoBitmap();
|
||||
}
|
||||
|
||||
/* Set some breakdown-related variables to the correct values. */
|
||||
if (SlXvIsFeatureMissing(XSLFI_IMPROVED_BREAKDOWNS)) {
|
||||
for (Train *v : Train::Iterate()) {
|
||||
|
@@ -107,7 +107,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_LINKGRAPH_MODES, XSCF_NULL, 1, 1, "linkgraph_modes", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_GAME_EVENTS, XSCF_NULL, 1, 1, "game_events", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_ROAD_LAYOUT_CHANGE_CTR, XSCF_NULL, 1, 1, "road_layout_change_ctr", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TOWN_CARGO_MATRIX, XSCF_NULL, 1, 1, "town_cargo_matrix", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TOWN_CARGO_MATRIX, XSCF_NULL, 0, 1, "town_cargo_matrix", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_STATE_CHECKSUM, XSCF_NULL, 1, 1, "state_checksum", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_DEBUG, XSCF_IGNORABLE_ALL, 1, 1, "debug", nullptr, nullptr, "DBGL,DBGC" },
|
||||
{ XSLFI_FLOW_STAT_FLAGS, XSCF_NULL, 1, 1, "flow_stat_flags", nullptr, nullptr, nullptr },
|
||||
|
@@ -72,7 +72,7 @@ enum SlXvFeatureIndex {
|
||||
XSLFI_LINKGRAPH_MODES, ///< Linkgraph additional distribution modes
|
||||
XSLFI_GAME_EVENTS, ///< Game event flags
|
||||
XSLFI_ROAD_LAYOUT_CHANGE_CTR, ///< Road layout change counter
|
||||
XSLFI_TOWN_CARGO_MATRIX, ///< Town cargo matrix savegame format changes
|
||||
XSLFI_TOWN_CARGO_MATRIX, ///< Town cargo matrix savegame format changes (now obsolete)
|
||||
XSLFI_STATE_CHECKSUM, ///< State checksum
|
||||
XSLFI_DEBUG, ///< Debugging info
|
||||
XSLFI_FLOW_STAT_FLAGS, ///< FlowStat flags
|
||||
|
@@ -48,13 +48,7 @@ void RebuildTownCaches(bool cargo_update_required)
|
||||
/* Update the population and num_house dependent values */
|
||||
for (Town *town : Town::Iterate()) {
|
||||
UpdateTownRadius(town);
|
||||
if (cargo_update_required) {
|
||||
UpdateTownCargoes(town);
|
||||
} else {
|
||||
UpdateTownCargoTotal(town);
|
||||
}
|
||||
}
|
||||
UpdateTownCargoBitmap();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,8 +209,8 @@ static const SaveLoad _town_desc[] = {
|
||||
|
||||
SLE_CONDLST(Town, psa_list, REF_STORAGE, SLV_161, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Town, cargo_produced, SLE_FILE_U32 | SLE_VAR_U64, SLV_166, SLV_EXTEND_CARGOTYPES),
|
||||
SLE_CONDVAR(Town, cargo_produced, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use
|
||||
SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION), ///< cargo_produced, no longer in use
|
||||
|
||||
/* reserve extra space in savegame here. (currently 30 bytes) */
|
||||
SLE_CONDNULL(30, SLV_2, SL_MAX_VERSION),
|
||||
@@ -272,19 +266,6 @@ static void Load_HIDS()
|
||||
Load_NewGRFMapping(_house_mngr);
|
||||
}
|
||||
|
||||
const SaveLoad *GetTileMatrixDesc()
|
||||
{
|
||||
/* Here due to private member vars. */
|
||||
static const SaveLoad _tilematrix_desc[] = {
|
||||
SLE_VAR(AcceptanceMatrix, area.tile, SLE_UINT32),
|
||||
SLE_VAR(AcceptanceMatrix, area.w, SLE_UINT16),
|
||||
SLE_VAR(AcceptanceMatrix, area.h, SLE_UINT16),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
return _tilematrix_desc;
|
||||
}
|
||||
|
||||
static void RealSave_Town(Town *t)
|
||||
{
|
||||
SlObjectSaveFiltered(t, _filtered_town_desc.data());
|
||||
@@ -296,11 +277,10 @@ static void RealSave_Town(Town *t)
|
||||
SlObjectSaveFiltered(&t->received[i], _filtered_town_received_desc.data());
|
||||
}
|
||||
|
||||
SlObjectSaveFiltered(&t->cargo_accepted, GetTileMatrixDesc()); // GetTileMatrixDesc() has no conditionals
|
||||
if (t->cargo_accepted.area.w != 0) {
|
||||
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
|
||||
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT64);
|
||||
}
|
||||
/* Write an empty matrix to avoid bumping savegame version. */
|
||||
SlWriteUint32(0); // tile
|
||||
SlWriteUint16(0); // w
|
||||
SlWriteUint16(0); // h
|
||||
}
|
||||
|
||||
static void Save_TOWN()
|
||||
@@ -339,24 +319,14 @@ static void Load_TOWN()
|
||||
SlErrorCorrupt("Invalid town name generator");
|
||||
}
|
||||
|
||||
if (!IsSavegameVersionBefore(SLV_166) && SlXvIsFeatureMissing(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||
if (!IsSavegameVersionBefore(SLV_166) || SlXvIsFeaturePresent(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||
SlSkipBytes(4); // tile
|
||||
uint16 w = SlReadUint16();
|
||||
uint16 h = SlReadUint16();
|
||||
if (w != 0) {
|
||||
SlSkipBytes(4 * (w / 4 * h / 4));
|
||||
SlSkipBytes((SlXvIsFeaturePresent(XSLFI_TOWN_CARGO_MATRIX) ? 8 : 4) * (w / 4 * h / 4));
|
||||
}
|
||||
}
|
||||
if (SlXvIsFeaturePresent(XSLFI_TOWN_CARGO_MATRIX)) {
|
||||
SlObjectLoadFiltered(&t->cargo_accepted, GetTileMatrixDesc()); // GetTileMatrixDesc() has no conditionals
|
||||
if (t->cargo_accepted.area.w != 0) {
|
||||
uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID;
|
||||
t->cargo_accepted.data = MallocT<CargoTypes>(arr_len);
|
||||
SlArray(t->cargo_accepted.data, arr_len, SLE_UINT64);
|
||||
}
|
||||
/* Rebuild total cargo acceptance. */
|
||||
UpdateTownCargoTotal(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "company_func.h"
|
||||
#include "strings_func.h"
|
||||
#include "error.h"
|
||||
#include "textbuf_gui.h"
|
||||
#include "window_gui.h"
|
||||
#include "window_func.h"
|
||||
#include "tile_map.h"
|
||||
@@ -851,6 +852,45 @@ bool MakeHeightmapScreenshot(const char *filename)
|
||||
return sf->proc(filename, HeightmapCallback, nullptr, MapSizeX(), MapSizeY(), 8, palette);
|
||||
}
|
||||
|
||||
static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the current query is about to confirm.
|
||||
|
||||
/**
|
||||
* Callback on the confirmation window for huge screenshots.
|
||||
* @param w Window with viewport
|
||||
* @param confirmed true on confirmation
|
||||
*/
|
||||
static void ScreenshotConfirmationCallback(Window *w, bool confirmed)
|
||||
{
|
||||
if (confirmed) MakeScreenshot(_confirmed_screenshot_type, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screenshot.
|
||||
* Ask for confirmation first if the screenshot will be huge.
|
||||
* @param t Screenshot type: World, defaultzoom, heightmap or viewport screenshot
|
||||
* @see MakeScreenshot
|
||||
*/
|
||||
void MakeScreenshotWithConfirm(ScreenshotType t)
|
||||
{
|
||||
ViewPort vp;
|
||||
SetupScreenshotViewport(t, &vp);
|
||||
|
||||
bool heightmap_or_minimap = t == SC_HEIGHTMAP || t == SC_MINIMAP;
|
||||
uint64_t width = (heightmap_or_minimap ? MapSizeX() : vp.width);
|
||||
uint64_t height = (heightmap_or_minimap ? MapSizeY() : vp.height);
|
||||
|
||||
if (width * height > 8192 * 8192) {
|
||||
/* Ask for confirmation */
|
||||
_confirmed_screenshot_type = t;
|
||||
SetDParam(0, width);
|
||||
SetDParam(1, height);
|
||||
ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, nullptr, ScreenshotConfirmationCallback);
|
||||
} else {
|
||||
/* Less than 64M pixels, just do it */
|
||||
MakeScreenshot(t, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a a success or failure message indicating the result of a screenshot action
|
||||
* @param ret whether the screenshot action was successful
|
||||
@@ -866,10 +906,12 @@ static void ShowScreenshotResultMessage(bool ret)
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an actual screenshot.
|
||||
* Make a screenshot.
|
||||
* Unconditionally take a screenshot of the requested type.
|
||||
* @param t the type of screenshot to make.
|
||||
* @param name the name to give to the screenshot.
|
||||
* @return true iff the screenshot was made successfully
|
||||
* @see MakeScreenshotWithConfirm
|
||||
*/
|
||||
bool MakeScreenshot(ScreenshotType t, const char *name)
|
||||
{
|
||||
|
@@ -30,6 +30,7 @@ class SmallMapWindow;
|
||||
void SetupScreenshotViewport(ScreenshotType t, struct ViewPort *vp);
|
||||
bool MakeHeightmapScreenshot(const char *filename);
|
||||
bool MakeSmallMapScreenshot(unsigned int width, unsigned int height, SmallMapWindow *window);
|
||||
void MakeScreenshotWithConfirm(ScreenshotType t);
|
||||
bool MakeScreenshot(ScreenshotType t, const char *name);
|
||||
bool MakeMinimapWorldScreenshot(const char *name);
|
||||
void SetScreenshotAuxiliaryText(const char *key, const char *value);
|
||||
|
@@ -8,31 +8,26 @@
|
||||
/** @file screenshot_gui.cpp GUI functions related to screenshots. */
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "gui.h"
|
||||
#include "viewport_func.h"
|
||||
#include "window_func.h"
|
||||
#include "window_gui.h"
|
||||
#include "screenshot.h"
|
||||
#include "textbuf_gui.h"
|
||||
#include "strings_func.h"
|
||||
|
||||
#include "widgets/screenshot_widget.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
static ScreenshotType _screenshot_type;
|
||||
|
||||
struct ScreenshotWindow : Window {
|
||||
ScreenshotWindow(WindowDesc *desc) : Window(desc) {
|
||||
ScreenshotWindow(WindowDesc *desc) : Window(desc)
|
||||
{
|
||||
this->CreateNestedTree();
|
||||
this->FinishInitNested();
|
||||
}
|
||||
|
||||
void OnPaint() override {
|
||||
void OnPaint() override
|
||||
{
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
void OnClick(Point pt, int widget, int click_count) override {
|
||||
void OnClick(Point pt, int widget, int click_count) override
|
||||
{
|
||||
if (widget < 0) return;
|
||||
ScreenshotType st;
|
||||
switch (widget) {
|
||||
@@ -44,37 +39,7 @@ struct ScreenshotWindow : Window {
|
||||
case WID_SC_TAKE_HEIGHTMAP: st = SC_HEIGHTMAP; break;
|
||||
case WID_SC_TAKE_MINIMAP: st = SC_MINIMAP; break;
|
||||
}
|
||||
TakeScreenshot(st);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screenshot.
|
||||
* Ask for confirmation if the screenshot will be huge.
|
||||
* @param t Screenshot type: World, defaultzoom, heightmap or viewport screenshot
|
||||
*/
|
||||
static void TakeScreenshot(ScreenshotType st) {
|
||||
ViewPort vp;
|
||||
SetupScreenshotViewport(st, &vp);
|
||||
if ((uint64)vp.width * (uint64)vp.height > 8192 * 8192) {
|
||||
/* Ask for confirmation */
|
||||
_screenshot_type = st;
|
||||
SetDParam(0, vp.width);
|
||||
SetDParam(1, vp.height);
|
||||
ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, nullptr, ScreenshotConfirmationCallback);
|
||||
}
|
||||
else {
|
||||
/* Less than 64M pixels, just do it */
|
||||
MakeScreenshot(st, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback on the confirmation window for huge screenshots.
|
||||
* @param w Window with viewport
|
||||
* @param confirmed true on confirmation
|
||||
*/
|
||||
static void ScreenshotConfirmationCallback(Window *w, bool confirmed) {
|
||||
if (confirmed) MakeScreenshot(_screenshot_type, nullptr);
|
||||
MakeScreenshotWithConfirm(st);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,7 +67,8 @@ static WindowDesc _screenshot_window_desc(
|
||||
_nested_screenshot, lengthof(_nested_screenshot)
|
||||
);
|
||||
|
||||
void ShowScreenshotWindow() {
|
||||
void ShowScreenshotWindow()
|
||||
{
|
||||
DeleteWindowById(WC_SCREENSHOT, 0);
|
||||
new ScreenshotWindow(&_screenshot_window_desc);
|
||||
}
|
||||
|
@@ -99,7 +99,7 @@ public:
|
||||
* Types of expenses.
|
||||
* @api -ai
|
||||
*/
|
||||
enum ExpensesType {
|
||||
enum ExpensesType : byte {
|
||||
EXPENSES_CONSTRUCTION = ::EXPENSES_CONSTRUCTION, ///< Construction costs.
|
||||
EXPENSES_NEW_VEHICLES = ::EXPENSES_NEW_VEHICLES, ///< New vehicles.
|
||||
EXPENSES_TRAIN_RUN = ::EXPENSES_TRAIN_RUN, ///< Running costs trains.
|
||||
|
@@ -36,7 +36,7 @@ public:
|
||||
/**
|
||||
* Goal types that can be given to a goal.
|
||||
*/
|
||||
enum GoalType {
|
||||
enum GoalType : byte {
|
||||
/* Note: these values represent part of the in-game GoalType enum */
|
||||
GT_NONE = ::GT_NONE, ///< Destination is not linked.
|
||||
GT_TILE = ::GT_TILE, ///< Destination is a tile.
|
||||
|
@@ -40,7 +40,7 @@ public:
|
||||
/**
|
||||
* Types of rail known to the game.
|
||||
*/
|
||||
enum RailType {
|
||||
enum RailType : byte {
|
||||
/* Note: these values represent part of the in-game static values */
|
||||
RAILTYPE_INVALID = ::INVALID_RAILTYPE, ///< Invalid RailType.
|
||||
};
|
||||
|
@@ -60,7 +60,7 @@ public:
|
||||
/**
|
||||
* Road/tram types
|
||||
*/
|
||||
enum RoadTramTypes {
|
||||
enum RoadTramTypes : uint8 {
|
||||
ROADTRAMTYPES_ROAD = ::RTTB_ROAD, ///< Road road types.
|
||||
ROADTRAMTYPES_TRAM = ::RTTB_TRAM, ///< Tram road types.
|
||||
};
|
||||
|
@@ -119,16 +119,16 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type)
|
||||
uint32 refid = 0;
|
||||
TileIndex reftile = 0;
|
||||
switch (type) {
|
||||
case SPET_LOCATION:
|
||||
case ::SPET_LOCATION:
|
||||
reftile = reference;
|
||||
break;
|
||||
case SPET_GOAL:
|
||||
case SPET_BUTTON_PUSH:
|
||||
case SPET_BUTTON_TILE:
|
||||
case SPET_BUTTON_VEHICLE:
|
||||
case ::SPET_GOAL:
|
||||
case ::SPET_BUTTON_PUSH:
|
||||
case ::SPET_BUTTON_TILE:
|
||||
case ::SPET_BUTTON_VEHICLE:
|
||||
refid = reference;
|
||||
break;
|
||||
case SPET_TEXT:
|
||||
case ::SPET_TEXT:
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
|
@@ -57,7 +57,7 @@ public:
|
||||
/**
|
||||
* Story page element types.
|
||||
*/
|
||||
enum StoryPageElementType {
|
||||
enum StoryPageElementType : byte {
|
||||
SPET_TEXT = ::SPET_TEXT, ///< An element that displays a block of text.
|
||||
SPET_LOCATION = ::SPET_LOCATION, ///< An element that displays a single line of text along with a button to view the referenced location.
|
||||
SPET_GOAL = ::SPET_GOAL, ///< An element that displays a goal.
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
* Formatting and layout flags for story page buttons.
|
||||
* The SPBF_FLOAT_LEFT and SPBF_FLOAT_RIGHT flags can not be combined.
|
||||
*/
|
||||
enum StoryPageButtonFlags {
|
||||
enum StoryPageButtonFlags : byte {
|
||||
SPBF_NONE = ::SPBF_NONE, ///< No special formatting for button.
|
||||
SPBF_FLOAT_LEFT = ::SPBF_FLOAT_LEFT, ///< Button is placed to the left of the following paragraph.
|
||||
SPBF_FLOAT_RIGHT = ::SPBF_FLOAT_RIGHT, ///< Button is placed to the right of the following paragraph.
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
/**
|
||||
* Mouse cursors usable by story page buttons.
|
||||
*/
|
||||
enum StoryPageButtonCursor {
|
||||
enum StoryPageButtonCursor : byte {
|
||||
SPBC_MOUSE = ::SPBC_MOUSE,
|
||||
SPBC_ZZZ = ::SPBC_ZZZ,
|
||||
SPBC_BUOY = ::SPBC_BUOY,
|
||||
|
@@ -63,12 +63,12 @@ protected:
|
||||
/**
|
||||
* If a user runs 'print' inside a script, this function gets the params.
|
||||
*/
|
||||
static void PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
|
||||
static void PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) WARN_FORMAT(2, 3);
|
||||
|
||||
/**
|
||||
* If an error has to be print, this function is called.
|
||||
*/
|
||||
static void ErrorPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...);
|
||||
static void ErrorPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) WARN_FORMAT(2, 3);
|
||||
|
||||
public:
|
||||
Squirrel(const char *APIName);
|
||||
|
@@ -35,7 +35,7 @@ char *strecpy(char *dst, const char *src, const char *last, bool quiet_mode = fa
|
||||
char *stredup(const char *src, const char *last = nullptr);
|
||||
|
||||
int CDECL seprintf(char *str, const char *last, const char *format, ...) WARN_FORMAT(3, 4);
|
||||
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap);
|
||||
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap) WARN_FORMAT(3, 0);
|
||||
|
||||
char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2);
|
||||
char *str_vfmt(const char *str, va_list ap);
|
||||
|
@@ -328,21 +328,28 @@ bool FindSubsidyTownCargoRoute()
|
||||
const Town *src_town = Town::GetRandom();
|
||||
if (src_town->cache.population < SUBSIDY_CARGO_MIN_POPULATION) return false;
|
||||
|
||||
CargoTypes town_cargo_produced = src_town->cargo_produced;
|
||||
CargoArray town_cargo_produced = GetProductionAroundTiles(src_town->xy, 1, 1, SUBSIDY_TOWN_CARGO_RADIUS);
|
||||
|
||||
/* Passenger subsidies are not handled here. */
|
||||
ClrBit(town_cargo_produced, CT_PASSENGERS);
|
||||
town_cargo_produced[CT_PASSENGERS] = 0;
|
||||
|
||||
uint8 cargo_count = 0;
|
||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||
if (town_cargo_produced[i] > 0) cargo_count++;
|
||||
}
|
||||
|
||||
/* No cargo produced at all? */
|
||||
if (town_cargo_produced == 0) return false;
|
||||
if (cargo_count == 0) return false;
|
||||
|
||||
/* Choose a random cargo that is produced in the town. */
|
||||
uint8 cargo_number = RandomRange(CountBits(town_cargo_produced));
|
||||
uint8 cargo_number = RandomRange(cargo_count);
|
||||
CargoID cid;
|
||||
FOR_EACH_SET_CARGO_ID(cid, town_cargo_produced) {
|
||||
for (cid = 0; cid < NUM_CARGO; cid++) {
|
||||
if (town_cargo_produced[cid] > 0) {
|
||||
if (cargo_number == 0) break;
|
||||
cargo_number--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Avoid using invalid NewGRF cargoes. */
|
||||
if (!CargoSpec::Get(cid)->IsValid() ||
|
||||
@@ -416,17 +423,18 @@ bool FindSubsidyIndustryCargoRoute()
|
||||
*/
|
||||
bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src)
|
||||
{
|
||||
/* Choose a random destination. Only consider towns if they can accept the cargo. */
|
||||
SourceType dst_type = (HasBit(_town_cargoes_accepted, cid) && Chance16(1, 2)) ? ST_TOWN : ST_INDUSTRY;
|
||||
/* Choose a random destination. */
|
||||
SourceType dst_type = Chance16(1, 2) ? ST_TOWN : ST_INDUSTRY;
|
||||
|
||||
SourceID dst;
|
||||
switch (dst_type) {
|
||||
case ST_TOWN: {
|
||||
/* Select a random town. */
|
||||
const Town *dst_town = Town::GetRandom();
|
||||
CargoArray town_cargo_accepted = GetAcceptanceAroundTiles(dst_town->xy, 1, 1, SUBSIDY_TOWN_CARGO_RADIUS);
|
||||
|
||||
/* Check if the town can accept this cargo. */
|
||||
if (!HasBit(dst_town->cargo_accepted_total, cid)) return false;
|
||||
if (town_cargo_accepted[cid] < 8) return false;
|
||||
|
||||
dst = dst_town->index;
|
||||
break;
|
||||
|
@@ -57,5 +57,6 @@ static const uint SUBSIDY_PAX_MIN_POPULATION = 400; ///< Min. population of to
|
||||
static const uint SUBSIDY_CARGO_MIN_POPULATION = 900; ///< Min. population of destination town for cargo route
|
||||
static const uint SUBSIDY_MAX_PCT_TRANSPORTED = 42; ///< Subsidy will be created only for towns/industries with less % transported
|
||||
static const uint SUBSIDY_MAX_DISTANCE = 70; ///< Max. length of subsidised route (DistanceManhattan)
|
||||
static const uint SUBSIDY_TOWN_CARGO_RADIUS = 6; ///< Extent of a tile area around town center when scanning for town cargo acceptance and production (6 ~= min catchmement + min station / 2)
|
||||
|
||||
#endif /* SUBSIDY_BASE_H */
|
||||
|
@@ -670,18 +670,6 @@ class NIHTown : public NIHelper {
|
||||
seprintf(buffer, lastof(buffer), " Index: %u", index);
|
||||
print(buffer);
|
||||
|
||||
char *b = buffer;
|
||||
b += seprintf(b, lastof(buffer), " cargo_produced: ");
|
||||
SetDParam(0, t->cargo_produced);
|
||||
b = GetString(b, STR_JUST_CARGO_LIST, lastof(buffer));
|
||||
print(buffer);
|
||||
|
||||
b = buffer;
|
||||
b += seprintf(b, lastof(buffer), " cargo_accepted_total: ");
|
||||
SetDParam(0, t->cargo_accepted_total);
|
||||
b = GetString(b, STR_JUST_CARGO_LIST, lastof(buffer));
|
||||
print(buffer);
|
||||
|
||||
seprintf(buffer, lastof(buffer), " Nearby stations: %u", (uint) t->stations_near.size());
|
||||
print(buffer);
|
||||
for (const Station *st : t->stations_near) {
|
||||
|
@@ -3343,7 +3343,7 @@ type = SLE_UINT8
|
||||
from = SLV_30
|
||||
def = 32
|
||||
min = 12
|
||||
max = 48
|
||||
max = 128
|
||||
str = STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE
|
||||
strval = STR_CONFIG_SETTING_TILE_LENGTH
|
||||
strhelp = STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT
|
||||
|
@@ -68,8 +68,6 @@ RailType _last_built_railtype;
|
||||
RoadType _last_built_roadtype;
|
||||
RoadType _last_built_tramtype;
|
||||
|
||||
static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the current query is about to confirm.
|
||||
|
||||
/** Toobar modes */
|
||||
enum ToolbarMode {
|
||||
TB_NORMAL,
|
||||
@@ -1084,37 +1082,6 @@ static CallBackFunction ToolbarHelpClick(Window *w)
|
||||
return CBF_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback on the confirmation window for huge screenshots.
|
||||
* @param w Window with viewport
|
||||
* @param confirmed true on confirmation
|
||||
*/
|
||||
static void ScreenshotConfirmCallback(Window *w, bool confirmed)
|
||||
{
|
||||
if (confirmed) MakeScreenshot(_confirmed_screenshot_type, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a screenshot of the world.
|
||||
* Ask for confirmation if the screenshot will be huge.
|
||||
* @param t Screenshot type: World or viewport screenshot
|
||||
*/
|
||||
static void MenuClickScreenshot(ScreenshotType t)
|
||||
{
|
||||
ViewPort vp;
|
||||
SetupScreenshotViewport(t, &vp);
|
||||
if ((uint64)vp.width * (uint64)vp.height > 8192 * 8192) {
|
||||
/* Ask for confirmation */
|
||||
SetDParam(0, vp.width);
|
||||
SetDParam(1, vp.height);
|
||||
_confirmed_screenshot_type = t;
|
||||
ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, nullptr, ScreenshotConfirmCallback);
|
||||
} else {
|
||||
/* Less than 64M pixels, just do it */
|
||||
MakeScreenshot(t, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle drawing of sprites' bounding boxes.
|
||||
* @note has only an effect when newgrf_developer_tools are active.
|
||||
@@ -2151,10 +2118,10 @@ struct MainToolbarWindow : Window {
|
||||
case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
|
||||
case MTHK_MUSIC: ShowMusicWindow(); break;
|
||||
case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
|
||||
case MTHK_SMALL_SCREENSHOT: MenuClickScreenshot(SC_VIEWPORT); break;
|
||||
case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickScreenshot(SC_ZOOMEDIN); break;
|
||||
case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickScreenshot(SC_DEFAULTZOOM); break;
|
||||
case MTHK_GIANT_SCREENSHOT: MenuClickScreenshot(SC_WORLD); break;
|
||||
case MTHK_SMALL_SCREENSHOT: MakeScreenshotWithConfirm(SC_VIEWPORT); break;
|
||||
case MTHK_ZOOMEDIN_SCREENSHOT: MakeScreenshotWithConfirm(SC_ZOOMEDIN); break;
|
||||
case MTHK_DEFAULTZOOM_SCREENSHOT: MakeScreenshotWithConfirm(SC_DEFAULTZOOM); break;
|
||||
case MTHK_GIANT_SCREENSHOT: MakeScreenshotWithConfirm(SC_WORLD); break;
|
||||
case MTHK_CHEATS: ShowCheatWindow(); break;
|
||||
case MTHK_TERRAFORM: ShowTerraformToolbar(); break;
|
||||
case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break;
|
||||
@@ -2528,10 +2495,10 @@ struct ScenarioEditorToolbarWindow : Window {
|
||||
case MTEHK_SIGN: cbf = ToolbarScenPlaceSign(this); break;
|
||||
case MTEHK_MUSIC: ShowMusicWindow(); break;
|
||||
case MTEHK_LANDINFO: cbf = PlaceLandBlockInfo(); break;
|
||||
case MTEHK_SMALL_SCREENSHOT: MenuClickScreenshot(SC_VIEWPORT); break;
|
||||
case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickScreenshot(SC_ZOOMEDIN); break;
|
||||
case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickScreenshot(SC_DEFAULTZOOM); break;
|
||||
case MTEHK_GIANT_SCREENSHOT: MenuClickScreenshot(SC_WORLD); break;
|
||||
case MTEHK_SMALL_SCREENSHOT: MakeScreenshotWithConfirm(SC_VIEWPORT); break;
|
||||
case MTEHK_ZOOMEDIN_SCREENSHOT: MakeScreenshotWithConfirm(SC_ZOOMEDIN); break;
|
||||
case MTEHK_DEFAULTZOOM_SCREENSHOT: MakeScreenshotWithConfirm(SC_DEFAULTZOOM); break;
|
||||
case MTEHK_GIANT_SCREENSHOT: MakeScreenshotWithConfirm(SC_WORLD); break;
|
||||
case MTEHK_ZOOM_IN: ToolbarZoomInClick(this); break;
|
||||
case MTEHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
|
||||
case MTEHK_TERRAFORM: ShowEditorTerraformToolbar(); break;
|
||||
|
12
src/town.h
12
src/town.h
@@ -15,7 +15,6 @@
|
||||
#include "subsidy_type.h"
|
||||
#include "newgrf_storage.h"
|
||||
#include "cargotype.h"
|
||||
#include "tilematrix_type.hpp"
|
||||
#include "openttd.h"
|
||||
#include "table/strings.h"
|
||||
#include "company_func.h"
|
||||
@@ -29,8 +28,6 @@ struct BuildingCounts {
|
||||
T class_count[HOUSE_CLASS_MAX];
|
||||
};
|
||||
|
||||
typedef TileMatrix<CargoTypes, 4> AcceptanceMatrix;
|
||||
|
||||
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings
|
||||
static const uint CUSTOM_TOWN_MAX_NUMBER = 5000; ///< this is the maximum number of towns a user can specify in customisation
|
||||
|
||||
@@ -89,10 +86,6 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
||||
|
||||
inline byte GetPercentTransported(CargoID cid) const { return this->supplied[cid].old_act * 256 / (this->supplied[cid].old_max + 1); }
|
||||
|
||||
/* Cargo production and acceptance stats. */
|
||||
CargoTypes cargo_produced; ///< Bitmap of all cargoes produced by houses in this town.
|
||||
AcceptanceMatrix cargo_accepted; ///< Bitmap of cargoes accepted by houses for each 4*4 (really 12*12) map square of the town.
|
||||
CargoTypes cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town.
|
||||
StationList stations_near; ///< NOSAVE: List of nearby stations.
|
||||
|
||||
uint16 time_until_rebuild; ///< time until we rebuild a house
|
||||
@@ -233,9 +226,6 @@ void ResetHouses();
|
||||
void ClearTownHouse(Town *t, TileIndex tile);
|
||||
void UpdateTownMaxPass(Town *t);
|
||||
void UpdateTownRadius(Town *t);
|
||||
void UpdateTownCargoes(Town *t);
|
||||
void UpdateTownCargoTotal(Town *t);
|
||||
void UpdateTownCargoBitmap();
|
||||
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags);
|
||||
Town *ClosestTownFromTile(TileIndex tile, uint threshold);
|
||||
void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags);
|
||||
@@ -344,8 +334,6 @@ static inline uint16 TownTicksToGameTicks(uint16 ticks) {
|
||||
}
|
||||
|
||||
|
||||
extern CargoTypes _town_cargoes_accepted;
|
||||
|
||||
RoadType GetTownRoadType(const Town *t);
|
||||
|
||||
#endif /* TOWN_H */
|
||||
|
@@ -60,7 +60,6 @@
|
||||
#include "safeguards.h"
|
||||
|
||||
TownID _new_town_id;
|
||||
CargoTypes _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses.
|
||||
|
||||
/* Initialize the town-pool */
|
||||
TownPool _town_pool("Town");
|
||||
@@ -939,91 +938,6 @@ static void ChangeTileOwner_Town(TileIndex tile, Owner old_owner, Owner new_owne
|
||||
/* not used */
|
||||
}
|
||||
|
||||
/** Update the total cargo acceptance of the whole town.
|
||||
* @param t The town to update.
|
||||
*/
|
||||
void UpdateTownCargoTotal(Town *t)
|
||||
{
|
||||
t->cargo_accepted_total = 0;
|
||||
|
||||
const TileArea &area = t->cargo_accepted.GetArea();
|
||||
TILE_AREA_LOOP_STEP(tile, area, AcceptanceMatrix::GRID) {
|
||||
t->cargo_accepted_total |= t->cargo_accepted[tile];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update accepted town cargoes around a specific tile.
|
||||
* @param t The town to update.
|
||||
* @param start Update the values around this tile.
|
||||
* @param update_total Set to true if the total cargo acceptance should be updated.
|
||||
*/
|
||||
static void UpdateTownCargoesSingleGridArea(Town *t, TileIndex start, bool update_total = true)
|
||||
{
|
||||
CargoArray accepted, produced;
|
||||
CargoTypes dummy = 0;
|
||||
|
||||
/* Gather acceptance for all houses in an area around the start tile. */
|
||||
TileArea area = AcceptanceMatrix::GetAreaForTile(start, 1);
|
||||
TILE_AREA_LOOP(tile, area) {
|
||||
if (!IsTileType(tile, MP_HOUSE) || GetTownIndex(tile) != t->index) continue;
|
||||
|
||||
AddAcceptedCargo_Town(tile, accepted, &dummy);
|
||||
AddProducedCargo_Town(tile, produced);
|
||||
}
|
||||
|
||||
/* Create bitmap of produced and accepted cargoes. */
|
||||
CargoTypes acc = 0;
|
||||
for (uint cid = 0; cid < NUM_CARGO; cid++) {
|
||||
if (accepted[cid] >= 8) SetBit(acc, cid);
|
||||
if (produced[cid] > 0) SetBit(t->cargo_produced, cid);
|
||||
}
|
||||
t->cargo_accepted[start] = acc;
|
||||
|
||||
if (update_total) UpdateTownCargoTotal(t);
|
||||
}
|
||||
|
||||
static void UpdateTownCargoesHouse(Town *t, TileIndex start, bool x_two_tiles, bool y_two_tiles, bool update_total = true)
|
||||
{
|
||||
TileIndex lower = TileAddSaturating(start, -AcceptanceMatrix::GRID, -AcceptanceMatrix::GRID);
|
||||
TileIndex upper = TileAddSaturating(start, AcceptanceMatrix::GRID + (x_two_tiles ? 1 : 0), AcceptanceMatrix::GRID + (y_two_tiles ? 1 : 0));
|
||||
for (uint x = TileX(lower) & ~(AcceptanceMatrix::GRID - 1); x <= TileX(upper); x += AcceptanceMatrix::GRID) {
|
||||
for (uint y = TileY(lower) & ~(AcceptanceMatrix::GRID - 1); y <= TileY(upper); y += AcceptanceMatrix::GRID) {
|
||||
UpdateTownCargoesSingleGridArea(t, TileXY(x, y), false);
|
||||
}
|
||||
}
|
||||
if (update_total) UpdateTownCargoTotal(t);
|
||||
}
|
||||
|
||||
/** Update cargo acceptance for the complete town.
|
||||
* @param t The town to update.
|
||||
*/
|
||||
void UpdateTownCargoes(Town *t)
|
||||
{
|
||||
t->cargo_produced = 0;
|
||||
|
||||
const TileArea &area = t->cargo_accepted.GetArea();
|
||||
if (area.tile != INVALID_TILE) {
|
||||
/* Update acceptance for each grid square. */
|
||||
TILE_AREA_LOOP_STEP(tile, area, AcceptanceMatrix::GRID) {
|
||||
UpdateTownCargoesSingleGridArea(t, tile, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the total acceptance. */
|
||||
UpdateTownCargoTotal(t);
|
||||
}
|
||||
|
||||
/** Updates the bitmap of all cargoes accepted by houses. */
|
||||
void UpdateTownCargoBitmap()
|
||||
{
|
||||
_town_cargoes_accepted = 0;
|
||||
|
||||
for (const Town *town : Town::Iterate()) {
|
||||
_town_cargoes_accepted |= town->cargo_accepted_total;
|
||||
}
|
||||
}
|
||||
|
||||
static bool GrowTown(Town *t);
|
||||
|
||||
static void TownTickHandler(Town *t)
|
||||
@@ -2166,8 +2080,6 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
/* 't' can't be nullptr since 'random' is false outside scenedit */
|
||||
assert(!random);
|
||||
|
||||
UpdateTownCargoBitmap();
|
||||
|
||||
if (_current_company == OWNER_DEITY) {
|
||||
SetDParam(0, t->index);
|
||||
AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile);
|
||||
@@ -2754,7 +2666,6 @@ static void DoBuildHouse(Town *t, TileIndex tile, HouseID house, byte random_bit
|
||||
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
|
||||
UpdateTownRadius(t);
|
||||
UpdateTownGrowthRate(t);
|
||||
UpdateTownCargoesHouse(t, tile, hs->building_flags & BUILDING_2_TILES_X, hs->building_flags & BUILDING_2_TILES_Y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2961,9 +2872,6 @@ void ClearTownHouse(Town *t, TileIndex tile)
|
||||
RemoveNearbyStations(t, tile, hs->building_flags);
|
||||
|
||||
UpdateTownRadius(t);
|
||||
|
||||
/* Update cargo acceptance. */
|
||||
UpdateTownCargoesHouse(t, tile, hs->building_flags & BUILDING_2_TILES_X, hs->building_flags & BUILDING_2_TILES_Y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4024,10 +3932,8 @@ void TownsMonthlyLoop()
|
||||
UpdateTownGrowth(t);
|
||||
UpdateTownRating(t);
|
||||
UpdateTownUnwanted(t);
|
||||
UpdateTownCargoes(t);
|
||||
}
|
||||
|
||||
UpdateTownCargoBitmap();
|
||||
}
|
||||
|
||||
void TownsYearlyLoop()
|
||||
|
@@ -2153,22 +2153,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
||||
if (IsInvisibilitySet(TO_BRIDGES)) return;
|
||||
|
||||
psid++;
|
||||
if (ti->z + 5 == z) {
|
||||
/* draw poles below for small bridges */
|
||||
if (psid->sprite != 0) {
|
||||
SpriteID image = psid->sprite;
|
||||
SpriteID pal = psid->pal;
|
||||
if (IsTransparencySet(TO_BRIDGES)) {
|
||||
SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
|
||||
pal = PALETTE_TO_TRANSPARENT;
|
||||
}
|
||||
|
||||
DrawGroundSpriteAt(image, pal, x - ti->x, y - ti->y, z - ti->z);
|
||||
}
|
||||
} else {
|
||||
/* draw pillars below for high bridges */
|
||||
DrawBridgePillars(psid, ti, axis, drawfarpillar, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1443,7 +1443,7 @@ void CallVehicleTicks()
|
||||
|
||||
if (!IsLocalCompany()) continue;
|
||||
|
||||
if (res.Succeeded()) {
|
||||
if (res.Succeeded() && res.GetCost() != 0) {
|
||||
ShowCostOrIncomeAnimation(x, y, z, res.GetCost());
|
||||
continue;
|
||||
}
|
||||
|
Reference in New Issue
Block a user