src/rail_cmd.cpp
branchnoai
changeset 9629 66dde6412125
parent 9626 79f2b5a0cdd7
child 9631 8a2d1c2ceb88
--- a/src/rail_cmd.cpp	Sun Jun 17 21:31:00 2007 +0000
+++ b/src/rail_cmd.cpp	Tue Jun 26 23:40:58 2007 +0000
@@ -189,7 +189,7 @@
 }
 
 
-static uint32 CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
+static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
 {
 	if (IsSteepSlope(tileh)) {
 		if (_patches.build_on_slopes && existing == 0) {
@@ -207,7 +207,7 @@
 
 		/* no special foundation */
 		if ((~_valid_tileh_slopes[0][tileh] & rail_bits) == 0) {
-			return 0;
+			return CommandCost();
 		} else if (!_patches.build_on_slopes) {
 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 		}
@@ -216,7 +216,7 @@
 					(rail_bits == TRACK_BIT_X || rail_bits == TRACK_BIT_Y) &&
 					(tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)
 				)) { // partly up
-			return (existing != 0) ? 0 : _price.terraform;
+			return CommandCost((existing != 0) ? 0 : _price.terraform);
 		}
 	}
 	return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
@@ -231,14 +231,14 @@
  * @param p1 railtype of being built piece (normal, mono, maglev)
  * @param p2 rail track to build
  */
-int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Slope tileh;
 	RailType railtype;
 	Track track;
 	TrackBits trackbit;
-	int32 cost = 0;
-	int32 ret;
+	CommandCost cost;
+	CommandCost ret;
 
 	if (!ValParamRailtype(p1) || !ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
 	railtype = (RailType)p1;
@@ -263,14 +263,14 @@
 
 			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 
 			/* If the rail types don't match, try to convert only if engines of
 			 * the present rail type are powered on the new rail type. */
 			if (GetRailType(tile) != railtype && HasPowerOnRail(GetRailType(tile), railtype)) {
 				ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
 				if (CmdFailed(ret)) return ret;
-				cost += ret;
+				cost.AddCost(ret);
 			}
 
 			if (flags & DC_EXEC) {
@@ -330,11 +330,11 @@
 		default:
 			ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 
 			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 			if (CmdFailed(ret)) return ret;
-			cost += ret;
+			cost.AddCost(ret);
 
 			if (flags & DC_EXEC) MakeRailNormal(tile, _current_player, trackbit, railtype);
 			break;
@@ -346,7 +346,7 @@
 		YapfNotifyTrackLayoutChange(tile, track);
 	}
 
-	return cost + _price.build_rail;
+	return cost.AddCost(_price.build_rail);
 }
 
 /** Remove a single piece of track
@@ -355,11 +355,11 @@
  * @param p1 unused
  * @param p2 rail orientation
  */
-int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Track track = (Track)p2;
 	TrackBits trackbit;
-	int32 cost = _price.remove_rail;
+	CommandCost cost(_price.remove_rail);
 	bool crossing = false;
 
 	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
@@ -397,7 +397,7 @@
 
 			/* Charge extra to remove signals on the track, if they are there */
 			if (HasSignalOnTrack(tile, track))
-				cost += DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS);
+				cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
 
 			if (flags & DC_EXEC) {
 				present ^= trackbit;
@@ -444,7 +444,7 @@
 };
 
 
-static int32 ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end)
+static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end)
 {
 	int x = TileX(start);
 	int y = TileY(start);
@@ -492,7 +492,7 @@
 			return CMD_ERROR;
 	}
 
-	return 0;
+	return CommandCost();
 }
 
 /** Build a stretch of railroad tracks.
@@ -504,9 +504,9 @@
  * - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
  */
-static int32 CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+static CommandCost CmdRailTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	int32 ret, total_cost = 0;
+	CommandCost ret, total_cost;
 	Track track = (Track)GB(p2, 4, 3);
 	Trackdir trackdir;
 	byte mode = HASBIT(p2, 7);
@@ -531,7 +531,7 @@
 			if ((_error_message != STR_1007_ALREADY_BUILT) && (mode == 0)) break;
 			_error_message = INVALID_STRING_ID;
 		} else {
-			total_cost += ret;
+			total_cost.AddCost(ret);
 		}
 
 		if (tile == end_tile) break;
