diff -r eec5a7dcbf61 -r fcf5fb2548eb src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp Mon Apr 14 20:32:36 2008 +0000 +++ b/src/roadveh_cmd.cpp Tue Apr 15 00:47:19 2008 +0000 @@ -10,11 +10,9 @@ #include "road_map.h" #include "roadveh.h" #include "station_map.h" -#include "timetable.h" -#include "engine.h" #include "command_func.h" -#include "station.h" -#include "news.h" +#include "station_base.h" +#include "news_func.h" #include "pathfind.h" #include "npf.h" #include "player_func.h" @@ -42,6 +40,7 @@ #include "autoreplace_gui.h" #include "gfx_func.h" #include "settings_type.h" +#include "order_func.h" #include "table/strings.h" @@ -437,7 +436,7 @@ /* search in all directions */ for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { - FollowTrack(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd); + FollowTrack(v->tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd); } if (rfdd.best_length != UINT_MAX) return GetDepotByTile(rfdd.tile); @@ -477,14 +476,15 @@ if (v->IsInDepot()) return CMD_ERROR; /* If the current orders are already goto-depot */ - if (v->current_order.type == OT_GOTO_DEPOT) { - if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OF_HALT_IN_DEPOT)) { + if (v->current_order.IsType(OT_GOTO_DEPOT)) { + bool halt_in_depot = v->current_order.GetDepotActionType() & ODATFB_HALT; + if (!!(p2 & DEPOT_SERVICE) == halt_in_depot) { /* We called with a different DEPOT_SERVICE setting. * Now we change the setting to apply the new one and let the vehicle head for the same depot. * Note: the if is (true for requesting service == true for ordered to stop in depot) */ if (flags & DC_EXEC) { - ClrBit(v->current_order.flags, OF_PART_OF_ORDERS); - ToggleBit(v->current_order.flags, OF_HALT_IN_DEPOT); + v->current_order.SetDepotOrderType(ODTF_MANUAL); + v->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return CommandCost(); @@ -494,11 +494,9 @@ if (flags & DC_EXEC) { /* If the orders to 'goto depot' are in the orders list (forced servicing), * then skip to the next order; effectively cancelling this forced service */ - if (HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) - v->cur_order_index++; + if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) v->cur_order_index++; - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return CommandCost(); @@ -508,14 +506,11 @@ if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT); if (flags & DC_EXEC) { - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); ClearSlot(v); - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; - if (!(p2 & DEPOT_SERVICE)) SetBit(v->current_order.flags, OF_HALT_IN_DEPOT); - v->current_order.refit_cargo = CT_INVALID; - v->current_order.dest = dep->index; + v->current_order.MakeGoToDepot(dep->index, ODTF_MANUAL); + if (!(p2 & DEPOT_SERVICE)) v->current_order.SetDepotActionType(ODATFB_HALT); v->dest_tile = dep->xy; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -585,9 +580,9 @@ uint32 x = _delta_xy_table[direction]; this->x_offs = GB(x, 0, 8); this->y_offs = GB(x, 8, 8); - this->sprite_width = GB(x, 16, 8); - this->sprite_height = GB(x, 24, 8); - this->z_height = 6; + this->x_extent = GB(x, 16, 8); + this->y_extent = GB(x, 24, 8); + this->z_extent = 6; } static void ClearCrashedStation(Vehicle *v) @@ -699,7 +694,7 @@ AddNewsItem( (pass == 1) ? STR_9031_ROAD_VEHICLE_CRASH_DRIVER : STR_9032_ROAD_VEHICLE_CRASH_DIE, - NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0), + NM_THIN, NF_VIEWPORT | NF_VEHICLE, NT_ACCIDENT, DNC_NONE, v->index, 0 ); @@ -755,89 +750,32 @@ } } -static void ProcessRoadVehOrder(Vehicle *v) +TileIndex RoadVehicle::GetOrderStationLocation(StationID station) { - const Order *order; - - switch (v->current_order.type) { - case OT_GOTO_DEPOT: - /* Let a depot order in the orderlist interrupt. */ - if (!(v->current_order.flags & OFB_PART_OF_ORDERS)) return; - if (v->current_order.flags & OFB_SERVICE_IF_NEEDED && - !VehicleNeedsService(v)) { - UpdateVehicleTimetable(v, true); - v->cur_order_index++; - } - break; + if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION; - case OT_LOADING: - case OT_LEAVESTATION: - return; - - default: break; - } - - if (v->cur_order_index >= v->num_orders) v->cur_order_index = 0; - - order = GetVehicleOrder(v, v->cur_order_index); + TileIndex dest = INVALID_TILE; + const RoadStop *rs = GetStation(station)->GetPrimaryRoadStop(this); + if (rs != NULL) { + uint mindist = MAX_UVALUE(uint); - if (order == NULL) { - v->current_order.Free(); - v->dest_tile = 0; - ClearSlot(v); - return; - } + for (; rs != NULL; rs = rs->GetNextRoadStop(this)) { + uint dist = DistanceManhattan(this->tile, rs->xy); - if (order->type == v->current_order.type && - order->flags == v->current_order.flags && - order->dest == v->current_order.dest) { - return; + if (dist < mindist) { + mindist = dist; + dest = rs->xy; + } + } } - v->current_order = *order; - - switch (order->type) { - case OT_GOTO_STATION: { - if (order->dest == v->last_station_visited) { - v->last_station_visited = INVALID_STATION; - } - - const RoadStop *rs = GetStation(order->dest)->GetPrimaryRoadStop(v); - - TileIndex dest = INVALID_TILE; - if (rs != NULL) { - uint mindist = MAX_UVALUE(uint); - - for (; rs != NULL; rs = rs->GetNextRoadStop(v)) { - uint dist = DistanceManhattan(v->tile, rs->xy); - - if (dist < mindist) { - mindist = dist; - dest = rs->xy; - } - } - } - - if (dest != INVALID_TILE) { - v->dest_tile = dest; - } else { - /* There is no stop left at the station, so don't even TRY to go there */ - v->cur_order_index++; - v->dest_tile = 0; - } - break; - } - - case OT_GOTO_DEPOT: - v->dest_tile = GetDepot(order->dest)->xy; - break; - - default: - v->dest_tile = 0; - break; + if (dest != INVALID_TILE) { + return dest; + } else { + /* There is no stop left at the station, so don't even TRY to go there */ + this->cur_order_index++; + return 0; } - - InvalidateVehicleOrder(v); } static void StartRoadVehSound(const Vehicle* v) @@ -918,28 +856,22 @@ if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) { /* Check if station was ever visited before */ if (!(st->had_vehicle_of_type & HVOT_BUS)) { - uint32 flags; - st->had_vehicle_of_type |= HVOT_BUS; SetDParam(0, st->index); - flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0); AddNewsItem( v->u.road.roadtype == ROADTYPE_ROAD ? STR_902F_CITIZENS_CELEBRATE_FIRST : STR_CITIZENS_CELEBRATE_FIRST_PASSENGER_TRAM, - flags, + NM_THIN, NF_VIEWPORT | NF_VEHICLE, (v->owner == _local_player) ? NT_ARRIVAL_PLAYER : NT_ARRIVAL_OTHER, DNC_NONE, v->index, 0); } } else { /* Check if station was ever visited before */ if (!(st->had_vehicle_of_type & HVOT_TRUCK)) { - uint32 flags; - st->had_vehicle_of_type |= HVOT_TRUCK; SetDParam(0, st->index); - flags = (v->owner == _local_player) ? NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_PLAYER, 0) : NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ARRIVAL_OTHER, 0); AddNewsItem( v->u.road.roadtype == ROADTYPE_ROAD ? STR_9030_CITIZENS_CELEBRATE_FIRST : STR_CITIZENS_CELEBRATE_FIRST_CARGO_TRAM, - flags, + NM_THIN, NF_VIEWPORT | NF_VEHICLE, (v->owner == _local_player) ? NT_ARRIVAL_PLAYER : NT_ARRIVAL_OTHER, DNC_NONE, v->index, 0 ); @@ -1176,7 +1108,7 @@ trackdirs = TRACKDIR_BIT_NONE; } else { /* Our station */ - RoadStop::Type rstype = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; + RoadStopType rstype = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK; if (GetRoadStopType(tile) != rstype) { /* Wrong station type */ @@ -1289,7 +1221,7 @@ if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track frd.maxtracklen = UINT_MAX; frd.mindist = UINT_MAX; - FollowTrack(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); + FollowTrack(tile, PATHFIND_FLAGS_NONE, 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; @@ -1461,7 +1393,7 @@ }; RoadBits required = required_roadbits[dir & 0x07]; - if ((required & GetAnyRoadBits(tile, v->u.road.roadtype)) == ROAD_NONE) { + if ((required & GetAnyRoadBits(tile, v->u.road.roadtype, true)) == ROAD_NONE) { dir = INVALID_TRACKDIR; } @@ -1698,7 +1630,7 @@ uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME; RoadBits tram; - if (v->u.road.roadtype == ROADTYPE_TRAM && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM)) == 1) { + if (v->u.road.roadtype == ROADTYPE_TRAM && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true)) == 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 @@ -1811,8 +1743,8 @@ 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) || (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->current_order.GetDestination() == 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))) { RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); @@ -1821,13 +1753,13 @@ /* Vehicle is at the stop position (at a bay) in a road stop. * Note, if vehicle is loading/unloading it has already been handled, * so if we get here the vehicle has just arrived or is just ready to leave. */ - if (v->current_order.type != OT_LEAVESTATION && - v->current_order.type != OT_GOTO_DEPOT) { + if (!v->current_order.IsType(OT_LEAVESTATION) && + !v->current_order.IsType(OT_GOTO_DEPOT)) { /* Vehicle has arrived at a bay in a road stop */ if (IsDriveThroughStopTile(v->tile)) { TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); - RoadStop::Type type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; + RoadStopType type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK; /* Check if next inline bay is free */ if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { @@ -1859,7 +1791,7 @@ } /* Vehicle is ready to leave a bay in a road stop */ - if (v->current_order.type != OT_GOTO_DEPOT) { + if (!v->current_order.IsType(OT_GOTO_DEPOT)) { if (rs->IsEntranceBusy()) { /* Road stop entrance is busy, so wait as there is nowhere else to go */ v->cur_speed = 0; @@ -1885,12 +1817,12 @@ if (v->dest_tile != v->u.road.slot->xy) { DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->u.road.slot->xy, v->dest_tile); } - if (v->current_order.type != OT_GOTO_STATION) { - DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.type); + if (!v->current_order.IsType(OT_GOTO_STATION)) { + DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType()); } else { - if (v->current_order.dest != st->index) + if (v->current_order.GetDestination() != st->index) DEBUG(ms, 2, " current station %d is not target station in current_order.station (%d)", - st->index, v->current_order.dest); + st->index, v->current_order.GetDestination()); } DEBUG(ms, 2, " force a slot clearing"); @@ -1945,10 +1877,10 @@ if (v->vehstatus & VS_STOPPED) return; - ProcessRoadVehOrder(v); + ProcessOrders(v); v->HandleLoading(); - if (v->current_order.type == OT_LOADING) return; + if (v->current_order.IsType(OT_LOADING)) return; if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return; @@ -1979,7 +1911,7 @@ static void CheckIfRoadVehNeedsService(Vehicle *v) { /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ - if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !VehicleNeedsService(v)) return; + if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; if (v->IsInDepot()) { VehicleServiceInDepot(v); return; @@ -1989,26 +1921,23 @@ const Depot *depot = FindClosestRoadDepot(v); if (depot == NULL || DistanceManhattan(v->tile, depot->xy) > 12) { - if (v->current_order.type == OT_GOTO_DEPOT) { - v->current_order.type = OT_DUMMY; - v->current_order.flags = 0; + if (v->current_order.IsType(OT_GOTO_DEPOT)) { + v->current_order.MakeDummy(); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } return; } - if (v->current_order.type == OT_GOTO_DEPOT && - v->current_order.flags & OFB_NON_STOP && + if (v->current_order.IsType(OT_GOTO_DEPOT) && + v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS && !Chance16(1, 20)) { return; } - if (v->current_order.type == OT_LOADING) v->LeaveStation(); + if (v->current_order.IsType(OT_LOADING)) v->LeaveStation(); ClearSlot(v); - v->current_order.type = OT_GOTO_DEPOT; - v->current_order.flags = OFB_NON_STOP; - v->current_order.dest = depot->index; + v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); v->dest_tile = depot->xy; InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } @@ -2026,15 +1955,15 @@ CheckOrders(this); /* Current slot has expired */ - if (this->current_order.type == OT_GOTO_STATION && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { + if (this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", this->unitnumber, this->index, this->u.road.slot->xy); ClearSlot(this); } /* update destination */ - if (!(this->vehstatus & VS_STOPPED) && this->current_order.type == OT_GOTO_STATION && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { - Station *st = GetStation(this->current_order.dest); + if (!(this->vehstatus & VS_STOPPED) && this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { + Station *st = GetStation(this->current_order.GetDestination()); RoadStop *rs = st->GetPrimaryRoadStop(this); RoadStop *best = NULL;