src/ai/default/default.cpp
branchNewGRF_ports
changeset 6878 7d1ff2f621c7
parent 6877 889301acc299
child 10184 fcf5fb2548eb
--- a/src/ai/default/default.cpp	Sun Feb 03 20:34:26 2008 +0000
+++ b/src/ai/default/default.cpp	Mon Mar 10 15:26:39 2008 +0000
@@ -69,10 +69,9 @@
 };
 
 
-static TrackBits GetRailTrackStatus(TileIndex tile)
+static inline TrackBits GetRailTrackStatus(TileIndex tile)
 {
-	uint32 r = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
-	return (TrackBits)(byte) (r | r >> 8);
+	return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
 }
 
 
@@ -112,8 +111,8 @@
 
 			/* not profitable? */
 			if (v->age >= 730 &&
-					v->profit_last_year < _price.station_value * 5 &&
-					v->profit_this_year < _price.station_value * 5) {
+					v->profit_last_year < _price.station_value * 5 * 256 &&
+					v->profit_this_year < _price.station_value * 5 * 256) {
 				_players_ai[p->index].state_counter = 0;
 				_players_ai[p->index].state = AIS_SELL_VEHICLE;
 				_players_ai[p->index].cur_veh = v;
@@ -1604,7 +1603,7 @@
 
 static bool AiCheckTrackResources(TileIndex tile, const AiDefaultBlockData *p, byte cargo)
 {
-	uint rad = (_patches.modified_catchment) ? CA_TRAIN : 4;
+	uint rad = (_patches.modified_catchment) ? CA_TRAIN : CA_UNMODIFIED;
 
 	for (; p->mode != 4; p++) {
 		AcceptedCargo values;
@@ -1902,7 +1901,7 @@
 	bool flag;
 };
 
-static bool AiEnumFollowTrack(TileIndex tile, AiRailPathFindData *a, int track, uint length, byte *state)
+static bool AiEnumFollowTrack(TileIndex tile, AiRailPathFindData *a, int track, uint length)
 {
 	if (a->flag) return true;
 
@@ -2198,26 +2197,55 @@
 	_players_ai[p->index].cur_tile_a += TileOffsByDiagDir(_players_ai[p->index].cur_dir_a);
 
 	if (arf.best_ptr[0] & 0x80) {
-		int i;
-		int32 bridge_len = GetTunnelBridgeLength(arf.bridge_end_tile, _players_ai[p->index].cur_tile_a);
-
-		/* Figure out which (rail)bridge type to build
-		 * start with best bridge, then go down to worse and worse bridges
-		 * unnecessary to check for worst bridge (i=0), since AI will always build
-		 * that. AI is so fucked up that fixing this small thing will probably not
-		 * solve a thing
-		 */
-		for (i = MAX_BRIDGES - 1; i != 0; i--) {
-			if (CheckBridge_Stuff(i, bridge_len)) {
-				CommandCost cost = DoCommand(arf.bridge_end_tile, _players_ai[p->index].cur_tile_a, i | (_players_ai[p->index].railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE);
-				if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 5)) break;
+		TileIndex t1 = _players_ai[p->index].cur_tile_a;
+		TileIndex t2 = arf.bridge_end_tile;
+
+		int32 bridge_len = GetTunnelBridgeLength(t1, t2);
+
+		DiagDirection dir = (TileX(t1) == TileX(t2) ? DIAGDIR_SE : DIAGDIR_SW);
+		Track track = AxisToTrack(DiagDirToAxis(dir));
+
+		if (t2 < t1) dir = ReverseDiagDir(dir);
+
+		/* try to build a long rail instead of bridge... */
+		bool fail = false;
+		CommandCost cost;
+		TileIndex t = t1;
+
+		/* try to build one rail on each tile - can't use CMD_BUILD_RAILROAD_TRACK now, it can build one part of track without failing */
+		do {
+			cost = DoCommand(t, _players_ai[p->index].railtype_to_use, track, DC_AUTO | DC_NO_WATER, CMD_BUILD_SINGLE_RAIL);
+			/* do not allow building over existing track */
+			if (CmdFailed(cost) || IsTileType(t, MP_RAILWAY)) {
+				fail = true;
+				break;
 			}
+			t += TileOffsByDiagDir(dir);
+		} while (t != t2);
+
+		/* can we build long track? */
+		if (!fail) cost = DoCommand(t1, t2, _players_ai[p->index].railtype_to_use | (track << 4), DC_AUTO | DC_NO_WATER, CMD_BUILD_RAILROAD_TRACK);
+
+		if (!fail && CmdSucceeded(cost) && cost.GetCost() <= p->player_money) {
+			DoCommand(t1, t2, _players_ai[p->index].railtype_to_use | (track << 4), DC_AUTO | DC_NO_WATER | DC_EXEC, CMD_BUILD_RAILROAD_TRACK);
+		} else {
+
+			/* Figure out which (rail)bridge type to build
+			 * start with best bridge, then go down to worse and worse bridges
+			 * unnecessary to check for worst bridge (i=0), since AI will always build that. */
+			int i;
+			for (i = MAX_BRIDGES - 1; i != 0; i--) {
+				if (CheckBridge_Stuff(i, bridge_len)) {
+					CommandCost cost = DoCommand(t1, t2, i | (_players_ai[p->index].railtype_to_use << 8), DC_AUTO, CMD_BUILD_BRIDGE);
+					if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 1) && cost.GetCost() < ((p->player_money + _economy.max_loan - p->current_loan) >> 5)) break;
+				}
+			}
+
+			/* Build it */
+			DoCommand(t1, t2, i | (_players_ai[p->index].railtype_to_use << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
 		}
 
-		// Build it
-		DoCommand(arf.bridge_end_tile, _players_ai[p->index].cur_tile_a, i | (_players_ai[p->index].railtype_to_use << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
-
-		_players_ai[p->index].cur_tile_a = arf.bridge_end_tile;
+		_players_ai[p->index].cur_tile_a = t2;
 		_players_ai[p->index].state_counter = 0;
 	} else if (arf.best_ptr[0] & 0x40) {
 		// tunnel
@@ -2639,8 +2667,7 @@
 		_cleared_town = NULL;
 
 		if (p->mode == 2) {
-			if (IsTileType(c, MP_ROAD) &&
-					GetRoadTileType(c) == ROAD_TILE_NORMAL &&
+			if (IsNormalRoadTile(c) &&
 					(GetRoadBits(c, ROADTYPE_ROAD) & p->attr) != 0) {
 				roadflag |= 2;
 
@@ -2682,7 +2709,7 @@
 
 			if (GetTileSlope(c, NULL) != SLOPE_FLAT) return CMD_ERROR;
 
-			if (!IsTileType(c, MP_ROAD) || GetRoadTileType(c) != ROAD_TILE_NORMAL) {
+			if (!IsNormalRoadTile(c)) {
 				ret = DoCommand(c, 0, 0, flag | DC_AUTO | DC_NO_WATER | DC_AI_BUILDING, CMD_LANDSCAPE_CLEAR);
 				if (CmdFailed(ret)) return CMD_ERROR;
 			}
@@ -2850,14 +2877,14 @@
 }
 
 
-static bool AiEnumFollowRoad(TileIndex tile, AiRoadEnum *a, int track, uint length, byte *state)
+static bool AiEnumFollowRoad(TileIndex tile, AiRoadEnum *a, int track, uint length)
 {
 	uint dist = DistanceManhattan(tile, a->dest);
 
 	if (dist <= a->best_dist) {
 		TileIndex tile2 = TILE_MASK(tile + TileOffsByDiagDir(_dir_by_track[track]));
 
-		if (IsTileType(tile2, MP_ROAD) && GetRoadTileType(tile2) == ROAD_TILE_NORMAL) {
+		if (IsNormalRoadTile(tile2)) {
 			a->best_dist = dist;
 			a->best_tile = tile;
 			a->best_track = track;
@@ -2885,7 +2912,7 @@
 	tile = TILE_MASK(_players_ai[p->index].cur_tile_a + TileOffsByDiagDir(dir));
 
 	if (IsRoadStopTile(tile) || IsTileDepotType(tile, TRANSPORT_ROAD)) return false;
-	bits = GetTileTrackStatus(tile, TRANSPORT_ROAD, ROADTYPES_ROAD) & _ai_road_table_and[dir];
+	bits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, ROADTYPES_ROAD)) & _ai_road_table_and[dir];
 	if (bits == 0) return false;
 
 	are.best_dist = (uint)-1;
@@ -3088,26 +3115,36 @@
 	tile = TILE_MASK(_players_ai[p->index].cur_tile_a + TileOffsByDiagDir(_players_ai[p->index].cur_dir_a));
 
 	if (arf.best_ptr[0] & 0x80) {
-		int i;
-		int32 bridge_len;
-		_players_ai[p->index].cur_tile_a = arf.bridge_end_tile;
-		bridge_len = GetTunnelBridgeLength(tile, _players_ai[p->index].cur_tile_a); // tile
-
-		/* Figure out what (road)bridge type to build
-		 * start with best bridge, then go down to worse and worse bridges
-		 * unnecessary to check for worse bridge (i=0), since AI will always build that.
-		 *AI is so fucked up that fixing this small thing will probably not solve a thing
-		 */
-		for (i = 10; i != 0; i--) {
-			if (CheckBridge_Stuff(i, bridge_len)) {
-				CommandCost cost = DoCommand(tile, _players_ai[p->index].cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE);
-				if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 5)) break;
+		TileIndex t1 = tile;
+		TileIndex t2 = arf.bridge_end_tile;
+
+		int32 bridge_len = GetTunnelBridgeLength(t1, t2);
+
+		Axis axis = (TileX(t1) == TileX(t2) ? AXIS_Y : AXIS_X);
+
+		/* try to build a long road instead of bridge - CMD_BUILD_LONG_ROAD has to fail if it couldn't build at least one piece! */
+ 		CommandCost cost = DoCommand(t2, t1, (t2 < t1 ? 1 : 2) | (axis << 2) | (ROADTYPE_ROAD << 3), DC_AUTO | DC_NO_WATER, CMD_BUILD_LONG_ROAD);
+
+		if (CmdSucceeded(cost) && cost.GetCost() <= p->player_money) {
+			DoCommand(t2, t1, (t2 < t1 ? 1 : 2) | (axis << 2) | (ROADTYPE_ROAD << 3), DC_AUTO | DC_EXEC | DC_NO_WATER, CMD_BUILD_LONG_ROAD);
+		} else {
+			int i;
+
+			/* Figure out what (road)bridge type to build
+			 * start with best bridge, then go down to worse and worse bridges
+			 * unnecessary to check for worse bridge (i=0), since AI will always build that */
+			for (i = MAX_BRIDGES - 1; i != 0; i--) {
+				if (CheckBridge_Stuff(i, bridge_len)) {
+					CommandCost cost = DoCommand(t1, t2, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO, CMD_BUILD_BRIDGE);
+					if (CmdSucceeded(cost) && cost.GetCost() < (p->player_money >> 1) && cost.GetCost() < ((p->player_money + _economy.max_loan - p->current_loan) >> 5)) break;
+				}
 			}
+
+			/* Build it */
+			DoCommand(t1, t2, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
 		}
 
-		// Build it
-		DoCommand(tile, _players_ai[p->index].cur_tile_a, i + ((0x80 | ROADTYPES_ROAD) << 8), DC_AUTO | DC_EXEC, CMD_BUILD_BRIDGE);
-
+		_players_ai[p->index].cur_tile_a = t2;
 		_players_ai[p->index].state_counter = 0;
 	} else if (arf.best_ptr[0] & 0x40) {
 		// tunnel
@@ -3403,7 +3440,7 @@
 
 	uint w = p->size_x[0];
 	uint h = p->size_y[0];
-	uint rad = _patches.modified_catchment ? p->portFSM->catchment : 4;
+	uint rad = _patches.modified_catchment ? p->portFSM->catchment : (uint)CA_UNMODIFIED;
 
 	if (cargo & 0x80) {
 		GetProductionAroundTiles(values, tile, w, h, rad);
@@ -3716,7 +3753,7 @@
 
 		if (IsLevelCrossing(tile)) goto is_rail_crossing;
 
-		if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
+		if (IsRoadDepot(tile)) {
 			DiagDirection dir;
 			TileIndex t;