--- a/src/road_cmd.cpp Sat Jun 02 19:59:29 2007 +0000
+++ b/src/road_cmd.cpp Sat Jul 14 19:42:58 2007 +0000
@@ -13,6 +13,7 @@
#include "table/sprites.h"
#include "table/strings.h"
#include "functions.h"
+#include "window.h"
#include "map.h"
#include "landscape.h"
#include "tile.h"
@@ -99,14 +100,18 @@
* @param flags operation to perform
* @param p1 bit 0..3 road pieces to remove (RoadBits)
* bit 4..5 road type
+ * bit 6 ignore the fact that the tram track has not been removed
+ * yet when removing the road bits when not actually doing
+ * it. Makes it possible to test whether the road bits can
+ * be removed from a level crossing without physically
+ * removing the tram bits before the test.
* @param p2 unused
*/
-int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
/* cost for removing inner/edge -roads */
static const uint16 road_remove_cost[2] = {50, 18};
- Town *t;
/* true if the roadpiece was always removeable,
* false if it was a center piece. Affects town ratings drop */
bool edge_road;
@@ -116,33 +121,25 @@
RoadType rt = (RoadType)GB(p1, 4, 2);
if (!IsValidRoadType(rt)) return CMD_ERROR;
- Owner owner;
+ Town *t = NULL;
switch (GetTileType(tile)) {
case MP_STREET:
- owner = GetRoadOwner(tile, rt);
+ if (_game_mode != GM_EDITOR && GetRoadOwner(tile, rt) == OWNER_TOWN) t = GetTownByTile(tile);
break;
case MP_STATION:
if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
- owner = GetTileOwner(tile);
break;
case MP_TUNNELBRIDGE:
if ((IsTunnel(tile) && GetTunnelTransportType(tile) != TRANSPORT_ROAD) ||
(IsBridge(tile) && GetBridgeTransportType(tile) != TRANSPORT_ROAD)) return CMD_ERROR;
- owner = GetTileOwner(tile);
break;
default:
return CMD_ERROR;
}
- if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
- t = GetTownByTile(tile);
- } else {
- t = NULL;
- }
-
RoadBits pieces = Extract<RoadBits, 0>(p1);
RoadTypes rts = GetRoadTypes(tile);
/* The tile doesn't have the given road type */
@@ -160,11 +157,11 @@
/* If it's the last roadtype, just clear the whole tile */
if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
- int32 cost;
+ CommandCost cost;
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
/* Pay for *every* tile of the bridge or tunnel */
- cost = (DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road;
+ cost.AddCost((DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road);
if (flags & DC_EXEC) {
SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
@@ -179,13 +176,13 @@
}
}
} else {
- cost = _price.remove_road;
+ cost.AddCost(_price.remove_road);
if (flags & DC_EXEC) {
SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
MarkTileDirtyByTile(tile);
}
}
- return cost;
+ return CommandCost(cost);
}
switch (GetRoadTileType(tile)) {
@@ -226,7 +223,7 @@
MarkTileDirtyByTile(tile);
}
}
- return CountRoadBits(c) * _price.remove_road;
+ return CommandCost(CountRoadBits(c) * _price.remove_road);
}
case ROAD_TILE_CROSSING: {
@@ -236,7 +233,7 @@
/* Don't allow road to be removed from the crossing when there is tram;
* we can't draw the crossing without trambits ;) */
- if (rt == ROADTYPE_ROAD && HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM)) return CMD_ERROR;
+ if (rt == ROADTYPE_ROAD && HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM) && ((flags & DC_EXEC) || !HASBIT(p1, 6))) return CMD_ERROR;
if (flags & DC_EXEC) {
if (rt == ROADTYPE_ROAD) {
@@ -252,7 +249,7 @@
MarkTileDirtyByTile(tile);
YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
}
- return _price.remove_road * 2;
+ return CommandCost(_price.remove_road * 2);
}
default:
@@ -295,7 +292,7 @@
};
-static uint32 CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
+static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
{
RoadBits road_bits;
@@ -314,12 +311,12 @@
if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
/* force that all bits are set when we have slopes */
if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
- return 0; // no extra cost
+ return CommandCost(); // no extra cost
}
/* foundation is used. Whole tile is leveled up */
if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
- return existing != 0 ? 0 : _price.terraform;
+ return CommandCost(existing != 0 ? 0 : _price.terraform);
}
/* partly leveled up tile, only if there's no road on that tile */
@@ -340,10 +337,10 @@
* bit 6..7 disallowed directions to toggle
* @param p2 the town that is building the road (0 if not applicable)
*/
-int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
- int32 cost = 0;
- int32 ret;
+ CommandCost cost;
+ CommandCost ret;
RoadBits existing = ROAD_NONE;
RoadBits all_bits = ROAD_NONE;
Slope tileh;
@@ -390,7 +387,7 @@
SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd);
MarkTileDirtyByTile(tile);
}
- return 0;
+ return CommandCost();
}
return_cmd_error(STR_1007_ALREADY_BUILT);
}
@@ -445,7 +442,7 @@
MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2);
MarkTileDirtyByTile(tile);
}
- return _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4);
+ return CommandCost(_price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
}
case MP_STATION:
@@ -467,7 +464,7 @@
do_clear:;
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret;
- cost += ret;
+ cost.AddCost(ret);
}
if (all_bits != pieces) {
@@ -475,10 +472,10 @@
ret = CheckRoadSlope(tileh, &pieces, all_bits | existing);
/* Return an error if we need to build a foundation (ret != 0) but the
* current patch-setting is turned off (or stupid AI@work) */
- if (CmdFailed(ret) || (ret != 0 && (!_patches.build_on_slopes || _is_old_ai_player))) {
+ if (CmdFailed(ret) || (ret.GetCost() != 0 && (!_patches.build_on_slopes || _is_old_ai_player))) {
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
}
- cost += ret;
+ cost.AddCost(ret);
}
if (IsTileType(tile, MP_STREET)) {
@@ -486,10 +483,10 @@
pieces &= ComplementRoadBits(existing);
}
- cost += CountRoadBits(pieces) * _price.build_road;
+ cost.AddCost(CountRoadBits(pieces) * _price.build_road);
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
/* Pay for *every* tile of the bridge or tunnel */
- cost *= DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile);
+ cost.MultiplyCost(DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile));
}
if (flags & DC_EXEC) {
@@ -499,6 +496,7 @@
if (existing == ROAD_NONE || rtt == ROAD_TILE_CROSSING) {
SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
SetRoadOwner(tile, rt, _current_player);
+ if (_current_player == OWNER_TOWN && rt == ROADTYPE_ROAD) SetTownIndex(tile, p2);
}
if (rtt != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rt);
} break;
@@ -547,7 +545,7 @@
* @return The cost and state of the operation
* @retval CMD_ERROR An error occured during the operation.
*/
-int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
+CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
{
/* not a railroad crossing? */
if (!IsLevelCrossing(tile)) return CMD_ERROR;
@@ -566,7 +564,7 @@
YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetCrossingRailBits(tile)));
}
- return _price.build_rail / 2;
+ return CommandCost(_price.build_rail / 2);
}
@@ -581,10 +579,10 @@
* - p2 = (bit 3 + 4) - road type
* - p2 = (bit 5) - set road direction
*/
-int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
{
TileIndex start_tile, tile;
- int32 cost, ret;
+ CommandCost cost, ret;
bool had_bridge = false;
bool had_success = false;
DisallowedRoadDirections drd = DRD_NORTHBOUND;
@@ -617,7 +615,6 @@
/* No disallowed direction bits have to be toggled */
if (!HASBIT(p2, 5)) drd = DRD_NONE;
- cost = 0;
tile = start_tile;
/* Start tile is the small number. */
for (;;) {
@@ -635,11 +632,11 @@
/* Only pay for the upgrade on one side of the bridge */
if (IsBridgeTile(tile)) {
if ((!had_bridge || GetBridgeRampDirection(tile) == DIAGDIR_SE || GetBridgeRampDirection(tile) == DIAGDIR_SW)) {
- cost += ret;
+ cost.AddCost(ret);
}
had_bridge = true;
} else {
- cost += ret;
+ cost.AddCost(ret);
}
}
@@ -661,10 +658,10 @@
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
* - p2 = (bit 3 + 4) - road type
*/
-int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
{
TileIndex start_tile, tile;
- int32 cost, ret;
+ CommandCost cost, ret;
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@@ -686,7 +683,6 @@
p2 ^= IS_INT_INSIDE(p2 & 3, 1, 3) ? 3 : 0;
}
- cost = 0;
tile = start_tile;
/* Start tile is the small number. */
for (;;) {
@@ -698,7 +694,7 @@
/* try to remove the halves. */
if (bits != 0) {
ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
- if (!CmdFailed(ret)) cost += ret;
+ if (CmdSucceeded(ret)) cost.AddCost(ret);
}
if (tile == end_tile) break;
@@ -706,7 +702,7 @@
tile += HASBIT(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
}
- return (cost == 0) ? CMD_ERROR : cost;
+ return (cost.GetCost() == 0) ? CMD_ERROR : cost;
}
/** Build a road depot.
@@ -719,9 +715,9 @@
* @todo When checking for the tile slope,
* distingush between "Flat land required" and "land sloped in wrong direction"
*/
-int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
- int32 cost;
+ CommandCost cost;
Depot *dep;
Slope tileh;
@@ -756,10 +752,10 @@
MakeRoadDepot(tile, _current_player, dir, rt);
MarkTileDirtyByTile(tile);
}
- return cost + _price.build_road_depot;
+ return cost.AddCost(_price.build_road_depot);
}
-static int32 RemoveRoadDepot(TileIndex tile, uint32 flags)
+static CommandCost RemoveRoadDepot(TileIndex tile, uint32 flags)
{
if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
return CMD_ERROR;
@@ -768,10 +764,10 @@
if (flags & DC_EXEC) DeleteDepot(GetDepotByTile(tile));
- return _price.remove_road_depot;
+ return CommandCost(_price.remove_road_depot);
}
-static int32 ClearTile_Road(TileIndex tile, byte flags)
+static CommandCost ClearTile_Road(TileIndex tile, byte flags)
{
switch (GetRoadTileType(tile)) {
case ROAD_TILE_NORMAL: {
@@ -785,12 +781,12 @@
!(flags & DC_AUTO)
) {
RoadTypes rts = GetRoadTypes(tile);
- int32 ret = 0;
+ CommandCost ret;
for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
if (HASBIT(rts, rt)) {
- int32 tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
+ CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
if (CmdFailed(tmp_ret)) return tmp_ret;
- ret += tmp_ret;
+ ret.AddCost(tmp_ret);
}
}
return ret;
@@ -800,12 +796,20 @@
#undef M
case ROAD_TILE_CROSSING: {
- int32 ret;
+ RoadTypes rts = GetRoadTypes(tile);
+ CommandCost ret;
if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
- ret = DoCommand(tile, GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
- if (CmdFailed(ret)) return CMD_ERROR;
+ /* Must iterate over the roadtypes in a reverse manner because
+ * tram tracks must be removed before the road bits. */
+ for (RoadType rt = ROADTYPE_HWAY; rt >= ROADTYPE_ROAD; rt--) {
+ if (HASBIT(rts, rt)) {
+ CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
+ if (CmdFailed(tmp_ret)) return tmp_ret;
+ ret.AddCost(tmp_ret);
+ }
+ }
if (flags & DC_EXEC) {
DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -980,13 +984,6 @@
DrawGroundSprite(image, pal);
- if (road != ROAD_NONE) {
- DisallowedRoadDirections drd = GetDisallowedRoadDirections(ti->tile);
- if (drd != DRD_NONE) {
- DrawRoadDetail(SPR_ONEWAY_BASE + drd - 1 + ((road == ROAD_X) ? 0 : 3), ti, 8, 8, 0);
- }
- }
-
/* For tram we overlay the road graphics with either tram tracks only
* (when there is actual road beneath the trams) or with tram tracks
* and some dirts which hides the road graphics */
@@ -1000,6 +997,13 @@
DrawGroundSprite(image, pal);
}
+ if (road != ROAD_NONE) {
+ DisallowedRoadDirections drd = GetDisallowedRoadDirections(ti->tile);
+ if (drd != DRD_NONE) {
+ DrawRoadDetail(SPR_ONEWAY_BASE + drd - 1 + ((road == ROAD_X) ? 0 : 3), ti, 8, 8, 0);
+ }
+ }
+
if (HasRoadWorks(ti->tile)) {
/* Road works */
DrawGroundSprite((road | tram) & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y, PAL_NONE);
@@ -1346,7 +1350,13 @@
if (v->type == VEH_ROAD &&
v->u.road.frame == 11 &&
_roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == v->u.road.state) {
- VehicleEnterDepot(v);
+ v->u.road.state = RVSB_IN_DEPOT;
+ v->vehstatus |= VS_HIDDEN;
+ v->direction = ReverseDir(v->direction);
+ if (v->next == NULL) VehicleEnterDepot(v);
+ v->tile = tile;
+
+ InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
return VETSB_ENTERED_WORMHOLE;
}
break;