mirror of https://github.com/OpenTTD/OpenTTD
(svn r20168) [1.0] -Backport from trunk:
- Fix: Do not scan /data and ~/data (if they happen to be your working directory). If it's the directory where your binary is located it will still scan them [FS#3949] (r20166) - Fix: Integer comparison failed in case the difference was more than "MAX_UINT"/2 [FS#3954] (r20162) - Fix: [YAPP] Converting a one-way block to a path signal with trains on both sides could lead to a train crash [FS#3937] (r20156) - Fix: [NewGRF] Improve handling of snowing of railtypes and (infra)structures on foundations [FS#3883] (r20153, r20132, r20126, r20125)release/1.0
parent
bf4fceef98
commit
cd5e653e8f
|
@ -1755,6 +1755,48 @@ function Regression::PrintSubsidy(subsidy_id)
|
||||||
print(" GetCargoType(): " + AISubsidy.GetCargoType(subsidy_id));
|
print(" GetCargoType(): " + AISubsidy.GetCargoType(subsidy_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Regression::Math()
|
||||||
|
{
|
||||||
|
print("");
|
||||||
|
print("--Math--");
|
||||||
|
print(" -2147483648 < -2147483647: " + (-2147483648 < -2147483647));
|
||||||
|
print(" -2147483648 < -1 : " + (-2147483648 < -1 ));
|
||||||
|
print(" -2147483648 < 0 : " + (-2147483648 < 0 ));
|
||||||
|
print(" -2147483648 < 1 : " + (-2147483648 < 1 ));
|
||||||
|
print(" -2147483648 < 2147483647: " + (-2147483648 < 2147483647));
|
||||||
|
|
||||||
|
print(" -2147483647 < -2147483648: " + (-2147483647 < -2147483648));
|
||||||
|
print(" -1 < -2147483648: " + (-1 < -2147483648));
|
||||||
|
print(" 0 < -2147483648: " + ( 0 < -2147483648));
|
||||||
|
print(" 1 < -2147483648: " + ( 1 < -2147483648));
|
||||||
|
print(" 2147483647 < -2147483648: " + ( 2147483647 < -2147483648));
|
||||||
|
|
||||||
|
print(" -1 > 2147483647: " + (-1 > 2147483647));
|
||||||
|
print(" -1 > 1 : " + (-1 > 1 ));
|
||||||
|
print(" -1 > 0 : " + (-1 > 0 ));
|
||||||
|
print(" -1 > -1 : " + (-1 > -1 ));
|
||||||
|
print(" -1 > -2147483648: " + (-1 > -2147483648));
|
||||||
|
|
||||||
|
print(" 1 > 2147483647: " + ( 1 > 2147483647));
|
||||||
|
print(" 1 > 1 : " + ( 1 > 1 ));
|
||||||
|
print(" 1 > 0 : " + ( 1 > 0 ));
|
||||||
|
print(" 1 > -1 : " + ( 1 > -1 ));
|
||||||
|
print(" 1 > -2147483648: " + ( 1 > -2147483648));
|
||||||
|
|
||||||
|
print(" 2147483647 > 2147483646: " + ( 2147483647 > 2147483646));
|
||||||
|
print(" 2147483647 > 1 : " + ( 2147483647 > 1 ));
|
||||||
|
print(" 2147483647 > 0 : " + ( 2147483647 > 0 ));
|
||||||
|
print(" 2147483647 > -1 : " + ( 2147483647 > -1 ));
|
||||||
|
print(" 2147483647 > -2147483648: " + ( 2147483647 > -2147483648));
|
||||||
|
|
||||||
|
print(" 2147483646 > 2147483647: " + ( 2147483646 > 2147483647));
|
||||||
|
print(" 1 > 2147483647: " + ( 1 > 2147483647));
|
||||||
|
print(" 0 > 2147483647: " + ( 0 > 2147483647));
|
||||||
|
print(" -1 > 2147483647: " + (-1 > 2147483647));
|
||||||
|
print(" -2147483648 > 2147483647: " + (-2147483648 > 2147483647));
|
||||||
|
|
||||||
|
print(" 13725 > -2147483648: " + ( 13725 > -2147483648));
|
||||||
|
}
|
||||||
|
|
||||||
function Regression::Start()
|
function Regression::Start()
|
||||||
{
|
{
|
||||||
|
@ -1820,5 +1862,7 @@ function Regression::Start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print(" IsEventWaiting: false");
|
print(" IsEventWaiting: false");
|
||||||
|
|
||||||
|
this.Math();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8630,4 +8630,37 @@ ERROR: HasNext() is invalid as Begin() is never called
|
||||||
GetEventType: 6
|
GetEventType: 6
|
||||||
Unknown Event
|
Unknown Event
|
||||||
IsEventWaiting: false
|
IsEventWaiting: false
|
||||||
|
|
||||||
|
--Math--
|
||||||
|
-2147483648 < -2147483647: true
|
||||||
|
-2147483648 < -1 : true
|
||||||
|
-2147483648 < 0 : true
|
||||||
|
-2147483648 < 1 : true
|
||||||
|
-2147483648 < 2147483647: true
|
||||||
|
-2147483647 < -2147483648: false
|
||||||
|
-1 < -2147483648: false
|
||||||
|
0 < -2147483648: false
|
||||||
|
1 < -2147483648: false
|
||||||
|
2147483647 < -2147483648: false
|
||||||
|
-1 > 2147483647: false
|
||||||
|
-1 > 1 : false
|
||||||
|
-1 > 0 : false
|
||||||
|
-1 > -1 : false
|
||||||
|
-1 > -2147483648: true
|
||||||
|
1 > 2147483647: false
|
||||||
|
1 > 1 : false
|
||||||
|
1 > 0 : true
|
||||||
|
1 > -1 : true
|
||||||
|
1 > -2147483648: true
|
||||||
|
2147483647 > 2147483646: true
|
||||||
|
2147483647 > 1 : true
|
||||||
|
2147483647 > 0 : true
|
||||||
|
2147483647 > -1 : true
|
||||||
|
2147483647 > -2147483648: true
|
||||||
|
2147483646 > 2147483647: false
|
||||||
|
1 > 2147483647: false
|
||||||
|
0 > 2147483647: false
|
||||||
|
-1 > 2147483647: false
|
||||||
|
-2147483648 > 2147483647: false
|
||||||
|
13725 > -2147483648: true
|
||||||
ERROR: The AI died unexpectedly.
|
ERROR: The AI died unexpectedly.
|
||||||
|
|
|
@ -253,6 +253,9 @@ The required 3rd party files listed in the section 4.1 "(Required) 3rd party fil
|
||||||
as well as other non-compulsory extensions (NewGRFs, AI, heightmaps, scenarios) can be
|
as well as other non-compulsory extensions (NewGRFs, AI, heightmaps, scenarios) can be
|
||||||
placed in a few different locations:
|
placed in a few different locations:
|
||||||
1. The current working directory (from where you started OpenTTD)
|
1. The current working directory (from where you started OpenTTD)
|
||||||
|
For non-Windows operating systems OpenTTD will not scan for files in this
|
||||||
|
directory if it is your personal directory, i.e. "~/", or when it is the
|
||||||
|
root directory, i.e. "/".
|
||||||
2. Your personal directory
|
2. Your personal directory
|
||||||
Windows: C:\My Documents (95, 98, ME)
|
Windows: C:\My Documents (95, 98, ME)
|
||||||
C:\Documents and Settings\<username>\My Documents\OpenTTD (2000, XP)
|
C:\Documents and Settings\<username>\My Documents\OpenTTD (2000, XP)
|
||||||
|
|
|
@ -186,7 +186,8 @@ bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
|
||||||
case OT_STRING:
|
case OT_STRING:
|
||||||
_RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
|
_RET_SUCCEED(scstrcmp(_stringval(o1),_stringval(o2)));
|
||||||
case OT_INTEGER:
|
case OT_INTEGER:
|
||||||
_RET_SUCCEED(_integer(o1)-_integer(o2));
|
/* FS#3954: wrong integer comparison */
|
||||||
|
_RET_SUCCEED((_integer(o1)<_integer(o2))?-1:(_integer(o1)==_integer(o2))?0:1);
|
||||||
case OT_FLOAT:
|
case OT_FLOAT:
|
||||||
_RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
|
_RET_SUCCEED((_float(o1)<_float(o2))?-1:1);
|
||||||
case OT_TABLE:
|
case OT_TABLE:
|
||||||
|
|
|
@ -165,20 +165,20 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
|
||||||
/**
|
/**
|
||||||
* Get the base wire sprite to use.
|
* Get the base wire sprite to use.
|
||||||
*/
|
*/
|
||||||
static inline SpriteID GetWireBase(TileIndex tile)
|
static inline SpriteID GetWireBase(TileIndex tile, bool upper_halftile = false)
|
||||||
{
|
{
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
|
||||||
SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES);
|
SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES, upper_halftile);
|
||||||
return wires == 0 ? SPR_WIRE_BASE : wires;
|
return wires == 0 ? SPR_WIRE_BASE : wires;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the base pylon sprite to use.
|
* Get the base pylon sprite to use.
|
||||||
*/
|
*/
|
||||||
static inline SpriteID GetPylonBase(TileIndex tile)
|
static inline SpriteID GetPylonBase(TileIndex tile, bool upper_halftile = false)
|
||||||
{
|
{
|
||||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
|
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
|
||||||
SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS);
|
SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS, upper_halftile);
|
||||||
return pylons == 0 ? SPR_PYLON_BASE : pylons;
|
return pylons == 0 ? SPR_PYLON_BASE : pylons;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,11 @@ static void DrawCatenaryRailway(const TileInfo *ti)
|
||||||
|
|
||||||
/* Half tile slopes coincide only with horizontal/vertical track.
|
/* Half tile slopes coincide only with horizontal/vertical track.
|
||||||
* Faking a flat slope results in the correct sprites on positions. */
|
* Faking a flat slope results in the correct sprites on positions. */
|
||||||
if (IsHalftileSlope(tileh[TS_HOME])) tileh[TS_HOME] = SLOPE_FLAT;
|
Corner halftile_corner = CORNER_INVALID;
|
||||||
|
if (IsHalftileSlope(tileh[TS_HOME])) {
|
||||||
|
halftile_corner = GetHalftileSlopeCorner(tileh[TS_HOME]);
|
||||||
|
tileh[TS_HOME] = SLOPE_FLAT;
|
||||||
|
}
|
||||||
|
|
||||||
TLG tlg = GetTLG(ti->tile);
|
TLG tlg = GetTLG(ti->tile);
|
||||||
byte PCPstatus = 0;
|
byte PCPstatus = 0;
|
||||||
|
@ -295,9 +299,17 @@ static void DrawCatenaryRailway(const TileInfo *ti)
|
||||||
|
|
||||||
AdjustTileh(ti->tile, &tileh[TS_HOME]);
|
AdjustTileh(ti->tile, &tileh[TS_HOME]);
|
||||||
|
|
||||||
SpriteID pylon_base = GetPylonBase(ti->tile);
|
SpriteID pylon_normal = GetPylonBase(ti->tile);
|
||||||
|
SpriteID pylon_halftile = (halftile_corner != CORNER_INVALID) ? GetPylonBase(ti->tile, true) : pylon_normal;
|
||||||
|
|
||||||
for (DiagDirection i = DIAGDIR_BEGIN; i < DIAGDIR_END; i++) {
|
for (DiagDirection i = DIAGDIR_BEGIN; i < DIAGDIR_END; i++) {
|
||||||
|
static const uint edge_corners[] = {
|
||||||
|
1 << CORNER_N | 1 << CORNER_E, // DIAGDIR_NE
|
||||||
|
1 << CORNER_S | 1 << CORNER_E, // DIAGDIR_SE
|
||||||
|
1 << CORNER_S | 1 << CORNER_W, // DIAGDIR_SW
|
||||||
|
1 << CORNER_N | 1 << CORNER_W, // DIAGDIR_NW
|
||||||
|
};
|
||||||
|
SpriteID pylon_base = (halftile_corner != CORNER_INVALID && HasBit(edge_corners[i], halftile_corner)) ? pylon_halftile : pylon_normal;
|
||||||
TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
|
TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
|
||||||
Foundation foundation = FOUNDATION_NONE;
|
Foundation foundation = FOUNDATION_NONE;
|
||||||
byte elevation = GetPCPElevation(ti->tile, i);
|
byte elevation = GetPCPElevation(ti->tile, i);
|
||||||
|
@ -426,11 +438,21 @@ static void DrawCatenaryRailway(const TileInfo *ti)
|
||||||
if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
|
if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteID wire_base = GetWireBase(ti->tile);
|
SpriteID wire_normal = GetWireBase(ti->tile);
|
||||||
|
SpriteID wire_halftile = (halftile_corner != CORNER_INVALID) ? GetWireBase(ti->tile, true) : wire_normal;
|
||||||
|
Track halftile_track;
|
||||||
|
switch (halftile_corner) {
|
||||||
|
case CORNER_W: halftile_track = TRACK_LEFT; break;
|
||||||
|
case CORNER_S: halftile_track = TRACK_LOWER; break;
|
||||||
|
case CORNER_E: halftile_track = TRACK_RIGHT; break;
|
||||||
|
case CORNER_N: halftile_track = TRACK_UPPER; break;
|
||||||
|
default: halftile_track = INVALID_TRACK; break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Drawing of pylons is finished, now draw the wires */
|
/* Drawing of pylons is finished, now draw the wires */
|
||||||
for (Track t = TRACK_BEGIN; t < TRACK_END; t++) {
|
for (Track t = TRACK_BEGIN; t < TRACK_END; t++) {
|
||||||
if (HasBit(wireconfig[TS_HOME], t)) {
|
if (HasBit(wireconfig[TS_HOME], t)) {
|
||||||
|
SpriteID wire_base = (t == halftile_track) ? wire_halftile : wire_normal;
|
||||||
byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) +
|
byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) +
|
||||||
(HasBit(PCPstatus, PCPpositions[t][1]) << 1);
|
(HasBit(PCPstatus, PCPpositions[t][1]) << 1);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct Fio {
|
||||||
FILE *handles[MAX_FILE_SLOTS]; ///< array of file handles we can have open
|
FILE *handles[MAX_FILE_SLOTS]; ///< array of file handles we can have open
|
||||||
byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file
|
byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file
|
||||||
const char *filenames[MAX_FILE_SLOTS]; ///< array of filenames we (should) have open
|
const char *filenames[MAX_FILE_SLOTS]; ///< array of filenames we (should) have open
|
||||||
char *shortnames[MAX_FILE_SLOTS];///< array of short names for spriteloader's use
|
char *shortnames[MAX_FILE_SLOTS]; ///< array of short names for spriteloader's use
|
||||||
#if defined(LIMITED_FDS)
|
#if defined(LIMITED_FDS)
|
||||||
uint open_handles; ///< current amount of open handles
|
uint open_handles; ///< current amount of open handles
|
||||||
uint usage_count[MAX_FILE_SLOTS]; ///< count how many times this file has been opened
|
uint usage_count[MAX_FILE_SLOTS]; ///< count how many times this file has been opened
|
||||||
|
@ -53,6 +53,9 @@ struct Fio {
|
||||||
|
|
||||||
static Fio _fio;
|
static Fio _fio;
|
||||||
|
|
||||||
|
/** Whether the working directory should be scanned. */
|
||||||
|
static bool _do_scan_working_directory = true;
|
||||||
|
|
||||||
/* Get current position in file */
|
/* Get current position in file */
|
||||||
size_t FioGetPos()
|
size_t FioGetPos()
|
||||||
{
|
{
|
||||||
|
@ -875,6 +878,33 @@ void ChangeWorkingDirectory(const char *exe)
|
||||||
#endif /* WITH_COCOA */
|
#endif /* WITH_COCOA */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we should scan the working directory.
|
||||||
|
* It should not be scanned if it's the root or
|
||||||
|
* the home directory as in both cases a big data
|
||||||
|
* directory can cause huge amounts of unrelated
|
||||||
|
* files scanned. Furthermore there are nearly no
|
||||||
|
* use cases for the home/root directory to have
|
||||||
|
* OpenTTD directories.
|
||||||
|
* @return true if it should be scanned.
|
||||||
|
*/
|
||||||
|
bool DoScanWorkingDirectory()
|
||||||
|
{
|
||||||
|
/* No working directory, so nothing to do. */
|
||||||
|
if (_searchpaths[SP_WORKING_DIR] == NULL) return false;
|
||||||
|
|
||||||
|
/* Working directory is root, so do nothing. */
|
||||||
|
if (strcmp(_searchpaths[SP_WORKING_DIR], PATHSEP) == 0) return false;
|
||||||
|
|
||||||
|
/* No personal/home directory, so the working directory won't be that. */
|
||||||
|
if (_searchpaths[SP_PERSONAL_DIR] == NULL) return true;
|
||||||
|
|
||||||
|
char tmp[MAX_PATH];
|
||||||
|
snprintf(tmp, lengthof(tmp), "%s%s", _searchpaths[SP_WORKING_DIR], PERSONAL_DIR);
|
||||||
|
AppendPathSeparator(tmp, MAX_PATH);
|
||||||
|
return strcmp(tmp, _searchpaths[SP_PERSONAL_DIR]) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the base (personal dir and game data dir) paths
|
* Determine the base (personal dir and game data dir) paths
|
||||||
* @param exe the path to the executable
|
* @param exe the path to the executable
|
||||||
|
@ -920,6 +950,8 @@ void DetermineBasePaths(const char *exe)
|
||||||
_searchpaths[SP_WORKING_DIR] = strdup(tmp);
|
_searchpaths[SP_WORKING_DIR] = strdup(tmp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_do_scan_working_directory = DoScanWorkingDirectory();
|
||||||
|
|
||||||
/* Change the working directory to that one of the executable */
|
/* Change the working directory to that one of the executable */
|
||||||
ChangeWorkingDirectory(exe);
|
ChangeWorkingDirectory(exe);
|
||||||
if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0';
|
if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0';
|
||||||
|
@ -960,7 +992,10 @@ void DeterminePaths(const char *exe)
|
||||||
DetermineBasePaths(exe);
|
DetermineBasePaths(exe);
|
||||||
|
|
||||||
Searchpath sp;
|
Searchpath sp;
|
||||||
FOR_ALL_SEARCHPATHS(sp) DEBUG(misc, 4, "%s added as search path", _searchpaths[sp]);
|
FOR_ALL_SEARCHPATHS(sp) {
|
||||||
|
if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
|
||||||
|
DEBUG(misc, 4, "%s added as search path", _searchpaths[sp]);
|
||||||
|
}
|
||||||
|
|
||||||
if (_config_file != NULL) {
|
if (_config_file != NULL) {
|
||||||
_personal_dir = strdup(_config_file);
|
_personal_dir = strdup(_config_file);
|
||||||
|
@ -1176,6 +1211,9 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r
|
||||||
uint num = 0;
|
uint num = 0;
|
||||||
|
|
||||||
FOR_ALL_SEARCHPATHS(sp) {
|
FOR_ALL_SEARCHPATHS(sp) {
|
||||||
|
/* Don't search in the working directory */
|
||||||
|
if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
|
||||||
|
|
||||||
FioAppendDirectory(path, MAX_PATH, sp, sd);
|
FioAppendDirectory(path, MAX_PATH, sp, sd);
|
||||||
num += ScanPath(this, extension, path, strlen(path), recursive);
|
num += ScanPath(this, extension, path, strlen(path), recursive);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@
|
||||||
#include "industrytype.h"
|
#include "industrytype.h"
|
||||||
#include "newgrf.h"
|
#include "newgrf.h"
|
||||||
#include "newgrf_commons.h"
|
#include "newgrf_commons.h"
|
||||||
|
#include "clear_map.h"
|
||||||
#include "station_map.h"
|
#include "station_map.h"
|
||||||
#include "tree_map.h"
|
#include "tree_map.h"
|
||||||
|
#include "tunnelbridge_map.h"
|
||||||
#include "core/mem_func.hpp"
|
#include "core/mem_func.hpp"
|
||||||
|
|
||||||
/** Constructor of generic class
|
/** Constructor of generic class
|
||||||
|
@ -278,13 +280,56 @@ void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its)
|
||||||
/** Function used by houses (and soon industries) to get information
|
/** Function used by houses (and soon industries) to get information
|
||||||
* on type of "terrain" the tile it is queries sits on.
|
* on type of "terrain" the tile it is queries sits on.
|
||||||
* @param tile TileIndex of the tile been queried
|
* @param tile TileIndex of the tile been queried
|
||||||
|
* @param upper_halftile If true, query upper halftile in case of rail tiles.
|
||||||
* @return value corresponding to the grf expected format:
|
* @return value corresponding to the grf expected format:
|
||||||
* Terrain type: 0 normal, 1 desert, 2 rainforest, 4 on or above snowline */
|
* Terrain type: 0 normal, 1 desert, 2 rainforest, 4 on or above snowline */
|
||||||
uint32 GetTerrainType(TileIndex tile)
|
uint32 GetTerrainType(TileIndex tile, bool upper_halftile)
|
||||||
{
|
{
|
||||||
switch (_settings_game.game_creation.landscape) {
|
switch (_settings_game.game_creation.landscape) {
|
||||||
case LT_TROPIC: return GetTropicZone(tile);
|
case LT_TROPIC: return GetTropicZone(tile);
|
||||||
case LT_ARCTIC: return GetTileZ(tile) > GetSnowLine() ? 4 : 0;
|
case LT_ARCTIC: {
|
||||||
|
bool has_snow;
|
||||||
|
switch (GetTileType(tile)) {
|
||||||
|
case MP_CLEAR:
|
||||||
|
has_snow = IsSnowTile(tile) && GetClearDensity(tile) >= 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_RAILWAY: {
|
||||||
|
RailGroundType ground = GetRailGroundType(tile);
|
||||||
|
has_snow = (ground == RAIL_GROUND_ICE_DESERT || (upper_halftile && ground == RAIL_GROUND_HALF_SNOW));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MP_ROAD:
|
||||||
|
has_snow = IsOnSnow(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_TREES: {
|
||||||
|
TreeGround ground = GetTreeGround(tile);
|
||||||
|
has_snow = (ground == TREE_GROUND_SNOW_DESERT || ground == TREE_GROUND_ROUGH_SNOW) && GetTreeDensity(tile) >= 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MP_TUNNELBRIDGE:
|
||||||
|
has_snow = HasTunnelBridgeSnowOrDesert(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_STATION:
|
||||||
|
case MP_HOUSE:
|
||||||
|
case MP_INDUSTRY:
|
||||||
|
case MP_UNMOVABLE:
|
||||||
|
/* These tiles usually have a levelling foundation. So use max Z */
|
||||||
|
has_snow = (GetTileMaxZ(tile) > GetSnowLine());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_WATER:
|
||||||
|
has_snow = (GetTileZ(tile) > GetSnowLine());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
return has_snow ? 4 : 0;
|
||||||
|
}
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ extern HouseOverrideManager _house_mngr;
|
||||||
extern IndustryOverrideManager _industry_mngr;
|
extern IndustryOverrideManager _industry_mngr;
|
||||||
extern IndustryTileOverrideManager _industile_mngr;
|
extern IndustryTileOverrideManager _industile_mngr;
|
||||||
|
|
||||||
uint32 GetTerrainType(TileIndex tile);
|
uint32 GetTerrainType(TileIndex tile, bool upper_halftile = false);
|
||||||
TileIndex GetNearbyTile(byte parameter, TileIndex tile);
|
TileIndex GetNearbyTile(byte parameter, TileIndex tile);
|
||||||
uint32 GetNearbyTileInformation(TileIndex tile);
|
uint32 GetNearbyTileInformation(TileIndex tile);
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ static uint32 RailTypeGetVariable(const ResolverObject *object, byte variable, b
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
case 0x40: return GetTerrainType(tile);
|
case 0x40: return GetTerrainType(tile, object->u.routes.upper_halftile);
|
||||||
case 0x41: return 0;
|
case 0x41: return 0;
|
||||||
case 0x42: return IsLevelCrossingTile(tile) && IsCrossingBarred(tile);
|
case 0x42: return IsLevelCrossingTile(tile) && IsCrossingBarred(tile);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ static const SpriteGroup *RailTypeResolveReal(const ResolverObject *object, cons
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile)
|
static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile, bool upper_halftile)
|
||||||
{
|
{
|
||||||
res->GetRandomBits = &RailTypeGetRandomBits;
|
res->GetRandomBits = &RailTypeGetRandomBits;
|
||||||
res->GetTriggers = &RailTypeGetTriggers;
|
res->GetTriggers = &RailTypeGetTriggers;
|
||||||
|
@ -72,6 +72,7 @@ static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile)
|
||||||
res->ResolveReal = &RailTypeResolveReal;
|
res->ResolveReal = &RailTypeResolveReal;
|
||||||
|
|
||||||
res->u.routes.tile = tile;
|
res->u.routes.tile = tile;
|
||||||
|
res->u.routes.upper_halftile = upper_halftile;
|
||||||
|
|
||||||
res->callback = CBID_NO_CALLBACK;
|
res->callback = CBID_NO_CALLBACK;
|
||||||
res->callback_param1 = 0;
|
res->callback_param1 = 0;
|
||||||
|
@ -82,7 +83,7 @@ static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile)
|
||||||
res->count = 0;
|
res->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg)
|
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, bool upper_halftile)
|
||||||
{
|
{
|
||||||
assert(rtsg < RTSG_END);
|
assert(rtsg < RTSG_END);
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp
|
||||||
const SpriteGroup *group;
|
const SpriteGroup *group;
|
||||||
ResolverObject object;
|
ResolverObject object;
|
||||||
|
|
||||||
NewRailTypeResolver(&object, tile);
|
NewRailTypeResolver(&object, tile, upper_halftile);
|
||||||
|
|
||||||
group = SpriteGroup::Resolve(rti->group[rtsg], &object);
|
group = SpriteGroup::Resolve(rti->group[rtsg], &object);
|
||||||
if (group == NULL || group->GetNumResults() == 0) return 0;
|
if (group == NULL || group->GetNumResults() == 0) return 0;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "rail.h"
|
#include "rail.h"
|
||||||
|
|
||||||
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg);
|
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, bool upper_halftile = false);
|
||||||
|
|
||||||
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile);
|
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile);
|
||||||
|
|
||||||
|
|
|
@ -342,6 +342,7 @@ struct ResolverObject {
|
||||||
} generic;
|
} generic;
|
||||||
struct {
|
struct {
|
||||||
TileIndex tile;
|
TileIndex tile;
|
||||||
|
bool upper_halftile; ///< Are we resolving sprites for the upper halftile?
|
||||||
} routes;
|
} routes;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,10 @@ Train *GetTrainForReservation(TileIndex tile, Track track)
|
||||||
* have a train on it. We need FollowReservation to ignore one-way signals
|
* have a train on it. We need FollowReservation to ignore one-way signals
|
||||||
* here, as one of the two search directions will be the "wrong" way. */
|
* here, as one of the two search directions will be the "wrong" way. */
|
||||||
for (int i = 0; i < 2; ++i, trackdir = ReverseTrackdir(trackdir)) {
|
for (int i = 0; i < 2; ++i, trackdir = ReverseTrackdir(trackdir)) {
|
||||||
|
/* If the tile has a one-way block signal in the current trackdir, skip the
|
||||||
|
* search in this direction as the reservation can't come from this side.*/
|
||||||
|
if (HasOnewaySignalBlockingTrackdir(tile, ReverseTrackdir(trackdir)) && !HasPbsSignalOnTrackdir(tile, trackdir)) continue;
|
||||||
|
|
||||||
FindTrainOnTrackInfo ftoti;
|
FindTrainOnTrackInfo ftoti;
|
||||||
ftoti.res = FollowReservation(GetTileOwner(tile), rts, tile, trackdir, true);
|
ftoti.res = FollowReservation(GetTileOwner(tile), rts, tile, trackdir, true);
|
||||||
|
|
||||||
|
|
|
@ -1750,8 +1750,9 @@ static void DrawTrackFence_WE_2(const TileInfo *ti, SpriteID base_image)
|
||||||
|
|
||||||
static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti)
|
static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti)
|
||||||
{
|
{
|
||||||
/* Base sprite for track fences. */
|
/* Base sprite for track fences.
|
||||||
SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES);
|
* Note: Halftile slopes only have fences on the upper part. */
|
||||||
|
SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES, IsHalftileSlope(ti->tileh));
|
||||||
if (base_image == 0) base_image = SPR_TRACK_FENCE_FLAT_X;
|
if (base_image == 0) base_image = SPR_TRACK_FENCE_FLAT_X;
|
||||||
|
|
||||||
switch (GetRailGroundType(ti->tile)) {
|
switch (GetRailGroundType(ti->tile)) {
|
||||||
|
@ -1910,6 +1911,8 @@ static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeIn
|
||||||
|
|
||||||
if (IsValidCorner(halftile_corner)) {
|
if (IsValidCorner(halftile_corner)) {
|
||||||
DrawFoundation(ti, HalftileFoundation(halftile_corner));
|
DrawFoundation(ti, HalftileFoundation(halftile_corner));
|
||||||
|
overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY, true);
|
||||||
|
ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND, true);
|
||||||
|
|
||||||
/* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
|
/* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
|
||||||
Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
|
Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
|
||||||
|
|
Loading…
Reference in New Issue