src/roadveh_cmd.cpp
branchnoai
changeset 9723 eee46cb39750
parent 9722 ebf0ece7d8f6
child 9724 b39bc69bb2f2
--- a/src/roadveh_cmd.cpp	Fri Nov 23 16:59:30 2007 +0000
+++ b/src/roadveh_cmd.cpp	Wed Jan 09 18:11:12 2008 +0000
@@ -5,25 +5,20 @@
 #include "stdafx.h"
 #include "openttd.h"
 #include "debug.h"
-#include "functions.h"
+#include "tile_cmd.h"
 #include "landscape.h"
 #include "road_map.h"
 #include "roadveh.h"
 #include "station_map.h"
 #include "table/strings.h"
-#include "strings.h"
-#include "map.h"
-#include "tile.h"
-#include "vehicle.h"
 #include "timetable.h"
 #include "engine.h"
-#include "command.h"
+#include "command_func.h"
 #include "station.h"
 #include "news.h"
 #include "pathfind.h"
 #include "npf.h"
 #include "player.h"
-#include "sound.h"
 #include "depot.h"
 #include "bridge.h"
 #include "tunnel_map.h"
@@ -35,10 +30,20 @@
 #include "newgrf_text.h"
 #include "newgrf_sound.h"
 #include "yapf/yapf.h"
-#include "date.h"
 #include "cargotype.h"
+#include "strings_func.h"
+#include "tunnelbridge_map.h"
+#include "functions.h"
+#include "window_func.h"
+#include "date_func.h"
+#include "vehicle_func.h"
+#include "sound_func.h"
+#include "variables.h"
+#include "autoreplace_gui.h"
+#include "gfx_func.h"
 #include "ai/ai.h"
 
+
 static const uint16 _roadveh_images[63] = {
 	0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
 	0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
@@ -95,7 +100,7 @@
 	if (is_custom_sprite(img)) {
 		image = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(img)));
 		if (image != 0) return image;
-		img = orig_road_vehicle_info[this->engine_type - ROAD_ENGINES_INDEX].image_index;
+		img = _orig_road_vehicle_info[this->engine_type - ROAD_ENGINES_INDEX].image_index;
 	}
 
 	image = direction + _roadveh_images[img];
@@ -114,14 +119,14 @@
 			DrawSprite(sprite, pal, x, y);
 			return;
 		}
-		spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
+		spritenum = _orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index;
 	}
 	DrawSprite(6 + _roadveh_images[spritenum], pal, x, y);
 }
 
 static CommandCost EstimateRoadVehCost(EngineID engine_type)
 {
-	return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
+	return CommandCost(EXPENSES_NEW_VEHICLES, ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5);
 }
 
 byte GetRoadVehLength(const Vehicle *v)
@@ -168,8 +173,6 @@
 
 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	cost = EstimateRoadVehCost(p1);
 	if (flags & DC_QUERY_COST) return cost;
 
@@ -234,7 +237,7 @@
 
 		v->last_station_visited = INVALID_STATION;
 		v->max_speed = rvi->max_speed;
-		v->engine_type = (byte)p1;
+		v->engine_type = (EngineID)p1;
 
 		e = GetEngine(p1);
 		v->reliability = e->reliability;
@@ -275,7 +278,7 @@
 		GetPlayer(_current_player)->num_engines[p1]++;
 	}
 
