(svn r8973) -Feature/Codechange: Changed the internal unit for aircraft velocities to from 8mph to 1km/h (peter1138), also give aircraft realsitic velocities (so that 1km/h is 1km/h independent of vehicle type) (peter1138). Introduce a flag to reduce aircraft speed in holding patterns to some realistic velocity. Use this flag for the city airport for the time being and make use of the different entry points for this airport type.

pull/155/head
celestar 17 years ago
parent f39b7b0019
commit 5828617a07

@ -862,21 +862,35 @@ static void PlayAircraftSound(const Vehicle* v)
}
}
/** Special velocities for aircraft
/**
* Special velocities for aircraft
*/
enum AircraftSpeedLimits {
SPEED_LIMIT_NONE = 0, ///< No environmental speed limit. Speed limit is type dependent
SPEED_LIMIT_TAXI = 12, ///< Maximum speed of an aircraft while taxiing
SPEED_LIMIT_BROKEN = 27, ///< Maximum speed of an aircraft that is broken
SPEED_LIMIT_TAXI = 50, ///< Maximum speed of an aircraft while taxiing
SPEED_LIMIT_APPROACH = 230, ///< Maximum speed of an aircraft on finals
SPEED_LIMIT_BROKEN = 320, ///< Maximum speed of an aircraft that is broken
SPEED_LIMIT_HOLD = 425, ///< Maximum speed of an aircraft that flies the holding pattern
SPEED_LIMIT_NONE = 0xFFFF ///< No environmental speed limit. Speed limit is type dependent
};
static bool UpdateAircraftSpeed(Vehicle *v, uint speed_limit)
/**
* Sets the new speed for an aircraft
* @param v The vehicle for which the speed should be obtained
* @param speed_limit The maximum speed the vehicle may have.
* @param hard_limit If true, the limit is directly enforced, otherwise the plane is slowed down gradually
* @return The number of position updates needed within the tick
*/
static int UpdateAircraftSpeed(Vehicle *v, uint speed_limit = SPEED_LIMIT_NONE, bool hard_limit = true)
{
uint spd = v->acceleration * 2;
uint spd = v->acceleration * 16;
byte t;
speed_limit = min(speed_limit, v->max_speed);
v->subspeed = (t=v->subspeed) + (byte)spd;
if (speed_limit == SPEED_LIMIT_NONE) speed_limit = v->max_speed;
if (!hard_limit && v->cur_speed > speed_limit) speed_limit = v->cur_speed - (v->cur_speed / 48);
spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), speed_limit);
/* adjust speed for broken vehicles */
@ -891,13 +905,9 @@ static bool UpdateAircraftSpeed(Vehicle *v, uint speed_limit)
if (!(v->direction & 1)) spd = spd * 3 / 4;
if (spd == 0) return false;
if ((byte)++spd == 0) return true;
v->progress = (t = v->progress) - (byte)spd;
return t < v->progress;
spd += v->progress;
v->progress = (byte)spd;
return spd >> 8;
}
/**
@ -922,20 +932,28 @@ static byte GetAircraftFlyingAltitude(const Vehicle *v)
case DIR_NE:
case DIR_E:
case DIR_SE:
base_altitude += 15;
base_altitude += 10;
break;
default: break;
}
/* Make faster planes fly higher so that they can overtake slower ones */
base_altitude += min(30 * (v->max_speed / 37), 90);
base_altitude += min(20 * (v->max_speed / 200), 90);
return base_altitude;
}
/**
* 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.
* @param v The vehicle that is moved. Must be the first vehicle of the chain
* @return Whether the position requested by the State Machine has been reached
*/
static bool AircraftController(Vehicle *v)
{
int count;
const Station *st = GetStation(v->u.air.targetairport);
/* prevent going to 0,0 if airport is deleted. */
@ -958,7 +976,8 @@ static bool AircraftController(Vehicle *v)
if (--u->cur_speed == 32) SndPlayVehicleFx(SND_18_HELICOPTER, v);
} else {
u->cur_speed = 32;
if (UpdateAircraftSpeed(v, SPEED_LIMIT_NONE)) {
count = UpdateAircraftSpeed(v);
if (count > 0) {
v->tile = 0;
/* Reached altitude? */
@ -966,7 +985,7 @@ static bool AircraftController(Vehicle *v)
v->cur_speed = 0;
return true;
}
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos+1);
SetAircraftPosition(v, v->x_pos, v->y_pos, min(v->z_pos + count, 184));
}
}
return false;
@ -974,7 +993,8 @@ static bool AircraftController(Vehicle *v)
/* Helicopter landing. */
if (amd->flag & AMED_HELI_LOWER) {
if (UpdateAircraftSpeed(v, SPEED_LIMIT_NONE)) {
count = UpdateAircraftSpeed(v);
if (count > 0) {
if (st->airport_tile == 0) {
/* FIXME - AircraftController -> if station no longer exists, do not land
* helicopter will circle until sign disappears, then go to next order
@ -988,7 +1008,7 @@ static bool AircraftController(Vehicle *v)
v->tile = st->airport_tile;
/* Find altitude of landing position. */
uint z = GetSlopeZ(x, y) + 1 + afc->delta_z;
int z = GetSlopeZ(x, y) + 1 + afc->delta_z;
if (z == v->z_pos) {
Vehicle *u = v->next->next;
@ -997,9 +1017,9 @@ static bool AircraftController(Vehicle *v)
if (u->cur_speed >= 80) return true;
u->cur_speed += 4;
} else if (v->z_pos > z) {
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos-1);
SetAircraftPosition(v, v->x_pos, v->y_pos, max(v->z_pos - count, z));
} else {
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos+1);
SetAircraftPosition(v, v->x_pos, v->y_pos, min(v->z_pos + count, z));
}
}
return false;
@ -1009,8 +1029,7 @@ static bool AircraftController(Vehicle *v)
uint dist = myabs(x + amd->x - v->x_pos) + myabs(y + amd->y - v->y_pos);
/* Need exact position? */
if (!(amd->flag & AMED_EXACTPOS) && dist <= (amd->flag & AMED_SLOWTURN ? 8U : 4U))
return true;
if (!(amd->flag & AMED_EXACTPOS) && dist <= (amd->flag & AMED_SLOWTURN ? 8U : 4U)) return true;
/* At final pos? */
if (dist == 0) {
@ -1032,71 +1051,82 @@ static bool AircraftController(Vehicle *v)
return false;
}
if (!UpdateAircraftSpeed(v, ((amd->flag & AMED_NOSPDCLAMP) == 0) ? SPEED_LIMIT_TAXI : SPEED_LIMIT_NONE)) return false;
uint speed_limit = SPEED_LIMIT_TAXI;
bool hard_limit = true;
if (amd->flag & AMED_NOSPDCLAMP) speed_limit = SPEED_LIMIT_NONE;
if (amd->flag & AMED_HOLD) { speed_limit = SPEED_LIMIT_HOLD; hard_limit = false; }
if (amd->flag & AMED_LAND) { speed_limit = SPEED_LIMIT_APPROACH; hard_limit = false; }
if (amd->flag & AMED_BRAKE) { speed_limit = SPEED_LIMIT_TAXI; hard_limit = false; }
count = UpdateAircraftSpeed(v, speed_limit, hard_limit);
if (count == 0) return false;
if (v->load_unload_time_rem != 0) v->load_unload_time_rem--;
/* Turn. Do it slowly if in the air. */
Direction newdir = GetDirectionTowards(v, x + amd->x, y + amd->y);
if (newdir != v->direction) {
if (amd->flag & AMED_SLOWTURN) {
if (v->load_unload_time_rem == 0) v->load_unload_time_rem = 8;
v->direction = newdir;
} else {
v->cur_speed >>= 1;
do {
/* Turn. Do it slowly if in the air. */
Direction newdir = GetDirectionTowards(v, x + amd->x, y + amd->y);
if (newdir != v->direction) {
v->direction = newdir;
if (amd->flag & AMED_SLOWTURN) {
if (v->load_unload_time_rem == 0) v->load_unload_time_rem = 8;
} else {
v->cur_speed >>= 1;
}
}
}
/* Move vehicle. */
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->tile = gp.new_tile;
/* Move vehicle. */
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
v->tile = gp.new_tile;
/* If vehicle is in the air, use tile coordinate 0. */
// if (amd->flag & (AMED_TAKEOFF | AMED_SLOWTURN | AMED_LAND)) v->tile = 0;
/* If vehicle is in the air, use tile coordinate 0. */
if (amd->flag & (AMED_TAKEOFF | AMED_SLOWTURN | AMED_LAND)) v->tile = 0;
/* Adjust Z for land or takeoff? */
uint z = v->z_pos;
/* Adjust Z for land or takeoff? */
uint z = v->z_pos;
if (amd->flag & AMED_TAKEOFF) {
z = min(z + 2, GetAircraftFlyingAltitude(v));
}
if (amd->flag & AMED_TAKEOFF) {
z = min(z + 2, GetAircraftFlyingAltitude(v));
}
if ((amd->flag & AMED_HOLD) && (z > 150)) z--;
if (amd->flag & AMED_LAND) {
if (st->airport_tile == 0) {
v->u.air.state = FLYING;
AircraftNextAirportPos_and_Order(v);
/* get aircraft back on running altitude */
SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v));
return false;
}
if (amd->flag & AMED_LAND) {
if (st->airport_tile == 0) {
/* Airport has been removed, abort the landing procedure */
v->u.air.state = FLYING;
AircraftNextAirportPos_and_Order(v);
/* get aircraft back on running altitude */
SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v));
continue;
}
uint curz = GetSlopeZ(x, y) + 1;
uint curz = GetSlopeZ(x, y) + 1;
if (curz > z) {
z++;
} else {
int t = max(1U, dist - 4);
if (curz > z) {
z++;
} else {
int t = max(1U, dist - 4);
z -= ((z - curz) + t - 1) / t;
if (z < curz) z = curz;
z -= ((z - curz) + t - 1) / t;
if (z < curz) z = curz;
}
}
}
/* We've landed. Decrase speed when we're reaching end of runway. */
if (amd->flag & AMED_BRAKE) {
uint curz = GetSlopeZ(x, y) + 1;
/* We've landed. Decrase speed when we're reaching end of runway. */
if (amd->flag & AMED_BRAKE) {
uint curz = GetSlopeZ(x, y) + 1;
if (z > curz) {
z--;
} else if (z < curz) {
z++;
}
if (z > curz) {
z--;
} else if (z < curz) {
z++;
}
if (dist < 64 && v->cur_speed > 12) v->cur_speed -= 4;
}
}
SetAircraftPosition(v, gp.x, gp.y, z);
SetAircraftPosition(v, gp.x, gp.y, z);
} while (--count != 0);
return false;
}
@ -2067,7 +2097,7 @@ void Aircraft_Tick(Vehicle *v)
AgeAircraftCargo(v);
for (uint i = 0; i != 6; i++) {
for (uint i = 0; i != 2; i++) {
AircraftEventHandler(v, i);
if (v->type != VEH_Aircraft) // In case it was deleted
break;

@ -84,7 +84,7 @@ static void AircraftDetailsWndProc(Window *w, WindowEvent *e)
/* Draw max speed */
{
SetDParam(0, v->max_speed * 128 / 10);
SetDParam(0, v->max_speed * 10 / 16);
DrawString(2, 25, STR_A00E_MAX_SPEED, 0);
}
@ -263,14 +263,14 @@ static void AircraftViewWndProc(Window *w, WindowEvent *e)
switch (v->current_order.type) {
case OT_GOTO_STATION: {
SetDParam(0, v->current_order.dest);
SetDParam(1, v->cur_speed * 8);
SetDParam(1, v->cur_speed * 10 / 16);
str = STR_HEADING_FOR_STATION + _patches.vehicle_speed;
} break;
case OT_GOTO_DEPOT: {
/* Aircrafts always go to a station, even if you say depot */
SetDParam(0, v->current_order.dest);
SetDParam(1, v->cur_speed * 8);
SetDParam(1, v->cur_speed * 10 / 16);
if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
str = STR_HEADING_FOR_HANGAR + _patches.vehicle_speed;
} else {
@ -285,7 +285,7 @@ static void AircraftViewWndProc(Window *w, WindowEvent *e)
default:
if (v->num_orders == 0) {
str = STR_NO_ORDERS + _patches.vehicle_speed;
SetDParam(0, v->cur_speed * 8);
SetDParam(0, v->cur_speed * 10 / 16);
} else {
str = STR_EMPTY;
}

@ -36,6 +36,7 @@ enum {
AMED_BRAKE = 1 << 5,
AMED_HELI_RAISE = 1 << 6,
AMED_HELI_LOWER = 1 << 7,
AMED_HOLD = 1 << 8
};
/* Movement States on Airports (headings target) */
@ -114,7 +115,7 @@ static const uint64
typedef struct AirportMovingData {
int16 x;
int16 y;
byte flag;
uint16 flag;
DirectionByte direction;
} AirportMovingData;

@ -86,7 +86,7 @@ static const AirportMovingData _airport_moving_data_commuter[37] = {
};
// City Airport (large) 6x6
static const AirportMovingData _airport_moving_data_town[25] = {
static const AirportMovingData _airport_moving_data_town[] = {
{ 85, 3, AMED_EXACTPOS, {DIR_SE} }, // 00 In Hangar
{ 85, 27, 0, {DIR_N} }, // 01 Taxi to right outside depot
{ 26, 41, AMED_EXACTPOS, {DIR_SW} }, // 02 Terminal 1
@ -100,18 +100,23 @@ static const AirportMovingData _airport_moving_data_town[25] = {
{ 89, 85, AMED_EXACTPOS, {DIR_NE} }, // 10 Taxi to start of runway (takeoff)
{ 3, 85, AMED_NOSPDCLAMP, {DIR_N} }, // 11 Accelerate to end of runway
{ -79, 85, AMED_NOSPDCLAMP | AMED_TAKEOFF, {DIR_N} }, // 12 Take off
{ 177, 85, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 13 Fly to landing position in air
{ 89, 85, AMED_NOSPDCLAMP | AMED_LAND, {DIR_N} }, // 14 Going down for land
{ 3, 85, AMED_NOSPDCLAMP | AMED_BRAKE, {DIR_N} }, // 15 Just landed, brake until end of runway
{ 20, 87, 0, {DIR_N} }, // 16 Just landed, turn around and taxi 1 square
{ 177, 87, AMED_HOLD | AMED_SLOWTURN, {DIR_N} }, // 13 Fly to landing position in air
{ 89, 87, AMED_HOLD | AMED_LAND, {DIR_N} }, // 14 Going down for land
{ 20, 87, AMED_NOSPDCLAMP | AMED_BRAKE, {DIR_N} }, // 15 Just landed, brake until end of runway
{ 20, 87, 0, {DIR_N} }, // 16 Just landed, turn around and taxi 1 square /* NOT USED */
{ 36, 71, 0, {DIR_N} }, // 17 Taxi from runway to crossing
{ -31, 193, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 18 Fly around waiting for a landing spot (north-east)
{ 1, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 19 Fly around waiting for a landing spot (north-west)
{ 257, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 20 Fly around waiting for a landing spot (south-west)
{ 273, 49, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 21 Fly around waiting for a landing spot (south)
{ 160, 87, AMED_HOLD | AMED_SLOWTURN, {DIR_N} }, // 18 Fly around waiting for a landing spot (north-east)
{ 140, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 19 Final approach fix
{ 257, 1, AMED_HOLD | AMED_SLOWTURN, {DIR_N} }, // 20 Fly around waiting for a landing spot (south-west)
{ 273, 49, AMED_HOLD | AMED_SLOWTURN, {DIR_N} }, // 21 Fly around waiting for a landing spot (south)
{ 44, 63, AMED_HELI_RAISE, {DIR_N} }, // 22 Helicopter takeoff
{ 28, 74, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 23 In position above landing spot helicopter
{ 28, 74, AMED_HELI_LOWER, {DIR_N} }, // 24 Helicopter landing
{ 145, 1, AMED_HOLD | AMED_SLOWTURN, {DIR_N} }, // 25 Fly around waiting for a landing spot (north-west)
{ -32, 1, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 26 Initial approach fix (north)
{ 300, -48, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 27 Initial approach fix (south)
{ 140, -48, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 28 Intermediadate Approach fix (south), IAF (west)
{ -32, 120, AMED_NOSPDCLAMP | AMED_SLOWTURN, {DIR_N} }, // 29 Initial approach fix (east)
};
// Metropolitan Airport (metropolitan) - 2 runways
@ -458,7 +463,7 @@ static const AirportFTAbuildup _airport_fta_commuter[] = {
static const TileIndexDiffC _airport_depots_city[] = { { 5, 0 } };
static const byte _airport_terminal_city[] = { 1, 3 };
static const byte _airport_entries_city[] = {19, 19, 19, 19};
static const byte _airport_entries_city[] = {26, 29, 27, 28};
static const AirportFTAbuildup _airport_fta_city[] = {
{ 0, HANGAR, NOTHING_block, 1 }, { 0, TAKEOFF, OUT_WAY_block, 1 }, { 0, 0, 0, 1 },
{ 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, 0, 0, 7 }, // for all else, go to 7
@ -477,11 +482,11 @@ static const AirportFTAbuildup _airport_fta_city[] = {
// landing
{ 13, FLYING, NOTHING_block, 18 }, { 13, LANDING, 0, 14 }, { 13, HELILANDING, 0, 23 },
{ 14, LANDING, RUNWAY_IN_OUT_block, 15 },
{ 15, 0, RUNWAY_IN_OUT_block, 16 },
{ 16, 0, RUNWAY_IN_OUT_block, 17 },
{ 15, 0, RUNWAY_IN_OUT_block, 17 },
{ 16, 0, RUNWAY_IN_OUT_block, 17 }, /* not used, left for compatibility */
{ 17, ENDLANDING, IN_WAY_block, 7 },
// In Air
{ 18, 0, NOTHING_block, 19 },
{ 18, 0, NOTHING_block, 25 },
{ 19, 0, NOTHING_block, 20 },
{ 20, 0, NOTHING_block, 21 },
{ 21, 0, NOTHING_block, 13 },
@ -489,6 +494,11 @@ static const AirportFTAbuildup _airport_fta_city[] = {
{ 22, HELITAKEOFF, NOTHING_block, 0 },
{ 23, HELILANDING, IN_WAY_block, 24 },
{ 24, HELIENDLANDING, IN_WAY_block, 17 },
{ 25, 0, NOTHING_block, 20},
{ 26, 0, NOTHING_block, 19},
{ 27, 0, NOTHING_block, 28},
{ 28, 0, NOTHING_block, 19},
{ 29, 0, NOTHING_block, 26},
{ MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE
};

@ -494,7 +494,7 @@ static int DrawAircraftPurchaseInfo(int x, int y, EngineID engine_number, const
/* Purchase cost - Max speed */
SetDParam(0, avi->base_cost * (_price.aircraft_base>>3)>>5);
SetDParam(1, avi->max_speed * 8);
SetDParam(1, avi->max_speed * 10 / 16);
DrawString(x, y, STR_PURCHASE_INFO_COST_SPEED, 0);
y += 10;

@ -68,7 +68,7 @@ typedef struct AircraftVehicleInfo {
byte subtype;
SoundFxByte sfx;
byte acceleration;
byte max_speed;
uint16 max_speed;
byte mail_capacity;
uint16 passenger_capacity;
} AircraftVehicleInfo;

@ -175,7 +175,7 @@ static void DrawAircraftEngineInfo(EngineID engine, int x, int y, int maxw)
{
const AircraftVehicleInfo *avi = AircraftVehInfo(engine);
SetDParam(0, (_price.aircraft_base >> 3) * avi->base_cost >> 5);
SetDParam(1, avi->max_speed * 8);
SetDParam(1, avi->max_speed);
SetDParam(2, avi->passenger_capacity);
SetDParam(3, avi->mail_capacity);
SetDParam(4, avi->running_cost * _price.aircraft_running >> 8);

@ -781,12 +781,12 @@ static bool AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, byte *
FOR_EACH_OBJECT avi[i].base_cost = grf_load_byte(&buf); // ?? is it base_cost?
break;
case 0x0C: /* Speed (1 unit is 8 mph) */
FOR_EACH_OBJECT avi[i].max_speed = grf_load_byte(&buf);
case 0x0C: /* Speed (1 unit is 8 mph, we translate to 1 unit is 1 km/h) */
FOR_EACH_OBJECT avi[i].max_speed = (grf_load_byte(&buf) * 129) / 10;
break;
case 0x0D: /* Acceleration */
FOR_EACH_OBJECT avi[i].acceleration = grf_load_byte(&buf);
FOR_EACH_OBJECT avi[i].acceleration = (grf_load_byte(&buf) * 129) / 10;
break;
case 0x0E: /* Running cost factor */

@ -40,6 +40,7 @@
#include "fileio.h"
#include "hal.h"
#include "airport.h"
#include "aircraft.h"
#include "console.h"
#include "screenshot.h"
#include "network/network.h"
@ -1818,6 +1819,20 @@ bool AfterLoadGame(void)
}
}
if (CheckSavegameVersion(50)) {
Vehicle *v;
/* Aircraft units changed from 8 mph to 1 km/h */
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_Aircraft && v->subtype <= AIR_AIRCRAFT) {
const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type);
v->cur_speed *= 129;
v->cur_speed /= 10;
v->max_speed = avi->max_speed;
v->acceleration = avi->acceleration;
}
}
}
if (CheckSavegameVersion(49)) FOR_ALL_PLAYERS(p) p->face = ConvertFromOldPlayerFace(p->face);
return true;

@ -28,7 +28,7 @@
#include "variables.h"
#include <setjmp.h>
extern const uint16 SAVEGAME_VERSION = 49;
extern const uint16 SAVEGAME_VERSION = 50;
uint16 _sl_version; ///< the major savegame version identifier
byte _sl_minor_version; ///< the minor savegame version, DO NOT USE!

@ -519,7 +519,7 @@ const ShipVehicleInfo orig_ship_vehicle_info[NUM_SHIP_ENGINES] = {
* @param h mail_capacity
* @param i passenger_capacity
*/
#define AVI(a, b, c, d, e, f, g, h, i) { a, b, c, d, {e}, f, g, h, i }
#define AVI(a, b, c, d, e, f, g, h, i) { a, b, c, d, {e}, f, (g * 129) / 10, h, i }
#define H AIR_HELI
#define P AIR_CTOL
#define J AIR_CTOL | AIR_FAST

Loading…
Cancel
Save