mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-04 06:00:15 +00:00
(svn r11871) -Fix [FS#1074]: do not update signals after each tile when building/removing a large block of track/signals/station
This commit is contained in:
parent
40a7ace4fa
commit
9556623281
@ -10,6 +10,7 @@
|
||||
#include "../player_base.h"
|
||||
#include "ai.h"
|
||||
#include "default/default.h"
|
||||
#include "../signal_func.h"
|
||||
|
||||
AIStruct _ai;
|
||||
AIPlayer _ai_player[MAX_PLAYERS];
|
||||
@ -159,6 +160,9 @@ static void AI_RunTick(PlayerID player)
|
||||
AiDoGameLoop(p);
|
||||
_is_old_ai_player = false;
|
||||
}
|
||||
|
||||
/* AI could change some track, so update signals */
|
||||
UpdateSignalsInBuffer();
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "debug.h"
|
||||
#include "player_func.h"
|
||||
#include "player_base.h"
|
||||
#include "signal_func.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
@ -642,6 +643,9 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, CommandCallback *callback,
|
||||
|
||||
SubtractMoneyFromPlayer(res2);
|
||||
|
||||
/* update signals if needed */
|
||||
UpdateSignalsInBuffer();
|
||||
|
||||
if (IsLocalPlayer() && _game_mode != GM_EDITOR) {
|
||||
if (res2.GetCost() != 0 && tile != 0) ShowCostOrIncomeAnimation(x, y, GetSlopeZ(x, y), res2.GetCost());
|
||||
if (_additional_cash_required != 0) {
|
||||
|
@ -440,10 +440,13 @@ void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player)
|
||||
TrackBits tracks = GetTrackBits(tile);
|
||||
do { // there may be two tracks with signals for TRACK_BIT_HORZ and TRACK_BIT_VERT
|
||||
Track track = RemoveFirstTrack(&tracks);
|
||||
if (HasSignalOnTrack(tile, track)) SetSignalsOnBothDir(tile, track, new_player);
|
||||
if (HasSignalOnTrack(tile, track)) AddTrackToSignalBuffer(tile, track, new_player);
|
||||
} while (tracks != TRACK_BIT_NONE);
|
||||
}
|
||||
} while (++tile != MapSize());
|
||||
|
||||
/* update signals in buffer */
|
||||
UpdateSignalsInBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
MarkTileDirtyByTile(tile);
|
||||
SetSignalsOnBothDir(tile, track, _current_player);
|
||||
AddTrackToSignalBuffer(tile, track, _current_player);
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
}
|
||||
|
||||
@ -502,12 +502,12 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32
|
||||
* are removing one of these pieces, we'll need to update signals for
|
||||
* both directions explicitly, as after the track is removed it won't
|
||||
* 'connect' with the other piece. */
|
||||
SetSignalsOnBothDir(tile, TRACK_X, owner);
|
||||
SetSignalsOnBothDir(tile, TRACK_Y, owner);
|
||||
AddTrackToSignalBuffer(tile, TRACK_X, owner);
|
||||
AddTrackToSignalBuffer(tile, TRACK_Y, owner);
|
||||
YapfNotifyTrackLayoutChange(tile, TRACK_X);
|
||||
YapfNotifyTrackLayoutChange(tile, TRACK_Y);
|
||||
} else {
|
||||
SetSignalsOnBothDir(tile, track, owner);
|
||||
AddTrackToSignalBuffer(tile, track, owner);
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
}
|
||||
}
|
||||
@ -745,7 +745,7 @@ CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p
|
||||
|
||||
d->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
|
||||
|
||||
UpdateSignalsOnSegment(tile, INVALID_DIAGDIR, _current_player);
|
||||
AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_player);
|
||||
YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
|
||||
d_auto_delete.Detach();
|
||||
}
|
||||
@ -871,7 +871,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32
|
||||
}
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
SetSignalsOnBothDir(tile, track, _current_player);
|
||||
AddTrackToSignalBuffer(tile, track, _current_player);
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
}
|
||||
|
||||
@ -1102,7 +1102,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint3
|
||||
SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
|
||||
}
|
||||
|
||||
SetSignalsOnBothDir(tile, track, GetTileOwner(tile));
|
||||
AddTrackToSignalBuffer(tile, track, GetTileOwner(tile));
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
@ -1314,7 +1314,7 @@ static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
|
||||
|
||||
DoClearSquare(tile);
|
||||
delete GetDepotByTile(tile);
|
||||
UpdateSignalsOnSegment(tile, dir, owner);
|
||||
AddSideToSignalBuffer(tile, dir, owner);
|
||||
YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
|
||||
}
|
||||
|
||||
|
100
src/signal.cpp
100
src/signal.cpp
@ -22,11 +22,14 @@
|
||||
|
||||
/** these are the maximums used for updating signal blocks */
|
||||
enum {
|
||||
SIG_TBU_SIZE = 64, ///< number of signals entering to block
|
||||
SIG_TBD_SIZE = 256, ///< number of intersections - open nodes in current block
|
||||
SIG_GLOB_SIZE = 64, ///< number of open blocks (block can be opened more times until detected)
|
||||
SIG_TBU_SIZE = 64, ///< number of signals entering to block
|
||||
SIG_TBD_SIZE = 256, ///< number of intersections - open nodes in current block
|
||||
SIG_GLOB_SIZE = 128, ///< number of open blocks (block can be opened more times until detected)
|
||||
SIG_GLOB_UPDATE = 64, ///< how many items need to be in _globset to force update
|
||||
};
|
||||
|
||||
assert_compile(SIG_GLOB_UPDATE <= SIG_GLOB_SIZE);
|
||||
|
||||
/** incidating trackbits with given enterdir */
|
||||
static const TrackBitsByte _enterdir_to_trackbits[DIAGDIR_END] = {
|
||||
{TRACK_BIT_3WAY_NE},
|
||||
@ -99,6 +102,16 @@ public:
|
||||
return this->n == lengthof(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the number of items
|
||||
* @return current number of items
|
||||
*/
|
||||
uint Items()
|
||||
{
|
||||
return this->n;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tries to remove first instance of given tile and dir
|
||||
* @param tile tile
|
||||
@ -534,6 +547,77 @@ static bool UpdateSignalsInBuffer(Owner owner)
|
||||
}
|
||||
|
||||
|
||||
static Owner _last_owner = INVALID_OWNER; ///< last owner whose track was put into _globset
|
||||
|
||||
|
||||
/**
|
||||
* Update signals in buffer
|
||||
* Called from 'outside'
|
||||
*/
|
||||
void UpdateSignalsInBuffer()
|
||||
{
|
||||
if (!_globset.IsEmpty()) {
|
||||
UpdateSignalsInBuffer(_last_owner);
|
||||
_last_owner = INVALID_OWNER; // invalidate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add track to signal update buffer
|
||||
*
|
||||
* @param tile tile where we start
|
||||
* @param track track at which ends we will update signals
|
||||
* @param owner owner whose signals we will update
|
||||
*/
|
||||
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
|
||||
{
|
||||
static const DiagDirection _search_dir_1[] = {
|
||||
DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
|
||||
};
|
||||
static const DiagDirection _search_dir_2[] = {
|
||||
DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
|
||||
};
|
||||
|
||||
/* do not allow signal updates for two players in one run */
|
||||
assert(_globset.IsEmpty() || owner == _last_owner);
|
||||
|
||||
_last_owner = owner;
|
||||
|
||||
_globset.Add(tile, _search_dir_1[track]);
|
||||
_globset.Add(tile, _search_dir_2[track]);
|
||||
|
||||
if (_globset.Items() >= SIG_GLOB_UPDATE) {
|
||||
/* too many items, force update */
|
||||
UpdateSignalsInBuffer(_last_owner);
|
||||
_last_owner = INVALID_OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add side of tile to signal update buffer
|
||||
*
|
||||
* @param tile tile where we start
|
||||
* @param side side of tile
|
||||
* @param owner owner whose signals we will update
|
||||
*/
|
||||
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
|
||||
{
|
||||
/* do not allow signal updates for two players in one run */
|
||||
assert(_globset.IsEmpty() || owner == _last_owner);
|
||||
|
||||
_last_owner = owner;
|
||||
|
||||
_globset.Add(tile, side);
|
||||
|
||||
if (_globset.Items() >= SIG_GLOB_UPDATE) {
|
||||
/* too many items, force update */
|
||||
UpdateSignalsInBuffer(_last_owner);
|
||||
_last_owner = INVALID_OWNER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update signals, starting at one side of a tile
|
||||
* Will check tile next to this at opposite side too
|
||||
@ -564,16 +648,8 @@ bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner)
|
||||
*/
|
||||
void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner)
|
||||
{
|
||||
static const DiagDirection _search_dir_1[] = {
|
||||
DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
|
||||
};
|
||||
static const DiagDirection _search_dir_2[] = {
|
||||
DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
|
||||
};
|
||||
|
||||
assert(_globset.IsEmpty());
|
||||
|
||||
_globset.Add(tile, _search_dir_1[track]);
|
||||
_globset.Add(tile, _search_dir_2[track]);
|
||||
AddTrackToSignalBuffer(tile, track, owner);
|
||||
UpdateSignalsInBuffer(owner);
|
||||
}
|
||||
|
@ -43,5 +43,8 @@ static inline byte SignalOnTrack(Track track)
|
||||
|
||||
bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection side, Owner owner);
|
||||
void SetSignalsOnBothDir(TileIndex tile, Track track, Owner owner);
|
||||
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner);
|
||||
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner);
|
||||
void UpdateSignalsInBuffer();
|
||||
|
||||
#endif /* SIGNAL_FUNC_H */
|
||||
|
@ -1073,7 +1073,7 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1,
|
||||
|
||||
tile += tile_delta;
|
||||
} while (--w);
|
||||
SetSignalsOnBothDir(tile_org, track, _current_player);
|
||||
AddTrackToSignalBuffer(tile_org, track, _current_player);
|
||||
YapfNotifyTrackLayoutChange(tile_org, track);
|
||||
tile_org += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta
|
||||
} while (--numtracks);
|
||||
@ -1209,7 +1209,7 @@ CommandCost CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1
|
||||
|
||||
DoClearSquare(tile2);
|
||||
st->rect.AfterRemoveTile(st, tile2);
|
||||
SetSignalsOnBothDir(tile2, track, owner);
|
||||
AddTrackToSignalBuffer(tile2, track, owner);
|
||||
YapfNotifyTrackLayoutChange(tile2, track);
|
||||
|
||||
DeallocateSpecFromStation(st, specindex);
|
||||
@ -1270,7 +1270,7 @@ static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 fla
|
||||
Track track = GetRailStationTrack(tile);
|
||||
Owner owner = GetTileOwner(tile); // _current_player can be OWNER_WATER
|
||||
DoClearSquare(tile);
|
||||
SetSignalsOnBothDir(tile, track, owner);
|
||||
AddTrackToSignalBuffer(tile, track, owner);
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
}
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ not_valid_below:;
|
||||
|
||||
if (flags & DC_EXEC && railtype != INVALID_RAILTYPE) {
|
||||
Track track = AxisToTrack(direction);
|
||||
UpdateSignalsOnSegment(tile_start, INVALID_DIAGDIR, _current_player);
|
||||
AddSideToSignalBuffer(tile_start, INVALID_DIAGDIR, _current_player);
|
||||
YapfNotifyTrackLayoutChange(tile_start, track);
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
|
||||
if (GB(p1, 9, 1) == TRANSPORT_RAIL) {
|
||||
MakeRailTunnel(start_tile, _current_player, direction, (RailType)GB(p1, 0, 4));
|
||||
MakeRailTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4));
|
||||
UpdateSignalsOnSegment(start_tile, INVALID_DIAGDIR, _current_player);
|
||||
AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_player);
|
||||
YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction)));
|
||||
} else {
|
||||
MakeRoadTunnel(start_tile, _current_player, direction, (RoadTypes)GB(p1, 0, 3));
|
||||
@ -612,8 +612,8 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags)
|
||||
DoClearSquare(endtile);
|
||||
|
||||
/* cannot use INVALID_DIAGDIR for signal update because the tunnel doesn't exist anymore */
|
||||
UpdateSignalsOnSegment(tile, ReverseDiagDir(dir), owner);
|
||||
UpdateSignalsOnSegment(endtile, dir, owner);
|
||||
AddSideToSignalBuffer(tile, ReverseDiagDir(dir), owner);
|
||||
AddSideToSignalBuffer(endtile, dir, owner);
|
||||
|
||||
Track track = AxisToTrack(DiagDirToAxis(dir));
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
@ -674,8 +674,8 @@ static CommandCost DoClearBridge(TileIndex tile, uint32 flags)
|
||||
|
||||
if (rail) {
|
||||
/* cannot use INVALID_DIAGDIR for signal update because the bridge doesn't exist anymore */
|
||||
UpdateSignalsOnSegment(tile, ReverseDiagDir(direction), owner);
|
||||
UpdateSignalsOnSegment(endtile, direction, owner);
|
||||
AddSideToSignalBuffer(tile, ReverseDiagDir(direction), owner);
|
||||
AddSideToSignalBuffer(endtile, direction, owner);
|
||||
|
||||
Track track = AxisToTrack(DiagDirToAxis(direction));
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
|
@ -648,6 +648,9 @@ static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs)
|
||||
MarkTileDirtyIfCanal(target + TileOffsByDir(dir));
|
||||
}
|
||||
}
|
||||
|
||||
/* update signals if needed */
|
||||
UpdateSignalsInBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove)
|
||||
MarkTileDirtyByTile(tile);
|
||||
} else {
|
||||
DoClearSquare(tile);
|
||||
SetSignalsOnBothDir(tile, track, owner);
|
||||
AddTrackToSignalBuffer(tile, track, owner);
|
||||
}
|
||||
YapfNotifyTrackLayoutChange(tile, track);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user