mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r9524) -Fix(FS#640,r8755): Implemented a "dummy" State Machine for stations who got their airport removed while there were still aircraft within the State Machine (and thus caused asserts)
This commit is contained in:
parent
386e298acd
commit
a1ab0d29fe
|
@ -943,6 +943,42 @@ static byte GetAircraftFlyingAltitude(const Vehicle *v)
|
|||
return base_altitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the entry point to an airport depending on direction which
|
||||
* the airport is being approached from. Each airport can have up to
|
||||
* four entry points for its approach system so that approaching
|
||||
* aircraft do not fly through each other or are forced to do 180
|
||||
* degree turns during the approach. The arrivals are grouped into
|
||||
* four sectors dependent on the DiagDirection from which the airport
|
||||
* is approached.
|
||||
*
|
||||
* @param v The vehicle that is approaching the airport
|
||||
* @param apc The Airport Class being approached.
|
||||
* @returns The index of the entry point
|
||||
*/
|
||||
static byte AircraftGetEntryPoint(const Vehicle *v, const AirportFTAClass *apc)
|
||||
{
|
||||
assert(v != NULL);
|
||||
assert(apc != NULL);
|
||||
|
||||
const Station *st = GetStation(v->u.air.targetairport);
|
||||
/* Make sure we don't go to 0,0 if the airport has been removed. */
|
||||
TileIndex tile = (st->airport_tile != 0) ? st->airport_tile : st->xy;
|
||||
|
||||
int delta_x = v->x_pos - TileX(tile) * TILE_SIZE;
|
||||
int delta_y = v->y_pos - TileY(tile) * TILE_SIZE;
|
||||
|
||||
DiagDirection dir;
|
||||
if (abs(delta_y) < abs(delta_x)) {
|
||||
/* We are northeast or southwest of the airport */
|
||||
dir = delta_x < 0 ? DIAGDIR_NE : DIAGDIR_SW;
|
||||
} else {
|
||||
/* We are northwest or southeast of the airport */
|
||||
dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE;
|
||||
}
|
||||
return apc->entry_points[dir];
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the movement of an aircraft. This function actually moves the vehicle
|
||||
* on the map and takes care of minor things like sound playback.
|
||||
|
@ -954,16 +990,23 @@ static bool AircraftController(Vehicle *v)
|
|||
{
|
||||
int count;
|
||||
const Station *st = GetStation(v->u.air.targetairport);
|
||||
const AirportFTAClass *afc = st->Airport();
|
||||
const AirportMovingData *amd;
|
||||
|
||||
/* prevent going to 0,0 if airport is deleted. */
|
||||
TileIndex tile = st->airport_tile;
|
||||
if (tile == 0) tile = st->xy;
|
||||
int x = TileX(tile) * TILE_SIZE;
|
||||
int y = TileY(tile) * TILE_SIZE;
|
||||
if (tile == 0) {
|
||||
tile = st->xy;
|
||||
|
||||
/* Jump into our "holding pattern" state machine if possible */
|
||||
if (v->u.air.pos >= afc->nofelements) v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc);
|
||||
}
|
||||
|
||||
/* get airport moving data */
|
||||
const AirportFTAClass *afc = st->Airport();
|
||||
const AirportMovingData *amd = afc->MovingData(v->u.air.pos);
|
||||
amd = afc->MovingData(v->u.air.pos);
|
||||
|
||||
int x = TileX(tile) * TILE_SIZE;
|
||||
int y = TileY(tile) * TILE_SIZE;
|
||||
|
||||
/* Helicopter raise */
|
||||
if (amd->flag & AMED_HELI_RAISE) {
|
||||
|
@ -1470,42 +1513,6 @@ static void AircraftLandAirplane(Vehicle *v)
|
|||
MaybeCrashAirplane(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the entry point to an airport depending on direction which
|
||||
* the airport is being approached from. Each airport can have up to
|
||||
* four entry points for its approach system so that approaching
|
||||
* aircraft do not fly through each other or are forced to do 180
|
||||
* degree turns during the approach. The arrivals are grouped into
|
||||
* four sectors dependent on the DiagDirection from which the airport
|
||||
* is approached.
|
||||
*
|
||||
* @param v The vehicle that is approaching the airport
|
||||
* @param apc The Airport Class being approached.
|
||||
* @returns The index of the entry point
|
||||
*/
|
||||
static byte AircraftGetEntryPoint(const Vehicle *v, const AirportFTAClass *apc)
|
||||
{
|
||||
assert(v != NULL);
|
||||
assert(apc != NULL);
|
||||
|
||||
const Station *st = GetStation(v->u.air.targetairport);
|
||||
/* Make sure we don't go to 0,0 if the airport has been removed. */
|
||||
TileIndex tile = (st->airport_tile != 0) ? st->airport_tile : st->xy;
|
||||
|
||||
int delta_x = v->x_pos - TileX(tile) * TILE_SIZE;
|
||||
int delta_y = v->y_pos - TileY(tile) * TILE_SIZE;
|
||||
|
||||
DiagDirection dir;
|
||||
if (abs(delta_y) < abs(delta_x)) {
|
||||
/* We are northeast or southwest of the airport */
|
||||
dir = delta_x < 0 ? DIAGDIR_NE : DIAGDIR_SW;
|
||||
} else {
|
||||
/* We are northwest or southeast of the airport */
|
||||
dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE;
|
||||
}
|
||||
return apc->entry_points[dir];
|
||||
}
|
||||
|
||||
|
||||
/** set the right pos when heading to other airports after takeoff */
|
||||
static void AircraftNextAirportPos_and_Order(Vehicle *v)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* - false: give a summarized report which only shows current and next position */
|
||||
//#define DEBUG_AIRPORT false
|
||||
|
||||
static AirportFTAClass *DummyAirport;
|
||||
static AirportFTAClass *CountryAirport;
|
||||
static AirportFTAClass *CityAirport;
|
||||
static AirportFTAClass *Oilrig;
|
||||
|
@ -34,6 +35,20 @@ static AirportFTAClass *HeliStation;
|
|||
|
||||
void InitializeAirports()
|
||||
{
|
||||
DummyAirport = new AirportFTAClass(
|
||||
_airport_moving_data_dummy,
|
||||
NULL,
|
||||
NULL,
|
||||
_airport_entries_dummy,
|
||||
AirportFTAClass::ALL,
|
||||
_airport_fta_dummy,
|
||||
NULL,
|
||||
0,
|
||||
0, 0,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
||||
CountryAirport = new AirportFTAClass(
|
||||
_airport_moving_data_country,
|
||||
_airport_terminal_country,
|
||||
|
@ -463,6 +478,7 @@ const AirportFTAClass *GetAirport(const byte airport_type)
|
|||
case AT_HELIDEPOT: return HeliDepot;
|
||||
case AT_INTERCON: return IntercontinentalAirport;
|
||||
case AT_HELISTATION: return HeliStation;
|
||||
case AT_DUMMY: return DummyAirport;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,16 +14,17 @@ enum {MAX_HEADINGS = 22};
|
|||
|
||||
// Airport types
|
||||
enum {
|
||||
AT_SMALL = 0,
|
||||
AT_LARGE = 1,
|
||||
AT_HELIPORT = 2,
|
||||
AT_METROPOLITAN = 3,
|
||||
AT_INTERNATIONAL = 4,
|
||||
AT_COMMUTER = 5,
|
||||
AT_HELIDEPOT = 6,
|
||||
AT_INTERCON = 7,
|
||||
AT_HELISTATION = 8,
|
||||
AT_OILRIG = 15
|
||||
AT_SMALL = 0,
|
||||
AT_LARGE = 1,
|
||||
AT_HELIPORT = 2,
|
||||
AT_METROPOLITAN = 3,
|
||||
AT_INTERNATIONAL = 4,
|
||||
AT_COMMUTER = 5,
|
||||
AT_HELIDEPOT = 6,
|
||||
AT_INTERCON = 7,
|
||||
AT_HELISTATION = 8,
|
||||
AT_OILRIG = 15,
|
||||
AT_DUMMY = 255
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,14 @@ struct AirportFTAbuildup {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/////*********Movement Positions on Airports********************///////
|
||||
|
||||
static const AirportMovingData _airport_moving_data_dummy[] = {
|
||||
{ 0, 0, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} },
|
||||
{ 0, 96, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} },
|
||||
{ 96, 96, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} },
|
||||
{ 96, 0, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} },
|
||||
};
|
||||
|
||||
// Country Airfield (small) 4x3
|
||||
static const AirportMovingData _airport_moving_data_country[22] = {
|
||||
{ 53, 3, AMED_EXACTPOS, {DIR_SE} }, // 00 In Hangar
|
||||
|
@ -376,6 +384,15 @@ static const AirportMovingData _airport_moving_data_oilrig[9] = {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/////**********Movement Machine on Airports*********************///////
|
||||
static const byte _airport_entries_dummy[] = {0, 1, 2, 3};
|
||||
static const AirportFTAbuildup _airport_fta_dummy[] = {
|
||||
{ 0, 0, 0, 3},
|
||||
{ 1, 0, 0, 0},
|
||||
{ 2, 0, 0, 1},
|
||||
{ 3, 0, 0, 2},
|
||||
{ MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
/* First element of terminals array tells us how many depots there are (to know size of array)
|
||||
* this may be changed later when airports are moved to external file */
|
||||
static const TileIndexDiffC _airport_depots_country[] = {{3, 0}};
|
||||
|
|
|
@ -118,7 +118,7 @@ struct Station {
|
|||
|
||||
const AirportFTAClass *Airport() const
|
||||
{
|
||||
assert(airport_tile != 0);
|
||||
if (airport_tile == 0) return GetAirport(AT_DUMMY);
|
||||
return GetAirport(airport_type);
|
||||
}
|
||||
|
||||
|
|
|
@ -1600,6 +1600,13 @@ static int32 RemoveAirport(Station *st, uint32 flags)
|
|||
|
||||
int32 cost = w * h * _price.remove_airport;
|
||||
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (!(v->type == VEH_AIRCRAFT && IsNormalAircraft(v))) continue;
|
||||
|
||||
if (v->u.air.targetairport == st->index && v->u.air.state != FLYING) return CMD_ERROR;
|
||||
}
|
||||
|
||||
BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
|
||||
if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
|
||||
|
||||
|
|
Loading…
Reference in New Issue