summaryrefslogtreecommitdiff
path: root/aircraft_cmd.c
diff options
context:
space:
mode:
authordominik <dominik@openttd.org>2005-01-05 13:15:27 +0000
committerdominik <dominik@openttd.org>2005-01-05 13:15:27 +0000
commit2543158c8e0d105148bc38522fba43aa3428d76a (patch)
tree90a8d181827d0a07756bf072c3b584160c36c7d3 /aircraft_cmd.c
parent61761cfab12d772a72e5cd2a17b7beb5a9a1ebf8 (diff)
downloadopenttd-2543158c8e0d105148bc38522fba43aa3428d76a.tar.xz
(svn r1385) Fix: [ 1095020 ] When all stations in an aircraft's order list are demolished, the plane eventually crashes (running out of fuel)
Diffstat (limited to 'aircraft_cmd.c')
-rw-r--r--aircraft_cmd.c92
1 files changed, 66 insertions, 26 deletions
diff --git a/aircraft_cmd.c b/aircraft_cmd.c
index 37c4e56d3..7da3de8f1 100644
--- a/aircraft_cmd.c
+++ b/aircraft_cmd.c
@@ -18,6 +18,7 @@ static bool AirportHasBlock(Vehicle *v, AirportFTA *current_pos, const AirportFT
static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *Airport);
static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *Airport);
static void AirportGoToNextPosition(Vehicle *v, const AirportFTAClass *Airport);
+static void CrashAirplane(Vehicle *v);
static void AircraftNextAirportPos_and_Order(Vehicle *v);
static byte GetAircraftFlyingAltitude(const Vehicle *v);
@@ -920,9 +921,20 @@ static void HandleCrashedAircraft(Vehicle *v)
{
uint32 r;
Station *st;
+ int z;
v->u.air.crashed_counter++;
+ st = DEREF_STATION(v->u.air.targetairport);
+
+ // make aircraft crash down to the ground
+ if ( st->airport_tile==0 && ((v->u.air.crashed_counter % 3) == 0) ) {
+ z = GetSlopeZ(v->x_pos, v->y_pos) + 1;
+ v->z_pos -= 1;
+ if (v->z_pos < z)
+ DoDeleteAircraft(v);
+ }
+
if (v->u.air.crashed_counter < 650) {
if (CHANCE16R(1,32,r)) {
v->direction = (v->direction+_crashed_aircraft_moddir[(r >> 16)&3]) & 7;
@@ -935,7 +947,6 @@ static void HandleCrashedAircraft(Vehicle *v)
EV_DEMOLISH);
}
} else if (v->u.air.crashed_counter >= 10000) {
- st = DEREF_STATION(v->u.air.targetairport);
// remove rubble of crashed airplane
// clear runway-in on all airports, set by crashing plane
@@ -989,13 +1000,25 @@ static void HandleAircraftSmoke(Vehicle *v)
}
}
+// returns true if the vehicle does have valid orders
+// false if none are valid
+static bool CheckForValidOrders(Vehicle *v)
+{
+ int i;
+ for (i = 0; i < v->num_orders; i++) {
+ if( v->schedule_ptr[i].type != OT_DUMMY )
+ return true;
+ }
+ return false;
+}
+
static void ProcessAircraftOrder(Vehicle *v)
{
Order order;
// OT_GOTO_DEPOT, OT_LOADING
- if (v->current_order.type >= OT_GOTO_DEPOT &&
- v->current_order.type <= OT_LOADING) {
+ if (v->current_order.type == OT_GOTO_DEPOT ||
+ v->current_order.type == OT_LOADING) {
if (v->current_order.type != OT_GOTO_DEPOT ||
!(v->current_order.flags & OF_UNLOAD))
return;
@@ -1031,6 +1054,9 @@ static void ProcessAircraftOrder(Vehicle *v)
v->u.air.targetairport = order.station;
}
+ if ( order.type == OT_DUMMY && !CheckForValidOrders(v))
+ CrashAirplane(v);
+
InvalidateVehicleOrderWidget(v);
}
@@ -1067,29 +1093,11 @@ static void HandleAircraftLoading(Vehicle *v, int mode)
InvalidateVehicleOrderWidget(v);
}
-static void MaybeCrashAirplane(Vehicle *v)
+static void CrashAirplane(Vehicle *v)
{
- Station *st;
- uint16 prob;
- int i;
uint16 amt;
-
- st = DEREF_STATION(v->u.air.targetairport);
-
- //FIXME -- MaybeCrashAirplane -> increase crashing chances of very modern airplanes on smaller than AT_METROPOLITAN airports
- prob = 0x10000 / 1500;
- if (st->airport_type == AT_SMALL && (AircraftVehInfo(v->engine_type)->subtype & 2) && !_cheats.no_jetcrash.value) {
- prob = 0x10000 / 20;
- }
-
- if ((uint16)Random() > prob)
- return;
-
- // Crash the airplane. Remove all goods stored at the station.
- for(i=0; i!=NUM_CARGO; i++) {
- st->goods[i].rating = 1;
- st->goods[i].waiting_acceptance &= ~0xFFF;
- }
+ Station *st;
+ StringID newsitem;
v->vehstatus |= VS_CRASHED;
v->u.air.crashed_counter = 0;
@@ -1104,17 +1112,49 @@ static void MaybeCrashAirplane(Vehicle *v)
v->cargo_count = 0;
v->next->cargo_count = 0,
+ st = DEREF_STATION(v->u.air.targetairport);
+ if(st->airport_tile==0) {
+ newsitem = STR_PLANE_CRASH_OUT_OF_FUEL;
+ } else {
+ SetDParam(1, st->index);
+ newsitem = STR_A034_PLANE_CRASH_DIE_IN_FIREBALL;
+ }
SetDParam(1, st->index);
- AddNewsItem(STR_A034_PLANE_CRASH_DIE_IN_FIREBALL,
+ AddNewsItem(newsitem,
NEWS_FLAGS(NM_THIN, NF_VIEWPORT|NF_VEHICLE, NT_ACCIDENT, 0),
v->index,
0);
- ModifyStationRatingAround(TILE_FROM_XY(v->x_pos, v->y_pos), v->owner, -160, 30);
SndPlayVehicleFx(SND_12_EXPLOSION, v);
}
+static void MaybeCrashAirplane(Vehicle *v)
+{
+ Station *st;
+ uint16 prob;
+ int i;
+
+ st = DEREF_STATION(v->u.air.targetairport);
+
+ //FIXME -- MaybeCrashAirplane -> increase crashing chances of very modern airplanes on smaller than AT_METROPOLITAN airports
+ prob = 0x10000 / 1500;
+ if (st->airport_type == AT_SMALL && (AircraftVehInfo(v->engine_type)->subtype & 2) && !_cheats.no_jetcrash.value) {
+ prob = 0x10000 / 20;
+ }
+
+ if ((uint16)Random() > prob)
+ return;
+
+ // Crash the airplane. Remove all goods stored at the station.
+ for(i=0; i!=NUM_CARGO; i++) {
+ st->goods[i].rating = 1;
+ st->goods[i].waiting_acceptance &= ~0xFFF;
+ }
+
+ CrashAirplane(v);
+}
+
// we've landed and just arrived at a terminal
static void AircraftEntersTerminal(Vehicle *v)
{