|
@@ -293,97 +293,97 @@ int32 CmdBuildSingleRail(int x, int y, u
|
|
|
int32 ret;
|
|
|
|
|
|
if (!ValParamRailtype(p1) || !ValParamTrackOrientation(p2)) return CMD_ERROR;
|
|
|
|
|
|
tile = TILE_FROM_XY(x, y);
|
|
|
tileh = GetTileSlope(tile, NULL);
|
|
|
m5 = _map5[tile];
|
|
|
rail_bit = 1 << p2;
|
|
|
|
|
|
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
|
|
|
|
|
switch (GetTileType(tile)) {
|
|
|
case MP_TUNNELBRIDGE:
|
|
|
if ((m5 & 0xC0) != 0xC0 || // not bridge middle part?
|
|
|
(m5 & 0x01 ? 1 : 2) != rail_bit) { // wrong direction?
|
|
|
// Get detailed error message
|
|
|
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
}
|
|
|
|
|
|
switch (m5 & 0x38) { // what's under the bridge?
|
|
|
case 0x00: // clear land
|
|
|
ret = CheckRailSlope(tileh, rail_bit, 0, tile);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
cost += ret;
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
SetTileOwner(tile, _current_player);
|
|
|
_map3_lo[tile] &= ~0x0F;
|
|
|
_map3_lo[tile] |= p1;
|
|
|
_map5[tile] = (m5 & 0xC7) | 0x20; // railroad under bridge
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case 0x20: // rail already there
|
|
|
return_cmd_error(STR_1007_ALREADY_BUILT);
|
|
|
|
|
|
default:
|
|
|
// Get detailed error message
|
|
|
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case MP_RAILWAY:
|
|
|
if (!CheckTrackCombination(m5, rail_bit, flags) ||
|
|
|
!EnsureNoVehicle(tile)) {
|
|
|
return CMD_ERROR;
|
|
|
}
|
|
|
if (m5 & RAIL_TYPE_SPECIAL ||
|
|
|
_map_owner[tile] != _current_player ||
|
|
|
!IsTileOwner(tile, _current_player) ||
|
|
|
(_map3_lo[tile] & 0xFU) != p1) {
|
|
|
// Get detailed error message
|
|
|
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
}
|
|
|
|
|
|
ret = CheckRailSlope(tileh, rail_bit, m5 & RAIL_BIT_MASK, tile);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
cost += ret;
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
_map2[tile] &= ~RAIL_MAP2LO_GROUND_MASK; // Bare land
|
|
|
_map5[tile] = m5 | rail_bit;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case MP_STREET:
|
|
|
if (!_valid_tileh_slopes[3][tileh]) // prevent certain slopes
|
|
|
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
|
|
|
if (!EnsureNoVehicle(tile)) return CMD_ERROR;
|
|
|
|
|
|
if ((m5 & 0xF0) == 0 && ( // normal road?
|
|
|
(rail_bit == 1 && m5 == 0x05) ||
|
|
|
(rail_bit == 2 && m5 == 0x0A) // correct direction?
|
|
|
)) {
|
|
|
if (flags & DC_EXEC) {
|
|
|
_map3_lo[tile] = GetTileOwner(tile);
|
|
|
SetTileOwner(tile, _current_player);
|
|
|
_map3_hi[tile] = p1;
|
|
|
_map5[tile] = 0x10 | (rail_bit == 1 ? 0x08 : 0x00); // level crossing
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if ((m5 & 0xF0) == 0x10 && (m5 & 0x08 ? 1 : 2) == rail_bit)
|
|
|
return_cmd_error(STR_1007_ALREADY_BUILT);
|
|
|
/* FALLTHROUGH */
|
|
|
|
|
|
default:
|
|
|
ret = CheckRailSlope(tileh, rail_bit, 0, tile);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
cost += ret;
|
|
|
|
|
|
ret = DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
if (CmdFailed(ret)) return ret;
|
|
|
cost += ret;
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
SetTileType(tile, MP_RAILWAY);
|