mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 22:28:56 +00:00
(svn r1567) -Fix: [110452] On horizontal/vertical tracks you are also charged for building/removing signals on the parallel track on the same tile. Signal updating is also correct. (Hackykid)
This commit is contained in:
parent
15630855dd
commit
e4a3d284b2
73
rail_cmd.c
73
rail_cmd.c
@ -873,6 +873,7 @@ int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
byte m5;
|
byte m5;
|
||||||
int32 cost;
|
int32 cost;
|
||||||
int track = p1 & 0x7;
|
int track = p1 & 0x7;
|
||||||
|
byte a,b,c,d;
|
||||||
|
|
||||||
assert(track >= 0 && track < 6); // only 6 possible track-combinations
|
assert(track >= 0 && track < 6); // only 6 possible track-combinations
|
||||||
|
|
||||||
@ -901,13 +902,21 @@ int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
if (!CheckTileOwnership(tile))
|
if (!CheckTileOwnership(tile))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
|
// calculate masks for..
|
||||||
|
a = _signals_table[track]; // .. signal for this track in one direction
|
||||||
|
b = _signals_table[track + 8]; // .. signal for this track in the other direction
|
||||||
|
c = a | b; // .. 2-way signal for this track
|
||||||
|
|
||||||
// If it had signals previously it is free to change orientation/pre-exit-combo signals
|
// If it had signals previously it is free to change orientation/pre-exit-combo signals
|
||||||
cost = 0;
|
cost = 0;
|
||||||
if (!(m5 & RAIL_TYPE_SIGNALS)) {
|
if (!(m5 & RAIL_TYPE_SIGNALS)) {
|
||||||
cost = _price.build_signals;
|
cost = _price.build_signals;
|
||||||
|
} else {
|
||||||
|
d = _map3_lo[tile] & c; // mask of built signals. it only affects &0xF0
|
||||||
|
if (d == 0) cost += _price.build_signals; // no signals built yet
|
||||||
// if converting signals<->semaphores, charge the player for it
|
// if converting signals<->semaphores, charge the player for it
|
||||||
} else if (p2 && ((HASBIT(p1, 3) && !HASBIT(_map3_hi[tile], 2)) || (!HASBIT(p1, 3) && HASBIT(_map3_hi[tile], 2)) ) ) {
|
if (p2 && ((HASBIT(p1, 3) && !HASBIT(_map3_hi[tile], 2)) || (!HASBIT(p1, 3) && HASBIT(_map3_hi[tile], 2)) ) )
|
||||||
cost += _price.build_signals + _price.remove_signals;
|
cost += _price.build_signals + _price.remove_signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
@ -918,23 +927,17 @@ int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
_map2[tile] |= 0xF0; // all signals are on
|
_map2[tile] |= 0xF0; // all signals are on
|
||||||
_map3_lo[tile] &= ~0xF0; // no signals built by default
|
_map3_lo[tile] &= ~0xF0; // no signals built by default
|
||||||
_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
|
_map3_hi[tile] = (p1 & 8) ? 4 : 0;// initial presignal state, semaphores depend on ctrl key
|
||||||
|
d = 0; // no existing signals
|
||||||
if (!p2)
|
if (!p2)
|
||||||
goto ignore_presig;
|
goto ignore_presig;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p2) { // not called from CmdBuildManySignals
|
if (!p2) { // not called from CmdBuildManySignals
|
||||||
if (!HASBIT(p1, 3)) { // not CTRL pressed
|
if (!HASBIT(p1, 3)) { // not CTRL pressed
|
||||||
byte a,b,c,d;
|
|
||||||
ignore_presig:
|
ignore_presig:
|
||||||
a = _signals_table[track]; // signal for this track in one direction
|
|
||||||
b = _signals_table[track + 8]; // signal for this track in the other direction
|
|
||||||
c = a | b;
|
|
||||||
d = _map3_lo[tile] & c; // mask of built signals. it only affects &0xF0
|
|
||||||
|
|
||||||
// Alternate between a|b, b, a
|
// Alternate between a|b, b, a
|
||||||
if ( d != 0 && d != a) {
|
if ( d != 0 && d != a)
|
||||||
c = (d==c)?b:a;
|
c = (d == c)?b:a;
|
||||||
}
|
|
||||||
|
|
||||||
_map3_lo[tile] = (_map3_lo[tile]&~(a|b)) | c;
|
_map3_lo[tile] = (_map3_lo[tile]&~(a|b)) | c;
|
||||||
} else // CTRL pressed
|
} else // CTRL pressed
|
||||||
@ -1064,7 +1067,7 @@ int32 CmdBuildManySignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove signals
|
/* Remove signals
|
||||||
* p1 = unused
|
* p1 bits 0..2 = track
|
||||||
* p2 = unused
|
* p2 = unused
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1072,6 +1075,8 @@ int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
{
|
{
|
||||||
TileInfo ti;
|
TileInfo ti;
|
||||||
uint tile;
|
uint tile;
|
||||||
|
int track = p1 & 0x7;
|
||||||
|
byte a,b,c,d;
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||||
|
|
||||||
@ -1094,16 +1099,29 @@ int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|||||||
if (_current_player != OWNER_WATER && !CheckTileOwnership(tile))
|
if (_current_player != OWNER_WATER && !CheckTileOwnership(tile))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
|
// calculate already built signals
|
||||||
|
a = _signals_table[track]; // signal for this track in one direction
|
||||||
|
b = _signals_table[track + 8]; // signal for this track in the other direction
|
||||||
|
c = a | b;
|
||||||
|
d = _map3_lo[tile] & c;
|
||||||
|
|
||||||
|
/* no signals on selected track? */
|
||||||
|
if (d == 0)
|
||||||
|
return CMD_ERROR;
|
||||||
|
|
||||||
/* Do it? */
|
/* Do it? */
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
byte bits = _map5[tile];
|
|
||||||
_map5[tile] &= ~RAIL_TYPE_SIGNALS;
|
_map3_lo[tile] &= ~c;
|
||||||
_map2[tile] &= ~0xF0;
|
|
||||||
CLRBIT(_map3_hi[tile], 2); // remove any possible semaphores
|
|
||||||
|
|
||||||
/* TTDBUG: this code contains a bug, if a tile contains 2 signals
|
/* removed last signal from tile? */
|
||||||
* on separate tracks, it won't work properly for the 2nd track */
|
if ((_map3_lo[tile] & 0xF0) == 0) {
|
||||||
SetSignalsOnBothDir(tile, FIND_FIRST_BIT(bits & RAIL_BIT_MASK));
|
_map5[tile] &= ~RAIL_TYPE_SIGNALS;
|
||||||
|
_map2[tile] &= ~0xF0;
|
||||||
|
CLRBIT(_map3_hi[tile], 2); // remove any possible semaphores
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSignalsOnBothDir(tile, track);
|
||||||
|
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
}
|
}
|
||||||
@ -1229,9 +1247,20 @@ regular_track:;
|
|||||||
return cost;
|
return cost;
|
||||||
|
|
||||||
} else if ((m5 & RAIL_TYPE_MASK)==RAIL_TYPE_SIGNALS) {
|
} else if ((m5 & RAIL_TYPE_MASK)==RAIL_TYPE_SIGNALS) {
|
||||||
cost = DoCommandByTile(tile, 0, 0, flags, CMD_REMOVE_SIGNALS);
|
cost = 0;
|
||||||
if (cost == CMD_ERROR)
|
if (_map3_lo[tile] & (_signals_table[0] | _signals_table[0 + 8])) { // check for signals in the first track
|
||||||
return CMD_ERROR;
|
ret = DoCommandByTile(tile, 0, 0, flags, CMD_REMOVE_SIGNALS);
|
||||||
|
if (ret == CMD_ERROR)
|
||||||
|
return CMD_ERROR;
|
||||||
|
cost += ret;
|
||||||
|
};
|
||||||
|
if (_map3_lo[tile] & (_signals_table[3] | _signals_table[3 + 8])) { // check for signals in the other track
|
||||||
|
ret = DoCommandByTile(tile, 3, 0, flags, CMD_REMOVE_SIGNALS);
|
||||||
|
if (ret == CMD_ERROR)
|
||||||
|
return CMD_ERROR;
|
||||||
|
cost += ret;
|
||||||
|
};
|
||||||
|
|
||||||
m5 &= RAIL_BIT_MASK;
|
m5 &= RAIL_BIT_MASK;
|
||||||
if (flags & DC_EXEC)
|
if (flags & DC_EXEC)
|
||||||
goto regular_track;
|
goto regular_track;
|
||||||
|
Loading…
Reference in New Issue
Block a user