mirror of https://github.com/OpenTTD/OpenTTD
(svn r1731) - Fix: [ 1106930 ] BugFix: placing signals with 2x1 drags workaround is completely rewritten. Also features checks for hacked/modified clients. Thanks a lot Hackykid!
parent
307c27892d
commit
abf2ae3f80
25
command.c
25
command.c
|
@ -22,8 +22,8 @@ DEF_COMMAND(CmdBuildRailroadStation);
|
||||||
DEF_COMMAND(CmdRemoveFromRailroadStation);
|
DEF_COMMAND(CmdRemoveFromRailroadStation);
|
||||||
DEF_COMMAND(CmdConvertRail);
|
DEF_COMMAND(CmdConvertRail);
|
||||||
|
|
||||||
DEF_COMMAND(CmdBuildSignals);
|
DEF_COMMAND(CmdBuildSingleSignal);
|
||||||
DEF_COMMAND(CmdRemoveSignals);
|
DEF_COMMAND(CmdRemoveSingleSignal);
|
||||||
|
|
||||||
DEF_COMMAND(CmdTerraformLand);
|
DEF_COMMAND(CmdTerraformLand);
|
||||||
|
|
||||||
|
@ -163,7 +163,8 @@ DEF_COMMAND(CmdRefitRailVehicle);
|
||||||
|
|
||||||
DEF_COMMAND(CmdStartScenario);
|
DEF_COMMAND(CmdStartScenario);
|
||||||
|
|
||||||
DEF_COMMAND(CmdBuildManySignals);
|
DEF_COMMAND(CmdBuildSignalTrack);
|
||||||
|
DEF_COMMAND(CmdRemoveSignalTrack);
|
||||||
|
|
||||||
DEF_COMMAND(CmdReplaceVehicle);
|
DEF_COMMAND(CmdReplaceVehicle);
|
||||||
|
|
||||||
|
@ -177,8 +178,8 @@ static CommandProc * const _command_proc_table[] = {
|
||||||
CmdBuildBridge, /* 5 */
|
CmdBuildBridge, /* 5 */
|
||||||
CmdBuildRailroadStation, /* 6 */
|
CmdBuildRailroadStation, /* 6 */
|
||||||
CmdBuildTrainDepot, /* 7 */
|
CmdBuildTrainDepot, /* 7 */
|
||||||
CmdBuildSignals, /* 8 */
|
CmdBuildSingleSignal, /* 8 */
|
||||||
CmdRemoveSignals, /* 9 */
|
CmdRemoveSingleSignal, /* 9 */
|
||||||
CmdTerraformLand, /* 10 */
|
CmdTerraformLand, /* 10 */
|
||||||
CmdPurchaseLandArea, /* 11 */
|
CmdPurchaseLandArea, /* 11 */
|
||||||
CmdSellLandArea, /* 12 */
|
CmdSellLandArea, /* 12 */
|
||||||
|
@ -302,12 +303,14 @@ static CommandProc * const _command_proc_table[] = {
|
||||||
CmdRestoreOrderIndex, /* 107 */
|
CmdRestoreOrderIndex, /* 107 */
|
||||||
CmdBuildLock, /* 108 */
|
CmdBuildLock, /* 108 */
|
||||||
CmdStartScenario, /* 109 */
|
CmdStartScenario, /* 109 */
|
||||||
CmdBuildManySignals, /* 110 */
|
CmdBuildSignalTrack, /* 110 */
|
||||||
//CmdDestroyIndustry, /* 109 */
|
CmdRemoveSignalTrack, /* 111 */
|
||||||
CmdDestroyCompanyHQ, /* 111 */
|
CmdDestroyCompanyHQ, /* 112 */
|
||||||
CmdGiveMoney, /* 112 */
|
CmdGiveMoney, /* 113 */
|
||||||
CmdChangePatchSetting, /* 113 */
|
CmdChangePatchSetting, /* 114 */
|
||||||
CmdReplaceVehicle, /* 114 */
|
CmdReplaceVehicle, /* 115 */
|
||||||
|
|
||||||
|
//CmdDestroyIndustry, /* 109 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This function range-checks a cmd, and checks if the cmd is not NULL */
|
/* This function range-checks a cmd, and checks if the cmd is not NULL */
|
||||||
|
|
13
command.h
13
command.h
|
@ -141,14 +141,15 @@ enum {
|
||||||
CMD_BUILD_LOCK = 108,
|
CMD_BUILD_LOCK = 108,
|
||||||
|
|
||||||
CMD_START_SCENARIO = 109,
|
CMD_START_SCENARIO = 109,
|
||||||
CMD_BUILD_MANY_SIGNALS = 110,
|
CMD_BUILD_SIGNAL_TRACK = 110,
|
||||||
|
CMD_REMOVE_SIGNAL_TRACK = 111,
|
||||||
|
|
||||||
|
CMD_DESTROY_COMPANY_HQ = 112,
|
||||||
|
CMD_GIVE_MONEY = 113,
|
||||||
|
CMD_CHANGE_PATCH_SETTING = 114,
|
||||||
|
|
||||||
|
CMD_REPLACE_VEHICLE = 115,
|
||||||
//CMD_DESTROY_INDUSTRY = 109,
|
//CMD_DESTROY_INDUSTRY = 109,
|
||||||
CMD_DESTROY_COMPANY_HQ = 111,
|
|
||||||
CMD_GIVE_MONEY = 112,
|
|
||||||
CMD_CHANGE_PATCH_SETTING = 113,
|
|
||||||
|
|
||||||
CMD_REPLACE_VEHICLE = 114,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
222
rail_cmd.c
222
rail_cmd.c
|
@ -512,64 +512,99 @@ skip_mark_dirty:;
|
||||||
static const struct {
|
static const struct {
|
||||||
int8 xinc[16];
|
int8 xinc[16];
|
||||||
int8 yinc[16];
|
int8 yinc[16];
|
||||||
byte initial[16];
|
|
||||||
} _railbit = {{
|
} _railbit = {{
|
||||||
// 0 1 2 3 4 5
|
// 0 1 2 3 4 5
|
||||||
16, 0,-16, 0, 16, 0, 0, 0,
|
-16, 0,-16, 0, 16, 0, 0, 0,
|
||||||
-16, 0, 0, 16, 0,-16, 0, 0,
|
16, 0, 0, 16, 0,-16, 0, 0,
|
||||||
},{
|
},{
|
||||||
0, 16, 0, 16, 0, 16, 0, 0,
|
0, 16, 0, 16, 0, 16, 0, 0,
|
||||||
0, -16, -16, 0,-16, 0, 0, 0,
|
0,-16,-16, 0,-16, 0, 0, 0,
|
||||||
},{
|
|
||||||
5, 1, 0, 4, // normal
|
|
||||||
2, 1, 8|0, 3, // x > sx
|
|
||||||
8|2, 8|1, 0, 8|3, // y > sy
|
|
||||||
8|5, 8|1, 8|0, 8|4, // x > sx && y > sy
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
static int32 ValidateAutoDrag(int *railbit, int x, int y, int ex, int ey)
|
||||||
/* Build either NE or NW sequence of tracks.
|
|
||||||
* p1 0:15 - end pt X
|
|
||||||
* p1 16:31 - end pt y
|
|
||||||
*
|
|
||||||
* p2 0:3 - rail type
|
|
||||||
* p2 4:7 - rail direction
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
|
||||||
{
|
{
|
||||||
int sx, sy;
|
int dx, dy, trdx, trdy;
|
||||||
|
|
||||||
|
if (*railbit > 5) return CMD_ERROR; // only 6 possible track-combinations
|
||||||
|
|
||||||
|
// calculate delta x,y from start to end tile
|
||||||
|
dx = ex - x;
|
||||||
|
dy = ey - y;
|
||||||
|
|
||||||
|
// calculate delta x,y for the first direction
|
||||||
|
trdx = _railbit.xinc[*railbit];
|
||||||
|
trdy = _railbit.yinc[*railbit];
|
||||||
|
|
||||||
|
if (*railbit & 0x6) {
|
||||||
|
trdx += _railbit.xinc[*railbit ^ 1];
|
||||||
|
trdy += _railbit.yinc[*railbit ^ 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate the direction
|
||||||
|
while (((trdx <= 0) && (dx > 0)) || ((trdx >= 0) && (dx < 0)) ||
|
||||||
|
((trdy <= 0) && (dy > 0)) || ((trdy >= 0) && (dy < 0))) {
|
||||||
|
if (*railbit < 8) { // first direction is invalid, try the other
|
||||||
|
SETBIT(*railbit, 3);
|
||||||
|
trdx = -trdx;
|
||||||
|
trdy = -trdy;
|
||||||
|
} else // other direction is invalid too, invalid drag
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (for diagonal tracks, this is already made sure of by above test), but:
|
||||||
|
// for non-diagonal tracks, check if the start and end tile are on 1 line
|
||||||
|
if (*railbit & 0x6) {
|
||||||
|
trdx = _railbit.xinc[*railbit];
|
||||||
|
trdy = _railbit.yinc[*railbit];
|
||||||
|
if ((abs(dx) != abs(dy)) && (abs(dx) + abs(trdy) != abs(dy) + abs(trdx)))
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build a stretch of railroad tracks.
|
||||||
|
* x,y= start tile
|
||||||
|
* p1 = end tile
|
||||||
|
* p2 = (bit 0-3) - railroad type normal/maglev
|
||||||
|
* p2 = (bit 4-6) - track-orientation, valid values: 0-5
|
||||||
|
* p2 = (bit 7) - 0 = build, 1 = remove tracks
|
||||||
|
*/
|
||||||
|
static int32 CmdRailTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
{
|
||||||
|
int ex, ey;
|
||||||
int32 ret, total_cost = 0;
|
int32 ret, total_cost = 0;
|
||||||
int railbit;
|
int railbit = (p2 >> 4) & 7;
|
||||||
|
byte mode = HASBIT(p2, 7);
|
||||||
|
|
||||||
|
/* unpack end point */
|
||||||
|
ex = TileX(p1) * 16;
|
||||||
|
ey = TileY(p1) * 16;
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||||
|
|
||||||
if (flags & DC_EXEC)
|
if (flags & DC_EXEC)
|
||||||
SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
|
SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
|
||||||
|
|
||||||
/* unpack end point */
|
if (ValidateAutoDrag(&railbit, x, y, ex, ey) == CMD_ERROR)
|
||||||
sx = (p1 & 0xFFFF) & ~0xF;
|
return CMD_ERROR;
|
||||||
sy = (p1 >> 16) & ~0xF;
|
|
||||||
|
|
||||||
railbit = _railbit.initial[(p2 >> 4) + (x > sx ? 4 : 0) + (y > sy ? 8 : 0)];
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
ret = DoCommand(x, y, p2&0xF, railbit&7, flags, CMD_BUILD_SINGLE_RAIL);
|
ret = DoCommand(x, y, p2&0x3, railbit&7, flags, (mode == 0) ? CMD_BUILD_SINGLE_RAIL : CMD_REMOVE_SINGLE_RAIL);
|
||||||
|
|
||||||
if (ret == CMD_ERROR) {
|
if (ret == CMD_ERROR) {
|
||||||
if (_error_message != STR_1007_ALREADY_BUILT)
|
if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0))
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
total_cost += ret;
|
total_cost += ret;
|
||||||
|
|
||||||
if (x == sx && y == sy)
|
if (x == ex && y == ey)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
x += _railbit.xinc[railbit];
|
x += _railbit.xinc[railbit];
|
||||||
y += _railbit.yinc[railbit];
|
y += _railbit.yinc[railbit];
|
||||||
|
|
||||||
// toggle railbit for the diagonal tiles
|
// toggle railbit for the non-diagonal tracks
|
||||||
if (railbit & 0x6) railbit ^= 1;
|
if (railbit & 0x6) railbit ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,48 +614,14 @@ int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return total_cost;
|
return total_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 CmdBuildRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
/* Remove either NE or NW sequence of tracks.
|
{
|
||||||
* p1 0:15 - start pt X
|
return CmdRailTrackHelper(x, y, flags, p1, p2);
|
||||||
* p1 16:31 - start pt y
|
}
|
||||||
*
|
|
||||||
* p2 0:3 - rail type
|
|
||||||
* p2 4:7 - rail direction
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
int32 CmdRemoveRailroadTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
int sx, sy;
|
return CmdRailTrackHelper(x, y, flags, p1, SETBIT(p2, 7));
|
||||||
int32 ret, total_cost = 0;
|
|
||||||
int railbit;
|
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
||||||
|
|
||||||
if (flags & DC_EXEC)
|
|
||||||
SndPlayTileFx(SND_20_SPLAT_2, TILE_FROM_XY(x,y));
|
|
||||||
|
|
||||||
/* unpack start point */
|
|
||||||
sx = (p1 & 0xFFFF) & ~0xF;
|
|
||||||
sy = (p1 >> 16) & ~0xF;
|
|
||||||
|
|
||||||
railbit = _railbit.initial[(p2 >> 4) + (x > sx ? 4 : 0) + (y > sy ? 8 : 0)];
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
ret = DoCommand(x, y, p2&0xF, railbit&7, flags, CMD_REMOVE_SINGLE_RAIL);
|
|
||||||
if (ret != CMD_ERROR) total_cost += ret;
|
|
||||||
if (x == sx && y == sy)
|
|
||||||
break;
|
|
||||||
x += _railbit.xinc[railbit];
|
|
||||||
y += _railbit.yinc[railbit];
|
|
||||||
// toggle railbit for the diagonal tiles
|
|
||||||
if (railbit & 0x6) railbit ^= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (total_cost == 0)
|
|
||||||
return CMD_ERROR;
|
|
||||||
|
|
||||||
return total_cost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a train depot
|
/* Build a train depot
|
||||||
|
@ -870,7 +871,7 @@ int32 CmdRenameWaypoint(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
* depending on context
|
* depending on context
|
||||||
* p2 = used for CmdBuildManySignals() to copy style of first signal
|
* p2 = used for CmdBuildManySignals() to copy style of first signal
|
||||||
*/
|
*/
|
||||||
int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
int32 CmdBuildSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
TileIndex tile = TILE_FROM_XY(x, y);
|
TileIndex tile = TILE_FROM_XY(x, y);
|
||||||
bool semaphore;
|
bool semaphore;
|
||||||
|
@ -992,68 +993,45 @@ int32 CmdBuildSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build many signals by dragging: AutoSignals
|
/* Build many signals by dragging: AutoSignals
|
||||||
x,y= start tile
|
* x,y = start tile
|
||||||
p1 = end tile
|
* p1 = end tile
|
||||||
p2 = (byte 0) - 0 = build, 1 = remove signals
|
* p2 = (bit 0) - 0 = build, 1 = remove signals
|
||||||
p2 = (byte 3) - 0 = signals, 1 = semaphores
|
* p2 = (bit 3) - 0 = signals, 1 = semaphores
|
||||||
p2 = (byte 7-4) - track-orientation
|
* p2 = (bit 4-6) - track-orientation, valid values: 0-5
|
||||||
p2 = (byte 8-) - track style
|
* p2 = (bit 24-31) - user defined signals_density
|
||||||
p2 = (byte 24-31) - user defined signals_density
|
|
||||||
*/
|
*/
|
||||||
int32 CmdBuildManySignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
static int32 CmdSignalTrackHelper(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
int ex, ey, railbit;
|
int ex, ey;
|
||||||
|
int railbit = (p2 >> 4) & 7;
|
||||||
bool error = true;
|
bool error = true;
|
||||||
TileIndex tile = TILE_FROM_XY(x, y);
|
TileIndex tile = TILE_FROM_XY(x, y);
|
||||||
int32 ret, total_cost, signal_ctr;
|
int32 ret, total_cost, signal_ctr;
|
||||||
byte m5, semaphores = (HASBIT(p2, 3)) ? 8 : 0;
|
byte m5, semaphores = (HASBIT(p2, 3)) ? 8 : 0;
|
||||||
int mode = (p2 >> 4)&0xF;
|
int mode = p2 & 0x1;
|
||||||
// for vertical/horizontal tracks, double the given signals density
|
// for vertical/horizontal tracks, double the given signals density
|
||||||
// since the original amount will be too dense (shorter tracks)
|
// since the original amount will be too dense (shorter tracks)
|
||||||
byte signal_density = (mode == 1 || mode == 2) ? (p2 >> 24) : (p2 >> 24) * 2;
|
byte signal_density = (railbit & 0x6) ? (p2 >> 24) * 2: (p2 >> 24);
|
||||||
byte signals = (p2 >> 8)&0xFF;
|
byte signals;
|
||||||
mode = p2 & 0x1; // build/remove signals
|
|
||||||
|
|
||||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||||
|
|
||||||
/* unpack end tile */
|
// unpack end tile
|
||||||
ex = TileX(p1) * 16;
|
ex = TileX(p1) * 16;
|
||||||
ey = TileY(p1) * 16;
|
ey = TileY(p1) * 16;
|
||||||
|
|
||||||
railbit = _railbit.initial[((p2 >> 4)&0xF) + (x > ex ? 4 : 0) + (y > ey ? 8 : 0)];
|
if (ValidateAutoDrag(&railbit, x, y, ex, ey) == CMD_ERROR)
|
||||||
|
return CMD_ERROR;
|
||||||
|
|
||||||
// copy the signal-style of the first rail-piece if existing
|
// copy the signal-style of the first rail-piece if existing
|
||||||
m5 = _map5[tile];
|
m5 = _map5[tile];
|
||||||
if (!(m5 & RAIL_TYPE_SPECIAL) && (m5 & RAIL_BIT_MASK) && (m5 & RAIL_TYPE_SIGNALS)) {
|
if (!(m5 & RAIL_TYPE_SPECIAL) && (m5 & RAIL_BIT_MASK) && (m5 & RAIL_TYPE_SIGNALS)) {
|
||||||
if (m5 & 0x3) // X,Y direction tracks
|
signals = _map3_lo[tile] & _signals_table_both[railbit];
|
||||||
signals = _map3_lo[tile]&0xC0;
|
if (signals == 0) signals = _signals_table_both[railbit];
|
||||||
else {
|
|
||||||
/* W-E or N-S direction, only copy the side which was chosen, leave
|
|
||||||
* the other side alone */
|
|
||||||
switch (signals) {
|
|
||||||
case 0x20: case 8: /* east corner (N-S), south corner (W-E) */
|
|
||||||
if (_map3_lo[tile]&0x30)
|
|
||||||
signals = _map3_lo[tile]&0x30;
|
|
||||||
else
|
|
||||||
signals = 0x30 | (_map3_lo[tile]&0xC0);
|
|
||||||
break;
|
|
||||||
case 0x10: case 4: /* west corner (N-S), north corner (W-E) */
|
|
||||||
if (_map3_lo[tile]&0xC0)
|
|
||||||
signals = _map3_lo[tile]&0xC0;
|
|
||||||
else
|
|
||||||
signals = 0xC0 | (_map3_lo[tile]&0x30);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
semaphores = (_map3_hi[tile] & ~3) ? 8 : 0; // copy signal/semaphores style (independent of CTRL)
|
semaphores = (_map3_hi[tile] & ~3) ? 8 : 0; // copy signal/semaphores style (independent of CTRL)
|
||||||
} else { // no signals exist, drag a two-way signal stretch
|
} else { // no signals exist, drag a two-way signal stretch
|
||||||
switch (signals) {
|
signals = _signals_table_both[railbit];
|
||||||
case 0x20: case 8: /* east corner (N-S), south corner (W-E) */
|
|
||||||
signals = 0x30; break;
|
|
||||||
case 0x10: case 4: /* west corner (N-S), north corner (W-E) */
|
|
||||||
signals = 0xC0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* signal_density_ctr - amount of tiles already processed
|
/* signal_density_ctr - amount of tiles already processed
|
||||||
|
@ -1089,19 +1067,25 @@ int32 CmdBuildManySignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
y += _railbit.yinc[railbit];
|
y += _railbit.yinc[railbit];
|
||||||
signal_ctr++;
|
signal_ctr++;
|
||||||
|
|
||||||
// toggle railbit for the diagonal tiles (|, -- tracks)
|
// toggle railbit for the non-diagonal tracks (|, -- tracks)
|
||||||
if (railbit & 0x6) railbit ^= 1;
|
if (railbit & 0x6) railbit ^= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (error) ? CMD_ERROR : total_cost;
|
return (error) ? CMD_ERROR : total_cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stub for the unified Signal builder/remover */
|
||||||
|
int32 CmdBuildSignalTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
{
|
||||||
|
return CmdSignalTrackHelper(x, y, flags, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove signals
|
/* Remove signals
|
||||||
* p1 bits 0..2 = track
|
* p1 bits 0..2 = track
|
||||||
* p2 = unused
|
* p2 = unused
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
int32 CmdRemoveSingleSignal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
{
|
{
|
||||||
TileInfo ti;
|
TileInfo ti;
|
||||||
uint tile;
|
uint tile;
|
||||||
|
@ -1159,6 +1143,12 @@ int32 CmdRemoveSignals(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return _price.remove_signals;
|
return _price.remove_signals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stub for the unified Signal builder/remover */
|
||||||
|
int32 CmdRemoveSignalTrack(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
{
|
||||||
|
return CmdSignalTrackHelper(x, y, flags, p1, SETBIT(p2, 1));
|
||||||
|
}
|
||||||
|
|
||||||
typedef int32 DoConvertRailProc(uint tile, uint totype, bool exec);
|
typedef int32 DoConvertRailProc(uint tile, uint totype, bool exec);
|
||||||
|
|
||||||
static int32 DoConvertRail(uint tile, uint totype, bool exec)
|
static int32 DoConvertRail(uint tile, uint totype, bool exec)
|
||||||
|
|
99
rail_gui.c
99
rail_gui.c
|
@ -309,117 +309,45 @@ static void BuildRailClick_Landscaping(Window *w)
|
||||||
ShowTerraformToolbar();
|
ShowTerraformToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DoRailroadTrack(int mode)
|
static void DoRailroadTrack(int mode)
|
||||||
{
|
{
|
||||||
DoCommandP(TILE_FROM_XY(_thd.selstart.x, _thd.selstart.y), PACK_POINT(_thd.selend.x, _thd.selend.y), (mode << 4) | _cur_railtype, NULL,
|
DoCommandP(TILE_FROM_XY(_thd.selstart.x, _thd.selstart.y), TILE_FROM_XY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL,
|
||||||
_remove_button_clicked ?
|
_remove_button_clicked ?
|
||||||
CMD_REMOVE_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
|
CMD_REMOVE_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
|
||||||
CMD_BUILD_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
|
CMD_BUILD_RAILROAD_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This function is more or less a hack because DoRailroadTrack() would otherwise screw up
|
|
||||||
static void SwapSelection(void)
|
|
||||||
{
|
|
||||||
TileHighlightData *thd = &_thd;
|
|
||||||
Point pt = thd->selstart;
|
|
||||||
thd->selstart.x = thd->selend.x & ~0xF;
|
|
||||||
thd->selstart.y = thd->selend.y & ~0xF;
|
|
||||||
thd->selend = pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void HandleAutodirPlacement(void)
|
static void HandleAutodirPlacement(void)
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = &_thd;
|
TileHighlightData *thd = &_thd;
|
||||||
int bit;
|
int trackstat = thd->drawstyle & 0xF; // 0..5
|
||||||
int dx = thd->selstart.x - (thd->selend.x&~0xF);
|
|
||||||
int dy = thd->selstart.y - (thd->selend.y&~0xF);
|
|
||||||
|
|
||||||
if (thd->drawstyle & HT_RAIL) { // one tile case
|
if (thd->drawstyle & HT_RAIL) { // one tile case
|
||||||
bit = thd->drawstyle & 0xF;
|
GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), trackstat);
|
||||||
GenericPlaceRail(TILE_FROM_XY(thd->selend.x, thd->selend.y), bit);
|
return;
|
||||||
} else if ( !(thd->drawstyle & 0xE) ) { // x/y dir
|
|
||||||
if (dx == 0) { // Y dir
|
|
||||||
DoRailroadTrack(1);
|
|
||||||
} else {
|
|
||||||
DoRailroadTrack(2);
|
|
||||||
}
|
|
||||||
} else if (myabs(dx)+myabs(dy) >= 32) { // long line (more than 2 tiles)
|
|
||||||
if(thd->drawstyle == (HT_LINE | HT_DIR_HU))
|
|
||||||
DoRailroadTrack(0);
|
|
||||||
if(thd->drawstyle == (HT_LINE | HT_DIR_HL))
|
|
||||||
DoRailroadTrack(3);
|
|
||||||
if(thd->drawstyle == (HT_LINE | HT_DIR_VL))
|
|
||||||
DoRailroadTrack(3);
|
|
||||||
if(thd->drawstyle == (HT_LINE | HT_DIR_VR))
|
|
||||||
DoRailroadTrack(0);
|
|
||||||
} else { // 2x1 pieces line
|
|
||||||
if(thd->drawstyle == (HT_LINE | HT_DIR_HU)) {
|
|
||||||
DoRailroadTrack(0);
|
|
||||||
} else if (thd->drawstyle == (HT_LINE | HT_DIR_HL)) {
|
|
||||||
SwapSelection();
|
|
||||||
DoRailroadTrack(0);
|
|
||||||
SwapSelection();
|
|
||||||
} else if (thd->drawstyle == (HT_LINE | HT_DIR_VL)) {
|
|
||||||
if(dx == 0) {
|
|
||||||
SwapSelection();
|
|
||||||
DoRailroadTrack(0);
|
|
||||||
SwapSelection();
|
|
||||||
} else {
|
|
||||||
DoRailroadTrack(3);
|
|
||||||
}
|
|
||||||
} else if (thd->drawstyle == (HT_LINE | HT_DIR_VR)) {
|
|
||||||
if(dx == 0) {
|
|
||||||
DoRailroadTrack(0);
|
|
||||||
} else {
|
|
||||||
SwapSelection();
|
|
||||||
DoRailroadTrack(3);
|
|
||||||
SwapSelection();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DoRailroadTrack(trackstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleAutoSignalPlacement(void)
|
static void HandleAutoSignalPlacement(void)
|
||||||
{
|
{
|
||||||
TileHighlightData *thd = &_thd;
|
TileHighlightData *thd = &_thd;
|
||||||
int mode = 0;
|
byte trackstat = thd->drawstyle & 0xF; // 0..5
|
||||||
uint trackstat = 0;
|
|
||||||
|
|
||||||
int dx = thd->selstart.x - (thd->selend.x&~0xF);
|
|
||||||
int dy = thd->selstart.y - (thd->selend.y&~0xF);
|
|
||||||
|
|
||||||
if (thd->drawstyle == HT_RECT) { // one tile case
|
if (thd->drawstyle == HT_RECT) { // one tile case
|
||||||
GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y));
|
GenericPlaceSignals(TILE_FROM_XY(thd->selend.x, thd->selend.y));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(thd->drawstyle & 0xE)) { // X/Y direction
|
|
||||||
mode = (dx == 0) ? VPM_FIX_X : VPM_FIX_Y;
|
|
||||||
trackstat = 0xC0;
|
|
||||||
} else if (myabs(dx) + myabs(dy) >= 32) { // long line (more than 2 tiles)
|
|
||||||
mode = ((thd->drawstyle & 0xF) == HT_DIR_HU || (thd->drawstyle & 0xF) == HT_DIR_VR) ? 0 : 3;
|
|
||||||
|
|
||||||
if (dx == dy || abs(dx - dy) == 16) // North<->South track |
|
|
||||||
trackstat = (thd->drawstyle & 1) ? 0x20 : 0x10;
|
|
||||||
else if (dx == -dy || abs(dx + dy) == 16) // East<->West track --
|
|
||||||
trackstat = (thd->drawstyle & 1) ? 8 : 4;
|
|
||||||
|
|
||||||
} else { // 2x1 pieces line
|
|
||||||
GenericPlaceSignals(TILE_FROM_XY(thd->selstart.x, thd->selstart.y));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _patches.drag_signals_density is given as a parameter such that each user in a network
|
// _patches.drag_signals_density is given as a parameter such that each user in a network
|
||||||
// game can specify his/her own signal density
|
// game can specify his/her own signal density
|
||||||
DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y),
|
DoCommandP(TILE_FROM_XY(thd->selstart.x, thd->selstart.y), TILE_FROM_XY(thd->selend.x, thd->selend.y),
|
||||||
(mode << 4) | (_remove_button_clicked | _ctrl_pressed) | (trackstat << 8) | (_patches.drag_signals_density << 24),
|
(_ctrl_pressed ? 1 << 3 : 0) | (trackstat << 4) | (_patches.drag_signals_density << 24),
|
||||||
CcPlaySound1E,
|
CcPlaySound1E,
|
||||||
(_remove_button_clicked ? CMD_BUILD_MANY_SIGNALS | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
|
(_remove_button_clicked ? CMD_REMOVE_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1013_CAN_T_REMOVE_SIGNALS_FROM) :
|
||||||
CMD_BUILD_MANY_SIGNALS | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE) ) );
|
CMD_BUILD_SIGNAL_TRACK | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1010_CAN_T_BUILD_SIGNALS_HERE) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static OnButtonClick * const _build_railroad_button_proc[] = {
|
static OnButtonClick * const _build_railroad_button_proc[] = {
|
||||||
|
@ -527,9 +455,8 @@ static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
|
||||||
DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO);
|
DoCommandP(end_tile, start_tile, _cur_railtype, CcPlaySound10, CMD_LEVEL_LAND | CMD_AUTO);
|
||||||
} else if (e->place.userdata == VPM_X_AND_Y_LIMITED) {
|
} else if (e->place.userdata == VPM_X_AND_Y_LIMITED) {
|
||||||
HandleStationPlacement(start_tile, end_tile);
|
HandleStationPlacement(start_tile, end_tile);
|
||||||
} else {
|
} else
|
||||||
DoRailroadTrack(e->place.userdata);
|
DoRailroadTrack(e->place.userdata & 1);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue