branch | noai |
changeset 9629 | 66dde6412125 |
parent 9628 | b5c2449616b5 |
child 9631 | 8a2d1c2ceb88 |
9628:b5c2449616b5 | 9629:66dde6412125 |
---|---|
12 #include "station_map.h" |
12 #include "station_map.h" |
13 #include "table/strings.h" |
13 #include "table/strings.h" |
14 #include "map.h" |
14 #include "map.h" |
15 #include "tile.h" |
15 #include "tile.h" |
16 #include "vehicle.h" |
16 #include "vehicle.h" |
17 #include "timetable.h" |
|
17 #include "engine.h" |
18 #include "engine.h" |
18 #include "command.h" |
19 #include "command.h" |
19 #include "station.h" |
20 #include "station.h" |
20 #include "news.h" |
21 #include "news.h" |
21 #include "pathfind.h" |
22 #include "pathfind.h" |
94 if (image != 0) return image; |
95 if (image != 0) return image; |
95 img = orig_road_vehicle_info[v->engine_type - ROAD_ENGINES_INDEX].image_index; |
96 img = orig_road_vehicle_info[v->engine_type - ROAD_ENGINES_INDEX].image_index; |
96 } |
97 } |
97 |
98 |
98 image = direction + _roadveh_images[img]; |
99 image = direction + _roadveh_images[img]; |
99 if (v->cargo_count >= v->cargo_cap / 2) image += _roadveh_full_adder[img]; |
100 if (v->cargo.Count() >= v->cargo_cap / 2U) image += _roadveh_full_adder[img]; |
100 return image; |
101 return image; |
101 } |
102 } |
102 |
103 |
103 void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal) |
104 void DrawRoadVehEngine(int x, int y, EngineID engine, SpriteID pal) |
104 { |
105 { |
114 spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index; |
115 spritenum = orig_road_vehicle_info[engine - ROAD_ENGINES_INDEX].image_index; |
115 } |
116 } |
116 DrawSprite(6 + _roadveh_images[spritenum], pal, x, y); |
117 DrawSprite(6 + _roadveh_images[spritenum], pal, x, y); |
117 } |
118 } |
118 |
119 |
119 static int32 EstimateRoadVehCost(EngineID engine_type) |
120 static CommandCost EstimateRoadVehCost(EngineID engine_type) |
120 { |
121 { |
121 return ((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5; |
122 return CommandCost(((_price.roadveh_base >> 3) * GetEngineProperty(engine_type, 0x11, RoadVehInfo(engine_type)->base_cost)) >> 5); |
122 } |
123 } |
123 |
124 |
124 byte GetRoadVehLength(const Vehicle *v) |
125 byte GetRoadVehLength(const Vehicle *v) |
125 { |
126 { |
126 byte length = 8; |
127 byte length = 8; |
154 * @param tile tile of depot where road vehicle is built |
155 * @param tile tile of depot where road vehicle is built |
155 * @param flags operation to perform |
156 * @param flags operation to perform |
156 * @param p1 bus/truck type being built (engine) |
157 * @param p1 bus/truck type being built (engine) |
157 * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number |
158 * @param p2 bit 0 when set, the unitnumber will be 0, otherwise it will be a free number |
158 */ |
159 */ |
159 int32 CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
160 CommandCost CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
160 { |
161 { |
161 int32 cost; |
162 CommandCost cost; |
162 Vehicle *v; |
163 Vehicle *v; |
163 UnitID unit_num; |
164 UnitID unit_num; |
164 Engine *e; |
165 Engine *e; |
165 |
166 |
166 if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE); |
167 if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE); |
217 v->spritenum = rvi->image_index; |
218 v->spritenum = rvi->image_index; |
218 v->cargo_type = rvi->cargo_type; |
219 v->cargo_type = rvi->cargo_type; |
219 v->cargo_subtype = 0; |
220 v->cargo_subtype = 0; |
220 v->cargo_cap = rvi->capacity; |
221 v->cargo_cap = rvi->capacity; |
221 // v->cargo_count = 0; |
222 // v->cargo_count = 0; |
222 v->value = cost; |
223 v->value = cost.GetCost(); |
223 // v->day_counter = 0; |
224 // v->day_counter = 0; |
224 // v->next_order_param = v->next_order = 0; |
225 // v->next_order_param = v->next_order = 0; |
225 // v->load_unload_time_rem = 0; |
226 // v->load_unload_time_rem = 0; |
226 // v->progress = 0; |
227 // v->progress = 0; |
227 |
228 |
271 InvalidateAutoreplaceWindow(VEH_ROAD); // updates the replace Road window |
272 InvalidateAutoreplaceWindow(VEH_ROAD); // updates the replace Road window |
272 |
273 |
273 GetPlayer(_current_player)->num_engines[p1]++; |
274 GetPlayer(_current_player)->num_engines[p1]++; |
274 } |
275 } |
275 |
276 |
276 return cost; |
277 return CommandCost(cost); |
277 } |
278 } |
278 |
279 |
279 /** Start/Stop a road vehicle. |
280 /** Start/Stop a road vehicle. |
280 * @param tile unused |
281 * @param tile unused |
281 * @param flags operation to perform |
282 * @param flags operation to perform |
282 * @param p1 road vehicle ID to start/stop |
283 * @param p1 road vehicle ID to start/stop |
283 * @param p2 unused |
284 * @param p2 unused |
284 */ |
285 */ |
285 int32 CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
286 CommandCost CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
286 { |
287 { |
287 Vehicle *v; |
288 Vehicle *v; |
288 uint16 callback; |
289 uint16 callback; |
289 |
290 |
290 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
291 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
310 v->cur_speed = 0; |
311 v->cur_speed = 0; |
311 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
312 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
312 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
313 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
313 } |
314 } |
314 |
315 |
315 return 0; |
316 return CommandCost(); |
316 } |
317 } |
317 |
318 |
318 void ClearSlot(Vehicle *v) |
319 void ClearSlot(Vehicle *v) |
319 { |
320 { |
320 RoadStop *rs = v->u.road.slot; |
321 RoadStop *rs = v->u.road.slot; |
345 * @param tile unused |
346 * @param tile unused |
346 * @param flags operation to perform |
347 * @param flags operation to perform |
347 * @param p1 vehicle ID to be sold |
348 * @param p1 vehicle ID to be sold |
348 * @param p2 unused |
349 * @param p2 unused |
349 */ |
350 */ |
350 int32 CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
351 CommandCost CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
351 { |
352 { |
352 Vehicle *v; |
353 Vehicle *v; |
353 |
354 |
354 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
355 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
355 |
356 |
371 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
372 DeleteWindowById(WC_VEHICLE_VIEW, v->index); |
372 DeleteDepotHighlightOfVehicle(v); |
373 DeleteDepotHighlightOfVehicle(v); |
373 DeleteVehicle(v); |
374 DeleteVehicle(v); |
374 } |
375 } |
375 |
376 |
376 return -(int32)v->value; |
377 return CommandCost(-v->value); |
377 } |
378 } |
378 |
379 |
379 struct RoadFindDepotData { |
380 struct RoadFindDepotData { |
380 uint best_length; |
381 uint best_length; |
381 TileIndex tile; |
382 TileIndex tile; |
413 } else if (_patches.new_pathfinding_all) { |
414 } else if (_patches.new_pathfinding_all) { |
414 NPFFoundTargetData ftd; |
415 NPFFoundTargetData ftd; |
415 /* See where we are now */ |
416 /* See where we are now */ |
416 Trackdir trackdir = GetVehicleTrackdir(v); |
417 Trackdir trackdir = GetVehicleTrackdir(v); |
417 |
418 |
418 ftd = NPFRouteToDepotBreadthFirst(v->tile, trackdir, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE); |
419 ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, v->tile, ReverseTrackdir(trackdir), TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPE, 0); |
419 if (ftd.best_bird_dist == 0) { |
420 if (ftd.best_bird_dist == 0) { |
420 return GetDepotByTile(ftd.node.tile); /* Target found */ |
421 return GetDepotByTile(ftd.node.tile); /* Target found */ |
421 } else { |
422 } else { |
422 return NULL; /* Target not found */ |
423 return NULL; /* Target not found */ |
423 } |
424 } |
445 * @param p1 vehicle ID to send to the depot |
446 * @param p1 vehicle ID to send to the depot |
446 * @param p2 various bitmasked elements |
447 * @param p2 various bitmasked elements |
447 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h) |
448 * - p2 bit 0-3 - DEPOT_ flags (see vehicle.h) |
448 * - p2 bit 8-10 - VLW flag (for mass goto depot) |
449 * - p2 bit 8-10 - VLW flag (for mass goto depot) |
449 */ |
450 */ |
450 int32 CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
451 CommandCost CmdSendRoadVehToDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
451 { |
452 { |
452 Vehicle *v; |
453 Vehicle *v; |
453 const Depot *dep; |
454 const Depot *dep; |
454 |
455 |
455 if (p2 & DEPOT_MASS_SEND) { |
456 if (p2 & DEPOT_MASS_SEND) { |
476 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
477 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
477 if (flags & DC_EXEC) { |
478 if (flags & DC_EXEC) { |
478 TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
479 TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT); |
479 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
480 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
480 } |
481 } |
481 return 0; |
482 return CommandCost(); |
482 } |
483 } |
483 |
484 |
484 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
485 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
485 if (flags & DC_EXEC) { |
486 if (flags & DC_EXEC) { |
486 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
487 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
490 |
491 |
491 v->current_order.type = OT_DUMMY; |
492 v->current_order.type = OT_DUMMY; |
492 v->current_order.flags = 0; |
493 v->current_order.flags = 0; |
493 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
494 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
494 } |
495 } |
495 return 0; |
496 return CommandCost(); |
496 } |
497 } |
497 |
498 |
498 dep = FindClosestRoadDepot(v); |
499 dep = FindClosestRoadDepot(v); |
499 if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT); |
500 if (dep == NULL) return_cmd_error(STR_9019_UNABLE_TO_FIND_LOCAL_DEPOT); |
500 |
501 |
509 v->current_order.dest = dep->index; |
510 v->current_order.dest = dep->index; |
510 v->dest_tile = dep->xy; |
511 v->dest_tile = dep->xy; |
511 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
512 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
512 } |
513 } |
513 |
514 |
514 return 0; |
515 return CommandCost(); |
515 } |
516 } |
516 |
517 |
517 /** Turn a roadvehicle around. |
518 /** Turn a roadvehicle around. |
518 * @param tile unused |
519 * @param tile unused |
519 * @param flags operation to perform |
520 * @param flags operation to perform |
520 * @param p1 vehicle ID to turn |
521 * @param p1 vehicle ID to turn |
521 * @param p2 unused |
522 * @param p2 unused |
522 */ |
523 */ |
523 int32 CmdTurnRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
524 CommandCost CmdTurnRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
524 { |
525 { |
525 Vehicle *v; |
526 Vehicle *v; |
526 |
527 |
527 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
528 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
528 |
529 |
546 if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR; |
547 if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR; |
547 if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR; |
548 if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR; |
548 |
549 |
549 if (flags & DC_EXEC) v->u.road.reverse_ctr = 180; |
550 if (flags & DC_EXEC) v->u.road.reverse_ctr = 180; |
550 |
551 |
551 return 0; |
552 return CommandCost(); |
552 } |
553 } |
553 |
554 |
554 |
555 |
555 void RoadVehicle::MarkDirty() |
556 void RoadVehicle::MarkDirty() |
556 { |
557 { |
674 uint16 pass = 1; |
675 uint16 pass = 1; |
675 |
676 |
676 v->u.road.crashed_ctr++; |
677 v->u.road.crashed_ctr++; |
677 |
678 |
678 for (Vehicle *u = v; u != NULL; u = u->next) { |
679 for (Vehicle *u = v; u != NULL; u = u->next) { |
679 if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo_count; |
680 if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count(); |
680 |
681 |
681 u->vehstatus |= VS_CRASHED; |
682 u->vehstatus |= VS_CRASHED; |
682 |
683 |
683 MarkAllViewportsDirty(u->left_coord, u->top_coord, u->right_coord + 1, u->bottom_coord + 1); |
684 MarkAllViewportsDirty(u->left_coord, u->top_coord, u->right_coord + 1, u->bottom_coord + 1); |
684 } |
685 } |
755 case OT_GOTO_DEPOT: |
756 case OT_GOTO_DEPOT: |
756 /* Let a depot order in the orderlist interrupt. */ |
757 /* Let a depot order in the orderlist interrupt. */ |
757 if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return; |
758 if (!(v->current_order.flags & OF_PART_OF_ORDERS)) return; |
758 if (v->current_order.flags & OF_SERVICE_IF_NEEDED && |
759 if (v->current_order.flags & OF_SERVICE_IF_NEEDED && |
759 !VehicleNeedsService(v)) { |
760 !VehicleNeedsService(v)) { |
761 UpdateVehicleTimetable(v, true); |
|
760 v->cur_order_index++; |
762 v->cur_order_index++; |
761 } |
763 } |
762 break; |
764 break; |
763 |
765 |
764 case OT_LOADING: |
766 case OT_LOADING: |
1782 |
1784 |
1783 static void RoadVehController(Vehicle *v) |
1785 static void RoadVehController(Vehicle *v) |
1784 { |
1786 { |
1785 /* decrease counters */ |
1787 /* decrease counters */ |
1786 v->tick_counter++; |
1788 v->tick_counter++; |
1789 v->current_order_time++; |
|
1787 if (v->u.road.reverse_ctr != 0) v->u.road.reverse_ctr--; |
1790 if (v->u.road.reverse_ctr != 0) v->u.road.reverse_ctr--; |
1788 |
1791 |
1789 /* handle crashed */ |
1792 /* handle crashed */ |
1790 if (v->u.road.crashed_ctr != 0) { |
1793 if (v->u.road.crashed_ctr != 0) { |
1791 RoadVehIsCrashed(v); |
1794 RoadVehIsCrashed(v); |
1821 } |
1824 } |
1822 |
1825 |
1823 static void AgeRoadVehCargo(Vehicle *v) |
1826 static void AgeRoadVehCargo(Vehicle *v) |
1824 { |
1827 { |
1825 if (_age_cargo_skip_counter != 0) return; |
1828 if (_age_cargo_skip_counter != 0) return; |
1826 if (v->cargo_days != 255) v->cargo_days++; |
1829 v->cargo.AgeCargo(); |
1827 } |
1830 } |
1828 |
1831 |
1829 void RoadVeh_Tick(Vehicle *v) |
1832 void RoadVeh_Tick(Vehicle *v) |
1830 { |
1833 { |
1831 AgeRoadVehCargo(v); |
1834 AgeRoadVehCargo(v); |
1884 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1887 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
1885 } |
1888 } |
1886 |
1889 |
1887 void OnNewDay_RoadVeh(Vehicle *v) |
1890 void OnNewDay_RoadVeh(Vehicle *v) |
1888 { |
1891 { |
1889 int32 cost; |
1892 CommandCost cost; |
1890 |
1893 |
1891 if (!IsRoadVehFront(v)) return; |
1894 if (!IsRoadVehFront(v)) return; |
1892 |
1895 |
1893 if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v); |
1896 if ((++v->day_counter & 7) == 0) DecreaseVehicleValue(v); |
1894 if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v); |
1897 if (v->u.road.blocked_ctr == 0) CheckVehicleBreakdown(v); |
1966 } |
1969 } |
1967 } |
1970 } |
1968 |
1971 |
1969 cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364; |
1972 cost = RoadVehInfo(v->engine_type)->running_cost * _price.roadveh_running / 364; |
1970 |
1973 |
1971 v->profit_this_year -= cost >> 8; |
1974 v->profit_this_year -= cost.GetCost() >> 8; |
1972 |
1975 |
1973 SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN); |
1976 SET_EXPENSES_TYPE(EXPENSES_ROADVEH_RUN); |
1974 SubtractMoneyFromPlayerFract(v->owner, cost); |
1977 SubtractMoneyFromPlayerFract(v->owner, CommandCost(cost)); |
1975 |
1978 |
1976 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1979 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
1977 InvalidateWindowClasses(WC_ROADVEH_LIST); |
1980 InvalidateWindowClasses(WC_ROADVEH_LIST); |
1978 } |
1981 } |
1979 |
1982 |
1999 * - p2 = (bit 0-7) - the new cargo type to refit to |
2002 * - p2 = (bit 0-7) - the new cargo type to refit to |
2000 * - p2 = (bit 8-15) - the new cargo subtype to refit to |
2003 * - p2 = (bit 8-15) - the new cargo subtype to refit to |
2001 * - p2 = (bit 16) - refit only this vehicle (ignored) |
2004 * - p2 = (bit 16) - refit only this vehicle (ignored) |
2002 * @return cost of refit or error |
2005 * @return cost of refit or error |
2003 */ |
2006 */ |
2004 int32 CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
2007 CommandCost CmdRefitRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
2005 { |
2008 { |
2006 Vehicle *v; |
2009 Vehicle *v; |
2007 int32 cost; |
2010 CommandCost cost; |
2008 CargoID new_cid = GB(p2, 0, 8); |
2011 CargoID new_cid = GB(p2, 0, 8); |
2009 byte new_subtype = GB(p2, 8, 8); |
2012 byte new_subtype = GB(p2, 8, 8); |
2010 uint16 capacity = CALLBACK_FAILED; |
2013 uint16 capacity = CALLBACK_FAILED; |
2011 |
2014 |
2012 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
2015 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
2058 default: capacity /= 4; break; |
2061 default: capacity /= 4; break; |
2059 } |
2062 } |
2060 } |
2063 } |
2061 _returned_refit_capacity = capacity; |
2064 _returned_refit_capacity = capacity; |
2062 |
2065 |
2063 cost = 0; |
|
2064 if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) { |
2066 if (IsHumanPlayer(v->owner) && new_cid != v->cargo_type) { |
2065 cost = GetRefitCost(v->engine_type); |
2067 cost = GetRefitCost(v->engine_type); |
2066 } |
2068 } |
2067 |
2069 |
2068 if (flags & DC_EXEC) { |
2070 if (flags & DC_EXEC) { |
2069 v->cargo_cap = capacity; |
2071 v->cargo_cap = capacity; |
2070 v->cargo_count = (v->cargo_type == new_cid) ? min(capacity, v->cargo_count) : 0; |
2072 v->cargo.Truncate((v->cargo_type == new_cid) ? capacity : 0); |
2071 v->cargo_type = new_cid; |
2073 v->cargo_type = new_cid; |
2072 v->cargo_subtype = new_subtype; |
2074 v->cargo_subtype = new_subtype; |
2073 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
2075 InvalidateWindow(WC_VEHICLE_DETAILS, v->index); |
2074 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
2076 InvalidateWindow(WC_VEHICLE_DEPOT, v->tile); |
2075 RebuildVehicleLists(); |
2077 RebuildVehicleLists(); |