From 2543158c8e0d105148bc38522fba43aa3428d76a Mon Sep 17 00:00:00 2001 From: dominik Date: Wed, 5 Jan 2005 13:15:27 +0000 Subject: (svn r1385) Fix: [ 1095020 ] When all stations in an aircraft's order list are demolished, the plane eventually crashes (running out of fuel) --- aircraft_cmd.c | 92 +++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 26 deletions(-) (limited to 'aircraft_cmd.c') 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) { -- cgit v1.2.3-54-g00ecf