diff --git a/roadveh_cmd.c b/roadveh_cmd.c index b5ed7807d6..8084ed4cc5 100644 --- a/roadveh_cmd.c +++ b/roadveh_cmd.c @@ -1330,12 +1330,14 @@ static void RoadVehController(Vehicle *v) BeginVehicleMove(v); if (v->u.road.state == 255) { + const Vehicle *u; GetNewVehiclePosResult gp; GetNewVehiclePos(v, &gp); - if (RoadVehFindCloseTo(v, gp.x, gp.y, v->direction) != NULL) { - v->cur_speed = 0; + u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction); + if (u != NULL && u->cur_speed < v->cur_speed) { + v->cur_speed = u->cur_speed; return; } @@ -1666,7 +1668,12 @@ void OnNewDay_RoadVeh(Vehicle *v) RoadStop* best = NULL; if (rs != NULL) { - if (DistanceManhattan(v->tile, st->xy) < 16) { + /* We try to obtain a slot if: + * 1) we're reasonably close to the primary road stop + * or + * 2) we're somewhere close to the station rectangle + */ + if (DistanceManhattan(v->tile, rs->xy) < 16 || PtInExtendedRect(&st->rect, TileX(v->tile), TileY(v->tile), 2)) { uint dist, badness; uint minbadness = UINT_MAX; diff --git a/station.h b/station.h index aaa1683843..affd7abe40 100644 --- a/station.h +++ b/station.h @@ -228,6 +228,7 @@ RoadStop * GetPrimaryRoadStop(const Station *st, RoadStopType type); uint GetNumRoadStops(const Station* st, RoadStopType type); RoadStop * AllocateRoadStop( void ); void ClearSlot(Vehicle *v); +bool PtInExtendedRect(Rect *r, int x, int y, int distance); static inline bool IsBuoy(const Station* st) { diff --git a/station_cmd.c b/station_cmd.c index 7929c23424..e1304a86c5 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -2234,7 +2234,14 @@ static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode) case TRANSPORT_WATER: // buoy is coded as a station, it is always on open water - if (IsBuoy_(tile)) return TRACK_BIT_ALL * 0x101; + if (IsBuoy_(tile)) { + TrackBits ts = TRACK_BIT_ALL; + // remove tracks that connect NE map edge + if (TileX(tile) == 0) ts &= ~(TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT); + // remove tracks that connect NW map edge + if (TileY(tile) == 0) ts &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER); + return ts * 0x101; + } break; case TRANSPORT_ROAD: @@ -3160,9 +3167,9 @@ const ChunkHandler _station_chunk_handlers[] = { }; -static inline bool PtInRectXY(Rect *r, int x, int y) +bool PtInExtendedRect(Rect *r, int x, int y, int distance) { - return (r->left <= x && x <= r->right && r->top <= y && y <= r->bottom); + return (r->left - distance <= x && x <= r->right + distance && r->top - distance <= y && y <= r->bottom + distance); } static void StationRect_Init(Station *st) @@ -3185,7 +3192,7 @@ static bool StationRect_BeforeAddTile(Station *st, TileIndex tile, StationRectMo // we are adding the first station tile r->left = r->right = x; r->top = r->bottom = y; - } else if (!PtInRectXY(r, x, y)) { + } else if (!PtInExtendedRect(r, x, y, 0)) { // current rect is not empty and new point is outside this rect // make new spread-out rectangle Rect new_rect = {min(x, r->left), min(y, r->top), max(x, r->right), max(y, r->bottom)}; @@ -3276,8 +3283,8 @@ static bool StationRect_AfterRemoveTile(Station *st, TileIndex tile) static bool StationRect_AfterRemoveRect(Station *st, TileIndex tile, int w, int h) { bool empty; - assert(PtInRectXY(&st->rect, TileX(tile), TileY(tile))); - assert(PtInRectXY(&st->rect, TileX(tile) + w - 1, TileY(tile) + h - 1)); + assert(PtInExtendedRect(&st->rect, TileX(tile), TileY(tile), 0)); + assert(PtInExtendedRect(&st->rect, TileX(tile) + w - 1, TileY(tile) + h - 1, 0)); empty = StationRect_AfterRemoveTile(st, tile); if (w != 1 || h != 1) empty = empty || StationRect_AfterRemoveTile(st, TILE_ADDXY(tile, w - 1, h - 1)); return empty; diff --git a/vehicle.c b/vehicle.c index 7b1dde8e7c..54f7b54f8b 100644 --- a/vehicle.c +++ b/vehicle.c @@ -576,7 +576,7 @@ void DestroyVehicle(Vehicle *v) UpdateVehiclePosHash(v, INVALID_COORD, 0); v->next_hash = INVALID_VEHICLE; - if (v->orders != NULL) DeleteVehicleOrders(v); + if (IsPlayerBuildableVehicleType(v)) DeleteVehicleOrders(v); /* Now remove any artic part. This will trigger an other * destroy vehicle, which on his turn can remove any @@ -1623,7 +1623,7 @@ int32 CmdMassStartStopVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2 } if (vehicle_list_window) { - uint16 id = GB(p1, 0, 16); + uint32 id = p1; uint16 window_type = p2 & VLW_MASK; engine_count = GenerateVehicleSortList((const Vehicle***)&vl, &engine_list_length, vehicle_type, _current_player, id, id, id, window_type); @@ -2368,7 +2368,7 @@ void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, ui * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h * @return the number of vehicles added to the list */ -uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type) +uint GenerateVehicleSortList(const Vehicle ***sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint32 depot_airport_index, uint16 window_type) { const uint subtype = (type != VEH_Aircraft) ? Train_Front : 2; uint n = 0; diff --git a/vehicle.h b/vehicle.h index a4377572de..a652343c9f 100644 --- a/vehicle.h +++ b/vehicle.h @@ -329,7 +329,7 @@ int CheckTrainStoppedInDepot(const Vehicle *v); bool VehicleNeedsService(const Vehicle *v); -uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint16 depot_airport_index, uint16 window_type); +uint GenerateVehicleSortList(const Vehicle*** sort_list, uint16 *length_of_array, byte type, PlayerID owner, StationID station, OrderID order, uint32 depot_airport_index, uint16 window_type); void BuildDepotVehicleList(byte type, TileIndex tile, Vehicle ***engine_list, uint16 *engine_list_length, uint16 *engine_count, Vehicle ***wagon_list, uint16 *wagon_list_length, uint16 *wagon_count); int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id); bool IsVehicleInDepot(const Vehicle *v); @@ -403,6 +403,18 @@ static inline void DeleteVehicle(Vehicle *v) v->type = 0; } +static inline bool IsPlayerBuildableVehicleType(const Vehicle *v) +{ + switch (v->type) { + case VEH_Train: + case VEH_Road: + case VEH_Ship: + case VEH_Aircraft: + return true; + } + return false; +} + #define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (IsValidVehicle(v)) #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)