|
@@ -278,25 +278,25 @@ CommandCost CmdBuildAircraft(TileIndex t
|
|
|
|
|
|
/* Prevent building aircraft types at places which can't handle them */
|
|
|
if (!CanAircraftUseStation(p1, tile)) return CMD_ERROR;
|
|
|
|
|
|
/* Allocate 2 or 3 vehicle structs, depending on type
|
|
|
* vl[0] = aircraft, vl[1] = shadow, [vl[2] = rotor] */
|
|
|
Vehicle *vl[3];
|
|
|
if (!Vehicle::AllocateList(vl, avi->subtype & AIR_CTOL ? 2 : 3)) {
|
|
|
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
|
|
}
|
|
|
|
|
|
UnitID unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_AIRCRAFT);
|
|
|
if (unit_num > _settings.vehicle.max_aircraft)
|
|
|
if (unit_num > _settings_game.vehicle.max_aircraft)
|
|
|
return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME);
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
Vehicle *v = vl[0]; // aircraft
|
|
|
Vehicle *u = vl[1]; // shadow
|
|
|
|
|
|
v = new (v) Aircraft();
|
|
|
u = new (u) Aircraft();
|
|
|
v->unitnumber = unit_num;
|
|
|
v->direction = DIR_SE;
|
|
|
|
|
|
v->owner = u->owner = _current_player;
|
|
@@ -395,25 +395,25 @@ CommandCost CmdBuildAircraft(TileIndex t
|
|
|
if (st->airport_tile + ToTileIndexDiff(apc->airport_depots[i]) == tile) {
|
|
|
assert(apc->layout[i].heading == HANGAR);
|
|
|
v->u.air.pos = apc->layout[i].position;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
v->u.air.state = HANGAR;
|
|
|
v->u.air.previous_pos = v->u.air.pos;
|
|
|
v->u.air.targetairport = GetStationIndex(tile);
|
|
|
v->SetNext(u);
|
|
|
|
|
|
v->service_interval = _settings.vehicle.servint_aircraft;
|
|
|
v->service_interval = _settings_game.vehicle.servint_aircraft;
|
|
|
|
|
|
v->date_of_last_service = _date;
|
|
|
v->build_year = u->build_year = _cur_year;
|
|
|
|
|
|
v->cur_image = u->cur_image = 0xEA0;
|
|
|
|
|
|
v->random_bits = VehicleRandomBits();
|
|
|
u->random_bits = VehicleRandomBits();
|
|
|
|
|
|
v->vehicle_flags = 0;
|
|
|
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
|
|
|
|
|
@@ -655,25 +655,25 @@ CommandCost CmdRefitAircraft(TileIndex t
|
|
|
v->cargo_subtype = new_subtype;
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindowClassesData(WC_AIRCRAFT_LIST, 0);
|
|
|
}
|
|
|
|
|
|
return cost;
|
|
|
}
|
|
|
|
|
|
|
|
|
static void CheckIfAircraftNeedsService(Vehicle *v)
|
|
|
{
|
|
|
if (_settings.vehicle.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return;
|
|
|
if (_settings_game.vehicle.servint_aircraft == 0 || !v->NeedsAutomaticServicing()) return;
|
|
|
if (v->IsInDepot()) {
|
|
|
VehicleServiceInDepot(v);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const Station *st = GetStation(v->current_order.GetDestination());
|
|
|
/* only goto depot if the target airport has terminals (eg. it is airport) */
|
|
|
if (st->IsValid() && st->airport_tile != 0 && st->Airport()->terminals != NULL) {
|
|
|
// printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index);
|
|
|
// v->u.air.targetairport = st->index;
|
|
|
v->current_order.MakeGoToDepot(st->index, ODTFB_SERVICE);
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
@@ -875,59 +875,59 @@ enum AircraftSpeedLimits {
|
|
|
* @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 * 16;
|
|
|
byte t;
|
|
|
|
|
|
/* Adjust speed limits by plane speed factor to prevent taxiing
|
|
|
* and take-off speeds being too low. */
|
|
|
speed_limit *= _settings.vehicle.plane_speed;
|
|
|
speed_limit *= _settings_game.vehicle.plane_speed;
|
|
|
|
|
|
if (v->u.air.cached_max_speed < speed_limit) {
|
|
|
if (v->cur_speed < speed_limit) hard_limit = false;
|
|
|
speed_limit = v->u.air.cached_max_speed;
|
|
|
}
|
|
|
|
|
|
speed_limit = min(speed_limit, v->max_speed);
|
|
|
|
|
|
v->subspeed = (t=v->subspeed) + (byte)spd;
|
|
|
|
|
|
/* Aircraft's current speed is used twice so that very fast planes are
|
|
|
* forced to slow down rapidly in the short distance needed. The magic
|
|
|
* value 16384 was determined to give similar results to the old speed/48
|
|
|
* method at slower speeds. This also results in less reduction at slow
|
|
|
* speeds to that aircraft do not get to taxi speed straight after
|
|
|
* touchdown. */
|
|
|
if (!hard_limit && v->cur_speed > speed_limit) {
|
|
|
speed_limit = v->cur_speed - max(1, ((v->cur_speed * v->cur_speed) / 16384) / _settings.vehicle.plane_speed);
|
|
|
speed_limit = v->cur_speed - max(1, ((v->cur_speed * v->cur_speed) / 16384) / _settings_game.vehicle.plane_speed);
|
|
|
}
|
|
|
|
|
|
spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), speed_limit);
|
|
|
|
|
|
/* adjust speed for broken vehicles */
|
|
|
if (v->vehstatus & VS_AIRCRAFT_BROKEN) spd = min(spd, SPEED_LIMIT_BROKEN);
|
|
|
|
|
|
/* updates statusbar only if speed have changed to save CPU time */
|
|
|
if (spd != v->cur_speed) {
|
|
|
v->cur_speed = spd;
|
|
|
if (_settings.gui.vehicle_speed)
|
|
|
if (_settings_client.gui.vehicle_speed)
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
}
|
|
|
|
|
|
/* Adjust distance moved by plane speed setting */
|
|
|
if (_settings.vehicle.plane_speed > 1) spd /= _settings.vehicle.plane_speed;
|
|
|
if (_settings_game.vehicle.plane_speed > 1) spd /= _settings_game.vehicle.plane_speed;
|
|
|
|
|
|
if (!(v->direction & 1)) spd = spd * 3 / 4;
|
|
|
|
|
|
spd += v->progress;
|
|
|
v->progress = (byte)spd;
|
|
|
return spd >> 8;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Gets the cruise altitude of an aircraft.
|
|
|
* The cruise altitude is determined by the velocity of the vehicle
|
|
|
* and the direction it is moving
|
|
@@ -1590,25 +1590,25 @@ static void AircraftEventHandler_InHanga
|
|
|
AircraftLeaveHangar(v);
|
|
|
AirportMove(v, apc);
|
|
|
}
|
|
|
|
|
|
/** At one of the Airport's Terminals */
|
|
|
static void AircraftEventHandler_AtTerminal(Vehicle *v, const AirportFTAClass *apc)
|
|
|
{
|
|
|
/* if we just arrived, execute EnterTerminal first */
|
|
|
if (v->u.air.previous_pos != v->u.air.pos) {
|
|
|
AircraftEventHandler_EnterTerminal(v, apc);
|
|
|
/* on an airport with helipads, a helicopter will always land there
|
|
|
* and get serviced at the same time - patch setting */
|
|
|
if (_settings.order.serviceathelipad) {
|
|
|
if (_settings_game.order.serviceathelipad) {
|
|
|
if (v->subtype == AIR_HELICOPTER && apc->helipads != NULL) {
|
|
|
/* an exerpt of ServiceAircraft, without the invisibility stuff */
|
|
|
v->date_of_last_service = _date;
|
|
|
v->breakdowns_since_last_service = 0;
|
|
|
v->reliability = GetEngine(v->engine_type)->reliability;
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
}
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (!v->current_order.IsValid()) return;
|