28 #include "newgrf_engine.h" |
28 #include "newgrf_engine.h" |
29 #include "newgrf_text.h" |
29 #include "newgrf_text.h" |
30 #include "newgrf_sound.h" |
30 #include "newgrf_sound.h" |
31 #include "yapf/yapf.h" |
31 #include "yapf/yapf.h" |
32 #include "date.h" |
32 #include "date.h" |
|
33 #include "cargotype.h" |
33 |
34 |
34 static const uint16 _roadveh_images[63] = { |
35 static const uint16 _roadveh_images[63] = { |
35 0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14, |
36 0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14, |
36 0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74, |
37 0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74, |
37 0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C, |
38 0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C, |
126 int32 cost; |
127 int32 cost; |
127 Vehicle *v; |
128 Vehicle *v; |
128 UnitID unit_num; |
129 UnitID unit_num; |
129 Engine *e; |
130 Engine *e; |
130 |
131 |
131 if (!IsEngineBuildable(p1, VEH_Road, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE); |
132 if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ENGINE_NOT_BUILDABLE); |
132 |
133 |
133 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
134 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
134 |
135 |
135 cost = EstimateRoadVehCost(p1); |
136 cost = EstimateRoadVehCost(p1); |
136 if (flags & DC_QUERY_COST) return cost; |
137 if (flags & DC_QUERY_COST) return cost; |
142 |
143 |
143 v = AllocateVehicle(); |
144 v = AllocateVehicle(); |
144 if (v == NULL) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
145 if (v == NULL) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
145 |
146 |
146 /* find the first free roadveh id */ |
147 /* find the first free roadveh id */ |
147 unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_Road); |
148 unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD); |
148 if (unit_num > _patches.max_roadveh) |
149 if (unit_num > _patches.max_roadveh) |
149 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
150 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
150 |
151 |
151 if (flags & DC_EXEC) { |
152 if (flags & DC_EXEC) { |
152 int x; |
153 int x; |
198 v->service_interval = _patches.servint_roadveh; |
199 v->service_interval = _patches.servint_roadveh; |
199 |
200 |
200 v->date_of_last_service = _date; |
201 v->date_of_last_service = _date; |
201 v->build_year = _cur_year; |
202 v->build_year = _cur_year; |
202 |
203 |
203 v->type = VEH_Road; |
204 v->type = VEH_ROAD; |
204 v->cur_image = 0xC15; |
205 v->cur_image = 0xC15; |
205 v->random_bits = VehicleRandomBits(); |
206 v->random_bits = VehicleRandomBits(); |
206 |
207 |
207 v->vehicle_flags = 0; |
208 v->vehicle_flags = 0; |
208 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
209 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
211 |
212 |
212 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
213 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); |
213 RebuildVehicleLists(); |
214 RebuildVehicleLists(); |
214 InvalidateWindow(WC_COMPANY, v->owner); |
215 InvalidateWindow(WC_COMPANY, v->owner); |
215 if (IsLocalPlayer()) |
216 if (IsLocalPlayer()) |
216 InvalidateAutoreplaceWindow(VEH_Road); // updates the replace Road window |
217 InvalidateAutoreplaceWindow(VEH_ROAD); // updates the replace Road window |
217 |
218 |
218 GetPlayer(_current_player)->num_engines[p1]++; |
219 GetPlayer(_current_player)->num_engines[p1]++; |
219 } |
220 } |
220 |
221 |
221 return cost; |
222 return cost; |
233 |
234 |
234 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
235 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
235 |
236 |
236 v = GetVehicle(p1); |
237 v = GetVehicle(p1); |
237 |
238 |
238 if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR; |
239 if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; |
239 |
240 |
240 /* Check if this road veh can be started/stopped. The callback will fail or |
241 /* Check if this road veh can be started/stopped. The callback will fail or |
241 * return 0xFF if it can. */ |
242 * return 0xFF if it can. */ |
242 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v); |
243 callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v); |
243 if (callback != CALLBACK_FAILED && callback != 0xFF) { |
244 if (callback != CALLBACK_FAILED && callback != 0xFF) { |
283 |
284 |
284 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
285 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
285 |
286 |
286 v = GetVehicle(p1); |
287 v = GetVehicle(p1); |
287 |
288 |
288 if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR; |
289 if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; |
289 |
290 |
290 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
291 SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES); |
291 |
292 |
292 if (!IsRoadVehInDepotStopped(v)) { |
293 if (!IsRoadVehInDepotStopped(v)) { |
293 return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE); |
294 return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE); |
304 } |
305 } |
305 |
306 |
306 return -(int32)v->value; |
307 return -(int32)v->value; |
307 } |
308 } |
308 |
309 |
309 typedef struct RoadFindDepotData { |
310 struct RoadFindDepotData { |
310 uint best_length; |
311 uint best_length; |
311 TileIndex tile; |
312 TileIndex tile; |
312 OwnerByte owner; |
313 OwnerByte owner; |
313 } RoadFindDepotData; |
314 }; |
314 |
315 |
315 static const DiagDirection _road_pf_directions[] = { |
316 static const DiagDirection _road_pf_directions[] = { |
316 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR, |
317 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR, |
317 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, INVALID_DIAGDIR, INVALID_DIAGDIR |
318 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, INVALID_DIAGDIR, INVALID_DIAGDIR |
318 }; |
319 }; |
382 const Depot *dep; |
383 const Depot *dep; |
383 |
384 |
384 if (p2 & DEPOT_MASS_SEND) { |
385 if (p2 & DEPOT_MASS_SEND) { |
385 /* Mass goto depot requested */ |
386 /* Mass goto depot requested */ |
386 if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR; |
387 if (!ValidVLWFlags(p2 & VLW_MASK)) return CMD_ERROR; |
387 return SendAllVehiclesToDepot(VEH_Road, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1); |
388 return SendAllVehiclesToDepot(VEH_ROAD, flags, p2 & DEPOT_SERVICE, _current_player, (p2 & VLW_MASK), p1); |
388 } |
389 } |
389 |
390 |
390 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
391 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
391 |
392 |
392 v = GetVehicle(p1); |
393 v = GetVehicle(p1); |
393 |
394 |
394 if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR; |
395 if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; |
395 |
396 |
396 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
397 if (v->vehstatus & VS_CRASHED) return CMD_ERROR; |
397 |
398 |
398 if (IsRoadVehInDepot(v)) return CMD_ERROR; |
399 if (IsRoadVehInDepot(v)) return CMD_ERROR; |
399 |
400 |
452 |
453 |
453 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
454 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
454 |
455 |
455 v = GetVehicle(p1); |
456 v = GetVehicle(p1); |
456 |
457 |
457 if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR; |
458 if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; |
458 |
459 |
459 if (v->vehstatus & VS_STOPPED || |
460 if (v->vehstatus & VS_STOPPED || |
460 v->u.road.crashed_ctr != 0 || |
461 v->u.road.crashed_ctr != 0 || |
461 v->breakdown_ctr != 0 || |
462 v->breakdown_ctr != 0 || |
462 v->u.road.overtaking != 0 || |
463 v->u.road.overtaking != 0 || |
575 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data) |
576 static void* EnumCheckRoadVehCrashTrain(Vehicle* v, void* data) |
576 { |
577 { |
577 const Vehicle* u = (Vehicle*)data; |
578 const Vehicle* u = (Vehicle*)data; |
578 |
579 |
579 return |
580 return |
580 v->type == VEH_Train && |
581 v->type == VEH_TRAIN && |
581 myabs(v->z_pos - u->z_pos) <= 6 && |
582 myabs(v->z_pos - u->z_pos) <= 6 && |
582 myabs(v->x_pos - u->x_pos) <= 4 && |
583 myabs(v->x_pos - u->x_pos) <= 4 && |
583 myabs(v->y_pos - u->y_pos) <= 4 ? |
584 myabs(v->y_pos - u->y_pos) <= 4 ? |
584 v : NULL; |
585 v : NULL; |
585 } |
586 } |
704 if (order->dest == v->last_station_visited) { |
704 if (order->dest == v->last_station_visited) { |
705 v->last_station_visited = INVALID_STATION; |
705 v->last_station_visited = INVALID_STATION; |
706 } |
706 } |
707 |
707 |
708 rs = GetStation(order->dest)->GetPrimaryRoadStop( |
708 rs = GetStation(order->dest)->GetPrimaryRoadStop( |
709 v->cargo_type == CT_PASSENGERS ? RoadStop::BUS : RoadStop::TRUCK |
709 IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK |
710 ); |
710 ); |
711 |
711 |
712 if (rs != NULL) { |
712 if (rs != NULL) { |
713 TileIndex dest = rs->xy; |
713 TileIndex dest = rs->xy; |
714 uint mindist = DistanceManhattan(v->tile, rs->xy); |
714 uint mindist = DistanceManhattan(v->tile, rs->xy); |
783 s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN; |
783 s = SND_1A_BUS_START_PULL_AWAY_WITH_HORN; |
784 SndPlayVehicleFx(s, v); |
784 SndPlayVehicleFx(s, v); |
785 } |
785 } |
786 } |
786 } |
787 |
787 |
788 typedef struct RoadVehFindData { |
788 struct RoadVehFindData { |
789 int x; |
789 int x; |
790 int y; |
790 int y; |
791 const Vehicle* veh; |
791 const Vehicle* veh; |
792 Direction dir; |
792 Direction dir; |
793 } RoadVehFindData; |
793 }; |
794 |
794 |
795 static void* EnumCheckRoadVehClose(Vehicle *v, void* data) |
795 static void* EnumCheckRoadVehClose(Vehicle *v, void* data) |
796 { |
796 { |
797 static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 }; |
797 static const int8 dist_x[] = { -4, -8, -4, -1, 4, 8, 4, 1 }; |
798 static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 }; |
798 static const int8 dist_y[] = { -4, -1, 4, 8, 4, 1, -4, -8 }; |
802 short x_diff = v->x_pos - rvf->x; |
802 short x_diff = v->x_pos - rvf->x; |
803 short y_diff = v->y_pos - rvf->y; |
803 short y_diff = v->y_pos - rvf->y; |
804 |
804 |
805 return |
805 return |
806 rvf->veh != v && |
806 rvf->veh != v && |
807 v->type == VEH_Road && |
807 v->type == VEH_ROAD && |
808 !IsRoadVehInDepot(v) && |
808 !IsRoadVehInDepot(v) && |
809 myabs(v->z_pos - rvf->veh->z_pos) < 6 && |
809 myabs(v->z_pos - rvf->veh->z_pos) < 6 && |
810 v->direction == rvf->dir && |
810 v->direction == rvf->dir && |
811 (dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) && |
811 (dist_x[v->direction] >= 0 || (x_diff > dist_x[v->direction] && x_diff <= 0)) && |
812 (dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) && |
812 (dist_x[v->direction] <= 0 || (x_diff < dist_x[v->direction] && x_diff >= 0)) && |
842 return u; |
842 return u; |
843 } |
843 } |
844 |
844 |
845 static void RoadVehArrivesAt(const Vehicle* v, Station* st) |
845 static void RoadVehArrivesAt(const Vehicle* v, Station* st) |
846 { |
846 { |
847 if (v->cargo_type == CT_PASSENGERS) { |
847 if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) { |
848 /* Check if station was ever visited before */ |
848 /* Check if station was ever visited before */ |
849 if (!(st->had_vehicle_of_type & HVOT_BUS)) { |
849 if (!(st->had_vehicle_of_type & HVOT_BUS)) { |
850 uint32 flags; |
850 uint32 flags; |
851 |
851 |
852 st->had_vehicle_of_type |= HVOT_BUS; |
852 st->had_vehicle_of_type |= HVOT_BUS; |
931 if (new_dir == old_dir) return old_dir; |
931 if (new_dir == old_dir) return old_dir; |
932 delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT); |
932 delta = (DirDifference(new_dir, old_dir) > DIRDIFF_REVERSE ? DIRDIFF_45LEFT : DIRDIFF_45RIGHT); |
933 return ChangeDir(old_dir, delta); |
933 return ChangeDir(old_dir, delta); |
934 } |
934 } |
935 |
935 |
936 typedef struct OvertakeData { |
936 struct OvertakeData { |
937 const Vehicle* u; |
937 const Vehicle* u; |
938 const Vehicle* v; |
938 const Vehicle* v; |
939 TileIndex tile; |
939 TileIndex tile; |
940 byte tilebits; |
940 byte tilebits; |
941 } OvertakeData; |
941 }; |
942 |
942 |
943 static void* EnumFindVehToOvertake(Vehicle* v, void* data) |
943 static void* EnumFindVehToOvertake(Vehicle* v, void* data) |
944 { |
944 { |
945 const OvertakeData* od = (OvertakeData*)data; |
945 const OvertakeData* od = (OvertakeData*)data; |
946 |
946 |
947 return |
947 return |
948 v->tile == od->tile && v->type == VEH_Road && v != od->u && v != od->v ? |
948 v->tile == od->tile && v->type == VEH_ROAD && v != od->u && v != od->v ? |
949 v : NULL; |
949 v : NULL; |
950 } |
950 } |
951 |
951 |
952 static bool FindRoadVehToOvertake(OvertakeData *od) |
952 static bool FindRoadVehToOvertake(OvertakeData *od) |
953 { |
953 { |
1028 |
1028 |
1029 for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {} |
1029 for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {} |
1030 return i; |
1030 return i; |
1031 } |
1031 } |
1032 |
1032 |
1033 typedef struct { |
1033 struct FindRoadToChooseData { |
1034 TileIndex dest; |
1034 TileIndex dest; |
1035 uint maxtracklen; |
1035 uint maxtracklen; |
1036 uint mindist; |
1036 uint mindist; |
1037 } FindRoadToChooseData; |
1037 }; |
1038 |
1038 |
1039 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
1039 static bool EnumRoadTrackFindDist(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
1040 { |
1040 { |
1041 FindRoadToChooseData* frd = (FindRoadToChooseData*)data; |
1041 FindRoadToChooseData* frd = (FindRoadToChooseData*)data; |
1042 uint dist = DistanceManhattan(tile, frd->dest); |
1042 uint dist = DistanceManhattan(tile, frd->dest); |
1090 if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) { |
1090 if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) { |
1091 /* different station owner or wrong orientation */ |
1091 /* different station owner or wrong orientation */ |
1092 trackdirs = TRACKDIR_BIT_NONE; |
1092 trackdirs = TRACKDIR_BIT_NONE; |
1093 } else { |
1093 } else { |
1094 /* Our station */ |
1094 /* Our station */ |
1095 RoadStop::Type rstype = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; |
1095 RoadStop::Type rstype = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; |
1096 |
1096 |
1097 if (GetRoadStopType(tile) != rstype) { |
1097 if (GetRoadStopType(tile) != rstype) { |
1098 /* Wrong station type */ |
1098 /* Wrong station type */ |
1099 trackdirs = TRACKDIR_BIT_NONE; |
1099 trackdirs = TRACKDIR_BIT_NONE; |
1100 } else { |
1100 } else { |
1254 RVC_DEPOT_START_FRAME = 6, |
1254 RVC_DEPOT_START_FRAME = 6, |
1255 /* Stop frame for a vehicle in a drive-through stop */ |
1255 /* Stop frame for a vehicle in a drive-through stop */ |
1256 RVC_DRIVE_THROUGH_STOP_FRAME = 7 |
1256 RVC_DRIVE_THROUGH_STOP_FRAME = 7 |
1257 }; |
1257 }; |
1258 |
1258 |
1259 typedef struct RoadDriveEntry { |
1259 struct RoadDriveEntry { |
1260 byte x,y; |
1260 byte x, y; |
1261 } RoadDriveEntry; |
1261 }; |
1262 |
1262 |
1263 #include "table/roadveh.h" |
1263 #include "table/roadveh.h" |
1264 |
1264 |
1265 static const byte _road_veh_data_1[] = { |
1265 static const byte _road_veh_data_1[] = { |
1266 20, 20, 16, 16, 0, 0, 0, 0, |
1266 20, 20, 16, 16, 0, 0, 0, 0, |
1545 * a through route, do not stop) */ |
1545 * a through route, do not stop) */ |
1546 if ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && |
1546 if ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && |
1547 _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || |
1547 _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || |
1548 (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && |
1548 (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && |
1549 v->current_order.dest == GetStationIndex(v->tile) && |
1549 v->current_order.dest == GetStationIndex(v->tile) && |
1550 GetRoadStopType(v->tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) && |
1550 GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) && |
1551 v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME)) { |
1551 v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME)) { |
1552 |
1552 |
1553 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
1553 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
1554 Station* st = GetStationByTile(v->tile); |
1554 Station* st = GetStationByTile(v->tile); |
1555 |
1555 |
1561 /* Vehicle has arrived at a bay in a road stop */ |
1561 /* Vehicle has arrived at a bay in a road stop */ |
1562 Order old_order; |
1562 Order old_order; |
1563 |
1563 |
1564 if (IsDriveThroughStopTile(v->tile)) { |
1564 if (IsDriveThroughStopTile(v->tile)) { |
1565 TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); |
1565 TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction)); |
1566 RoadStop::Type type = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; |
1566 RoadStop::Type type = IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK; |
1567 |
1567 |
1568 assert(HASBIT(v->u.road.state, RVS_IS_STOPPING)); |
1568 assert(HASBIT(v->u.road.state, RVS_IS_STOPPING)); |
1569 |
1569 |
1570 /* Check if next inline bay is free */ |
1570 /* Check if next inline bay is free */ |
1571 if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { |
1571 if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { |
1616 if (rs->IsEntranceBusy()) { |
1616 if (rs->IsEntranceBusy()) { |
1617 /* Road stop entrance is busy, so wait as there is nowhere else to go */ |
1617 /* Road stop entrance is busy, so wait as there is nowhere else to go */ |
1618 v->cur_speed = 0; |
1618 v->cur_speed = 0; |
1619 return; |
1619 return; |
1620 } |
1620 } |
1621 v->current_order.type = OT_NOTHING; |
1621 v->current_order.Free(); |
1622 v->current_order.flags = 0; |
|
1623 ClearSlot(v); |
1622 ClearSlot(v); |
1624 } |
1623 } |
1625 |
1624 |
1626 if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true); |
1625 if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true); |
1627 |
1626 |
1754 if (v->vehstatus & VS_STOPPED) return; |
1753 if (v->vehstatus & VS_STOPPED) return; |
1755 |
1754 |
1756 /* update destination */ |
1755 /* update destination */ |
1757 if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) { |
1756 if (v->current_order.type == OT_GOTO_STATION && v->u.road.slot == NULL && !(v->vehstatus & VS_CRASHED)) { |
1758 Station* st = GetStation(v->current_order.dest); |
1757 Station* st = GetStation(v->current_order.dest); |
1759 RoadStop* rs = st->GetPrimaryRoadStop(v->cargo_type == CT_PASSENGERS ? RoadStop::BUS : RoadStop::TRUCK); |
1758 RoadStop* rs = st->GetPrimaryRoadStop(IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK); |
1760 RoadStop* best = NULL; |
1759 RoadStop* best = NULL; |
1761 |
1760 |
1762 if (rs != NULL) { |
1761 if (rs != NULL) { |
1763 /* We try to obtain a slot if: |
1762 /* We try to obtain a slot if: |
1764 * 1) we're reasonably close to the primary road stop |
1763 * 1) we're reasonably close to the primary road stop |
1822 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1821 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1823 InvalidateWindowClasses(WC_ROADVEH_LIST); |
1822 InvalidateWindowClasses(WC_ROADVEH_LIST); |
1824 } |
1823 } |
1825 |
1824 |
1826 |
1825 |
1827 void RoadVehiclesYearlyLoop(void) |
1826 void RoadVehiclesYearlyLoop() |
1828 { |
1827 { |
1829 Vehicle *v; |
1828 Vehicle *v; |
1830 |
1829 |
1831 FOR_ALL_VEHICLES(v) { |
1830 FOR_ALL_VEHICLES(v) { |
1832 if (v->type == VEH_Road) { |
1831 if (v->type == VEH_ROAD) { |
1833 v->profit_last_year = v->profit_this_year; |
1832 v->profit_last_year = v->profit_this_year; |
1834 v->profit_this_year = 0; |
1833 v->profit_this_year = 0; |
1835 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1834 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1836 } |
1835 } |
1837 } |
1836 } |
1854 |
1853 |
1855 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
1854 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
1856 |
1855 |
1857 v = GetVehicle(p1); |
1856 v = GetVehicle(p1); |
1858 |
1857 |
1859 if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR; |
1858 if (v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; |
1860 if (!IsRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE); |
1859 if (!IsRoadVehInDepotStopped(v)) return_cmd_error(STR_9013_MUST_BE_STOPPED_INSIDE); |
1861 |
1860 |
1862 if (new_cid > NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR; |
1861 if (new_cid >= NUM_CARGO || !CanRefitTo(v->engine_type, new_cid)) return CMD_ERROR; |
1863 |
1862 |
1864 SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN); |
1863 SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN); |
1865 |
1864 |
1866 if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) { |
1865 if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_REFIT_CAPACITY)) { |
1867 /* Back up the cargo type */ |
1866 /* Back up the cargo type */ |