mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-07-07 12:59:43 +01:00
(svn r16247) [0.7] -Backport from trunk:
- Fix: [NoAI] Make sure AITunnel::BuildTunnel returns what the documentation says it does (r16244) - Fix: [NoAI] CmdBuildTunnel could be called with invalid parameters from the API code, causing crashes later [FS#2875] (r16243) - Fix: [NewGRF] ActionB should use the online parameters from GRFFile instead of the initial user-specified values from GRFConfig. Also use the values as they were set when the ActionB was executed, not as they are set when the message is shown (r16223) - Fix: Possible crashes when quiting OpenTTD or forcing resizes/redraws of the screen during map generation [FS#2862] (r16220) - Fix: Shared orders without orders were not properly converted causing corrupt/invalid orders when loading pre 0.7 savegames [FS#2878] (r16214)
This commit is contained in:
parent
909af50aaa
commit
1e9fd18e6a
@ -23,14 +23,26 @@
|
|||||||
/* If it's a tunnel alread, take the easy way out! */
|
/* If it's a tunnel alread, take the easy way out! */
|
||||||
if (IsTunnelTile(tile)) return ::GetOtherTunnelEnd(tile);
|
if (IsTunnelTile(tile)) return ::GetOtherTunnelEnd(tile);
|
||||||
|
|
||||||
::DoCommand(tile, 0, 0, DC_AUTO, CMD_BUILD_TUNNEL);
|
uint start_z;
|
||||||
return _build_tunnel_endtile == 0 ? INVALID_TILE : _build_tunnel_endtile;
|
Slope start_tileh = ::GetTileSlope(tile, &start_z);
|
||||||
|
DiagDirection direction = ::GetInclinedSlopeDirection(start_tileh);
|
||||||
|
if (direction == INVALID_DIAGDIR) return INVALID_TILE;
|
||||||
|
|
||||||
|
TileIndexDiff delta = ::TileOffsByDiagDir(direction);
|
||||||
|
uint end_z;
|
||||||
|
do {
|
||||||
|
tile += delta;
|
||||||
|
if (!::IsValidTile(tile)) return INVALID_TILE;
|
||||||
|
|
||||||
|
::GetTileSlope(tile, &end_z);
|
||||||
|
} while (start_z != end_z);
|
||||||
|
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
|
static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
|
||||||
{
|
{
|
||||||
if (!AITunnel::_BuildTunnelRoad2()) {
|
if (!AITunnel::_BuildTunnelRoad2()) {
|
||||||
AIObject::SetLastCommandRes(false);
|
|
||||||
AIInstance::DoCommandReturn(instance);
|
AIInstance::DoCommandReturn(instance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -43,7 +55,6 @@ static void _DoCommandReturnBuildTunnel2(class AIInstance *instance)
|
|||||||
static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
|
static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
|
||||||
{
|
{
|
||||||
if (!AITunnel::_BuildTunnelRoad1()) {
|
if (!AITunnel::_BuildTunnelRoad1()) {
|
||||||
AIObject::SetLastCommandRes(false);
|
|
||||||
AIInstance::DoCommandReturn(instance);
|
AIInstance::DoCommandReturn(instance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -62,7 +73,7 @@ static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
|
|||||||
uint type = 0;
|
uint type = 0;
|
||||||
if (vehicle_type == AIVehicle::VT_ROAD) {
|
if (vehicle_type == AIVehicle::VT_ROAD) {
|
||||||
type |= (TRANSPORT_ROAD << 9);
|
type |= (TRANSPORT_ROAD << 9);
|
||||||
type |= RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
|
type |= ::RoadTypeToRoadTypes((::RoadType)AIObject::GetRoadType());
|
||||||
} else {
|
} else {
|
||||||
type |= (TRANSPORT_RAIL << 9);
|
type |= (TRANSPORT_RAIL << 9);
|
||||||
type |= AIRail::GetCurrentRailType();
|
type |= AIRail::GetCurrentRailType();
|
||||||
@ -74,10 +85,7 @@ static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
AIObject::SetCallbackVariable(0, start);
|
AIObject::SetCallbackVariable(0, start);
|
||||||
if (!AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &_DoCommandReturnBuildTunnel1)) return false;
|
return AIObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &_DoCommandReturnBuildTunnel1);
|
||||||
|
|
||||||
/* In case of test-mode, test if we can build both road pieces */
|
|
||||||
return _BuildTunnelRoad1();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITunnel::_BuildTunnelRoad1()
|
/* static */ bool AITunnel::_BuildTunnelRoad1()
|
||||||
@ -89,10 +97,7 @@ static void _DoCommandReturnBuildTunnel1(class AIInstance *instance)
|
|||||||
DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
|
DiagDirection dir_1 = (DiagDirection)((::TileX(start) == ::TileX(end)) ? (::TileY(start) < ::TileY(end) ? DIAGDIR_NW : DIAGDIR_SE) : (::TileX(start) < ::TileX(end) ? DIAGDIR_NE : DIAGDIR_SW));
|
||||||
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
|
DiagDirection dir_2 = ::ReverseDiagDir(dir_1);
|
||||||
|
|
||||||
if (!AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildTunnel2)) return false;
|
return AIObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (AIObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &_DoCommandReturnBuildTunnel2);
|
||||||
|
|
||||||
/* In case of test-mode, test the other road piece too */
|
|
||||||
return _BuildTunnelRoad2();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool AITunnel::_BuildTunnelRoad2()
|
/* static */ bool AITunnel::_BuildTunnelRoad2()
|
||||||
|
@ -46,11 +46,15 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tile that exits on the other end of a (would be) tunnel starting
|
* Get the tile that exits on the other end of a (would be) tunnel starting
|
||||||
* at tile.
|
* at tile. If there is no 'simple' inclined slope at the start tile,
|
||||||
|
* this function will return AIMap::TILE_INVALID.
|
||||||
* @param tile The tile that is an entrance to a tunnel or the tile where you may want to build a tunnel.
|
* @param tile The tile that is an entrance to a tunnel or the tile where you may want to build a tunnel.
|
||||||
* @pre AIMap::IsValidTile(tile).
|
* @pre AIMap::IsValidTile(tile).
|
||||||
* @return The TileIndex that is the other end of the (would be) tunnel, or
|
* @return The TileIndex that is the other end of the (would be) tunnel, or
|
||||||
* AIMap::TILE_INVALID if no other end was found (can't build tunnel).
|
* AIMap::TILE_INVALID if no other end was found (can't build tunnel).
|
||||||
|
* @note Even if this function returns a valid tile, that is no guarantee
|
||||||
|
* that building a tunnel will succeed. Use BuildTunnel in AITestMode to
|
||||||
|
* check whether a tunnel can actually be build.
|
||||||
*/
|
*/
|
||||||
static TileIndex GetOtherTunnelEnd(TileIndex tile);
|
static TileIndex GetOtherTunnelEnd(TileIndex tile);
|
||||||
|
|
||||||
|
@ -47,32 +47,10 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date);
|
|||||||
* in the genworld.h and genworld.c! -- TrueLight */
|
* in the genworld.h and genworld.c! -- TrueLight */
|
||||||
gw_info _gw;
|
gw_info _gw;
|
||||||
|
|
||||||
/**
|
/** Rights for the map generation */
|
||||||
* Set the status of the Paint flag.
|
ThreadMutex *_genworld_mapgen_mutex = ThreadMutex::New();
|
||||||
* If it is true, the thread will hold with any futher generating till
|
/** Rights for the painting */
|
||||||
* the drawing of the screen is done. This is handled by
|
ThreadMutex *_genworld_paint_mutex = ThreadMutex::New();
|
||||||
* SetGeneratingWorldProgress(), so calling that function will stall
|
|
||||||
* from time to time.
|
|
||||||
*/
|
|
||||||
void SetGeneratingWorldPaintStatus(bool status)
|
|
||||||
{
|
|
||||||
_gw.wait_for_draw = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the thread wants the main program to do a (full) paint.
|
|
||||||
* If this returns false, please do not update the screen. Because we are
|
|
||||||
* writing in a thread, it can cause damaged data (reading and writing the
|
|
||||||
* same tile at the same time).
|
|
||||||
*/
|
|
||||||
bool IsGeneratingWorldReadyForPaint()
|
|
||||||
{
|
|
||||||
/* If we are in quit_thread mode, ignore this and always return false. This
|
|
||||||
* forces the screen to not be drawn, and the GUI not to wait for a draw. */
|
|
||||||
if (!_gw.active || _gw.quit_thread || !_gw.threaded) return false;
|
|
||||||
|
|
||||||
return _gw.wait_for_draw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells if the world generation is done in a thread or not.
|
* Tells if the world generation is done in a thread or not.
|
||||||
@ -100,6 +78,7 @@ static void CleanupGeneration()
|
|||||||
|
|
||||||
DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
|
DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
_genworld_mapgen_mutex->EndCritical();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,6 +88,7 @@ static void _GenerateWorld(void *arg)
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
_generating_world = true;
|
_generating_world = true;
|
||||||
|
_genworld_mapgen_mutex->BeginCritical();
|
||||||
if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
|
if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
|
||||||
/* Set the Random() seed to generation_seed so we produce the same map with the same seed */
|
/* Set the Random() seed to generation_seed so we produce the same map with the same seed */
|
||||||
if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
|
if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
|
||||||
@ -194,6 +174,7 @@ static void _GenerateWorld(void *arg)
|
|||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
_generating_world = false;
|
_generating_world = false;
|
||||||
|
_genworld_mapgen_mutex->EndCritical();
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,11 +204,16 @@ void GenerateWorldSetAbortCallback(gw_abort_proc *proc)
|
|||||||
void WaitTillGeneratedWorld()
|
void WaitTillGeneratedWorld()
|
||||||
{
|
{
|
||||||
if (_gw.thread == NULL) return;
|
if (_gw.thread == NULL) return;
|
||||||
|
|
||||||
|
_genworld_mapgen_mutex->EndCritical();
|
||||||
|
_genworld_paint_mutex->EndCritical();
|
||||||
_gw.quit_thread = true;
|
_gw.quit_thread = true;
|
||||||
_gw.thread->Join();
|
_gw.thread->Join();
|
||||||
delete _gw.thread;
|
delete _gw.thread;
|
||||||
_gw.thread = NULL;
|
_gw.thread = NULL;
|
||||||
_gw.threaded = false;
|
_gw.threaded = false;
|
||||||
|
_genworld_mapgen_mutex->BeginCritical();
|
||||||
|
_genworld_paint_mutex->BeginCritical();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -280,7 +266,6 @@ void GenerateWorld(GenerateWorldMode mode, uint size_x, uint size_y)
|
|||||||
_gw.abort = false;
|
_gw.abort = false;
|
||||||
_gw.abortp = NULL;
|
_gw.abortp = NULL;
|
||||||
_gw.lc = _local_company;
|
_gw.lc = _local_company;
|
||||||
_gw.wait_for_draw = false;
|
|
||||||
_gw.quit_thread = false;
|
_gw.quit_thread = false;
|
||||||
_gw.threaded = true;
|
_gw.threaded = true;
|
||||||
|
|
||||||
@ -315,7 +300,9 @@ void GenerateWorld(GenerateWorldMode mode, uint size_x, uint size_y)
|
|||||||
!ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread)) {
|
!ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread)) {
|
||||||
DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
|
DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
|
||||||
_gw.threaded = false;
|
_gw.threaded = false;
|
||||||
|
_genworld_mapgen_mutex->EndCritical();
|
||||||
_GenerateWorld(NULL);
|
_GenerateWorld(NULL);
|
||||||
|
_genworld_mapgen_mutex->BeginCritical();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ enum {
|
|||||||
LG_TERRAGENESIS = 1, ///< TerraGenesis Perlin landscape generator
|
LG_TERRAGENESIS = 1, ///< TerraGenesis Perlin landscape generator
|
||||||
|
|
||||||
GENERATE_NEW_SEED = UINT_MAX, ///< Create a new random seed
|
GENERATE_NEW_SEED = UINT_MAX, ///< Create a new random seed
|
||||||
|
|
||||||
|
GENWORLD_REDRAW_TIMEOUT = 200, ///< Timeout between redraws
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Modes for GenerateWorld */
|
/* Modes for GenerateWorld */
|
||||||
@ -32,7 +34,6 @@ typedef void gw_abort_proc();
|
|||||||
struct gw_info {
|
struct gw_info {
|
||||||
bool active; ///< Is generating world active
|
bool active; ///< Is generating world active
|
||||||
bool abort; ///< Whether to abort the thread ASAP
|
bool abort; ///< Whether to abort the thread ASAP
|
||||||
bool wait_for_draw; ///< Are we waiting on a draw event
|
|
||||||
bool quit_thread; ///< Do we want to quit the active thread
|
bool quit_thread; ///< Do we want to quit the active thread
|
||||||
bool threaded; ///< Whether we run _GenerateWorld threaded
|
bool threaded; ///< Whether we run _GenerateWorld threaded
|
||||||
GenerateWorldMode mode;///< What mode are we making a world in
|
GenerateWorldMode mode;///< What mode are we making a world in
|
||||||
@ -69,8 +70,6 @@ static inline bool IsGeneratingWorld()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* genworld.cpp */
|
/* genworld.cpp */
|
||||||
void SetGeneratingWorldPaintStatus(bool status);
|
|
||||||
bool IsGeneratingWorldReadyForPaint();
|
|
||||||
bool IsGenerateWorldThreaded();
|
bool IsGenerateWorldThreaded();
|
||||||
void GenerateWorldSetCallback(gw_done_proc *proc);
|
void GenerateWorldSetCallback(gw_done_proc *proc);
|
||||||
void GenerateWorldSetAbortCallback(gw_abort_proc *proc);
|
void GenerateWorldSetAbortCallback(gw_abort_proc *proc);
|
||||||
@ -89,4 +88,7 @@ void StartNewGameWithoutGUI(uint seed);
|
|||||||
void ShowCreateScenario();
|
void ShowCreateScenario();
|
||||||
void StartScenarioEditor();
|
void StartScenarioEditor();
|
||||||
|
|
||||||
|
extern class ThreadMutex *_genworld_mapgen_mutex;
|
||||||
|
extern class ThreadMutex *_genworld_paint_mutex;
|
||||||
|
|
||||||
#endif /* GENWORLD_H */
|
#endif /* GENWORLD_H */
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "landscape_type.h"
|
#include "landscape_type.h"
|
||||||
#include "querystring_gui.h"
|
#include "querystring_gui.h"
|
||||||
#include "town.h"
|
#include "town.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
@ -1037,8 +1038,8 @@ static void _SetGeneratingWorldProgress(gwp_class cls, uint progress, uint total
|
|||||||
_tp.percent = percent_table[cls];
|
_tp.percent = percent_table[cls];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't update the screen too often. So update it once in every 200ms */
|
/* Don't update the screen too often. So update it once in every once in a while... */
|
||||||
if (!_network_dedicated && _tp.timer != 0 && _realtime_tick - _tp.timer < 200) return;
|
if (!_network_dedicated && _tp.timer != 0 && _realtime_tick - _tp.timer < GENWORLD_REDRAW_TIMEOUT) return;
|
||||||
|
|
||||||
/* Percentage is about the number of completed tasks, so 'current - 1' */
|
/* Percentage is about the number of completed tasks, so 'current - 1' */
|
||||||
_tp.percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (_tp.current == 0 ? 0 : _tp.current - 1) / _tp.total;
|
_tp.percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (_tp.current == 0 ? 0 : _tp.current - 1) / _tp.total;
|
||||||
@ -1064,12 +1065,15 @@ static void _SetGeneratingWorldProgress(gwp_class cls, uint progress, uint total
|
|||||||
|
|
||||||
InvalidateWindow(WC_GENERATE_PROGRESS_WINDOW, 0);
|
InvalidateWindow(WC_GENERATE_PROGRESS_WINDOW, 0);
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
SetGeneratingWorldPaintStatus(true);
|
|
||||||
|
|
||||||
/* We wait here till the paint is done, so we don't read and write
|
/* Release the rights to the map generator, and acquire the rights to the
|
||||||
* on the same tile at the same moment. Nasty hack, but that happens
|
* paint thread. The 'other' thread already has the paint thread rights so
|
||||||
* if you implement threading afterwards */
|
* this ensures us that we are waiting until the paint thread is done
|
||||||
while (IsGeneratingWorldReadyForPaint()) { CSleep(10); }
|
* before we reacquire the mapgen rights */
|
||||||
|
_genworld_mapgen_mutex->EndCritical();
|
||||||
|
_genworld_paint_mutex->BeginCritical();
|
||||||
|
_genworld_mapgen_mutex->BeginCritical();
|
||||||
|
_genworld_paint_mutex->EndCritical();
|
||||||
|
|
||||||
_tp.timer = _realtime_tick;
|
_tp.timer = _realtime_tick;
|
||||||
}
|
}
|
||||||
|
20
src/gfx.cpp
20
src/gfx.cpp
@ -18,6 +18,7 @@
|
|||||||
#include "core/sort_func.hpp"
|
#include "core/sort_func.hpp"
|
||||||
#include "landscape_type.h"
|
#include "landscape_type.h"
|
||||||
#include "network/network_func.h"
|
#include "network/network_func.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
#include "table/palettes.h"
|
#include "table/palettes.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
@ -1392,7 +1393,18 @@ void DrawDirtyBlocks()
|
|||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (IsGeneratingWorld() && !IsGeneratingWorldReadyForPaint()) return;
|
if (IsGeneratingWorld()) {
|
||||||
|
/* We are generating the world, so release our rights to the map and
|
||||||
|
* painting while we are waiting a bit. */
|
||||||
|
_genworld_paint_mutex->EndCritical();
|
||||||
|
_genworld_mapgen_mutex->EndCritical();
|
||||||
|
|
||||||
|
/* Wait a while and update _realtime_tick so we are given the rights */
|
||||||
|
CSleep(GENWORLD_REDRAW_TIMEOUT);
|
||||||
|
_realtime_tick += GENWORLD_REDRAW_TIMEOUT;
|
||||||
|
_genworld_paint_mutex->BeginCritical();
|
||||||
|
_genworld_mapgen_mutex->BeginCritical();
|
||||||
|
}
|
||||||
|
|
||||||
y = 0;
|
y = 0;
|
||||||
do {
|
do {
|
||||||
@ -1460,12 +1472,6 @@ void DrawDirtyBlocks()
|
|||||||
_invalid_rect.top = h;
|
_invalid_rect.top = h;
|
||||||
_invalid_rect.right = 0;
|
_invalid_rect.right = 0;
|
||||||
_invalid_rect.bottom = 0;
|
_invalid_rect.bottom = 0;
|
||||||
|
|
||||||
/* If we are generating a world, and waiting for a paint run, mark it here
|
|
||||||
* as done painting, so we can continue generating. */
|
|
||||||
if (IsGeneratingWorld() && IsGeneratingWorldReadyForPaint()) {
|
|
||||||
SetGeneratingWorldPaintStatus(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -4380,7 +4380,8 @@ static void GRFLoadError(byte *buf, size_t len)
|
|||||||
/* Only two parameter numbers can be used in the string. */
|
/* Only two parameter numbers can be used in the string. */
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
for (; i < 2 && len > 0; i++) {
|
for (; i < 2 && len > 0; i++) {
|
||||||
error->param_number[i] = grf_load_byte(&buf);
|
uint param_number = grf_load_byte(&buf);
|
||||||
|
error->param_value[i] = (param_number < _cur_grffile->param_end ? _cur_grffile->param[param_number] : 0);
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
error->num_params = i;
|
error->num_params = i;
|
||||||
|
@ -53,8 +53,8 @@ struct GRFError {
|
|||||||
char *data; ///< Additional data for message and custom_message
|
char *data; ///< Additional data for message and custom_message
|
||||||
StringID message; ///< Default message
|
StringID message; ///< Default message
|
||||||
StringID severity; ///< Info / Warning / Error / Fatal
|
StringID severity; ///< Info / Warning / Error / Fatal
|
||||||
uint8 num_params; ///< Number of additinal parameters for custom_message (0, 1 or 2)
|
uint8 num_params; ///< Number of additinal parameters for message and custom_message (0, 1 or 2)
|
||||||
uint8 param_number[2]; ///< GRF parameters to show for custom_message
|
uint32 param_value[2]; ///< Values of GRF parameters to show for message and custom_message
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Information about GRF, used in the game and (part of it) in savegames */
|
/** Information about GRF, used in the game and (part of it) in savegames */
|
||||||
|
@ -57,12 +57,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, uint bott
|
|||||||
SetDParam (3, STR_JUST_RAW_STRING);
|
SetDParam (3, STR_JUST_RAW_STRING);
|
||||||
SetDParamStr(4, c->error->data);
|
SetDParamStr(4, c->error->data);
|
||||||
for (uint i = 0; i < c->error->num_params; i++) {
|
for (uint i = 0; i < c->error->num_params; i++) {
|
||||||
uint32 param = 0;
|
SetDParam(5 + i, c->error->param_value[i]);
|
||||||
byte param_number = c->error->param_number[i];
|
|
||||||
|
|
||||||
if (param_number < c->num_params) param = c->param[param_number];
|
|
||||||
|
|
||||||
SetDParam(5 + i, param);
|
|
||||||
}
|
}
|
||||||
GetString(message, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
|
GetString(message, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "elrail_func.h"
|
#include "elrail_func.h"
|
||||||
#include "rev.h"
|
#include "rev.h"
|
||||||
#include "highscore.h"
|
#include "highscore.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
#include "newgrf_commons.h"
|
#include "newgrf_commons.h"
|
||||||
|
|
||||||
@ -652,6 +653,10 @@ int ttd_main(int argc, char *argv[])
|
|||||||
InitializeGUI();
|
InitializeGUI();
|
||||||
IConsoleCmdExec("exec scripts/autoexec.scr 0");
|
IConsoleCmdExec("exec scripts/autoexec.scr 0");
|
||||||
|
|
||||||
|
/* Take our initial lock on whatever we might want to do! */
|
||||||
|
_genworld_paint_mutex->BeginCritical();
|
||||||
|
_genworld_mapgen_mutex->BeginCritical();
|
||||||
|
|
||||||
GenerateWorld(GW_EMPTY, 64, 64); // Make the viewport initialization happy
|
GenerateWorld(GW_EMPTY, 64, 64); // Make the viewport initialization happy
|
||||||
WaitTillGeneratedWorld();
|
WaitTillGeneratedWorld();
|
||||||
|
|
||||||
|
@ -298,6 +298,18 @@ void AfterLoadVehicles(bool part_of_load)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CheckSavegameVersion(105)) {
|
||||||
|
/* Before 105 there was no order for shared orders, thus it messed up horribly */
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
if (v->First() != v || v->orders.list != NULL || v->previous_shared != NULL || v->next_shared == NULL) continue;
|
||||||
|
|
||||||
|
v->orders.list = new OrderList(NULL, v);
|
||||||
|
for (Vehicle *u = v; u != NULL; u = u->next_shared) {
|
||||||
|
u->orders.list = v->orders.list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CheckValidVehicles();
|
CheckValidVehicles();
|
||||||
|
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
Loading…
Reference in New Issue
Block a user