roadveh_cmd.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #include "stdafx.h"
00013 #include "roadveh.h"
00014 #include "command_func.h"
00015 #include "news_func.h"
00016 #include "pathfinder/npf/npf_func.h"
00017 #include "station_base.h"
00018 #include "company_func.h"
00019 #include "articulated_vehicles.h"
00020 #include "newgrf_sound.h"
00021 #include "pathfinder/yapf/yapf.h"
00022 #include "strings_func.h"
00023 #include "tunnelbridge_map.h"
00024 #include "date_func.h"
00025 #include "vehicle_func.h"
00026 #include "sound_func.h"
00027 #include "ai/ai.hpp"
00028 #include "game/game.hpp"
00029 #include "depot_map.h"
00030 #include "effectvehicle_func.h"
00031 #include "roadstop_base.h"
00032 #include "spritecache.h"
00033 #include "core/random_func.hpp"
00034 #include "company_base.h"
00035 #include "core/backup_type.hpp"
00036 #include "newgrf.h"
00037 #include "zoom_func.h"
00038 
00039 #include "table/strings.h"
00040 
00041 static const uint16 _roadveh_images[63] = {
00042   0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
00043   0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
00044   0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
00045   0xC54, 0xC64, 0xC5C, 0xC6C, 0xC44, 0xC5C, 0xC64, 0xCAC,
00046   0xCB4, 0xCBC, 0xD94, 0xD9C, 0xDA4, 0xDAC, 0xDB4, 0xDBC,
00047   0xDCC, 0xDD4, 0xDE4, 0xDDC, 0xDEC, 0xDC4, 0xDDC, 0xDE4,
00048   0xE2C, 0xE34, 0xE3C, 0xC14, 0xC1C, 0xC2C, 0xC3C, 0xC4C,
00049   0xC5C, 0xC64, 0xC6C, 0xC74, 0xC84, 0xC94, 0xCA4
00050 };
00051 
00052 static const uint16 _roadveh_full_adder[63] = {
00053    0,  88,   0,   0,   0,   0,  48,  48,
00054   48,  48,   0,   0,  64,  64,   0,  16,
00055   16,   0,  88,   0,   0,   0,   0,  48,
00056   48,  48,  48,   0,   0,  64,  64,   0,
00057   16,  16,   0,  88,   0,   0,   0,   0,
00058   48,  48,  48,  48,   0,   0,  64,  64,
00059    0,  16,  16,   0,   8,   8,   8,   8,
00060    0,   0,   0,   8,   8,   8,   8
00061 };
00062 
00064 static const TrackdirBits _road_enter_dir_to_reachable_trackdirs[DIAGDIR_END] = {
00065   TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_X_NE,    // Enter from north east
00066   TRACKDIR_BIT_LEFT_S  | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_Y_SE,    // Enter from south east
00067   TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_X_SW    | TRACKDIR_BIT_RIGHT_S, // Enter from south west
00068   TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_Y_NW     // Enter from north west
00069 };
00070 
00071 static const Trackdir _road_reverse_table[DIAGDIR_END] = {
00072   TRACKDIR_RVREV_NE, TRACKDIR_RVREV_SE, TRACKDIR_RVREV_SW, TRACKDIR_RVREV_NW
00073 };
00074 
00076 static const Trackdir _roadveh_depot_exit_trackdir[DIAGDIR_END] = {
00077   TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW
00078 };
00079 
00080 
00085 bool RoadVehicle::IsBus() const
00086 {
00087   assert(this->IsFrontEngine());
00088   return IsCargoInClass(this->cargo_type, CC_PASSENGERS);
00089 }
00090 
00096 int RoadVehicle::GetDisplayImageWidth(Point *offset) const
00097 {
00098   int reference_width = ROADVEHINFO_DEFAULT_VEHICLE_WIDTH;
00099 
00100   if (offset != NULL) {
00101     offset->x = reference_width / 2;
00102     offset->y = 0;
00103   }
00104   return this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH;
00105 }
00106 
00107 static SpriteID GetRoadVehIcon(EngineID engine, EngineImageType image_type)
00108 {
00109   const Engine *e = Engine::Get(engine);
00110   uint8 spritenum = e->u.road.image_index;
00111 
00112   if (is_custom_sprite(spritenum)) {
00113     SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W, image_type);
00114     if (sprite != 0) return sprite;
00115 
00116     spritenum = e->original_image_index;
00117   }
00118 
00119   return DIR_W + _roadveh_images[spritenum];
00120 }
00121 
00122 SpriteID RoadVehicle::GetImage(Direction direction, EngineImageType image_type) const
00123 {
00124   uint8 spritenum = this->spritenum;
00125   SpriteID sprite;
00126 
00127   if (is_custom_sprite(spritenum)) {
00128     sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type);
00129     if (sprite != 0) return sprite;
00130 
00131     spritenum = this->GetEngine()->original_image_index;
00132   }
00133 
00134   sprite = direction + _roadveh_images[spritenum];
00135 
00136   if (this->cargo.Count() >= this->cargo_cap / 2U) sprite += _roadveh_full_adder[spritenum];
00137 
00138   return sprite;
00139 }
00140 
00150 void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
00151 {
00152   SpriteID sprite = GetRoadVehIcon(engine, image_type);
00153   const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
00154   preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI), right - UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI));
00155   DrawSprite(sprite, pal, preferred_x, y);
00156 }
00157 
00163 static uint GetRoadVehLength(const RoadVehicle *v)
00164 {
00165   const Engine *e = v->GetEngine();
00166   uint length = VEHICLE_LENGTH;
00167 
00168   uint16 veh_len = CALLBACK_FAILED;
00169   if (e->GetGRF() != NULL && e->GetGRF()->grf_version >= 8) {
00170     /* Use callback 36 */
00171     veh_len = GetVehicleProperty(v, PROP_ROADVEH_SHORTEN_FACTOR, CALLBACK_FAILED);
00172   } else {
00173     /* Use callback 11 */
00174     veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, v->engine_type, v);
00175   }
00176   if (veh_len == CALLBACK_FAILED) veh_len = e->u.road.shorten_factor;
00177   if (veh_len != 0) {
00178     if (veh_len >= VEHICLE_LENGTH) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_LENGTH, veh_len);
00179     length -= Clamp(veh_len, 0, VEHICLE_LENGTH - 1);
00180   }
00181 
00182   return length;
00183 }
00184 
00191 void RoadVehUpdateCache(RoadVehicle *v, bool same_length)
00192 {
00193   assert(v->type == VEH_ROAD);
00194   assert(v->IsFrontEngine());
00195 
00196   v->InvalidateNewGRFCacheOfChain();
00197 
00198   v->gcache.cached_total_length = 0;
00199 
00200   for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
00201     /* Check the v->first cache. */
00202     assert(u->First() == v);
00203 
00204     /* Update the 'first engine' */
00205     u->gcache.first_engine = (v == u) ? INVALID_ENGINE : v->engine_type;
00206 
00207     /* Update the length of the vehicle. */
00208     uint veh_len = GetRoadVehLength(u);
00209     /* Verify length hasn't changed. */
00210     if (same_length && veh_len != u->gcache.cached_veh_length) VehicleLengthChanged(u);
00211 
00212     u->gcache.cached_veh_length = veh_len;
00213     v->gcache.cached_total_length += u->gcache.cached_veh_length;
00214 
00215     /* Update visual effect */
00216     v->UpdateVisualEffect();
00217 
00218     /* Invalidate the vehicle colour map */
00219     u->colourmap = PAL_NONE;
00220 
00221     /* Update cargo aging period. */
00222     u->vcache.cached_cargo_age_period = GetVehicleProperty(u, PROP_ROADVEH_CARGO_AGE_PERIOD, EngInfo(u->engine_type)->cargo_age_period);
00223   }
00224 
00225   uint max_speed = GetVehicleProperty(v, PROP_ROADVEH_SPEED, 0);
00226   v->vcache.cached_max_speed = (max_speed != 0) ? max_speed * 4 : RoadVehInfo(v->engine_type)->max_speed;
00227 }
00228 
00238 CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret)
00239 {
00240   if (HasTileRoadType(tile, ROADTYPE_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE);
00241 
00242   if (flags & DC_EXEC) {
00243     const RoadVehicleInfo *rvi = &e->u.road;
00244 
00245     RoadVehicle *v = new RoadVehicle();
00246     *ret = v;
00247     v->direction = DiagDirToDir(GetRoadDepotDirection(tile));
00248     v->owner = _current_company;
00249 
00250     v->tile = tile;
00251     int x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
00252     int y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
00253     v->x_pos = x;
00254     v->y_pos = y;
00255     v->z_pos = GetSlopePixelZ(x, y);
00256 
00257     v->state = RVSB_IN_DEPOT;
00258     v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
00259 
00260     v->spritenum = rvi->image_index;
00261     v->cargo_type = e->GetDefaultCargoType();
00262     v->cargo_cap = rvi->capacity;
00263 
00264     v->last_station_visited = INVALID_STATION;
00265     v->last_loading_station = INVALID_STATION;
00266     v->engine_type = e->index;
00267     v->gcache.first_engine = INVALID_ENGINE; // needs to be set before first callback
00268 
00269     v->reliability = e->reliability;
00270     v->reliability_spd_dec = e->reliability_spd_dec;
00271     v->max_age = e->GetLifeLengthInDays();
00272     _new_vehicle_id = v->index;
00273 
00274     v->service_interval = Company::Get(v->owner)->settings.vehicle.servint_roadveh;
00275 
00276     v->date_of_last_service = _date;
00277     v->build_year = _cur_year;
00278 
00279     v->cur_image = SPR_IMG_QUERY;
00280     v->random_bits = VehicleRandomBits();
00281     v->SetFrontEngine();
00282 
00283     v->roadtype = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
00284     v->compatible_roadtypes = RoadTypeToRoadTypes(v->roadtype);
00285     v->gcache.cached_veh_length = VEHICLE_LENGTH;
00286 
00287     if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
00288 
00289     AddArticulatedParts(v);
00290     v->InvalidateNewGRFCacheOfChain();
00291 
00292     /* Call various callbacks after the whole consist has been constructed */
00293     for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
00294       u->cargo_cap = u->GetEngine()->DetermineCapacity(u);
00295       v->InvalidateNewGRFCache();
00296       u->InvalidateNewGRFCache();
00297     }
00298     RoadVehUpdateCache(v);
00299     /* Initialize cached values for realistic acceleration. */
00300     if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) v->CargoChanged();
00301 
00302     VehicleUpdatePosition(v);
00303 
00304     CheckConsistencyOfArticulatedVehicle(v);
00305   }
00306 
00307   return CommandCost();
00308 }
00309 
00310 static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance)
00311 {
00312   if (IsRoadDepotTile(v->tile)) return FindDepotData(v->tile, 0);
00313 
00314   switch (_settings_game.pf.pathfinder_for_roadvehs) {
00315     case VPF_NPF: return NPFRoadVehicleFindNearestDepot(v, max_distance);
00316     case VPF_YAPF: return YapfRoadVehicleFindNearestDepot(v, max_distance);
00317 
00318     default: NOT_REACHED();
00319   }
00320 }
00321 
00322 bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)
00323 {
00324   FindDepotData rfdd = FindClosestRoadDepot(this, 0);
00325   if (rfdd.best_length == UINT_MAX) return false;
00326 
00327   if (location    != NULL) *location    = rfdd.tile;
00328   if (destination != NULL) *destination = GetDepotIndex(rfdd.tile);
00329 
00330   return true;
00331 }
00332 
00342 CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00343 {
00344   RoadVehicle *v = RoadVehicle::GetIfValid(p1);
00345   if (v == NULL) return CMD_ERROR;
00346 
00347   if (!v->IsPrimaryVehicle()) return CMD_ERROR;
00348 
00349   CommandCost ret = CheckOwnership(v->owner);
00350   if (ret.Failed()) return ret;
00351 
00352   if ((v->vehstatus & VS_STOPPED) ||
00353       (v->vehstatus & VS_CRASHED) ||
00354       v->breakdown_ctr != 0 ||
00355       v->overtaking != 0 ||
00356       v->state == RVSB_WORMHOLE ||
00357       v->IsInDepot() ||
00358       v->current_order.IsType(OT_LOADING)) {
00359     return CMD_ERROR;
00360   }
00361 
00362   if (IsNormalRoadTile(v->tile) && GetDisallowedRoadDirections(v->tile) != DRD_NONE) return CMD_ERROR;
00363 
00364   if (IsTileType(v->tile, MP_TUNNELBRIDGE) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
00365 
00366   if (flags & DC_EXEC) v->reverse_ctr = 180;
00367 
00368   return CommandCost();
00369 }
00370 
00371 
00372 void RoadVehicle::MarkDirty()
00373 {
00374   for (RoadVehicle *v = this; v != NULL; v = v->Next()) {
00375     v->UpdateViewport(false, false);
00376   }
00377   this->CargoChanged();
00378 }
00379 
00380 void RoadVehicle::UpdateDeltaXY(Direction direction)
00381 {
00382   static const int8 _delta_xy_table[8][10] = {
00383     /* y_extent, x_extent, y_offs, x_offs, y_bb_offs, x_bb_offs, y_extent_shorten, x_extent_shorten, y_bb_offs_shorten, x_bb_offs_shorten */
00384     {3, 3, -1, -1,  0,  0, -1, -1, -1, -1}, // N
00385     {3, 7, -1, -3,  0, -1,  0, -1,  0,  0}, // NE
00386     {3, 3, -1, -1,  0,  0,  1, -1,  1, -1}, // E
00387     {7, 3, -3, -1, -1,  0,  0,  0,  1,  0}, // SE
00388     {3, 3, -1, -1,  0,  0,  1,  1,  1,  1}, // S
00389     {3, 7, -1, -3,  0, -1,  0,  0,  0,  1}, // SW
00390     {3, 3, -1, -1,  0,  0, -1,  1, -1,  1}, // W
00391     {7, 3, -3, -1, -1,  0, -1,  0,  0,  0}, // NW
00392   };
00393 
00394   int shorten = VEHICLE_LENGTH - this->gcache.cached_veh_length;
00395   if (!IsDiagonalDirection(direction)) shorten >>= 1;
00396 
00397   const int8 *bb = _delta_xy_table[direction];
00398   this->x_bb_offs     = bb[5] + bb[9] * shorten;
00399   this->y_bb_offs     = bb[4] + bb[8] * shorten;;
00400   this->x_offs        = bb[3];
00401   this->y_offs        = bb[2];
00402   this->x_extent      = bb[1] + bb[7] * shorten;
00403   this->y_extent      = bb[0] + bb[6] * shorten;
00404   this->z_extent      = 6;
00405 }
00406 
00411 inline int RoadVehicle::GetCurrentMaxSpeed() const
00412 {
00413   if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) return min(this->vcache.cached_max_speed, this->current_order.max_speed * 2);
00414 
00415   int max_speed = this->vcache.cached_max_speed;
00416 
00417   /* Limit speed to 50% while reversing, 75% in curves. */
00418   for (const RoadVehicle *u = this; u != NULL; u = u->Next()) {
00419     if (this->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)this->state)) {
00420       max_speed = this->vcache.cached_max_speed / 2;
00421       break;
00422     } else if ((u->direction & 1) == 0) {
00423       max_speed = this->vcache.cached_max_speed * 3 / 4;
00424     }
00425   }
00426 
00427   return min(max_speed, this->current_order.max_speed * 2);
00428 }
00429 
00434 static void DeleteLastRoadVeh(RoadVehicle *v)
00435 {
00436   Vehicle *u = v;
00437   for (; v->Next() != NULL; v = v->Next()) u = v;
00438   u->SetNext(NULL);
00439 
00440   /* Only leave the road stop when we're really gone. */
00441   if (IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
00442 
00443   delete v;
00444 }
00445 
00446 static void RoadVehSetRandomDirection(RoadVehicle *v)
00447 {
00448   static const DirDiff delta[] = {
00449     DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
00450   };
00451 
00452   do {
00453     uint32 r = Random();
00454 
00455     v->direction = ChangeDir(v->direction, delta[r & 3]);
00456     v->UpdateViewport(true, true);
00457   } while ((v = v->Next()) != NULL);
00458 }
00459 
00465 static bool RoadVehIsCrashed(RoadVehicle *v)
00466 {
00467   v->crashed_ctr++;
00468   if (v->crashed_ctr == 2) {
00469     CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
00470   } else if (v->crashed_ctr <= 45) {
00471     if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v);
00472   } else if (v->crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) {
00473     bool ret = v->Next() != NULL;
00474     DeleteLastRoadVeh(v);
00475     return ret;
00476   }
00477 
00478   return true;
00479 }
00480 
00487 static Vehicle *EnumCheckRoadVehCrashTrain(Vehicle *v, void *data)
00488 {
00489   const Vehicle *u = (Vehicle*)data;
00490 
00491   return (v->type == VEH_TRAIN &&
00492       abs(v->z_pos - u->z_pos) <= 6 &&
00493       abs(v->x_pos - u->x_pos) <= 4 &&
00494       abs(v->y_pos - u->y_pos) <= 4) ? v : NULL;
00495 }
00496 
00497 uint RoadVehicle::Crash(bool flooded)
00498 {
00499   uint pass = this->GroundVehicleBase::Crash(flooded);
00500   if (this->IsFrontEngine()) {
00501     pass += 1; // driver
00502 
00503     /* If we're in a drive through road stop we ought to leave it */
00504     if (IsInsideMM(this->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
00505       RoadStop::GetByTile(this->tile, GetRoadStopType(this->tile))->Leave(this);
00506     }
00507   }
00508   this->crashed_ctr = flooded ? 2000 : 1; // max 2220, disappear pretty fast when flooded
00509   return pass;
00510 }
00511 
00512 static void RoadVehCrash(RoadVehicle *v)
00513 {
00514   uint pass = v->Crash();
00515 
00516   AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
00517   Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_RV_LEVEL_CROSSING));
00518 
00519   SetDParam(0, pass);
00520   AddVehicleNewsItem(
00521     (pass == 1) ?
00522       STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER : STR_NEWS_ROAD_VEHICLE_CRASH,
00523     NT_ACCIDENT,
00524     v->index
00525   );
00526 
00527   ModifyStationRatingAround(v->tile, v->owner, -160, 22);
00528   SndPlayVehicleFx(SND_12_EXPLOSION, v);
00529 }
00530 
00531 static bool RoadVehCheckTrainCrash(RoadVehicle *v)
00532 {
00533   for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
00534     if (u->state == RVSB_WORMHOLE) continue;
00535 
00536     TileIndex tile = u->tile;
00537 
00538     if (!IsLevelCrossingTile(tile)) continue;
00539 
00540     if (HasVehicleOnPosXY(v->x_pos, v->y_pos, u, EnumCheckRoadVehCrashTrain)) {
00541       RoadVehCrash(v);
00542       return true;
00543     }
00544   }
00545 
00546   return false;
00547 }
00548 
00549 TileIndex RoadVehicle::GetOrderStationLocation(StationID station)
00550 {
00551   if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
00552 
00553   const Station *st = Station::Get(station);
00554   if (!CanVehicleUseStation(this, st)) {
00555     /* There is no stop left at the station, so don't even TRY to go there */
00556     this->IncrementRealOrderIndex();
00557     return 0;
00558   }
00559 
00560   return st->xy;
00561 }
00562 
00563 static void StartRoadVehSound(const RoadVehicle *v)
00564 {
00565   if (!PlayVehicleSound(v, VSE_START)) {
00566     SoundID s = RoadVehInfo(v->engine_type)->sfx;
00567     if (s == SND_19_BUS_START_PULL_AWAY && (v->tick_counter & 3) == 0) {
00568       s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN;
00569     }
00570     SndPlayVehicleFx(s, v);
00571   }
00572 }
00573 
00574 struct RoadVehFindData {
00575   int x;
00576   int y;
00577   const Vehicle *veh;
00578   Vehicle *best;
00579   uint best_diff;
00580   Direction dir;
00581 };
00582 
00583 static Vehicle *EnumCheckRoadVehClose(Vehicle *v, void *data)
00584 {
00585   static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 };
00586   static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 };
00587 
00588   RoadVehFindData *rvf = (RoadVehFindData*)data;
00589 
00590   short x_diff = v->x_pos - rvf->x;
00591   short y_diff = v->y_pos - rvf->y;
00592 
00593   if (v->type == VEH_ROAD &&
00594       !v->IsInDepot() &&
00595       abs(v->z_pos - rvf->veh->z_pos) < 6 &&
00596       v->direction == rvf->dir &&
00597       rvf->veh->First() != v->First() &&
00598       (dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) &&
00599       (dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) &&
00600       (dist_y[v->direction] >= 0 || (y_diff > dist_y[v->direction] && y_diff <= 0)) &&
00601       (dist_y[v->direction] <= 0 || (y_diff < dist_y[v->direction] && y_diff >= 0))) {
00602     uint diff = abs(x_diff) + abs(y_diff);
00603 
00604     if (diff < rvf->best_diff || (diff == rvf->best_diff && v->index < rvf->best->index)) {
00605       rvf->best = v;
00606       rvf->best_diff = diff;
00607     }
00608   }
00609 
00610   return NULL;
00611 }
00612 
00613 static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction dir, bool update_blocked_ctr = true)
00614 {
00615   RoadVehFindData rvf;
00616   RoadVehicle *front = v->First();
00617 
00618   if (front->reverse_ctr != 0) return NULL;
00619 
00620   rvf.x = x;
00621   rvf.y = y;
00622   rvf.dir = dir;
00623   rvf.veh = v;
00624   rvf.best_diff = UINT_MAX;
00625 
00626   if (front->state == RVSB_WORMHOLE) {
00627     FindVehicleOnPos(v->tile, &rvf, EnumCheckRoadVehClose);
00628     FindVehicleOnPos(GetOtherTunnelBridgeEnd(v->tile), &rvf, EnumCheckRoadVehClose);
00629   } else {
00630     FindVehicleOnPosXY(x, y, &rvf, EnumCheckRoadVehClose);
00631   }
00632 
00633   /* This code protects a roadvehicle from being blocked for ever
00634    * If more than 1480 / 74 days a road vehicle is blocked, it will
00635    * drive just through it. The ultimate backup-code of TTD.
00636    * It can be disabled. */
00637   if (rvf.best_diff == UINT_MAX) {
00638     front->blocked_ctr = 0;
00639     return NULL;
00640   }
00641 
00642   if (update_blocked_ctr && ++front->blocked_ctr > 1480) return NULL;
00643 
00644   return RoadVehicle::From(rvf.best);
00645 }
00646 
00652 static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
00653 {
00654   if (v->IsBus()) {
00655     /* Check if station was ever visited before */
00656     if (!(st->had_vehicle_of_type & HVOT_BUS)) {
00657       st->had_vehicle_of_type |= HVOT_BUS;
00658       SetDParam(0, st->index);
00659       AddVehicleNewsItem(
00660         v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL,
00661         (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
00662         v->index,
00663         st->index
00664       );
00665       AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
00666       Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
00667     }
00668   } else {
00669     /* Check if station was ever visited before */
00670     if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
00671       st->had_vehicle_of_type |= HVOT_TRUCK;
00672       SetDParam(0, st->index);
00673       AddVehicleNewsItem(
00674         v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL,
00675         (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER,
00676         v->index,
00677         st->index
00678       );
00679       AI::NewEvent(v->owner, new ScriptEventStationFirstVehicle(st->index, v->index));
00680       Game::NewEvent(new ScriptEventStationFirstVehicle(st->index, v->index));
00681     }
00682   }
00683 }
00684 
00692 int RoadVehicle::UpdateSpeed()
00693 {
00694   switch (_settings_game.vehicle.roadveh_acceleration_model) {
00695     default: NOT_REACHED();
00696     case AM_ORIGINAL:
00697       return this->DoUpdateSpeed(this->overtaking != 0 ? 512 : 256, 0, this->GetCurrentMaxSpeed());
00698 
00699     case AM_REALISTIC:
00700       return this->DoUpdateSpeed(this->GetAcceleration() + (this->overtaking != 0 ? 256 : 0), this->GetAccelerationStatus() == AS_BRAKE ? 0 : 4, this->GetCurrentMaxSpeed());
00701   }
00702 }
00703 
00704 static Direction RoadVehGetNewDirection(const RoadVehicle *v, int x, int y)
00705 {
00706   static const Direction _roadveh_new_dir[] = {
00707     DIR_N , DIR_NW, DIR_W , INVALID_DIR,
00708     DIR_NE, DIR_N , DIR_SW, INVALID_DIR,
00709     DIR_E , DIR_SE, DIR_S
00710   };
00711 
00712   x = x - v->x_pos + 1;
00713   y = y - v->y_pos + 1;
00714 
00715   if ((uint)x > 2 || (uint)y > 2) return v->direction;
00716   return _roadveh_new_dir[y * 4 + x];
00717 }
00718 
00719 static Direction RoadVehGetSlidingDirection(const RoadVehicle *v, int x, int y)
00720 {
00721   Direction new_dir = RoadVehGetNewDirection(v, x, y);
00722   Direction old_dir = v->direction;
00723   DirDiff delta;
00724 
00725   if (new_dir == old_dir) return old_dir;
00726   delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT);
00727   return ChangeDir(old_dir, delta);
00728 }
00729 
00730 struct OvertakeData {
00731   const RoadVehicle *u;
00732   const RoadVehicle *v;
00733   TileIndex tile;
00734   Trackdir trackdir;
00735 };
00736 
00737 static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data)
00738 {
00739   const OvertakeData *od = (OvertakeData*)data;
00740 
00741   return (v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v) ? v : NULL;
00742 }
00743 
00750 static bool CheckRoadBlockedForOvertaking(OvertakeData *od)
00751 {
00752   TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->compatible_roadtypes);
00753   TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts);
00754   TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing
00755   TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits);
00756 
00757   /* Track does not continue along overtaking direction || track has junction || levelcrossing is barred */
00758   if (!HasBit(trackdirbits, od->trackdir) || (trackbits & ~TRACK_BIT_CROSS) || (red_signals != TRACKDIR_BIT_NONE)) return true;
00759 
00760   /* Are there more vehicles on the tile except the two vehicles involved in overtaking */
00761   return HasVehicleOnPos(od->tile, od, EnumFindVehBlockingOvertake);
00762 }
00763 
00764 static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
00765 {
00766   OvertakeData od;
00767 
00768   od.v = v;
00769   od.u = u;
00770 
00771   if (u->vcache.cached_max_speed >= v->vcache.cached_max_speed &&
00772       !(u->vehstatus & VS_STOPPED) &&
00773       u->cur_speed != 0) {
00774     return;
00775   }
00776 
00777   /* Trams can't overtake other trams */
00778   if (v->roadtype == ROADTYPE_TRAM) return;
00779 
00780   /* Don't overtake in stations */
00781   if (IsTileType(v->tile, MP_STATION) || IsTileType(u->tile, MP_STATION)) return;
00782 
00783   /* For now, articulated road vehicles can't overtake anything. */
00784   if (v->HasArticulatedPart()) return;
00785 
00786   /* Vehicles are not driving in same direction || direction is not a diagonal direction */
00787   if (v->direction != u->direction || !(v->direction & 1)) return;
00788 
00789   /* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
00790   if (v->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->state & RVSB_TRACKDIR_MASK))) return;
00791 
00792   od.trackdir = DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
00793 
00794   /* Are the current and the next tile suitable for overtaking?
00795    *  - Does the track continue along od.trackdir
00796    *  - No junctions
00797    *  - No barred levelcrossing
00798    *  - No other vehicles in the way
00799    */
00800   od.tile = v->tile;
00801   if (CheckRoadBlockedForOvertaking(&od)) return;
00802 
00803   od.tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction));
00804   if (CheckRoadBlockedForOvertaking(&od)) return;
00805 
00806   /* When the vehicle in front of us is stopped we may only take
00807    * half the time to pass it than when the vehicle is moving. */
00808   v->overtaking_ctr = (od.u->cur_speed == 0 || (od.u->vehstatus & VS_STOPPED)) ? RV_OVERTAKE_TIMEOUT / 2 : 0;
00809   v->overtaking = RVSB_DRIVE_SIDE;
00810 }
00811 
00812 static void RoadZPosAffectSpeed(RoadVehicle *v, byte old_z)
00813 {
00814   if (old_z == v->z_pos || _settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) return;
00815 
00816   if (old_z < v->z_pos) {
00817     v->cur_speed = v->cur_speed * 232 / 256; // slow down by ~10%
00818   } else {
00819     uint16 spd = v->cur_speed + 2;
00820     if (spd <= v->vcache.cached_max_speed) v->cur_speed = spd;
00821   }
00822 }
00823 
00824 static int PickRandomBit(uint bits)
00825 {
00826   uint i;
00827   uint num = RandomRange(CountBits(bits));
00828 
00829   for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
00830   return i;
00831 }
00832 
00841 static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection enterdir)
00842 {
00843 #define return_track(x) { best_track = (Trackdir)x; goto found_best_track; }
00844 
00845   TileIndex desttile;
00846   Trackdir best_track;
00847   bool path_found = true;
00848 
00849   TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes);
00850   TrackdirBits red_signals = TrackStatusToRedSignals(ts); // crossing
00851   TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts);
00852 
00853   if (IsTileType(tile, MP_ROAD)) {
00854     if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->compatible_roadtypes) == 0)) {
00855       /* Road depot owned by another company or with the wrong orientation */
00856       trackdirs = TRACKDIR_BIT_NONE;
00857     }
00858   } else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
00859     /* Standard road stop (drive-through stops are treated as normal road) */
00860 
00861     if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || v->HasArticulatedPart()) {
00862       /* different station owner or wrong orientation or the vehicle has articulated parts */
00863       trackdirs = TRACKDIR_BIT_NONE;
00864     } else {
00865       /* Our station */
00866       RoadStopType rstype = v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK;
00867 
00868       if (GetRoadStopType(tile) != rstype) {
00869         /* Wrong station type */
00870         trackdirs = TRACKDIR_BIT_NONE;
00871       } else {
00872         /* Proper station type, check if there is free loading bay */
00873         if (!_settings_game.pf.roadveh_queue && IsStandardRoadStopTile(tile) &&
00874             !RoadStop::GetByTile(tile, rstype)->HasFreeBay()) {
00875           /* Station is full and RV queuing is off */
00876           trackdirs = TRACKDIR_BIT_NONE;
00877         }
00878       }
00879     }
00880   }
00881   /* The above lookups should be moved to GetTileTrackStatus in the
00882    * future, but that requires more changes to the pathfinder and other
00883    * stuff, probably even more arguments to GTTS.
00884    */
00885 
00886   /* Remove tracks unreachable from the enter dir */
00887   trackdirs &= _road_enter_dir_to_reachable_trackdirs[enterdir];
00888   if (trackdirs == TRACKDIR_BIT_NONE) {
00889     /* No reachable tracks, so we'll reverse */
00890     return_track(_road_reverse_table[enterdir]);
00891   }
00892 
00893   if (v->reverse_ctr != 0) {
00894     bool reverse = true;
00895     if (v->roadtype == ROADTYPE_TRAM) {
00896       /* Trams may only reverse on a tile if it contains at least the straight
00897        * trackbits or when it is a valid turning tile (i.e. one roadbit) */
00898       RoadBits rb = GetAnyRoadBits(tile, ROADTYPE_TRAM);
00899       RoadBits straight = AxisToRoadBits(DiagDirToAxis(enterdir));
00900       reverse = ((rb & straight) == straight) ||
00901                 (rb == DiagDirToRoadBits(enterdir));
00902     }
00903     if (reverse) {
00904       v->reverse_ctr = 0;
00905       if (v->tile != tile) {
00906         return_track(_road_reverse_table[enterdir]);
00907       }
00908     }
00909   }
00910 
00911   desttile = v->dest_tile;
00912   if (desttile == 0) {
00913     /* We've got no destination, pick a random track */
00914     return_track(PickRandomBit(trackdirs));
00915   }
00916 
00917   /* Only one track to choose between? */
00918   if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) {
00919     return_track(FindFirstBit2x64(trackdirs));
00920   }
00921 
00922   switch (_settings_game.pf.pathfinder_for_roadvehs) {
00923     case VPF_NPF:  best_track = NPFRoadVehicleChooseTrack(v, tile, enterdir, trackdirs, path_found); break;
00924     case VPF_YAPF: best_track = YapfRoadVehicleChooseTrack(v, tile, enterdir, trackdirs, path_found); break;
00925 
00926     default: NOT_REACHED();
00927   }
00928   v->HandlePathfindingResult(path_found);
00929 
00930 found_best_track:;
00931 
00932   if (HasBit(red_signals, best_track)) return INVALID_TRACKDIR;
00933 
00934   return best_track;
00935 }
00936 
00937 struct RoadDriveEntry {
00938   byte x, y;
00939 };
00940 
00941 #include "table/roadveh_movement.h"
00942 
00943 static bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
00944 {
00945   /* Don't leave unless v and following wagons are in the depot. */
00946   for (const RoadVehicle *u = v; u != NULL; u = u->Next()) {
00947     if (u->state != RVSB_IN_DEPOT || u->tile != v->tile) return false;
00948   }
00949 
00950   DiagDirection dir = GetRoadDepotDirection(v->tile);
00951   v->direction = DiagDirToDir(dir);
00952 
00953   Trackdir tdir = _roadveh_depot_exit_trackdir[dir];
00954   const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir];
00955 
00956   int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
00957   int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
00958 
00959   if (first) {
00960     /* We are leaving a depot, but have to go to the exact same one; re-enter */
00961     if (v->current_order.IsType(OT_GOTO_DEPOT) && v->tile == v->dest_tile) {
00962       VehicleEnterDepot(v);
00963       return true;
00964     }
00965 
00966     if (RoadVehFindCloseTo(v, x, y, v->direction, false) != NULL) return true;
00967 
00968     VehicleServiceInDepot(v);
00969 
00970     StartRoadVehSound(v);
00971 
00972     /* Vehicle is about to leave a depot */
00973     v->cur_speed = 0;
00974   }
00975 
00976   v->vehstatus &= ~VS_HIDDEN;
00977   v->state = tdir;
00978   v->frame = RVC_DEPOT_START_FRAME;
00979 
00980   v->x_pos = x;
00981   v->y_pos = y;
00982   VehicleUpdatePosition(v);
00983   v->UpdateInclination(true, true);
00984 
00985   InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
00986 
00987   return true;
00988 }
00989 
00990 static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicle *prev, TileIndex tile, DiagDirection entry_dir, bool already_reversed)
00991 {
00992   if (prev->tile == v->tile && !already_reversed) {
00993     /* If the previous vehicle is on the same tile as this vehicle is
00994      * then it must have reversed. */
00995     return _road_reverse_table[entry_dir];
00996   }
00997 
00998   byte prev_state = prev->state;
00999   Trackdir dir;
01000 
01001   if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
01002     DiagDirection diag_dir = INVALID_DIAGDIR;
01003 
01004     if (IsTileType(tile, MP_TUNNELBRIDGE)) {
01005       diag_dir = GetTunnelBridgeDirection(tile);
01006     } else if (IsRoadDepotTile(tile)) {
01007       diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
01008     }
01009 
01010     if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR;
01011     dir = DiagDirToDiagTrackdir(diag_dir);
01012   } else {
01013     if (already_reversed && prev->tile != tile) {
01014       /*
01015        * The vehicle has reversed, but did not go straight back.
01016        * It immediately turn onto another tile. This means that
01017        * the roadstate of the previous vehicle cannot be used
01018        * as the direction we have to go with this vehicle.
01019        *
01020        * Next table is build in the following way:
01021        *  - first row for when the vehicle in front went to the northern or
01022        *    western tile, second for southern and eastern.
01023        *  - columns represent the entry direction.
01024        *  - cell values are determined by the Trackdir one has to take from
01025        *    the entry dir (column) to the tile in north or south by only
01026        *    going over the trackdirs used for turning 90 degrees, i.e.
01027        *    TRACKDIR_{UPPER,RIGHT,LOWER,LEFT}_{N,E,S,W}.
01028        */
01029       static const Trackdir reversed_turn_lookup[2][DIAGDIR_END] = {
01030         { TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N,  TRACKDIR_UPPER_E },
01031         { TRACKDIR_RIGHT_S, TRACKDIR_LOWER_W, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S  }};
01032       dir = reversed_turn_lookup[prev->tile < tile ? 0 : 1][ReverseDiagDir(entry_dir)];
01033     } else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) {
01034       dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
01035     } else if (prev_state < TRACKDIR_END) {
01036       dir = (Trackdir)prev_state;
01037     } else {
01038       return INVALID_TRACKDIR;
01039     }
01040   }
01041 
01042   /* Do some sanity checking. */
01043   static const RoadBits required_roadbits[] = {
01044     ROAD_X,            ROAD_Y,            ROAD_NW | ROAD_NE, ROAD_SW | ROAD_SE,
01045     ROAD_NW | ROAD_SW, ROAD_NE | ROAD_SE, ROAD_X,            ROAD_Y
01046   };
01047   RoadBits required = required_roadbits[dir & 0x07];
01048 
01049   if ((required & GetAnyRoadBits(tile, v->roadtype, true)) == ROAD_NONE) {
01050     dir = INVALID_TRACKDIR;
01051   }
01052 
01053   return dir;
01054 }
01055 
01063 static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r)
01064 {
01065   /* The 'current' company is not necessarily the owner of the vehicle. */
01066   Backup<CompanyByte> cur_company(_current_company, c, FILE_LINE);
01067 
01068   CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, DC_NONE, CMD_BUILD_ROAD);
01069 
01070   cur_company.Restore();
01071   return ret.Succeeded();
01072 }
01073 
01074 static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
01075 {
01076   if (v->overtaking != 0)  {
01077     if (IsTileType(v->tile, MP_STATION)) {
01078       /* Force us to be not overtaking! */
01079       v->overtaking = 0;
01080     } else if (++v->overtaking_ctr >= RV_OVERTAKE_TIMEOUT) {
01081       /* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
01082        *  if the vehicle started a corner. To protect that, only allow an abort of
01083        *  overtake if we are on straight roads */
01084       if (v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->state)) {
01085         v->overtaking = 0;
01086       }
01087     }
01088   }
01089 
01090   /* If this vehicle is in a depot and we've reached this point it must be
01091    * one of the articulated parts. It will stay in the depot until activated
01092    * by the previous vehicle in the chain when it gets to the right place. */
01093   if (v->IsInDepot()) return true;
01094 
01095   if (v->state == RVSB_WORMHOLE) {
01096     /* Vehicle is entering a depot or is on a bridge or in a tunnel */
01097     GetNewVehiclePosResult gp = GetNewVehiclePos(v);
01098 
01099     /* Apply bridge speed limit */
01100     if (!(v->vehstatus & VS_HIDDEN)) {
01101       RoadVehicle *first = v->First();
01102       first->cur_speed = min(first->cur_speed, GetBridgeSpec(GetBridgeType(v->tile))->speed * 2);
01103     }
01104 
01105     if (v->IsFrontEngine()) {
01106       const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
01107       if (u != NULL) {
01108         v->cur_speed = u->First()->cur_speed;
01109         return false;
01110       }
01111     }
01112 
01113     if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
01114       /* Vehicle has just entered a bridge or tunnel */
01115       v->x_pos = gp.x;
01116       v->y_pos = gp.y;
01117       VehicleUpdatePosition(v);
01118       v->UpdateInclination(true, true);
01119       return true;
01120     }
01121 
01122     v->x_pos = gp.x;
01123     v->y_pos = gp.y;
01124     VehicleUpdatePosition(v);
01125     if ((v->vehstatus & VS_HIDDEN) == 0) VehicleUpdateViewport(v, true);
01126     return true;
01127   }
01128 
01129   /* Get move position data for next frame.
01130    * For a drive-through road stop use 'straight road' move data.
01131    * In this case v->state is masked to give the road stop entry direction. */
01132   RoadDriveEntry rd = _road_drive_data[v->roadtype][(
01133     (HasBit(v->state, RVS_IN_DT_ROAD_STOP) ? v->state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->state) +
01134     (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking][v->frame + 1];
01135 
01136   if (rd.x & RDE_NEXT_TILE) {
01137     TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3));
01138     Trackdir dir;
01139 
01140     if (v->IsFrontEngine()) {
01141       /* If this is the front engine, look for the right path. */
01142       dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
01143     } else {
01144       dir = FollowPreviousRoadVehicle(v, prev, tile, (DiagDirection)(rd.x & 3), false);
01145     }
01146 
01147     if (dir == INVALID_TRACKDIR) {
01148       if (!v->IsFrontEngine()) error("Disconnecting road vehicle.");
01149       v->cur_speed = 0;
01150       return false;
01151     }
01152 
01153 again:
01154     uint start_frame = RVC_DEFAULT_START_FRAME;
01155     if (IsReversingRoadTrackdir(dir)) {
01156       /* When turning around we can't be overtaking. */
01157       v->overtaking = 0;
01158 
01159       /* Turning around */
01160       if (v->roadtype == ROADTYPE_TRAM) {
01161         /* Determine the road bits the tram needs to be able to turn around
01162          * using the 'big' corner loop. */
01163         RoadBits needed;
01164         switch (dir) {
01165           default: NOT_REACHED();
01166           case TRACKDIR_RVREV_NE: needed = ROAD_SW; break;
01167           case TRACKDIR_RVREV_SE: needed = ROAD_NW; break;
01168           case TRACKDIR_RVREV_SW: needed = ROAD_NE; break;
01169           case TRACKDIR_RVREV_NW: needed = ROAD_SE; break;
01170         }
01171         if ((v->Previous() != NULL && v->Previous()->tile == tile) ||
01172             (v->IsFrontEngine() && IsNormalRoadTile(tile) && !HasRoadWorks(tile) &&
01173               (needed & GetRoadBits(tile, ROADTYPE_TRAM)) != ROAD_NONE)) {
01174           /*
01175            * Taking the 'big' corner for trams only happens when:
01176            * - The previous vehicle in this (articulated) tram chain is
01177            *   already on the 'next' tile, we just follow them regardless of
01178            *   anything. When it is NOT on the 'next' tile, the tram started
01179            *   doing a reversing turn when the piece of tram track on the next
01180            *   tile did not exist yet. Do not use the big tram loop as that is
01181            *   going to cause the tram to split up.
01182            * - Or the front of the tram can drive over the next tile.
01183            */
01184         } else if (!v->IsFrontEngine() || !CanBuildTramTrackOnTile(v->owner, tile, needed) || ((~needed & GetAnyRoadBits(v->tile, ROADTYPE_TRAM, false)) == ROAD_NONE)) {
01185           /*
01186            * Taking the 'small' corner for trams only happens when:
01187            * - We are not the from vehicle of an articulated tram.
01188            * - Or when the company cannot build on the next tile.
01189            *
01190            * The 'small' corner means that the vehicle is on the end of a
01191            * tram track and needs to start turning there. To do this properly
01192            * the tram needs to start at an offset in the tram turning 'code'
01193            * for 'big' corners. It furthermore does not go to the next tile,
01194            * so that needs to be fixed too.
01195            */
01196           tile = v->tile;
01197           start_frame = RVC_TURN_AROUND_START_FRAME_SHORT_TRAM;
01198         } else {
01199           /* The company can build on the next tile, so wait till (s)he does. */
01200           v->cur_speed = 0;
01201           return false;
01202         }
01203       } else if (IsNormalRoadTile(v->tile) && GetDisallowedRoadDirections(v->tile) != DRD_NONE) {
01204         v->cur_speed = 0;
01205         return false;
01206       } else {
01207         tile = v->tile;
01208       }
01209     }
01210 
01211     /* Get position data for first frame on the new tile */
01212     const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking];
01213 
01214     int x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
01215     int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
01216 
01217     Direction new_dir = RoadVehGetSlidingDirection(v, x, y);
01218     if (v->IsFrontEngine()) {
01219       Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir);
01220       if (u != NULL) {
01221         v->cur_speed = u->First()->cur_speed;
01222         return false;
01223       }
01224     }
01225 
01226     uint32 r = VehicleEnterTile(v, tile, x, y);
01227     if (HasBit(r, VETS_CANNOT_ENTER)) {
01228       if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
01229         v->cur_speed = 0;
01230         return false;
01231       }
01232       /* Try an about turn to re-enter the previous tile */
01233       dir = _road_reverse_table[rd.x & 3];
01234       goto again;
01235     }
01236 
01237     if (IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
01238       if (IsReversingRoadTrackdir(dir) && IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
01239         /* New direction is trying to turn vehicle around.
01240          * We can't turn at the exit of a road stop so wait.*/
01241         v->cur_speed = 0;
01242         return false;
01243       }
01244 
01245       /* If we are a drive through road stop and the next tile is of
01246        * the same road stop and the next tile isn't this one (i.e. we
01247        * are not reversing), then keep the reservation and state.
01248        * This way we will not be shortly unregister from the road
01249        * stop. It also makes it possible to load when on the edge of
01250        * two road stops; otherwise you could get vehicles that should
01251        * be loading but are not actually loading. */
01252       if (IsDriveThroughStopTile(v->tile) &&
01253           RoadStop::IsDriveThroughRoadStopContinuation(v->tile, tile) &&
01254           v->tile != tile) {
01255         /* So, keep 'our' state */
01256         dir = (Trackdir)v->state;
01257       } else if (IsRoadStop(v->tile)) {
01258         /* We're not continuing our drive through road stop, so leave. */
01259         RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
01260       }
01261     }
01262 
01263     if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
01264       v->tile = tile;
01265       v->state = (byte)dir;
01266       v->frame = start_frame;
01267     }
01268     if (new_dir != v->direction) {
01269       v->direction = new_dir;
01270       if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) v->cur_speed -= v->cur_speed >> 2;
01271     }
01272     v->x_pos = x;
01273     v->y_pos = y;
01274     VehicleUpdatePosition(v);
01275     RoadZPosAffectSpeed(v, v->UpdateInclination(true, true));
01276     return true;
01277   }
01278 
01279   if (rd.x & RDE_TURNED) {
01280     /* Vehicle has finished turning around, it will now head back onto the same tile */
01281     Trackdir dir;
01282     uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME;
01283 
01284     if (v->roadtype == ROADTYPE_TRAM && !IsRoadDepotTile(v->tile) && HasExactlyOneBit(GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true))) {
01285       /*
01286        * The tram is turning around with one tram 'roadbit'. This means that
01287        * it is using the 'big' corner 'drive data'. However, to support the
01288        * trams to take a small corner, there is a 'turned' marker in the middle
01289        * of the turning 'drive data'. When the tram took the long corner, we
01290        * will still use the 'big' corner drive data, but we advance it one
01291        * frame. We furthermore set the driving direction so the turning is
01292        * going to be properly shown.
01293        */
01294       turn_around_start_frame = RVC_START_FRAME_AFTER_LONG_TRAM;
01295       switch (rd.x & 0x3) {
01296         default: NOT_REACHED();
01297         case DIAGDIR_NW: dir = TRACKDIR_RVREV_SE; break;
01298         case DIAGDIR_NE: dir = TRACKDIR_RVREV_SW; break;
01299         case DIAGDIR_SE: dir = TRACKDIR_RVREV_NW; break;
01300         case DIAGDIR_SW: dir = TRACKDIR_RVREV_NE; break;
01301       }
01302     } else {
01303       if (v->IsFrontEngine()) {
01304         /* If this is the front engine, look for the right path. */
01305         dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3));
01306       } else {
01307         dir = FollowPreviousRoadVehicle(v, prev, v->tile, (DiagDirection)(rd.x & 3), true);
01308       }
01309     }
01310 
01311     if (dir == INVALID_TRACKDIR) {
01312       v->cur_speed = 0;
01313       return false;
01314     }
01315 
01316     const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir];
01317 
01318     int x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x;
01319     int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
01320 
01321     Direction new_dir = RoadVehGetSlidingDirection(v, x, y);
01322     if (v->IsFrontEngine() && RoadVehFindCloseTo(v, x, y, new_dir) != NULL) return false;
01323 
01324     uint32 r = VehicleEnterTile(v, v->tile, x, y);
01325     if (HasBit(r, VETS_CANNOT_ENTER)) {
01326       v->cur_speed = 0;
01327       return false;
01328     }
01329 
01330     v->state = dir;
01331     v->frame = turn_around_start_frame;
01332 
01333     if (new_dir != v->direction) {
01334       v->direction = new_dir;
01335       if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) v->cur_speed -= v->cur_speed >> 2;
01336     }
01337 
01338     v->x_pos = x;
01339     v->y_pos = y;
01340     VehicleUpdatePosition(v);
01341     RoadZPosAffectSpeed(v, v->UpdateInclination(true, true));
01342     return true;
01343   }
01344 
01345   /* This vehicle is not in a wormhole and it hasn't entered a new tile. If
01346    * it's on a depot tile, check if it's time to activate the next vehicle in
01347    * the chain yet. */
01348   if (v->Next() != NULL && IsRoadDepotTile(v->tile)) {
01349     if (v->frame == v->gcache.cached_veh_length + RVC_DEPOT_START_FRAME) {
01350       RoadVehLeaveDepot(v->Next(), false);
01351     }
01352   }
01353 
01354   /* Calculate new position for the vehicle */
01355   int x = (v->x_pos & ~15) + (rd.x & 15);
01356   int y = (v->y_pos & ~15) + (rd.y & 15);
01357 
01358   Direction new_dir = RoadVehGetSlidingDirection(v, x, y);
01359 
01360   if (v->IsFrontEngine() && !IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
01361     /* Vehicle is not in a road stop.
01362      * Check for another vehicle to overtake */
01363     RoadVehicle *u = RoadVehFindCloseTo(v, x, y, new_dir);
01364 
01365     if (u != NULL) {
01366       u = u->First();
01367       /* There is a vehicle in front overtake it if possible */
01368       if (v->overtaking == 0) RoadVehCheckOvertake(v, u);
01369       if (v->overtaking == 0) v->cur_speed = u->cur_speed;
01370 
01371       /* In case an RV is stopped in a road stop, why not try to load? */
01372       if (v->cur_speed == 0 && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
01373           v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
01374           v->owner == GetTileOwner(v->tile) && !v->current_order.IsType(OT_LEAVESTATION) &&
01375           GetRoadStopType(v->tile) == (v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK)) {
01376         Station *st = Station::GetByTile(v->tile);
01377         v->last_station_visited = st->index;
01378         RoadVehArrivesAt(v, st);
01379         v->BeginLoading();
01380       }
01381       return false;
01382     }
01383   }
01384 
01385   Direction old_dir = v->direction;
01386   if (new_dir != old_dir) {
01387     v->direction = new_dir;
01388     if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) v->cur_speed -= v->cur_speed >> 2;
01389     if (old_dir != v->state) {
01390       /* The vehicle is in a road stop */
01391       v->UpdateInclination(false, true);
01392       /* Note, return here means that the frame counter is not incremented
01393        * for vehicles changing direction in a road stop. This causes frames to
01394        * be repeated. (XXX) Is this intended? */
01395       return true;
01396     }
01397   }
01398 
01399   /* If the vehicle is in a normal road stop and the frame equals the stop frame OR
01400    * if the vehicle is in a drive-through road stop and this is the destination station
01401    * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
01402    * (the station test and stop type test ensure that other vehicles, using the road stop as
01403    * a through route, do not stop) */
01404   if (v->IsFrontEngine() && ((IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
01405       _road_stop_stop_frame[v->state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->frame) ||
01406       (IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
01407       v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
01408       v->owner == GetTileOwner(v->tile) &&
01409       GetRoadStopType(v->tile) == (v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
01410       v->frame == RVC_DRIVE_THROUGH_STOP_FRAME))) {
01411 
01412     RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
01413     Station *st = Station::GetByTile(v->tile);
01414 
01415     /* Vehicle is at the stop position (at a bay) in a road stop.
01416      * Note, if vehicle is loading/unloading it has already been handled,
01417      * so if we get here the vehicle has just arrived or is just ready to leave. */
01418     if (!HasBit(v->state, RVS_ENTERED_STOP)) {
01419       /* Vehicle has arrived at a bay in a road stop */
01420 
01421       if (IsDriveThroughStopTile(v->tile)) {
01422         TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction));
01423 
01424         /* Check if next inline bay is free and has compatible road. */
01425         if (RoadStop::IsDriveThroughRoadStopContinuation(v->tile, next_tile) && (GetRoadTypes(next_tile) & v->compatible_roadtypes) != 0) {
01426           v->frame++;
01427           v->x_pos = x;
01428           v->y_pos = y;
01429           VehicleUpdatePosition(v);
01430           RoadZPosAffectSpeed(v, v->UpdateInclination(true, false));
01431           return true;
01432         }
01433       }
01434 
01435       rs->SetEntranceBusy(false);
01436       SetBit(v->state, RVS_ENTERED_STOP);
01437 
01438       v->last_station_visited = st->index;
01439 
01440       if (IsDriveThroughStopTile(v->tile) || (v->current_order.IsType(OT_GOTO_STATION) && v->current_order.GetDestination() == st->index)) {
01441         RoadVehArrivesAt(v, st);
01442         v->BeginLoading();
01443         return false;
01444       }
01445     } else {
01446       /* Vehicle is ready to leave a bay in a road stop */
01447       if (rs->IsEntranceBusy()) {
01448         /* Road stop entrance is busy, so wait as there is nowhere else to go */
01449         v->cur_speed = 0;
01450         return false;
01451       }
01452       if (v->current_order.IsType(OT_LEAVESTATION)) v->current_order.Free();
01453     }
01454 
01455     if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
01456 
01457     StartRoadVehSound(v);
01458     SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
01459   }
01460 
01461   /* Check tile position conditions - i.e. stop position in depot,
01462    * entry onto bridge or into tunnel */
01463   uint32 r = VehicleEnterTile(v, v->tile, x, y);
01464   if (HasBit(r, VETS_CANNOT_ENTER)) {
01465     v->cur_speed = 0;
01466     return false;
01467   }
01468 
01469   if (v->current_order.IsType(OT_LEAVESTATION) && IsDriveThroughStopTile(v->tile)) {
01470     v->current_order.Free();
01471   }
01472 
01473   /* Move to next frame unless vehicle arrived at a stop position
01474    * in a depot or entered a tunnel/bridge */
01475   if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->frame++;
01476   v->x_pos = x;
01477   v->y_pos = y;
01478   VehicleUpdatePosition(v);
01479   RoadZPosAffectSpeed(v, v->UpdateInclination(false, true));
01480   return true;
01481 }
01482 
01483 static bool RoadVehController(RoadVehicle *v)
01484 {
01485   /* decrease counters */
01486   v->tick_counter++;
01487   v->current_order_time++;
01488   if (v->reverse_ctr != 0) v->reverse_ctr--;
01489 
01490   /* handle crashed */
01491   if (v->vehstatus & VS_CRASHED || RoadVehCheckTrainCrash(v)) {
01492     return RoadVehIsCrashed(v);
01493   }
01494 
01495   /* road vehicle has broken down? */
01496   if (v->HandleBreakdown()) return true;
01497   if (v->vehstatus & VS_STOPPED) return true;
01498 
01499   ProcessOrders(v);
01500   v->HandleLoading();
01501 
01502   if (v->current_order.IsType(OT_LOADING)) return true;
01503 
01504   if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return true;
01505 
01506   v->ShowVisualEffect();
01507 
01508   /* Check how far the vehicle needs to proceed */
01509   int j = v->UpdateSpeed();
01510 
01511   int adv_spd = v->GetAdvanceDistance();
01512   bool blocked = false;
01513   while (j >= adv_spd) {
01514     j -= adv_spd;
01515 
01516     RoadVehicle *u = v;
01517     for (RoadVehicle *prev = NULL; u != NULL; prev = u, u = u->Next()) {
01518       if (!IndividualRoadVehicleController(u, prev)) {
01519         blocked = true;
01520         break;
01521       }
01522     }
01523     if (blocked) break;
01524 
01525     /* Determine distance to next map position */
01526     adv_spd = v->GetAdvanceDistance();
01527 
01528     /* Test for a collision, but only if another movement will occur. */
01529     if (j >= adv_spd && RoadVehCheckTrainCrash(v)) break;
01530   }
01531 
01532   v->SetLastSpeed();
01533 
01534   for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
01535     if ((u->vehstatus & VS_HIDDEN) != 0) continue;
01536 
01537     u->UpdateViewport(false, false);
01538   }
01539 
01540   /* If movement is blocked, set 'progress' to its maximum, so the roadvehicle does
01541    * not accelerate again before it can actually move. I.e. make sure it tries to advance again
01542    * on next tick to discover whether it is still blocked. */
01543   if (v->progress == 0) v->progress = blocked ? adv_spd - 1 : j;
01544 
01545   return true;
01546 }
01547 
01548 Money RoadVehicle::GetRunningCost() const
01549 {
01550   const Engine *e = this->GetEngine();
01551   if (e->u.road.running_cost_class == INVALID_PRICE) return 0;
01552 
01553   uint cost_factor = GetVehicleProperty(this, PROP_ROADVEH_RUNNING_COST_FACTOR, e->u.road.running_cost);
01554   if (cost_factor == 0) return 0;
01555 
01556   return GetPrice(e->u.road.running_cost_class, cost_factor, e->GetGRF());
01557 }
01558 
01559 bool RoadVehicle::Tick()
01560 {
01561   if (this->IsFrontEngine()) {
01562     if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++;
01563     return RoadVehController(this);
01564   }
01565 
01566   return true;
01567 }
01568 
01569 static void CheckIfRoadVehNeedsService(RoadVehicle *v)
01570 {
01571   /* If we already got a slot at a stop, use that FIRST, and go to a depot later */
01572   if (Company::Get(v->owner)->settings.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return;
01573   if (v->IsChainInDepot()) {
01574     VehicleServiceInDepot(v);
01575     return;
01576   }
01577 
01578   uint max_penalty;
01579   switch (_settings_game.pf.pathfinder_for_roadvehs) {
01580     case VPF_NPF:  max_penalty = _settings_game.pf.npf.maximum_go_to_depot_penalty;  break;
01581     case VPF_YAPF: max_penalty = _settings_game.pf.yapf.maximum_go_to_depot_penalty; break;
01582     default: NOT_REACHED();
01583   }
01584 
01585   FindDepotData rfdd = FindClosestRoadDepot(v, max_penalty);
01586   /* Only go to the depot if it is not too far out of our way. */
01587   if (rfdd.best_length == UINT_MAX || rfdd.best_length > max_penalty) {
01588     if (v->current_order.IsType(OT_GOTO_DEPOT)) {
01589       /* If we were already heading for a depot but it has
01590        * suddenly moved farther away, we continue our normal
01591        * schedule? */
01592       v->current_order.MakeDummy();
01593       SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
01594     }
01595     return;
01596   }
01597 
01598   DepotID depot = GetDepotIndex(rfdd.tile);
01599 
01600   if (v->current_order.IsType(OT_GOTO_DEPOT) &&
01601       v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS &&
01602       !Chance16(1, 20)) {
01603     return;
01604   }
01605 
01606   SetBit(v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
01607   v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
01608   v->dest_tile = rfdd.tile;
01609   SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
01610 }
01611 
01612 void RoadVehicle::OnNewDay()
01613 {
01614   AgeVehicle(this);
01615 
01616   if (!this->IsFrontEngine()) return;
01617 
01618   if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this);
01619   if (this->blocked_ctr == 0) CheckVehicleBreakdown(this);
01620 
01621   CheckIfRoadVehNeedsService(this);
01622 
01623   CheckOrders(this);
01624 
01625   if (this->running_ticks == 0) return;
01626 
01627   CommandCost cost(EXPENSES_ROADVEH_RUN, this->GetRunningCost() * this->running_ticks / (DAYS_IN_YEAR * DAY_TICKS));
01628 
01629   this->profit_this_year -= cost.GetCost();
01630   this->running_ticks = 0;
01631 
01632   SubtractMoneyFromCompanyFract(this->owner, cost);
01633 
01634   SetWindowDirty(WC_VEHICLE_DETAILS, this->index);
01635   SetWindowClassesDirty(WC_ROADVEH_LIST);
01636 }
01637 
01638 Trackdir RoadVehicle::GetVehicleTrackdir() const
01639 {
01640   if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
01641 
01642   if (this->IsInDepot()) {
01643     /* We'll assume the road vehicle is facing outwards */
01644     return DiagDirToDiagTrackdir(GetRoadDepotDirection(this->tile));
01645   }
01646 
01647   if (IsStandardRoadStopTile(this->tile)) {
01648     /* We'll assume the road vehicle is facing outwards */
01649     return DiagDirToDiagTrackdir(GetRoadStopDir(this->tile)); // Road vehicle in a station
01650   }
01651 
01652   /* Drive through road stops / wormholes (tunnels) */
01653   if (this->state > RVSB_TRACKDIR_MASK) return DiagDirToDiagTrackdir(DirToDiagDir(this->direction));
01654 
01655   /* If vehicle's state is a valid track direction (vehicle is not turning around) return it,
01656    * otherwise transform it into a valid track direction */
01657   return (Trackdir)((IsReversingRoadTrackdir((Trackdir)this->state)) ? (this->state - 6) : this->state);
01658 }