-	return CommandCost(cost);
+	return cost;
 }
 
 /** Start/Stop a road vehicle.
@@ -362,13 +365,11 @@
 
 	if (HASBITS(v->vehstatus, VS_CRASHED)) return_cmd_error(STR_CAN_T_SELL_DESTROYED_VEHICLE);
 
-	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
-
 	if (!CheckRoadVehInDepotStopped(v)) {
 		return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
 	}
 
-	CommandCost ret(-v->value);
+	CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value);
 
 	if (flags & DC_EXEC) {
 		// Invalidate depot
@@ -550,8 +551,7 @@
 
 	if (IsTileType(v->tile, MP_ROAD) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) return CMD_ERROR;
 
-	if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
-	if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR;
+	if (IsTileType(v->tile, MP_TUNNELBRIDGE) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
 
@@ -1018,7 +1018,7 @@
 	const OvertakeData* od = (OvertakeData*)data;
 
 	return
-		v->tile == od->tile && v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v ?
+		v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v ?
 			v : NULL;
 }
 
@@ -1276,18 +1276,17 @@
 		uint best_dist = (uint)-1;
 		uint best_maxlen = (uint)-1;
 		uint bitmask = (uint)trackdirs;
-		for (int i = 0; bitmask != 0; bitmask >>= 1, i++) {
-			if (HasBit(bitmask, 0)) {
-				if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track
-				frd.maxtracklen = (uint)-1;
-				frd.mindist = (uint)-1;
-				FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
+		uint i;
+		FOR_EACH_SET_BIT(i, bitmask) {
+			if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track
+			frd.maxtracklen = (uint)-1;
+			frd.mindist = (uint)-1;
+			FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd);
 
-				if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
-					best_dist = frd.mindist;
-					best_maxlen = frd.maxtracklen;
-					best_track = (Trackdir)i;
-				}
+			if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
+				best_dist = frd.mindist;
+				best_maxlen = frd.maxtracklen;
+				best_track = (Trackdir)i;
 			}
 		}
 	}
@@ -1409,10 +1408,8 @@
 	if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
 		DiagDirection diag_dir = INVALID_DIAGDIR;
 
-		if (IsTunnelTile(tile)) {
-			diag_dir = GetTunnelDirection(tile);
-		} else if (IsBridgeTile(tile)) {
-			diag_dir = GetBridgeRampDirection(tile);
+		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
+			diag_dir = GetTunnelBridgeDirection(tile);
 		} else if (IsTileType(tile, MP_ROAD) && GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
 			diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
 		}
@@ -1465,25 +1462,21 @@
 
 /**
  * Can a tram track build without destruction on the given tile?
+ * @param p the player that would be building the tram tracks
  * @param t the tile to build on.
+ * @param r the road bits needed.
  * @return true when a track track can be build on 't'
  */
-static bool CanBuildTramTrackOnTile(TileIndex t)
+static bool CanBuildTramTrackOnTile(PlayerID p, TileIndex t, RoadBits r)
 {
-	switch (GetTileType(t)) {
-		case MP_CLEAR:
-		case MP_TREES:
-			return true;
+	/* The 'current' player is not necessarily the owner of the vehicle. */
+	PlayerID original_player = _current_player;
+	_current_player = p;
 
-		case MP_ROAD:
-			return GetRoadTileType(t) == ROAD_TILE_NORMAL;
+	CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, 0, CMD_BUILD_ROAD);
 
-		case MP_WATER:
-			return IsCoast(t);
-
-		default:
-			return false;
-	}
+	_current_player = original_player;
+	return CmdSucceeded(ret);
 }
 
 static bool IndividualRoadVehicleController(Vehicle *v, const Vehicle *prev)
@@ -1495,13 +1488,17 @@
 	uint32 r;
 
 	if (v->u.road.overtaking != 0)  {
-		if (++v->u.road.overtaking_ctr >= 35)
+		if (IsTileType(v->tile, MP_STATION)) {
+			/* Force us to be not overtaking! */
+			v->u.road.overtaking = 0;
+		} else if (++v->u.road.overtaking_ctr >= 35) {
 			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
 			 *  if the vehicle started a corner. To protect that, only allow an abort of
 			 *  overtake if we are on straight roads */
 			if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) {
 				v->u.road.overtaking = 0;
 			}
+		}
 	}
 
 	/* If this vehicle is in a depot and we've reached this point it must be
@@ -1593,7 +1590,7 @@
 					 *   going to cause the tram to split up.
 					 * - Or the front of the tram can drive over the next tile.
 					 */
