203 |
203 |
204 v = vl[0]; |
204 v = vl[0]; |
205 |
205 |
206 /* find the first free roadveh id */ |
206 /* find the first free roadveh id */ |
207 unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD); |
207 unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD); |
208 if (unit_num > _patches.max_roadveh) |
208 if (unit_num > _settings.vehicle.max_roadveh) |
209 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
209 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
210 |
210 |
211 if (flags & DC_EXEC) { |
211 if (flags & DC_EXEC) { |
212 int x; |
212 int x; |
213 int y; |
213 int y; |
255 v->max_age = e->lifelength * 366; |
255 v->max_age = e->lifelength * 366; |
256 _new_vehicle_id = v->index; |
256 _new_vehicle_id = v->index; |
257 |
257 |
258 v->name = NULL; |
258 v->name = NULL; |
259 |
259 |
260 v->service_interval = _patches.servint_roadveh; |
260 v->service_interval = _settings.vehicle.servint_roadveh; |
261 |
261 |
262 v->date_of_last_service = _date; |
262 v->date_of_last_service = _date; |
263 v->build_year = _cur_year; |
263 v->build_year = _cur_year; |
264 |
264 |
265 v->cur_image = 0xC15; |
265 v->cur_image = 0xC15; |
278 AddArticulatedParts(vl, VEH_ROAD); |
278 AddArticulatedParts(vl, VEH_ROAD); |
279 |
279 |
280 VehiclePositionChanged(v); |
280 VehiclePositionChanged(v); |
281 |
281 |
282 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
282 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
283 RebuildVehicleLists(); |
283 InvalidateWindowClassesData(WC_ROADVEH_LIST, 0); |
284 InvalidateWindow(WC_COMPANY, v->owner); |
284 InvalidateWindow(WC_COMPANY, v->owner); |
285 if (IsLocalPlayer()) |
285 if (IsLocalPlayer()) |
286 InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window |
286 InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the replace Road window |
287 |
287 |
288 GetPlayer(_current_player)->num_engines[p1]++; |
288 GetPlayer(_current_player)->num_engines[p1]++; |
379 CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value); |
379 CommandCost ret(EXPENSES_NEW_VEHICLES, -v->value); |
380 |
380 |
381 if (flags & DC_EXEC) { |
381 if (flags & DC_EXEC) { |
382 // Invalidate depot |
382 // Invalidate depot |
383 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
383 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
384 RebuildVehicleLists(); |
384 InvalidateWindowClassesData(WC_ROADVEH_LIST, 0); |
385 InvalidateWindow(WC_COMPANY, v->owner); |
385 InvalidateWindow(WC_COMPANY, v->owner); |
386 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
386 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
387 DeleteDepotHighlightOfVehicle(v); |
387 DeleteDepotHighlightOfVehicle(v); |
388 delete v; |
388 delete v; |
389 } |
389 } |
417 return false; |
417 return false; |
418 } |
418 } |
419 |
419 |
420 static const Depot* FindClosestRoadDepot(const Vehicle* v) |
420 static const Depot* FindClosestRoadDepot(const Vehicle* v) |
421 { |
421 { |
422 switch (_patches.pathfinder_for_roadvehs) { |
422 switch (_settings.pf.pathfinder_for_roadvehs) { |
423 case VPF_YAPF: /* YAPF */ |
423 case VPF_YAPF: /* YAPF */ |
424 return YapfFindNearestRoadDepot(v); |
424 return YapfFindNearestRoadDepot(v); |
425 |
425 |
426 case VPF_NPF: { /* NPF */ |
426 case VPF_NPF: { /* NPF */ |
427 /* See where we are now */ |
427 /* See where we are now */ |
572 for (; v->Next() != NULL; v = v->Next()) u = v; |
572 for (; v->Next() != NULL; v = v->Next()) u = v; |
573 u->SetNext(NULL); |
573 u->SetNext(NULL); |
574 |
574 |
575 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
575 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
576 |
576 |
577 RebuildVehicleLists(); |
577 InvalidateWindowClassesData(WC_ROADVEH_LIST, 0); |
578 InvalidateWindow(WC_COMPANY, v->owner); |
578 InvalidateWindow(WC_COMPANY, v->owner); |
579 |
579 |
580 if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v); |
580 if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v); |
581 |
581 |
582 MarkSingleVehicleDirty(v); |
582 MarkSingleVehicleDirty(v); |
700 |
700 |
701 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
701 InvalidateWindow(WC_VEHICLE_VIEW, v->index); |
702 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
702 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
703 |
703 |
704 if (!PlayVehicleSound(v, VSE_BREAKDOWN)) { |
704 if (!PlayVehicleSound(v, VSE_BREAKDOWN)) { |
705 SndPlayVehicleFx((_opt.landscape != LT_TOYLAND) ? |
705 SndPlayVehicleFx((_settings.game_creation.landscape != LT_TOYLAND) ? |
706 SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v); |
706 SND_0F_VEHICLE_BREAKDOWN : SND_35_COMEDY_BREAKDOWN, v); |
707 } |
707 } |
708 |
708 |
709 if (!(v->vehstatus & VS_HIDDEN)) { |
709 if (!(v->vehstatus & VS_HIDDEN)) { |
710 Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE); |
710 Vehicle *u = CreateEffectVehicleRel(v, 4, 4, 5, EV_BREAKDOWN_SMOKE); |
861 } |
861 } |
862 |
862 |
863 /* updates statusbar only if speed have changed to save CPU time */ |
863 /* updates statusbar only if speed have changed to save CPU time */ |
864 if (spd != v->cur_speed) { |
864 if (spd != v->cur_speed) { |
865 v->cur_speed = spd; |
865 v->cur_speed = spd; |
866 if (_patches.vehicle_speed) { |
866 if (_settings.gui.vehicle_speed) { |
867 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
867 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); |
868 } |
868 } |
869 } |
869 } |
870 |
870 |
871 /* Decrease somewhat when turning */ |
871 /* Decrease somewhat when turning */ |
1083 if (GetRoadStopType(tile) != rstype) { |
1083 if (GetRoadStopType(tile) != rstype) { |
1084 /* Wrong station type */ |
1084 /* Wrong station type */ |
1085 trackdirs = TRACKDIR_BIT_NONE; |
1085 trackdirs = TRACKDIR_BIT_NONE; |
1086 } else { |
1086 } else { |
1087 /* Proper station type, check if there is free loading bay */ |
1087 /* Proper station type, check if there is free loading bay */ |
1088 if (!_patches.roadveh_queue && IsStandardRoadStopTile(tile) && |
1088 if (!_settings.pf.roadveh_queue && IsStandardRoadStopTile(tile) && |
1089 !GetRoadStopByTile(tile, rstype)->HasFreeBay()) { |
1089 !GetRoadStopByTile(tile, rstype)->HasFreeBay()) { |
1090 /* Station is full and RV queuing is off */ |
1090 /* Station is full and RV queuing is off */ |
1091 trackdirs = TRACKDIR_BIT_NONE; |
1091 trackdirs = TRACKDIR_BIT_NONE; |
1092 } |
1092 } |
1093 } |
1093 } |
1122 /* Only one track to choose between? */ |
1122 /* Only one track to choose between? */ |
1123 if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) { |
1123 if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) { |
1124 return_track(FindFirstBit2x64(trackdirs)); |
1124 return_track(FindFirstBit2x64(trackdirs)); |
1125 } |
1125 } |
1126 |
1126 |
1127 switch (_patches.pathfinder_for_roadvehs) { |
1127 switch (_settings.pf.pathfinder_for_roadvehs) { |
1128 case VPF_YAPF: { /* YAPF */ |
1128 case VPF_YAPF: { /* YAPF */ |
1129 Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir); |
1129 Trackdir trackdir = YapfChooseRoadTrack(v, tile, enterdir); |
1130 if (trackdir != INVALID_TRACKDIR) return_track(trackdir); |
1130 if (trackdir != INVALID_TRACKDIR) return_track(trackdir); |
1131 return_track(PickRandomBit(trackdirs)); |
1131 return_track(PickRandomBit(trackdirs)); |
1132 } break; |
1132 } break; |
1271 |
1271 |
1272 DiagDirection dir = GetRoadDepotDirection(v->tile); |
1272 DiagDirection dir = GetRoadDepotDirection(v->tile); |
1273 v->direction = DiagDirToDir(dir); |
1273 v->direction = DiagDirToDir(dir); |
1274 |
1274 |
1275 Trackdir tdir = _roadveh_depot_exit_trackdir[dir]; |
1275 Trackdir tdir = _roadveh_depot_exit_trackdir[dir]; |
1276 const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + tdir]; |
1276 const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_settings.vehicle.road_side << RVS_DRIVE_SIDE) + tdir]; |
1277 |
1277 |
1278 int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF); |
1278 int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF); |
1279 int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF); |
1279 int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF); |
1280 |
1280 |
1281 if (first) { |
1281 if (first) { |
1449 /* Get move position data for next frame. |
1449 /* Get move position data for next frame. |
1450 * For a drive-through road stop use 'straight road' move data. |
1450 * For a drive-through road stop use 'straight road' move data. |
1451 * In this case v->u.road.state is masked to give the road stop entry direction. */ |
1451 * In this case v->u.road.state is masked to give the road stop entry direction. */ |
1452 rd = _road_drive_data[v->u.road.roadtype][( |
1452 rd = _road_drive_data[v->u.road.roadtype][( |
1453 (HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) + |
1453 (HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) + |
1454 (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1]; |
1454 (_settings.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1]; |
1455 |
1455 |
1456 if (rd.x & RDE_NEXT_TILE) { |
1456 if (rd.x & RDE_NEXT_TILE) { |
1457 TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); |
1457 TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); |
1458 Trackdir dir; |
1458 Trackdir dir; |
1459 uint32 r; |
1459 uint32 r; |
1527 tile = v->tile; |
1527 tile = v->tile; |
1528 } |
1528 } |
1529 } |
1529 } |
1530 |
1530 |
1531 /* Get position data for first frame on the new tile */ |
1531 /* Get position data for first frame on the new tile */ |
1532 rdp = _road_drive_data[v->u.road.roadtype][(dir + (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking]; |
1532 rdp = _road_drive_data[v->u.road.roadtype][(dir + (_settings.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking]; |
1533 |
1533 |
1534 x = TileX(tile) * TILE_SIZE + rdp[start_frame].x; |
1534 x = TileX(tile) * TILE_SIZE + rdp[start_frame].x; |
1535 y = TileY(tile) * TILE_SIZE + rdp[start_frame].y; |
1535 y = TileY(tile) * TILE_SIZE + rdp[start_frame].y; |
1536 |
1536 |
1537 newdir = RoadVehGetSlidingDirection(v, x, y); |
1537 newdir = RoadVehGetSlidingDirection(v, x, y); |
1630 if (dir == INVALID_TRACKDIR) { |
1630 if (dir == INVALID_TRACKDIR) { |
1631 v->cur_speed = 0; |
1631 v->cur_speed = 0; |
1632 return false; |
1632 return false; |
1633 } |
1633 } |
1634 |
1634 |
1635 rdp = _road_drive_data[v->u.road.roadtype][(_opt.road_side << RVS_DRIVE_SIDE) + dir]; |
1635 rdp = _road_drive_data[v->u.road.roadtype][(_settings.vehicle.road_side << RVS_DRIVE_SIDE) + dir]; |
1636 |
1636 |
1637 x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x; |
1637 x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x; |
1638 y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y; |
1638 y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y; |
1639 |
1639 |
1640 newdir = RoadVehGetSlidingDirection(v, x, y); |
1640 newdir = RoadVehGetSlidingDirection(v, x, y); |
1709 * if the vehicle is in a drive-through road stop and this is the destination station |
1709 * if the vehicle is in a drive-through road stop and this is the destination station |
1710 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame... |
1710 * and it's the correct type of stop (bus or truck) and the frame equals the stop frame... |
1711 * (the station test and stop type test ensure that other vehicles, using the road stop as |
1711 * (the station test and stop type test ensure that other vehicles, using the road stop as |
1712 * a through route, do not stop) */ |
1712 * a through route, do not stop) */ |
1713 if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && |
1713 if (IsRoadVehFront(v) && ((IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && |
1714 _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || |
1714 _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || |
1715 (IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && |
1715 (IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && |
1716 v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) && |
1716 v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) && |
1717 GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && |
1717 GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && |
1718 v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { |
1718 v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { |
1719 |
1719 |
1885 } |
1885 } |
1886 |
1886 |
1887 static void CheckIfRoadVehNeedsService(Vehicle *v) |
1887 static void CheckIfRoadVehNeedsService(Vehicle *v) |
1888 { |
1888 { |
1889 /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ |
1889 /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ |
1890 if (v->u.road.slot != NULL || _patches.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; |
1890 if (v->u.road.slot != NULL || _settings.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; |
1891 if (v->IsInDepot()) { |
1891 if (v->IsInDepot()) { |
1892 VehicleServiceInDepot(v); |
1892 VehicleServiceInDepot(v); |
1893 return; |
1893 return; |
1894 } |
1894 } |
1895 |
1895 |
2114 v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0); |
2114 v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0); |
2115 v->cargo_type = new_cid; |
2115 v->cargo_type = new_cid; |
2116 v->cargo_subtype = new_subtype; |
2116 v->cargo_subtype = new_subtype; |
2117 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
2117 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
2118 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
2118 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
2119 RebuildVehicleLists(); |
2119 InvalidateWindowClassesData(WC_ROADVEH_LIST, 0); |
2120 } |
2120 } |
2121 |
2121 |
2122 if (only_this) break; |
2122 if (only_this) break; |
2123 } |
2123 } |
2124 |
2124 |