summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcelestar <celestar@openttd.org>2007-03-29 13:52:34 +0000
committercelestar <celestar@openttd.org>2007-03-29 13:52:34 +0000
commita1ab0d29fe5d5f0e5b90cc0908837f6b301d32f7 (patch)
tree37ea5878b75e7b5f0193b94c6d3c2aa3e1e9b498
parent386e298acd7855feb54d7b75ce0e3144db487649 (diff)
downloadopenttd-a1ab0d29fe5d5f0e5b90cc0908837f6b301d32f7.tar.xz
(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)
-rw-r--r--src/aircraft_cmd.cpp89
-rw-r--r--src/airport.cpp16
-rw-r--r--src/airport.h21
-rw-r--r--src/airport_movement.h17
-rw-r--r--src/station.h2
-rw-r--r--src/station_cmd.cpp7
6 files changed, 100 insertions, 52 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index 6bd9a4a1c..caa6bfa85 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -944,6 +944,42 @@ static byte GetAircraftFlyingAltitude(const Vehicle *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];
+}
+
+/**
* 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,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)
diff --git a/src/airport.cpp b/src/airport.cpp
index a2c59d89b..539687997 100644
--- a/src/airport.cpp
+++ b/src/airport.cpp
@@ -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;
}
}
diff --git a/src/airport.h b/src/airport.h
index 27af62e62..1113f03a0 100644
--- a/src/airport.h
+++ b/src/airport.h
@@ -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
};
diff --git a/src/airport_movement.h b/src/airport_movement.h
index 53d6174d5..02e5fef26 100644
--- a/src/airport_movement.h
+++ b/src/airport_movement.h
@@ -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}};
diff --git a/src/station.h b/src/station.h
index 3a4ef31cf..6bd6820d1 100644
--- a/src/station.h
+++ b/src/station.h
@@ -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);
}
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 6341fd7df..00f77d44f 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -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;