-				} else if (!IsRoadVehFront(v) || !CanBuildTramTrackOnTile(tile)) {
+				} else if (!IsRoadVehFront(v) || !CanBuildTramTrackOnTile(v->owner, tile, needed)) {
 					/*
 					 * Taking the 'small' corner for trams only happens when:
 					 * - We are not the from vehicle of an articulated tram.
@@ -1646,8 +1643,8 @@
 			goto again;
 		}
 
-		if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
-			if (IsReversingRoadTrackdir(dir) && IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
+		if (IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
+			if (IsReversingRoadTrackdir(dir) && IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
 				/* New direction is trying to turn vehicle around.
 				 * We can't turn at the exit of a road stop so wait.*/
 				v->cur_speed = 0;
@@ -1692,7 +1689,7 @@
 		uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME;
 
 		RoadBits tram;
-		if (v->u.road.roadtype == ROADTYPE_TRAM && CountBits(tram = GetRoadBits(v->tile, ROADTYPE_TRAM)) == 1) {
+		if (v->u.road.roadtype == ROADTYPE_TRAM && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM)) == 1) {
 			/*
 			 * The tram is turning around with one tram 'roadbit'. This means that
 			 * it is using the 'big' corner 'drive data'. However, to support the
@@ -1769,7 +1766,7 @@
 
 	new_dir = RoadVehGetSlidingDirection(v, x, y);
 
-	if (IsRoadVehFront(v) && !IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
+	if (IsRoadVehFront(v) && !IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
 		/* Vehicle is not in a road stop.
 		 * Check for another vehicle to overtake */
 		Vehicle* u = RoadVehFindCloseTo(v, x, y, new_dir);
@@ -1804,9 +1801,9 @@
 	 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
 	 * (the station test and stop type test ensure that other vehicles, using the road stop as
 	 * a through route, do not stop) */
-	if (IsRoadVehFront(v) && ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
+	if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
 			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
-			(IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
+			(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
 			v->current_order.dest == GetStationIndex(v->tile) &&
 			GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
 			v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
@@ -1992,7 +1989,7 @@
 
 	if (v->current_order.type == OT_GOTO_DEPOT &&
 			v->current_order.flags & OF_NON_STOP &&
-			!CHANCE16(1, 20)) {
+			!Chance16(1, 20)) {
 		return;
 	}
 
@@ -2008,7 +2005,7 @@
 
 void OnNewDay_RoadVeh(Vehicle *v)
 {
-	CommandCost cost;
+	CommandCost cost(EXPENSES_ROADVEH_RUN);
 
 	if (!IsRoadVehFront(v)) return;
 
@@ -2088,12 +2085,11 @@
 		}
 	}
 
-	cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364;
+	cost = CommandCost(EXPENSES_ROADVEH_RUN, RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364);
 
 	v->profit_this_year -= cost.GetCost() >> 8;
 
-	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
-	SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost));
+	SubtractMoneyFromPlayerFract(v->owner, cost);
 
 	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 	InvalidateWindowClasses(WC_ROADVEH_LIST);
@@ -2126,7 +2122,7 @@
 CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
-	CommandCost cost;
+	CommandCost cost(EXPENSES_ROADVEH_RUN);
 	CargoID new_cid = GB(p2, 0, 8);
 	byte new_subtype = GB(p2, 8, 8);
 	bool only_this = HasBit(p2, 16);
@@ -2139,11 +2135,10 @@
 
 	if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR;
 	if (!CheckRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE);
+	if (v->vehstatus & VS_CRASHED) return_cmd_error(STR_CAN_T_REFIT_DESTROYED_VEHICLE);
 
 	if (new_cid >= NUM_CARGO) return CMD_ERROR;
 
-	SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN);
-
 	for (; v != NULL; v = v->Next()) {
 		/* XXX: We refit all the attached wagons en-masse if they can be
 		 * refitted. This is how TTDPatch does it.  TODO: Have some nice