(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);
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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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)