mirror of https://github.com/OpenTTD/OpenTTD
(svn r14347) [0.6] -Backport from trunk:
- Fix: Invalid v->u.air.targetairport could cause crashes at several places [FS#2300] (r14343, 14344) - Fix: Signs from old savegames were lost (causing little memory leaks) (r14340) - Fix: When a company was renamed and then manager was renamed before building anything, company name changed (r14328) - Fix: When you rename a town before building something and build something near that town your company would be called "<old townname> Transport" [FS#2251] (r14327) - Fix: Free any blocks that a helicopter may have on an oilrig when the helicopter gets forcefully removed (bankruptcy). For other airports this isn't needed as they can't be used by multiple companies [FS#2241] (r14324) - Fix: Possible assert when renaming removed waypoint (r14322) - Fix: Properly delete orders so the pool doesn't fill up (r14319) - Fix: Do not allow building road over level crossings and drive-through road stops in the wrong direction; do not allow adding roadtypes to non-drive through road stops; pay for all added road bits [FS#2268] (r14316, r14315, r14314, r14308)release/0.6
parent
d53ec0c4cd
commit
cbc69f8067
|
@ -127,4 +127,6 @@ struct Aircraft : public Vehicle {
|
||||||
void OnNewDay();
|
void OnNewDay();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Station *GetTargetAirportIfValid(const Vehicle *v);
|
||||||
|
|
||||||
#endif /* AIRCRAFT_H */
|
#endif /* AIRCRAFT_H */
|
||||||
|
|
|
@ -595,9 +595,9 @@ CommandCost CmdSendAircraftToHangar(TileIndex tile, uint32 flags, uint32 p1, uin
|
||||||
} else {
|
} else {
|
||||||
bool next_airport_has_hangar = true;
|
bool next_airport_has_hangar = true;
|
||||||
StationID next_airport_index = v->u.air.targetairport;
|
StationID next_airport_index = v->u.air.targetairport;
|
||||||
const Station *st = GetStation(next_airport_index);
|
const Station *st = GetTargetAirportIfValid(v);
|
||||||
/* If the station is not a valid airport or if it has no hangars */
|
/* If the station is not a valid airport or if it has no hangars */
|
||||||
if (!st->IsValid() || st->airport_tile == 0 || st->Airport()->nof_depots == 0) {
|
if (st == NULL || st->Airport()->nof_depots == 0) {
|
||||||
/* the aircraft has to search for a hangar on its own */
|
/* the aircraft has to search for a hangar on its own */
|
||||||
StationID station = FindNearestHangar(v);
|
StationID station = FindNearestHangar(v);
|
||||||
|
|
||||||
|
@ -1023,9 +1023,16 @@ static byte AircraftGetEntryPoint(const Vehicle *v, const AirportFTAClass *apc)
|
||||||
assert(v != NULL);
|
assert(v != NULL);
|
||||||
assert(apc != NULL);
|
assert(apc != NULL);
|
||||||
|
|
||||||
const Station *st = GetStation(v->u.air.targetairport);
|
/* In the case the station doesn't exit anymore, set target tile 0.
|
||||||
/* Make sure we don't go to 0,0 if the airport has been removed. */
|
* It doesn't hurt much, aircraft will go to next order, nearest hangar
|
||||||
TileIndex tile = (st->airport_tile != 0) ? st->airport_tile : st->xy;
|
* or it will simply crash in next tick */
|
||||||
|
TileIndex tile = 0;
|
||||||
|
|
||||||
|
if (IsValidStationID(v->u.air.targetairport)) {
|
||||||
|
const Station *st = GetStation(v->u.air.targetairport);
|
||||||
|
/* Make sure we don't go to 0,0 if the airport has been removed. */
|
||||||
|
tile = (st->airport_tile != 0) ? st->airport_tile : st->xy;
|
||||||
|
}
|
||||||
|
|
||||||
int delta_x = v->x_pos - TileX(tile) * TILE_SIZE;
|
int delta_x = v->x_pos - TileX(tile) * TILE_SIZE;
|
||||||
int delta_y = v->y_pos - TileY(tile) * TILE_SIZE;
|
int delta_y = v->y_pos - TileY(tile) * TILE_SIZE;
|
||||||
|
@ -1051,15 +1058,22 @@ static byte AircraftGetEntryPoint(const Vehicle *v, const AirportFTAClass *apc)
|
||||||
static bool AircraftController(Vehicle *v)
|
static bool AircraftController(Vehicle *v)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
const Station *st = GetStation(v->u.air.targetairport);
|
|
||||||
const AirportFTAClass *afc = st->Airport();
|
StationID target = v->u.air.targetairport;
|
||||||
const AirportMovingData *amd;
|
|
||||||
|
/* NULL if station is invalid */
|
||||||
|
const Station *st = IsValidStationID(target) ? GetStation(target) : NULL;
|
||||||
|
/* 0 if there is no station */
|
||||||
|
TileIndex tile = 0;
|
||||||
|
if (st != NULL) {
|
||||||
|
tile = st->airport_tile;
|
||||||
|
if (tile == 0) tile = st->xy;
|
||||||
|
}
|
||||||
|
/* DUMMY if there is no station or no airport */
|
||||||
|
const AirportFTAClass *afc = tile == 0 ? GetAirport(AT_DUMMY) : st->Airport();
|
||||||
|
|
||||||
/* prevent going to 0,0 if airport is deleted. */
|
/* prevent going to 0,0 if airport is deleted. */
|
||||||
TileIndex tile = st->airport_tile;
|
if (st == NULL || st->airport_tile == 0) {
|
||||||
if (tile == 0) {
|
|
||||||
tile = st->xy;
|
|
||||||
|
|
||||||
/* Jump into our "holding pattern" state machine if possible */
|
/* Jump into our "holding pattern" state machine if possible */
|
||||||
if (v->u.air.pos >= afc->nofelements) {
|
if (v->u.air.pos >= afc->nofelements) {
|
||||||
v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc);
|
v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc);
|
||||||
|
@ -1075,7 +1089,7 @@ static bool AircraftController(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get airport moving data */
|
/* get airport moving data */
|
||||||
amd = afc->MovingData(v->u.air.pos);
|
const AirportMovingData *amd = afc->MovingData(v->u.air.pos);
|
||||||
|
|
||||||
int x = TileX(tile) * TILE_SIZE;
|
int x = TileX(tile) * TILE_SIZE;
|
||||||
int y = TileY(tile) * TILE_SIZE;
|
int y = TileY(tile) * TILE_SIZE;
|
||||||
|
@ -1107,7 +1121,7 @@ static bool AircraftController(Vehicle *v)
|
||||||
|
|
||||||
/* Helicopter landing. */
|
/* Helicopter landing. */
|
||||||
if (amd->flag & AMED_HELI_LOWER) {
|
if (amd->flag & AMED_HELI_LOWER) {
|
||||||
if (st->airport_tile == 0) {
|
if (st == NULL) {
|
||||||
/* FIXME - AircraftController -> if station no longer exists, do not land
|
/* FIXME - AircraftController -> if station no longer exists, do not land
|
||||||
* helicopter will circle until sign disappears, then go to next order
|
* helicopter will circle until sign disappears, then go to next order
|
||||||
* what to do when it is the only order left, right now it just stays in 1 place */
|
* what to do when it is the only order left, right now it just stays in 1 place */
|
||||||
|
@ -1118,7 +1132,7 @@ static bool AircraftController(Vehicle *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vehicle is now at the airport. */
|
/* Vehicle is now at the airport. */
|
||||||
v->tile = st->airport_tile;
|
v->tile = tile;
|
||||||
|
|
||||||
/* Find altitude of landing position. */
|
/* Find altitude of landing position. */
|
||||||
int z = GetSlopeZ(x, y) + 1 + afc->delta_z;
|
int z = GetSlopeZ(x, y) + 1 + afc->delta_z;
|
||||||
|
@ -1272,10 +1286,10 @@ static void HandleCrashedAircraft(Vehicle *v)
|
||||||
{
|
{
|
||||||
v->u.air.crashed_counter++;
|
v->u.air.crashed_counter++;
|
||||||
|
|
||||||
Station *st = GetStation(v->u.air.targetairport);
|
Station *st = GetTargetAirportIfValid(v);
|
||||||
|
|
||||||
/* make aircraft crash down to the ground */
|
/* make aircraft crash down to the ground */
|
||||||
if (v->u.air.crashed_counter < 500 && st->airport_tile==0 && ((v->u.air.crashed_counter % 3) == 0) ) {
|
if (v->u.air.crashed_counter < 500 && st == NULL && ((v->u.air.crashed_counter % 3) == 0) ) {
|
||||||
uint z = GetSlopeZ(v->x_pos, v->y_pos);
|
uint z = GetSlopeZ(v->x_pos, v->y_pos);
|
||||||
v->z_pos -= 1;
|
v->z_pos -= 1;
|
||||||
if (v->z_pos == z) {
|
if (v->z_pos == z) {
|
||||||
|
@ -1306,9 +1320,11 @@ static void HandleCrashedAircraft(Vehicle *v)
|
||||||
/* clear runway-in on all airports, set by crashing plane
|
/* clear runway-in on all airports, set by crashing plane
|
||||||
* small airports use AIRPORT_BUSY, city airports use RUNWAY_IN_OUT_block, etc.
|
* small airports use AIRPORT_BUSY, city airports use RUNWAY_IN_OUT_block, etc.
|
||||||
* but they all share the same number */
|
* but they all share the same number */
|
||||||
CLRBITS(st->airport_flags, RUNWAY_IN_block);
|
if (st != NULL) {
|
||||||
CLRBITS(st->airport_flags, RUNWAY_IN_OUT_block); // commuter airport
|
CLRBITS(st->airport_flags, RUNWAY_IN_block);
|
||||||
CLRBITS(st->airport_flags, RUNWAY_IN2_block); // intercontinental
|
CLRBITS(st->airport_flags, RUNWAY_IN_OUT_block); // commuter airport
|
||||||
|
CLRBITS(st->airport_flags, RUNWAY_IN2_block); // intercontinental
|
||||||
|
}
|
||||||
|
|
||||||
MarkSingleVehicleDirty(v);
|
MarkSingleVehicleDirty(v);
|
||||||
|
|
||||||
|
@ -1401,8 +1417,8 @@ static void ProcessAircraftOrder(Vehicle *v)
|
||||||
* go to a depot, we have to keep that order so the aircraft
|
* go to a depot, we have to keep that order so the aircraft
|
||||||
* actually stops.
|
* actually stops.
|
||||||
*/
|
*/
|
||||||
const Station *st = GetStation(v->u.air.targetairport);
|
const Station *st = GetTargetAirportIfValid(v);
|
||||||
if (!st->IsValid() || st->airport_tile == 0) {
|
if (st == NULL) {
|
||||||
CommandCost ret;
|
CommandCost ret;
|
||||||
PlayerID old_player = _current_player;
|
PlayerID old_player = _current_player;
|
||||||
|
|
||||||
|
@ -1456,16 +1472,15 @@ static void CrashAirplane(Vehicle *v)
|
||||||
|
|
||||||
v->cargo.Truncate(0);
|
v->cargo.Truncate(0);
|
||||||
v->Next()->cargo.Truncate(0);
|
v->Next()->cargo.Truncate(0);
|
||||||
const Station *st = GetStation(v->u.air.targetairport);
|
const Station *st = GetTargetAirportIfValid(v);
|
||||||
StringID newsitem;
|
StringID newsitem;
|
||||||
if (st->airport_tile == 0) {
|
if (st == NULL) {
|
||||||
newsitem = STR_PLANE_CRASH_OUT_OF_FUEL;
|
newsitem = STR_PLANE_CRASH_OUT_OF_FUEL;
|
||||||
} else {
|
} else {
|
||||||
SetDParam(1, st->index);
|
SetDParam(1, st->index);
|
||||||
newsitem = STR_A034_PLANE_CRASH_DIE_IN_FIREBALL;
|
newsitem = STR_A034_PLANE_CRASH_DIE_IN_FIREBALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDParam(1, st->index);
|
|
||||||
AddNewsItem(newsitem,
|
AddNewsItem(newsitem,
|
||||||
NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
|
NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
|
||||||
v->index,
|
v->index,
|
||||||
|
@ -1541,7 +1556,8 @@ static void AircraftNextAirportPos_and_Order(Vehicle *v)
|
||||||
v->current_order.type == OT_GOTO_DEPOT)
|
v->current_order.type == OT_GOTO_DEPOT)
|
||||||
v->u.air.targetairport = v->current_order.dest;
|
v->u.air.targetairport = v->current_order.dest;
|
||||||
|
|
||||||
const AirportFTAClass *apc = GetStation(v->u.air.targetairport)->Airport();
|
const Station *st = GetTargetAirportIfValid(v);
|
||||||
|
const AirportFTAClass *apc = st == NULL ? GetAirport(AT_DUMMY) : st->Airport();
|
||||||
v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc);
|
v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2185,6 +2201,24 @@ void Aircraft::Tick()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns aircraft's target station if v->u.air.target_airport
|
||||||
|
* is a valid station with airport.
|
||||||
|
* @param v vehicle to get target airport for
|
||||||
|
* @return pointer to target station, NULL if invalid
|
||||||
|
*/
|
||||||
|
Station *GetTargetAirportIfValid(const Vehicle *v)
|
||||||
|
{
|
||||||
|
assert(v->type == VEH_AIRCRAFT);
|
||||||
|
|
||||||
|
StationID sid = v->u.air.targetairport;
|
||||||
|
|
||||||
|
if (!IsValidStationID(sid)) return NULL;
|
||||||
|
|
||||||
|
Station *st = GetStation(sid);
|
||||||
|
|
||||||
|
return st->airport_tile == 0 ? NULL : st;
|
||||||
|
}
|
||||||
|
|
||||||
/** need to be called to load aircraft from old version */
|
/** need to be called to load aircraft from old version */
|
||||||
void UpdateOldAircraft()
|
void UpdateOldAircraft()
|
||||||
{
|
{
|
||||||
|
|
|
@ -335,7 +335,7 @@ void ShowRenameWaypointWindow(const Waypoint *wp)
|
||||||
int id = wp->index;
|
int id = wp->index;
|
||||||
|
|
||||||
/* Are we allowed to change the name of the waypoint? */
|
/* Are we allowed to change the name of the waypoint? */
|
||||||
if (!CheckTileOwnership(wp->xy)) {
|
if (!IsTileType(wp->xy, MP_RAILWAY) || !CheckTileOwnership(wp->xy)) {
|
||||||
ShowErrorMessage(_error_message, STR_CANT_CHANGE_WAYPOINT_NAME,
|
ShowErrorMessage(_error_message, STR_CANT_CHANGE_WAYPOINT_NAME,
|
||||||
TileX(wp->xy) * TILE_SIZE, TileY(wp->xy) * TILE_SIZE);
|
TileX(wp->xy) * TILE_SIZE, TileY(wp->xy) * TILE_SIZE);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -271,7 +271,7 @@ CommandCost CmdChangePresidentName(TileIndex tile, uint32 flags, uint32 p1, uint
|
||||||
free(p->president_name);
|
free(p->president_name);
|
||||||
p->president_name = strdup(_cmd_text);
|
p->president_name = strdup(_cmd_text);
|
||||||
|
|
||||||
if (p->name_1 == STR_SV_UNNAMED) {
|
if (p->name_1 == STR_SV_UNNAMED && p->name == NULL) {
|
||||||
char buf[80];
|
char buf[80];
|
||||||
|
|
||||||
snprintf(buf, lengthof(buf), "%s Transport", _cmd_text);
|
snprintf(buf, lengthof(buf), "%s Transport", _cmd_text);
|
||||||
|
|
|
@ -1401,6 +1401,14 @@ bool AfterLoadGame()
|
||||||
wp->name = CopyFromOldName(wp->string);
|
wp->name = CopyFromOldName(wp->string);
|
||||||
wp->string = STR_EMPTY;
|
wp->string = STR_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint i = 0; i < GetSignPoolSize(); i++) {
|
||||||
|
/* invalid signs are determined by si->ower == INVALID_PLAYER now */
|
||||||
|
Sign *si = GetSign(i);
|
||||||
|
if (!si->IsValid() && si->name != NULL) {
|
||||||
|
si->owner = OWNER_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert road side to my format. */
|
/* convert road side to my format. */
|
||||||
|
|
|
@ -493,7 +493,7 @@ CommandCost CmdDeleteOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Give the item free */
|
/* Give the item free */
|
||||||
order->Free();
|
delete order;
|
||||||
|
|
||||||
u = GetFirstVehicleFromSharedList(v);
|
u = GetFirstVehicleFromSharedList(v);
|
||||||
DeleteOrderWarnings(u);
|
DeleteOrderWarnings(u);
|
||||||
|
|
|
@ -314,7 +314,7 @@ static void GenerateCompanyName(Player *p)
|
||||||
|
|
||||||
t = ClosestTownFromTile(tile, (uint)-1);
|
t = ClosestTownFromTile(tile, (uint)-1);
|
||||||
|
|
||||||
if (IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST+1)) {
|
if (t->name == NULL && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) {
|
||||||
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
|
str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_PLAYERNAME_START;
|
||||||
strp = t->townnameparts;
|
strp = t->townnameparts;
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,8 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cost.AddCost(_price.remove_road);
|
assert(IsDriveThroughStopTile(tile));
|
||||||
|
cost.AddCost(_price.remove_road * 2);
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
|
SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
|
@ -468,9 +469,11 @@ CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case ROAD_TILE_CROSSING:
|
case ROAD_TILE_CROSSING:
|
||||||
if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
|
|
||||||
all_bits = GetCrossingRoadBits(tile);
|
all_bits = GetCrossingRoadBits(tile);
|
||||||
if (pieces & ComplementRoadBits(all_bits)) goto do_clear;
|
if (pieces & ComplementRoadBits(all_bits)) goto do_clear;
|
||||||
|
pieces = all_bits; // we need to pay for both roadbits
|
||||||
|
|
||||||
|
if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -518,15 +521,15 @@ CommandCost CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return CommandCost(EXPENSES_CONSTRUCTION, _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
|
return CommandCost(EXPENSES_CONSTRUCTION, _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
case MP_STATION:
|
case MP_STATION: {
|
||||||
if (!IsRoadStop(tile)) goto do_clear;
|
if (!IsDriveThroughStopTile(tile)) goto do_clear;
|
||||||
if (IsDriveThroughStopTile(tile)) {
|
|
||||||
if (pieces & ~AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(tile)))) goto do_clear;
|
RoadBits curbits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(tile)));
|
||||||
} else {
|
if (pieces & ~curbits) goto do_clear;
|
||||||
if (pieces & ~DiagDirToRoadBits(GetRoadStopDir(tile))) goto do_clear;
|
pieces = curbits; // we need to pay for both roadbits
|
||||||
}
|
|
||||||
if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
|
if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
|
if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
|
||||||
|
@ -612,6 +615,7 @@ do_clear:;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MP_STATION:
|
case MP_STATION:
|
||||||
|
assert(IsDriveThroughStopTile(tile));
|
||||||
SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
|
SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "command_func.h"
|
#include "command_func.h"
|
||||||
|
#include "aircraft.h"
|
||||||
|
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
@ -73,6 +74,13 @@ Station::~Station()
|
||||||
loading_vehicles.front()->LeaveStation();
|
loading_vehicles.front()->LeaveStation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vehicle *v;
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
if (v->type == VEH_AIRCRAFT && IsNormalAircraft(v) && v->u.air.targetairport == this->index) {
|
||||||
|
v->u.air.targetairport = INVALID_STATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
RebuildStationLists();
|
RebuildStationLists();
|
||||||
InvalidateWindowClasses(WC_STATION_LIST);
|
InvalidateWindowClasses(WC_STATION_LIST);
|
||||||
|
|
|
@ -51,6 +51,7 @@ static inline void SetTimetableParams(int param1, int param2, uint32 time)
|
||||||
static void DrawTimetableWindow(Window *w)
|
static void DrawTimetableWindow(Window *w)
|
||||||
{
|
{
|
||||||
const Vehicle *v = GetVehicle(w->window_number);
|
const Vehicle *v = GetVehicle(w->window_number);
|
||||||
|
if (WP(w, order_d).sel >= v->num_orders * 2) WP(w, order_d).sel = -1;
|
||||||
int selected = WP(w, order_d).sel;
|
int selected = WP(w, order_d).sel;
|
||||||
|
|
||||||
SetVScrollCount(w, v->num_orders * 2);
|
SetVScrollCount(w, v->num_orders * 2);
|
||||||
|
|
|
@ -629,6 +629,13 @@ void Vehicle::PreDestructor()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->type == VEH_ROAD) ClearSlot(this);
|
if (this->type == VEH_ROAD) ClearSlot(this);
|
||||||
|
if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) {
|
||||||
|
Station *st = GetTargetAirportIfValid(this);
|
||||||
|
if (st != NULL) {
|
||||||
|
const AirportFTA *layout = st->Airport()->layout;
|
||||||
|
CLRBITS(st->airport_flags, layout[this->u.air.previous_pos].block | layout[this->u.air.pos].block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this->type != VEH_TRAIN || (this->type == VEH_TRAIN && (IsFrontEngine(this) || IsFreeWagon(this)))) {
|
if (this->type != VEH_TRAIN || (this->type == VEH_TRAIN && (IsFrontEngine(this) || IsFreeWagon(this)))) {
|
||||||
InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
|
InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile);
|
||||||
|
|
|
@ -369,7 +369,7 @@ CommandCost CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
|
||||||
if (!IsValidWaypointID(p1)) return CMD_ERROR;
|
if (!IsValidWaypointID(p1)) return CMD_ERROR;
|
||||||
|
|
||||||
wp = GetWaypoint(p1);
|
wp = GetWaypoint(p1);
|
||||||
if (!CheckTileOwnership(wp->xy)) return CMD_ERROR;
|
if (!IsTileType(wp->xy, MP_RAILWAY) || !CheckTileOwnership(wp->xy)) return CMD_ERROR;
|
||||||
|
|
||||||
if (!StrEmpty(_cmd_text)) {
|
if (!StrEmpty(_cmd_text)) {
|
||||||
if (!IsUniqueWaypointName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
|
if (!IsUniqueWaypointName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
|
||||||
|
|
Loading…
Reference in New Issue