(svn r8626) [0.5] -Backport from trunk (8294, 8296, 8536, 8540, 8609):

-Fix: deleting a vehicle with shared orders, but no orders would fail to reset prev_shared and next_shared
-Fix: GenerateVehicleSortList()/CmdMassStartStopVehicle() tried to put a TileIndex into an uint16
-Fix (FS#577): Road Vehicles now can obtain a slot even if the station is very spread out 
-Fix[YAPF]: Assert when buoy is placed on NE or NW map edge (Dan)
-Fix: a road vehicle that is very close after another (slower) road vehicle gets its speed reset to 0 when entering a tunnel, which causes a traffic jam outside of the tunnel.
This commit is contained in:
rubidium 2007-02-08 10:41:45 +00:00
parent 4e3652f337
commit 0543461f5e
5 changed files with 40 additions and 13 deletions

View File

@ -1330,12 +1330,14 @@ static void RoadVehController(Vehicle *v)
BeginVehicleMove(v); BeginVehicleMove(v);
if (v->u.road.state == 255) { if (v->u.road.state == 255) {
const Vehicle *u;
GetNewVehiclePosResult gp; GetNewVehiclePosResult gp;
GetNewVehiclePos(v, &gp); GetNewVehiclePos(v, &gp);
if (RoadVehFindCloseTo(v, gp.x, gp.y, v->direction) != NULL) { u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
v->cur_speed = 0; if (u != NULL && u->cur_speed < v->cur_speed) {
v->cur_speed = u->cur_speed;
return; return;
} }
@ -1666,7 +1668,12 @@ void OnNewDay_RoadVeh(Vehicle *v)
RoadStop* best = NULL; RoadStop* best = NULL;
if (rs != 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 dist, badness;
uint minbadness = UINT_MAX; uint minbadness = UINT_MAX;

View File

@ -228,6 +228,7 @@ RoadStop * GetPrimaryRoadStop(const Station *st, RoadStopType type);
uint GetNumRoadStops(const Station* st, RoadStopType type); uint GetNumRoadStops(const Station* st, RoadStopType type);
RoadStop * AllocateRoadStop( void ); RoadStop * AllocateRoadStop( void );
void ClearSlot(Vehicle *v); void ClearSlot(Vehicle *v);
bool PtInExtendedRect(Rect *r, int x, int y, int distance);
static inline bool IsBuoy(const Station* st) static inline bool IsBuoy(const Station* st)
{ {

View File

@ -2234,7 +2234,14 @@ static uint32 GetTileTrackStatus_Station(TileIndex tile, TransportType mode)
case TRANSPORT_WATER: case TRANSPORT_WATER:
// buoy is coded as a station, it is always on open 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; break;
case TRANSPORT_ROAD: 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) 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 // we are adding the first station tile
r->left = r->right = x; r->left = r->right = x;
r->top = r->bottom = y; 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 // current rect is not empty and new point is outside this rect
// make new spread-out rectangle // make new spread-out rectangle
Rect new_rect = {min(x, r->left), min(y, r->top), max(x, r->right), max(y, r->bottom)}; 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) static bool StationRect_AfterRemoveRect(Station *st, TileIndex tile, int w, int h)
{ {
bool empty; bool empty;
assert(PtInRectXY(&st->rect, TileX(tile), TileY(tile))); assert(PtInExtendedRect(&st->rect, TileX(tile), TileY(tile), 0));
assert(PtInRectXY(&st->rect, TileX(tile) + w - 1, TileY(tile) + h - 1)); assert(PtInExtendedRect(&st->rect, TileX(tile) + w - 1, TileY(tile) + h - 1, 0));
empty = StationRect_AfterRemoveTile(st, tile); empty = StationRect_AfterRemoveTile(st, tile);
if (w != 1 || h != 1) empty = empty || StationRect_AfterRemoveTile(st, TILE_ADDXY(tile, w - 1, h - 1)); if (w != 1 || h != 1) empty = empty || StationRect_AfterRemoveTile(st, TILE_ADDXY(tile, w - 1, h - 1));
return empty; return empty;

View File

@ -576,7 +576,7 @@ void DestroyVehicle(Vehicle *v)
UpdateVehiclePosHash(v, INVALID_COORD, 0); UpdateVehiclePosHash(v, INVALID_COORD, 0);
v->next_hash = INVALID_VEHICLE; 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 /* Now remove any artic part. This will trigger an other
* destroy vehicle, which on his turn can remove any * 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) { if (vehicle_list_window) {
uint16 id = GB(p1, 0, 16); uint32 id = p1;
uint16 window_type = p2 & VLW_MASK; uint16 window_type = p2 & VLW_MASK;
engine_count = GenerateVehicleSortList((const Vehicle***)&vl, &engine_list_length, vehicle_type, _current_player, id, id, id, window_type); 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 * @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 * @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; const uint subtype = (type != VEH_Aircraft) ? Train_Front : 2;
uint n = 0; uint n = 0;

View File

@ -329,7 +329,7 @@ int CheckTrainStoppedInDepot(const Vehicle *v);
bool VehicleNeedsService(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); 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); int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id);
bool IsVehicleInDepot(const Vehicle *v); bool IsVehicleInDepot(const Vehicle *v);
@ -403,6 +403,18 @@ static inline void DeleteVehicle(Vehicle *v)
v->type = 0; 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_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) #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)