175 /* The ai_new queries the vehicle cost before building the route, |
175 /* The ai_new queries the vehicle cost before building the route, |
176 * so we must check against cheaters no sooner than now. --pasky */ |
176 * so we must check against cheaters no sooner than now. --pasky */ |
177 if (!IsTileDepotType(tile, TRANSPORT_ROAD)) return CMD_ERROR; |
177 if (!IsTileDepotType(tile, TRANSPORT_ROAD)) return CMD_ERROR; |
178 if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; |
178 if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; |
179 |
179 |
180 if (HASBIT(GetRoadTypes(tile), ROADTYPE_TRAM) != HASBIT(EngInfo(p1)->misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_DEPOT_WRONG_DEPOT_TYPE); |
180 if (HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) != HasBit(EngInfo(p1)->misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_DEPOT_WRONG_DEPOT_TYPE); |
181 |
181 |
182 uint num_vehicles = 1 + CountArticulatedParts(p1, false); |
182 uint num_vehicles = 1 + CountArticulatedParts(p1, false); |
183 |
183 |
184 /* Allow for the front and the articulated parts, plus one to "terminate" the list. */ |
184 /* Allow for the front and the articulated parts, plus one to "terminate" the list. */ |
185 Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); |
185 Vehicle **vl = (Vehicle**)alloca(sizeof(*vl) * (num_vehicles + 1)); |
190 } |
190 } |
191 |
191 |
192 v = vl[0]; |
192 v = vl[0]; |
193 |
193 |
194 /* find the first free roadveh id */ |
194 /* find the first free roadveh id */ |
195 unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD); |
195 unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_ROAD); |
196 if (unit_num > _patches.max_roadveh) |
196 if (unit_num > _patches.max_roadveh) |
197 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
197 return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); |
198 |
198 |
199 if (flags & DC_EXEC) { |
199 if (flags & DC_EXEC) { |
200 int x; |
200 int x; |
250 |
250 |
251 v->cur_image = 0xC15; |
251 v->cur_image = 0xC15; |
252 v->random_bits = VehicleRandomBits(); |
252 v->random_bits = VehicleRandomBits(); |
253 SetRoadVehFront(v); |
253 SetRoadVehFront(v); |
254 |
254 |
255 v->u.road.roadtype = HASBIT(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; |
255 v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; |
256 v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype); |
256 v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype); |
257 v->u.road.cached_veh_length = GetRoadVehLength(v); |
257 v->u.road.cached_veh_length = GetRoadVehLength(v); |
258 |
258 |
259 v->vehicle_flags = 0; |
259 v->vehicle_flags = 0; |
260 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
260 if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SETBIT(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); |
474 |
474 |
475 if (v->IsInDepot()) return CMD_ERROR; |
475 if (v->IsInDepot()) return CMD_ERROR; |
476 |
476 |
477 /* If the current orders are already goto-depot */ |
477 /* If the current orders are already goto-depot */ |
478 if (v->current_order.type == OT_GOTO_DEPOT) { |
478 if (v->current_order.type == OT_GOTO_DEPOT) { |
479 if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) { |
479 if (!!(p2 & DEPOT_SERVICE) == HasBit(v->current_order.flags, OFB_HALT_IN_DEPOT)) { |
480 /* We called with a different DEPOT_SERVICE setting. |
480 /* We called with a different DEPOT_SERVICE setting. |
481 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
481 * Now we change the setting to apply the new one and let the vehicle head for the same depot. |
482 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
482 * Note: the if is (true for requesting service == true for ordered to stop in depot) */ |
483 if (flags & DC_EXEC) { |
483 if (flags & DC_EXEC) { |
484 CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS); |
484 CLRBIT(v->current_order.flags, OFB_PART_OF_ORDERS); |
490 |
490 |
491 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
491 if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders |
492 if (flags & DC_EXEC) { |
492 if (flags & DC_EXEC) { |
493 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
493 /* If the orders to 'goto depot' are in the orders list (forced servicing), |
494 * then skip to the next order; effectively cancelling this forced service */ |
494 * then skip to the next order; effectively cancelling this forced service */ |
495 if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) |
495 if (HasBit(v->current_order.flags, OFB_PART_OF_ORDERS)) |
496 v->cur_order_index++; |
496 v->cur_order_index++; |
497 |
497 |
498 v->current_order.type = OT_DUMMY; |
498 v->current_order.type = OT_DUMMY; |
499 v->current_order.flags = 0; |
499 v->current_order.flags = 0; |
500 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
500 InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR); |
595 |
595 |
596 /* Mark the station entrance as not busy */ |
596 /* Mark the station entrance as not busy */ |
597 rs->SetEntranceBusy(false); |
597 rs->SetEntranceBusy(false); |
598 |
598 |
599 /* Free the parking bay */ |
599 /* Free the parking bay */ |
600 rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY)); |
600 rs->FreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY)); |
601 } |
601 } |
602 |
602 |
603 static void DeleteLastRoadVeh(Vehicle *v) |
603 static void DeleteLastRoadVeh(Vehicle *v) |
604 { |
604 { |
605 Vehicle *u = v; |
605 Vehicle *u = v; |
1272 best_track = INVALID_TRACKDIR; |
1272 best_track = INVALID_TRACKDIR; |
1273 uint best_dist = (uint)-1; |
1273 uint best_dist = (uint)-1; |
1274 uint best_maxlen = (uint)-1; |
1274 uint best_maxlen = (uint)-1; |
1275 uint bitmask = (uint)trackdirs; |
1275 uint bitmask = (uint)trackdirs; |
1276 for (int i = 0; bitmask != 0; bitmask >>= 1, i++) { |
1276 for (int i = 0; bitmask != 0; bitmask >>= 1, i++) { |
1277 if (HASBIT(bitmask, 0)) { |
1277 if (HasBit(bitmask, 0)) { |
1278 if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track |
1278 if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track |
1279 frd.maxtracklen = (uint)-1; |
1279 frd.maxtracklen = (uint)-1; |
1280 frd.mindist = (uint)-1; |
1280 frd.mindist = (uint)-1; |
1281 FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); |
1281 FollowTrack(tile, 0x2000 | TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); |
1282 |
1282 |
1414 diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile)); |
1414 diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile)); |
1415 } |
1415 } |
1416 |
1416 |
1417 if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR; |
1417 if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR; |
1418 dir = DiagdirToDiagTrackdir(diag_dir); |
1418 dir = DiagdirToDiagTrackdir(diag_dir); |
1419 } else if (HASBIT(prev_state, RVS_IN_DT_ROAD_STOP)) { |
1419 } else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) { |
1420 dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK); |
1420 dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK); |
1421 } else if (prev_state < TRACKDIR_END) { |
1421 } else if (prev_state < TRACKDIR_END) { |
1422 if (already_reversed && prev->tile != tile) { |
1422 if (already_reversed && prev->tile != tile) { |
1423 /* |
1423 /* |
1424 * The vehicle has reversed, but did not go straight back. |
1424 * The vehicle has reversed, but did not go straight back. |
1517 if (u != NULL && u->First()->cur_speed < v->cur_speed) { |
1517 if (u != NULL && u->First()->cur_speed < v->cur_speed) { |
1518 v->cur_speed = u->First()->cur_speed; |
1518 v->cur_speed = u->First()->cur_speed; |
1519 return false; |
1519 return false; |
1520 } |
1520 } |
1521 |
1521 |
1522 if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HASBIT(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { |
1522 if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) { |
1523 /* Vehicle has just entered a bridge or tunnel */ |
1523 /* Vehicle has just entered a bridge or tunnel */ |
1524 v->cur_image = v->GetImage(v->direction); |
1524 v->cur_image = v->GetImage(v->direction); |
1525 v->UpdateDeltaXY(v->direction); |
1525 v->UpdateDeltaXY(v->direction); |
1526 SetRoadVehPosition(v,gp.x,gp.y); |
1526 SetRoadVehPosition(v,gp.x,gp.y); |
1527 return true; |
1527 return true; |
1536 |
1536 |
1537 /* Get move position data for next frame. |
1537 /* Get move position data for next frame. |
1538 * For a drive-through road stop use 'straight road' move data. |
1538 * For a drive-through road stop use 'straight road' move data. |
1539 * In this case v->u.road.state is masked to give the road stop entry direction. */ |
1539 * In this case v->u.road.state is masked to give the road stop entry direction. */ |
1540 rd = _road_drive_data[v->u.road.roadtype][( |
1540 rd = _road_drive_data[v->u.road.roadtype][( |
1541 (HASBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) + |
1541 (HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) + |
1542 (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1]; |
1542 (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1]; |
1543 |
1543 |
1544 if (rd.x & RDE_NEXT_TILE) { |
1544 if (rd.x & RDE_NEXT_TILE) { |
1545 TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); |
1545 TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); |
1546 Trackdir dir; |
1546 Trackdir dir; |
1631 return false; |
1631 return false; |
1632 } |
1632 } |
1633 } |
1633 } |
1634 |
1634 |
1635 r = VehicleEnterTile(v, tile, x, y); |
1635 r = VehicleEnterTile(v, tile, x, y); |
1636 if (HASBIT(r, VETS_CANNOT_ENTER)) { |
1636 if (HasBit(r, VETS_CANNOT_ENTER)) { |
1637 if (!IsTileType(tile, MP_TUNNELBRIDGE)) { |
1637 if (!IsTileType(tile, MP_TUNNELBRIDGE)) { |
1638 v->cur_speed = 0; |
1638 v->cur_speed = 0; |
1639 return false; |
1639 return false; |
1640 } |
1640 } |
1641 /* Try an about turn to re-enter the previous tile */ |
1641 /* Try an about turn to re-enter the previous tile */ |
1653 if (IsRoadStop(v->tile)) { |
1653 if (IsRoadStop(v->tile)) { |
1654 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
1654 RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); |
1655 |
1655 |
1656 /* Vehicle is leaving a road stop tile, mark bay as free |
1656 /* Vehicle is leaving a road stop tile, mark bay as free |
1657 * For drive-through stops, only do it if the vehicle stopped here */ |
1657 * For drive-through stops, only do it if the vehicle stopped here */ |
1658 if (IsStandardRoadStopTile(v->tile) || HASBIT(v->u.road.state, RVS_IS_STOPPING)) { |
1658 if (IsStandardRoadStopTile(v->tile) || HasBit(v->u.road.state, RVS_IS_STOPPING)) { |
1659 rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY)); |
1659 rs->FreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY)); |
1660 CLRBIT(v->u.road.state, RVS_IS_STOPPING); |
1660 CLRBIT(v->u.road.state, RVS_IS_STOPPING); |
1661 } |
1661 } |
1662 if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false); |
1662 if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false); |
1663 } |
1663 } |
1664 } |
1664 } |
1665 |
1665 |
1666 if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) { |
1666 if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { |
1667 v->tile = tile; |
1667 v->tile = tile; |
1668 v->u.road.state = (byte)dir; |
1668 v->u.road.state = (byte)dir; |
1669 v->u.road.frame = start_frame; |
1669 v->u.road.frame = start_frame; |
1670 } |
1670 } |
1671 if (newdir != v->direction) { |
1671 if (newdir != v->direction) { |
1728 |
1728 |
1729 newdir = RoadVehGetSlidingDirection(v, x, y); |
1729 newdir = RoadVehGetSlidingDirection(v, x, y); |
1730 if (IsRoadVehFront(v) && RoadVehFindCloseTo(v, x, y, newdir) != NULL) return false; |
1730 if (IsRoadVehFront(v) && RoadVehFindCloseTo(v, x, y, newdir) != NULL) return false; |
1731 |
1731 |
1732 r = VehicleEnterTile(v, v->tile, x, y); |
1732 r = VehicleEnterTile(v, v->tile, x, y); |
1733 if (HASBIT(r, VETS_CANNOT_ENTER)) { |
1733 if (HasBit(r, VETS_CANNOT_ENTER)) { |
1734 v->cur_speed = 0; |
1734 v->cur_speed = 0; |
1735 return false; |
1735 return false; |
1736 } |
1736 } |
1737 |
1737 |
1738 v->u.road.state = dir; |
1738 v->u.road.state = dir; |
1824 |
1824 |
1825 /* Check if next inline bay is free */ |
1825 /* Check if next inline bay is free */ |
1826 if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { |
1826 if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) { |
1827 RoadStop *rs_n = GetRoadStopByTile(next_tile, type); |
1827 RoadStop *rs_n = GetRoadStopByTile(next_tile, type); |
1828 |
1828 |
1829 if (rs_n->IsFreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY))) { |
1829 if (rs_n->IsFreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY))) { |
1830 /* Bay in next stop along is free - use it */ |
1830 /* Bay in next stop along is free - use it */ |
1831 ClearSlot(v); |
1831 ClearSlot(v); |
1832 rs_n->num_vehicles++; |
1832 rs_n->num_vehicles++; |
1833 v->u.road.slot = rs_n; |
1833 v->u.road.slot = rs_n; |
1834 v->dest_tile = rs_n->xy; |
1834 v->dest_tile = rs_n->xy; |
1895 } |
1895 } |
1896 |
1896 |
1897 /* Check tile position conditions - i.e. stop position in depot, |
1897 /* Check tile position conditions - i.e. stop position in depot, |
1898 * entry onto bridge or into tunnel */ |
1898 * entry onto bridge or into tunnel */ |
1899 r = VehicleEnterTile(v, v->tile, x, y); |
1899 r = VehicleEnterTile(v, v->tile, x, y); |
1900 if (HASBIT(r, VETS_CANNOT_ENTER)) { |
1900 if (HasBit(r, VETS_CANNOT_ENTER)) { |
1901 v->cur_speed = 0; |
1901 v->cur_speed = 0; |
1902 return false; |
1902 return false; |
1903 } |
1903 } |
1904 |
1904 |
1905 /* Move to next frame unless vehicle arrived at a stop position |
1905 /* Move to next frame unless vehicle arrived at a stop position |
1906 * in a depot or entered a tunnel/bridge */ |
1906 * in a depot or entered a tunnel/bridge */ |
1907 if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++; |
1907 if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++; |
1908 |
1908 |
1909 v->cur_image = v->GetImage(v->direction); |
1909 v->cur_image = v->GetImage(v->direction); |
1910 v->UpdateDeltaXY(v->direction); |
1910 v->UpdateDeltaXY(v->direction); |
1911 RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); |
1911 RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); |
1912 return true; |
1912 return true; |
2124 { |
2124 { |
2125 Vehicle *v; |
2125 Vehicle *v; |
2126 CommandCost cost; |
2126 CommandCost cost; |
2127 CargoID new_cid = GB(p2, 0, 8); |
2127 CargoID new_cid = GB(p2, 0, 8); |
2128 byte new_subtype = GB(p2, 8, 8); |
2128 byte new_subtype = GB(p2, 8, 8); |
2129 bool only_this = HASBIT(p2, 16); |
2129 bool only_this = HasBit(p2, 16); |
2130 uint16 capacity = CALLBACK_FAILED; |
2130 uint16 capacity = CALLBACK_FAILED; |
2131 uint total_capacity = 0; |
2131 uint total_capacity = 0; |
2132 |
2132 |
2133 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
2133 if (!IsValidVehicleID(p1)) return CMD_ERROR; |
2134 |
2134 |
2147 * [Refit] button near each wagon. */ |
2147 * [Refit] button near each wagon. */ |
2148 if (!CanRefitTo(v->engine_type, new_cid)) continue; |
2148 if (!CanRefitTo(v->engine_type, new_cid)) continue; |
2149 |
2149 |
2150 if (v->cargo_cap == 0) continue; |
2150 if (v->cargo_cap == 0) continue; |
2151 |
2151 |
2152 if (HASBIT(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) { |
2152 if (HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_REFIT_CAPACITY)) { |
2153 /* Back up the cargo type */ |
2153 /* Back up the cargo type */ |
2154 CargoID temp_cid = v->cargo_type; |
2154 CargoID temp_cid = v->cargo_type; |
2155 byte temp_subtype = v->cargo_subtype; |
2155 byte temp_subtype = v->cargo_subtype; |
2156 v->cargo_type = new_cid; |
2156 v->cargo_type = new_cid; |
2157 v->cargo_subtype = new_subtype; |
2157 v->cargo_subtype = new_subtype; |