--- 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