@@ -542,7 +542,7 @@
 		if (!IsDiagonalTrackdir(trackdir)) ToggleBitT(trackdir, 0);
 	}
 
-	return (total_cost == 0) ? CMD_ERROR : total_cost;
+	return (total_cost.GetCost() == 0) ? CMD_ERROR : total_cost;
 }
 
 /** Build rail on a stretch of track.
@@ -556,7 +556,7 @@
  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
  * @see CmdRailTrackHelper
  */
-int32 CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	return CmdRailTrackHelper(tile, flags, p1, CLRBIT(p2, 7));
 }
@@ -572,7 +572,7 @@
  * - p2 = (bit 7)   - 0 = build, 1 = remove tracks
  * @see CmdRailTrackHelper
  */
-int32 CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRemoveRailroadTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	return CmdRailTrackHelper(tile, flags, p1, SETBIT(p2, 7));
 }
@@ -586,10 +586,10 @@
  * @todo When checking for the tile slope,
  * distingush between "Flat land required" and "land sloped in wrong direction"
  */
-int32 CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Depot *d;
-	int32 cost, ret;
+	CommandCost cost;
 	Slope tileh;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
@@ -617,9 +617,8 @@
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
 
-	ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
-	if (CmdFailed(ret)) return CMD_ERROR;
-	cost = ret;
+	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
+	if (CmdFailed(cost)) return CMD_ERROR;
 
 	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
@@ -637,7 +636,7 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return cost + _price.build_train_depot;
+	return cost.AddCost(_price.build_train_depot);
 }
 
 /** Build signals, alternate between double/single, signal/semaphore,
@@ -652,12 +651,12 @@
  * @param p2 used for CmdBuildManySignals() to copy direction of first signal
  * TODO: p2 should be replaced by two bits for "along" and "against" the track.
  */
-int32 CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Track track = (Track)GB(p1, 0, 3);
 	bool pre_signal = HASBIT(p1, 3);
 	SignalVariant sigvar = (pre_signal ^ HASBIT(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC;
-	int32 cost;
+	CommandCost cost;
 
 	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicleOnGround(tile))
 		return CMD_ERROR;
@@ -686,14 +685,14 @@
 
 	if (!HasSignalOnTrack(tile, track)) {
 		/* build new signals */
-		cost = _price.build_signals;
+		cost = CommandCost(_price.build_signals);
 	} else {
 		if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
 			/* convert signals <-> semaphores */
-			cost = _price.build_signals + _price.remove_signals;
+			cost = CommandCost(_price.build_signals + _price.remove_signals);
 		} else {
 			/* it is free to change orientation/pre-exit-combo signals */
-			cost = 0;
+			cost = CommandCost();
 		}
 	}
 
@@ -749,9 +748,10 @@
  * - p2 = (bit  5)    - 0 = build, 1 = remove signals
  * - p2 = (bit 24-31) - user defined signals_density
  */
-static int32 CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+static CommandCost CmdSignalTrackHelper(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	int32 ret, total_cost, signal_ctr;
+	CommandCost ret, total_cost;
+	int signal_ctr;
 	byte signals;
 	bool error = true;
 	TileIndex end_tile;
@@ -798,7 +798,7 @@
 	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
 	 *              and convert all others to semaphore/signal
 	 * remove     - 1 remove signals, 0 build signals */
-	signal_ctr = total_cost = 0;
+	signal_ctr = 0;
 	for (;;) {
 		/* only build/remove signals with the specified density */
 		if (signal_ctr % signal_density == 0) {
@@ -808,9 +808,9 @@
 			ret = DoCommand(tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
 
 			/* Be user-friendly and try placing signals as much as possible */
-			if (!CmdFailed(ret)) {
+			if (CmdSucceeded(ret)) {
 				error = false;
-				total_cost += ret;
+				total_cost.AddCost(ret);
 			}
 		}
 
@@ -839,7 +839,7 @@
  * - p2 = (bit 24-31) - user defined signals_density
  * @see CmdSignalTrackHelper
  */
-int32 CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdBuildSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	return CmdSignalTrackHelper(tile, flags, p1, p2);
 }
@@ -853,7 +853,7 @@
  *           - (bit  4)    - 0 = signals, 1 = semaphores
  * @param p2 unused
  */
-int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Track track = (Track)GB(p1, 0, 3);
 
@@ -886,7 +886,7 @@
 		MarkTileDirtyByTile(tile);
 	}
 
-	return _price.remove_signals;
+	return CommandCost(_price.remove_signals);
 }
 
 /** Remove signals on a stretch of track.
@@ -902,12 +902,12 @@
  * - p2 = (bit 24-31) - user defined signals_density
  * @see CmdSignalTrackHelper
  */
-int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 5)); // bit 5 is remove bit
 }
 
-typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
+typedef CommandCost DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
 
 /**
  * Switches the rail type.
@@ -919,7 +919,7 @@
  * @return            The cost and state of the operation
  * @retval CMD_ERROR  An error occured during the operation.
  */
-static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec)
+static CommandCost DoConvertRail(TileIndex tile, RailType totype, bool exec)
 {
 	if (!CheckTileOwnership(tile)) return CMD_ERROR;
 
@@ -956,12 +956,12 @@
 		}
 	}
 
-	return _price.build_rail / 2;
+	return CommandCost(_price.build_rail / 2);
 }
 
-extern int32 DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
-extern int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec);
-extern int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
+extern CommandCost DoConvertStationRail(TileIndex tile, RailType totype, bool exec);
+extern CommandCost DoConvertStreetRail(TileIndex tile, RailType totype, bool exec);
+extern CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec);
 
 /** Convert one rail type to the other. You can convert normal rail to
  * monorail/maglev easily or vice-versa.
@@ -970,9 +970,10 @@
  * @param p1 start tile of drag
  * @param p2 new railtype to convert to
  */
-int32 CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	int32 ret, cost, money;
+	CommandCost ret, cost;
+	Money money;
 	int ex;
 	int ey;
 	int sx, sy, x, y;
@@ -991,8 +992,6 @@
 	if (ey < sy) Swap(ey, sy);
 
 	money = GetAvailableMoneyForCommand();
-	cost = 0;
-	ret = 0;
 
 	for (x = sx; x <= ex; ++x) {
 		for (y = sy; y <= ey; ++y) {
@@ -1009,23 +1008,23 @@
 
 			ret = proc(tile, (RailType)p2, false);
 			if (CmdFailed(ret)) continue;
-			cost += ret;
 
 			if (flags & DC_EXEC) {
-				money -= ret;
+				money -= ret.GetCost();
 				if (money < 0) {
-					_additional_cash_required = ret;
-					return cost - ret;
+					_additional_cash_required = ret.GetCost();
+					return cost;
 				}
 				proc(tile, (RailType)p2, true);
 			}
+			cost.AddCost(ret);
 		}
 	}
 
-	return (cost == 0) ? ret : cost;
+	return (cost.GetCost() == 0) ? ret : cost;
 }
 
-static int32 RemoveTrainDepot(TileIndex tile, uint32 flags)
+static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags)
 {
 	if (!CheckTileOwnership(tile) && _current_player != OWNER_WATER)
 		return CMD_ERROR;
@@ -1041,13 +1040,13 @@
 		YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir)));
 	}
 
-	return _price.remove_train_depot;
+	return CommandCost(_price.remove_train_depot);
 }
 
-static int32 ClearTile_Track(TileIndex tile, byte flags)
+static CommandCost ClearTile_Track(TileIndex tile, byte flags)
 {
-	int32 cost;
-	int32 ret;
+	CommandCost cost;
+	CommandCost ret;
 
 	if (flags & DC_AUTO) {
 		if (!IsTileOwner(tile, _current_player))
@@ -1060,8 +1059,6 @@
 		}
 	}
 
-	cost = 0;
-
 	switch (GetRailTileType(tile)) {
 		case RAIL_TILE_SIGNALS:
 		case RAIL_TILE_NORMAL: {
@@ -1070,7 +1067,7 @@
 				Track track = RemoveFirstTrack(&tracks);
 				ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
 				if (CmdFailed(ret)) return CMD_ERROR;
-				cost += ret;
+				cost.AddCost(ret);
 			}
 			return cost;
 		}
@@ -1291,9 +1288,6 @@
 		if (track & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w, PAL_NONE);
 		if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PAL_NONE);
 	}
-
-	if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
-
 }
 
 static void DrawSignals(TileIndex tile, TrackBits rails)
@@ -1342,6 +1336,8 @@
 
 		if (HASBIT(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti);
 
+		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
+
 		if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails);
 	} else {
 		/* draw depot/waypoint */