mirror of https://github.com/OpenTTD/OpenTTD.git
(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:
parent
4e3652f337
commit
0543461f5e
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
14
vehicle.h
14
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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue