mirror of https://github.com/OpenTTD/OpenTTD
(svn r19857) [1.0] -Backport from trunk:
- Fix: If a waypoint is immediately followed by a path signal a reservation would be made from that path signal before the waypoint is marked passed. As a result the order to go to the waypoint is used to reserve the path after the waypoint and as such trains get lost [FS#3770] (r19784) - Fix: NULL pointer deference when testing relative scope *action2 on an unbuilt engine [FS#3828] (r19782) - Fix: Crash on too long paths [FS#3807] (r19780, r19779, r19778, r19777, r19776) - Fix: MP_VOID tiles shall have no tropic zone [FS#3820] (r19769) - Fix: Half-desert tiles would never revert back to clear tiles (r19768)release/1.0
parent
3f1bc42eb0
commit
eee6e228c7
|
@ -189,19 +189,40 @@ static void TileLoopClearAlps(TileIndex tile)
|
|||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if at least one surrounding tile is desert
|
||||
* @param tile tile to check
|
||||
* @return does this tile have at least one desert tile around?
|
||||
*/
|
||||
static inline bool NeighbourIsDesert(TileIndex tile)
|
||||
{
|
||||
return GetTropicZone(tile + TileDiffXY( 1, 0)) == TROPICZONE_DESERT ||
|
||||
GetTropicZone(tile + TileDiffXY( -1, 0)) == TROPICZONE_DESERT ||
|
||||
GetTropicZone(tile + TileDiffXY( 0, 1)) == TROPICZONE_DESERT ||
|
||||
GetTropicZone(tile + TileDiffXY( 0, -1)) == TROPICZONE_DESERT;
|
||||
}
|
||||
|
||||
static void TileLoopClearDesert(TileIndex tile)
|
||||
{
|
||||
if (IsClearGround(tile, CLEAR_DESERT)) return;
|
||||
/* Current desert level - 0 if it is not desert */
|
||||
uint current = 0;
|
||||
if (IsClearGround(tile, CLEAR_DESERT)) current = GetClearDensity(tile);
|
||||
|
||||
/* Expected desert level - 0 if it shouldn't be desert */
|
||||
uint expected = 0;
|
||||
if (GetTropicZone(tile) == TROPICZONE_DESERT) {
|
||||
SetClearGroundDensity(tile, CLEAR_DESERT, 3);
|
||||
expected = 3;
|
||||
} else if (NeighbourIsDesert(tile)) {
|
||||
expected = 1;
|
||||
}
|
||||
|
||||
if (current == expected) return;
|
||||
|
||||
if (expected == 0) {
|
||||
SetClearGroundDensity(tile, CLEAR_GRASS, 3);
|
||||
} else {
|
||||
if (GetTropicZone(tile + TileDiffXY( 1, 0)) != TROPICZONE_DESERT &&
|
||||
GetTropicZone(tile + TileDiffXY(-1, 0)) != TROPICZONE_DESERT &&
|
||||
GetTropicZone(tile + TileDiffXY( 0, 1)) != TROPICZONE_DESERT &&
|
||||
GetTropicZone(tile + TileDiffXY( 0, -1)) != TROPICZONE_DESERT)
|
||||
return;
|
||||
SetClearGroundDensity(tile, CLEAR_DESERT, 1);
|
||||
/* Transition from clear to desert is not smooth (after clearing desert tile) */
|
||||
SetClearGroundDensity(tile, CLEAR_DESERT, expected);
|
||||
}
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
|
|
|
@ -448,16 +448,21 @@ void FioCreateDirectory(const char *name)
|
|||
* It does not add the path separator to zero-sized strings.
|
||||
* @param buf string to append the separator to
|
||||
* @param buflen the length of the buf
|
||||
* @return true iff the operation succeeded
|
||||
*/
|
||||
void AppendPathSeparator(char *buf, size_t buflen)
|
||||
bool AppendPathSeparator(char *buf, size_t buflen)
|
||||
{
|
||||
size_t s = strlen(buf);
|
||||
|
||||
/* Length of string + path separator + '\0' */
|
||||
if (s != 0 && buf[s - 1] != PATHSEPCHAR && s + 2 < buflen) {
|
||||
if (s != 0 && buf[s - 1] != PATHSEPCHAR) {
|
||||
if (s + 2 >= buflen) return false;
|
||||
|
||||
buf[s] = PATHSEPCHAR;
|
||||
buf[s + 1] = '\0';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -534,7 +539,18 @@ static void SimplifyFileName(char *name)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool TarListAddFile(const char *filename)
|
||||
/* static */ uint TarScanner::DoScan() {
|
||||
DEBUG(misc, 1, "Scanning for tars");
|
||||
TarScanner fs;
|
||||
uint num = fs.Scan(".tar", DATA_DIR, false);
|
||||
num += fs.Scan(".tar", AI_DIR, false);
|
||||
num += fs.Scan(".tar", AI_LIBRARY_DIR, false);
|
||||
num += fs.Scan(".tar", SCENARIO_DIR, false);
|
||||
DEBUG(misc, 1, "Scan complete, found %d files", num);
|
||||
return num;
|
||||
}
|
||||
|
||||
bool TarScanner::AddFile(const char *filename, size_t basepath_length)
|
||||
{
|
||||
/* The TAR-header, repeated for every file */
|
||||
typedef struct TarHeader {
|
||||
|
@ -820,66 +836,6 @@ bool ExtractTar(const char *tar_filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
static int ScanPathForTarFiles(const char *path, size_t basepath_length)
|
||||
{
|
||||
extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
|
||||
|
||||
uint num = 0;
|
||||
struct stat sb;
|
||||
struct dirent *dirent;
|
||||
DIR *dir;
|
||||
|
||||
if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0;
|
||||
|
||||
while ((dirent = readdir(dir)) != NULL) {
|
||||
const char *d_name = FS2OTTD(dirent->d_name);
|
||||
char filename[MAX_PATH];
|
||||
|
||||
if (!FiosIsValidFile(path, dirent, &sb)) continue;
|
||||
|
||||
snprintf(filename, lengthof(filename), "%s%s", path, d_name);
|
||||
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
/* Directory */
|
||||
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
|
||||
AppendPathSeparator(filename, lengthof(filename));
|
||||
num += ScanPathForTarFiles(filename, basepath_length);
|
||||
} else if (S_ISREG(sb.st_mode)) {
|
||||
/* File */
|
||||
char *ext = strrchr(filename, '.');
|
||||
|
||||
/* If no extension or extension isn't .tar, skip the file */
|
||||
if (ext == NULL) continue;
|
||||
if (strcasecmp(ext, ".tar") != 0) continue;
|
||||
|
||||
if (TarListAddFile(filename)) num++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return num;
|
||||
}
|
||||
|
||||
void ScanForTarFiles()
|
||||
{
|
||||
Searchpath sp;
|
||||
char path[MAX_PATH];
|
||||
uint num = 0;
|
||||
|
||||
DEBUG(misc, 1, "Scanning for tars");
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
FioAppendDirectory(path, MAX_PATH, sp, DATA_DIR);
|
||||
num += ScanPathForTarFiles(path, strlen(path));
|
||||
FioAppendDirectory(path, MAX_PATH, sp, AI_DIR);
|
||||
num += ScanPathForTarFiles(path, strlen(path));
|
||||
FioAppendDirectory(path, MAX_PATH, sp, AI_LIBRARY_DIR);
|
||||
num += ScanPathForTarFiles(path, strlen(path));
|
||||
FioAppendDirectory(path, MAX_PATH, sp, SCENARIO_DIR);
|
||||
num += ScanPathForTarFiles(path, strlen(path));
|
||||
}
|
||||
DEBUG(misc, 1, "Scan complete, found %d files", num);
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(WINCE)
|
||||
/**
|
||||
* Determine the base (personal dir and game data dir) paths
|
||||
|
@ -1079,7 +1035,7 @@ void DeterminePaths(const char *exe)
|
|||
}
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
ScanForTarFiles();
|
||||
TarScanner::DoScan();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1158,7 +1114,7 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s
|
|||
/* Directory */
|
||||
if (!recursive) continue;
|
||||
if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
|
||||
AppendPathSeparator(filename, lengthof(filename));
|
||||
if (!AppendPathSeparator(filename, lengthof(filename))) continue;
|
||||
num += ScanPath(fs, extension, filename, basepath_length, recursive);
|
||||
} else if (S_ISREG(sb.st_mode)) {
|
||||
/* File */
|
||||
|
@ -1245,6 +1201,6 @@ uint FileScanner::Scan(const char *extension, const char *directory, bool recurs
|
|||
{
|
||||
char path[MAX_PATH];
|
||||
strecpy(path, directory, lastof(path));
|
||||
AppendPathSeparator(path, lengthof(path));
|
||||
if (!AppendPathSeparator(path, lengthof(path))) return 0;
|
||||
return ScanPath(this, extension, path, strlen(path), recursive);
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ char *FioAppendDirectory(char *buf, size_t buflen, Searchpath sp, Subdirectory s
|
|||
char *FioGetDirectory(char *buf, size_t buflen, Subdirectory subdir);
|
||||
|
||||
void SanitizeFilename(char *filename);
|
||||
void AppendPathSeparator(char *buf, size_t buflen);
|
||||
bool AppendPathSeparator(char *buf, size_t buflen);
|
||||
void DeterminePaths(const char *exe);
|
||||
void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize);
|
||||
bool FileExists(const char *filename);
|
||||
|
@ -87,6 +87,14 @@ public:
|
|||
virtual bool AddFile(const char *filename, size_t basepath_length) = 0;
|
||||
};
|
||||
|
||||
/** Helper for scanning for files with tar as extension */
|
||||
class TarScanner : FileScanner {
|
||||
public:
|
||||
/* virtual */ bool AddFile(const char *filename, size_t basepath_length);
|
||||
|
||||
/** Do the scan for Tars. */
|
||||
static uint DoScan();
|
||||
};
|
||||
|
||||
/* Implementation of opendir/readdir/closedir for Windows */
|
||||
#if defined(WIN32)
|
||||
|
|
|
@ -827,6 +827,8 @@ static void CreateDesertOrRainForest()
|
|||
for (TileIndex tile = 0; tile != MapSize(); ++tile) {
|
||||
if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
|
||||
if (!IsValidTile(tile)) continue;
|
||||
|
||||
for (data = _make_desert_or_rainforest_data;
|
||||
data != endof(_make_desert_or_rainforest_data); ++data) {
|
||||
TileIndex t = AddTileIndexDiffCWrap(tile, *data);
|
||||
|
@ -845,6 +847,8 @@ static void CreateDesertOrRainForest()
|
|||
for (TileIndex tile = 0; tile != MapSize(); ++tile) {
|
||||
if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
|
||||
if (!IsValidTile(tile)) continue;
|
||||
|
||||
for (data = _make_desert_or_rainforest_data;
|
||||
data != endof(_make_desert_or_rainforest_data); ++data) {
|
||||
TileIndex t = AddTileIndexDiffCWrap(tile, *data);
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
extern bool TarListAddFile(const char *filename);
|
||||
extern bool HasScenario(const ContentInfo *ci, bool md5sum);
|
||||
ClientNetworkContentSocketHandler _network_content_client;
|
||||
|
||||
|
@ -498,7 +497,8 @@ void ClientNetworkContentSocketHandler::AfterDownload()
|
|||
if (GunzipFile(this->curInfo)) {
|
||||
unlink(GetFullFilename(this->curInfo, true));
|
||||
|
||||
TarListAddFile(GetFullFilename(this->curInfo, false));
|
||||
TarScanner ts;
|
||||
ts.AddFile(GetFullFilename(this->curInfo, false), 0);
|
||||
|
||||
if (this->curInfo->type == CONTENT_TYPE_BASE_MUSIC) {
|
||||
/* Music can't be in a tar. So extract the tar! */
|
||||
|
|
|
@ -383,6 +383,7 @@ static inline const Vehicle *GRV(const ResolverObject *object)
|
|||
case VSG_SCOPE_SELF: return object->u.vehicle.self;
|
||||
case VSG_SCOPE_PARENT: return object->u.vehicle.parent;
|
||||
case VSG_SCOPE_RELATIVE: {
|
||||
if (object->u.vehicle.self == NULL) return NULL;
|
||||
const Vehicle *v = NULL;
|
||||
switch (GB(object->count, 6, 2)) {
|
||||
default: NOT_REACHED();
|
||||
|
|
|
@ -92,17 +92,20 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot)
|
|||
bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb)
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
|
||||
int res;
|
||||
#if defined(__MORPHOS__) || defined(__AMIGAOS__)
|
||||
/* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */
|
||||
if (FiosIsRoot(path)) {
|
||||
snprintf(filename, lengthof(filename), "%s:%s", path, ent->d_name);
|
||||
res = snprintf(filename, lengthof(filename), "%s:%s", path, ent->d_name);
|
||||
} else // XXX - only next line!
|
||||
#else
|
||||
assert(path[strlen(path) - 1] == PATHSEPCHAR);
|
||||
if (strlen(path) > 2) assert(path[strlen(path) - 2] != PATHSEPCHAR);
|
||||
#endif
|
||||
snprintf(filename, lengthof(filename), "%s%s", path, ent->d_name);
|
||||
res = snprintf(filename, lengthof(filename), "%s%s", path, ent->d_name);
|
||||
|
||||
/* Could we fully concatenate the path and filename? */
|
||||
if (res >= (int)lengthof(filename) || res < 0) return false;
|
||||
|
||||
return stat(filename, sb) == 0;
|
||||
}
|
||||
|
|
|
@ -2065,6 +2065,13 @@ bool AfterLoadGame()
|
|||
}
|
||||
}
|
||||
|
||||
if (CheckSavegameVersion(141)) {
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
/* Reset tropic zone for VOID tiles, they shall not have any. */
|
||||
if (IsTileType(t, MP_VOID)) SetTropicZone(t, TROPICZONE_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Road stops is 'only' updating some caches */
|
||||
AfterLoadRoadStops();
|
||||
AfterLoadLabelMaps();
|
||||
|
|
|
@ -87,9 +87,6 @@ void ScriptScanner::ScanScriptDir(const char *info_file_name, Subdirectory searc
|
|||
char buf[MAX_PATH];
|
||||
Searchpath sp;
|
||||
|
||||
extern void ScanForTarFiles();
|
||||
ScanForTarFiles();
|
||||
|
||||
FOR_ALL_SEARCHPATHS(sp) {
|
||||
FioAppendDirectory(buf, MAX_PATH, sp, search_dir);
|
||||
if (FileExists(buf)) this->ScanDir(buf, info_file_name);
|
||||
|
|
|
@ -395,7 +395,13 @@ void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2);
|
|||
#define _stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
#if !defined(MAX_PATH)
|
||||
#if defined(MAX_PATH)
|
||||
/* It's already defined, no need to override */
|
||||
#elif defined(PATH_MAX) && PATH_MAX > 0
|
||||
/* Use the value from PATH_MAX, if it exists */
|
||||
#define MAX_PATH PATH_MAX
|
||||
#else
|
||||
/* If all else fails, hardcode something :( */
|
||||
#define MAX_PATH 260
|
||||
#endif
|
||||
|
||||
|
|
|
@ -186,6 +186,7 @@ static inline bool IsTileOwner(TileIndex tile, Owner owner)
|
|||
static inline void SetTropicZone(TileIndex tile, TropicZone type)
|
||||
{
|
||||
assert(tile < MapSize());
|
||||
assert(!IsTileType(tile, MP_VOID) || type == TROPICZONE_NORMAL);
|
||||
SB(_m[tile].m6, 0, 2, type);
|
||||
}
|
||||
|
||||
|
|
|
@ -2230,6 +2230,8 @@ static void CheckNextTrainTile(Train *v)
|
|||
if ((v->tile == v->dest_tile && v->current_order.IsType(OT_GOTO_DEPOT)) || v->track == TRACK_BIT_DEPOT) return;
|
||||
/* Exit if we are on a station tile and are going to stop. */
|
||||
if (IsRailStationTile(v->tile) && v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile))) return;
|
||||
/* If we reached our waypoint, make sure we see that. */
|
||||
if (v->current_order.IsType(OT_GOTO_WAYPOINT) && IsRailWaypointTile(v->tile) && GetStationIndex(v->tile) == v->current_order.GetDestination()) ProcessOrders(v);
|
||||
/* Exit if the current order doesn't have a destination, but the train has orders. */
|
||||
if ((v->current_order.IsType(OT_NOTHING) || v->current_order.IsType(OT_LEAVESTATION) || v->current_order.IsType(OT_LOADING)) && v->GetNumOrders() > 0) return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue