Changeset - r6394:6d3f6c6d16b6
[Not reviewed]
master
0 6 0
celestar - 17 years ago 2007-03-29 13:52:34
celestar@openttd.org
(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)
6 files changed with 100 insertions and 52 deletions:
0 comments (0 inline, 0 general)
src/aircraft_cmd.cpp
Show inline comments
 
@@ -944,6 +944,42 @@ static byte GetAircraftFlyingAltitude(co
 
}
 

	
 
/**
 
 * 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.
 
 * @todo    De-mystify the cur_speed values for helicopter rotors.
 
@@ -954,17 +990,24 @@ static bool AircraftController(Vehicle *
 
{
 
	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;
 
	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 */
 
	amd = afc->MovingData(v->u.air.pos);
 

	
 
	int x = TileX(tile) * TILE_SIZE;
 
	int y = TileY(tile) * TILE_SIZE;
 

	
 
	/*  get airport moving data */
 
	const AirportFTAClass *afc = st->Airport();
 
	const AirportMovingData *amd = afc->MovingData(v->u.air.pos);
 

	
 
	/* Helicopter raise */
 
	if (amd->flag & AMED_HELI_RAISE) {
 
		Vehicle *u = v->next->next;
 
@@ -1470,42 +1513,6 @@ static void AircraftLandAirplane(Vehicle
 
	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)
src/airport.cpp
Show inline comments
 
@@ -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 
 
		case AT_HELIDEPOT:     return HeliDepot;
 
		case AT_INTERCON:      return IntercontinentalAirport;
 
		case AT_HELISTATION:   return HeliStation;
 
		case AT_DUMMY:         return DummyAirport;
 
	}
 
}
 

	
src/airport.h
Show inline comments
 
@@ -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
 
};
 

	
 

	
src/airport_movement.h
Show inline comments
 
@@ -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_
 

	
 
///////////////////////////////////////////////////////////////////////
 
/////**********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}};
src/station.h
Show inline comments
 
@@ -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);
 
		}
 

	
src/station_cmd.cpp
Show inline comments
 
@@ -1600,6 +1600,13 @@ static int32 RemoveAirport(Station *st, 
 

	
 
	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;
 

	
0 comments (0 inline, 0 general)