|
@@ -812,70 +812,69 @@ static void SetAircraftPosition(Vehicle
|
|
|
safe_y = clamp(y - 1, 0, MapMaxY() * TILE_SIZE);
|
|
|
u->x_pos = x;
|
|
|
u->y_pos = y - ((v->z_pos-GetSlopeZ(safe_x, safe_y)) >> 3);;
|
|
|
|
|
|
safe_y = clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
|
|
|
u->z_pos = GetSlopeZ(safe_x, safe_y);
|
|
|
u->cur_image = v->cur_image;
|
|
|
|
|
|
BeginVehicleMove(u);
|
|
|
VehiclePositionChanged(u);
|
|
|
EndVehicleMove(u);
|
|
|
|
|
|
u = u->next;
|
|
|
if (u != NULL) {
|
|
|
u->x_pos = x;
|
|
|
u->y_pos = y;
|
|
|
u->z_pos = z + 5;
|
|
|
|
|
|
BeginVehicleMove(u);
|
|
|
VehiclePositionChanged(u);
|
|
|
EndVehicleMove(u);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void ServiceAircraft(Vehicle *v)
|
|
|
/** Handle Aircraft specific tasks when a an Aircraft enters a hangar
|
|
|
* Made inline because it's only called from one location (VehicleEnterDepot)
|
|
|
* Can't be moved to vehicle.c because it calls static Aircraft specific functions
|
|
|
* @param *v Vehicle that enters the hangar
|
|
|
*/
|
|
|
inline void HandleAircraftEnterHangar(Vehicle *v)
|
|
|
{
|
|
|
Vehicle *u;
|
|
|
|
|
|
v->cur_speed = 0;
|
|
|
v->subspeed = 0;
|
|
|
v->progress = 0;
|
|
|
v->vehstatus |= VS_HIDDEN;
|
|
|
|
|
|
u = v->next;
|
|
|
u->vehstatus |= VS_HIDDEN;
|
|
|
u = u->next;
|
|
|
if (u != NULL) {
|
|
|
u->vehstatus |= VS_HIDDEN;
|
|
|
u->cur_speed = 0;
|
|
|
}
|
|
|
|
|
|
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
|
|
|
VehicleServiceInDepot(v);
|
|
|
InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
|
|
|
}
|
|
|
|
|
|
static void PlayAircraftSound(const Vehicle* v)
|
|
|
{
|
|
|
if (!PlayVehicleSound(v, VSE_START)) {
|
|
|
SndPlayVehicleFx(AircraftVehInfo(v->engine_type)->sfx, v);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static bool UpdateAircraftSpeed(Vehicle *v)
|
|
|
{
|
|
|
uint spd = v->acceleration * 2;
|
|
|
byte t;
|
|
|
|
|
|
v->subspeed = (t=v->subspeed) + (byte)spd;
|
|
|
spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), v->max_speed);
|
|
|
|
|
|
// adjust speed for broken vehicles
|
|
|
if (v->vehstatus & VS_AIRCRAFT_BROKEN) spd = min(spd, 27);
|
|
|
|
|
|
//updates statusbar only if speed have changed to save CPU time
|
|
|
if (spd != v->cur_speed) {
|
|
|
v->cur_speed = spd;
|
|
|
if (_patches.vehicle_speed)
|
|
@@ -1364,90 +1363,48 @@ static void AircraftEntersTerminal(Vehic
|
|
|
AddNewsItem(
|
|
|
STR_A033_CITIZENS_CELEBRATE_FIRST,
|
|
|
flags,
|
|
|
v->index,
|
|
|
0);
|
|
|
}
|
|
|
|
|
|
old_order = v->current_order;
|
|
|
v->current_order.type = OT_LOADING;
|
|
|
v->current_order.flags = 0;
|
|
|
|
|
|
if (old_order.type == OT_GOTO_STATION &&
|
|
|
v->current_order.dest == v->last_station_visited) {
|
|
|
v->current_order.flags =
|
|
|
(old_order.flags & (OF_FULL_LOAD | OF_UNLOAD | OF_TRANSFER)) | OF_NON_STOP;
|
|
|
}
|
|
|
|
|
|
SET_EXPENSES_TYPE(EXPENSES_AIRCRAFT_INC);
|
|
|
LoadUnloadVehicle(v);
|
|
|
MarkAircraftDirty(v);
|
|
|
InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
|
|
|
InvalidateWindowClasses(WC_AIRCRAFT_LIST);
|
|
|
}
|
|
|
|
|
|
|
|
|
static void AircraftEnterHangar(Vehicle *v)
|
|
|
{
|
|
|
Order old_order;
|
|
|
|
|
|
ServiceAircraft(v);
|
|
|
InvalidateWindowClasses(WC_AIRCRAFT_LIST);
|
|
|
|
|
|
TriggerVehicle(v, VEHICLE_TRIGGER_DEPOT);
|
|
|
|
|
|
if (v->current_order.type == OT_GOTO_DEPOT) {
|
|
|
int32 cost;
|
|
|
|
|
|
InvalidateWindow(WC_VEHICLE_VIEW, v->index);
|
|
|
|
|
|
old_order = v->current_order;
|
|
|
v->current_order.type = OT_NOTHING;
|
|
|
v->current_order.flags = 0;
|
|
|
|
|
|
_current_player = v->owner;
|
|
|
cost = DoCommand(v->tile, v->index, old_order.refit_cargo | old_order.refit_subtype << 8, DC_EXEC, CMD_REFIT_AIRCRAFT);
|
|
|
if (!CmdFailed(cost) && v->owner == _local_player && cost != 0) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
|
|
|
|
|
|
if (HASBIT(old_order.flags, OFB_PART_OF_ORDERS)) {
|
|
|
v->cur_order_index++;
|
|
|
} else if (HASBIT(old_order.flags, OFB_HALT_IN_DEPOT)) { // force depot visit
|
|
|
v->vehstatus |= VS_STOPPED;
|
|
|
InvalidateWindowClasses(WC_AIRCRAFT_LIST);
|
|
|
|
|
|
if (v->owner == _local_player) {
|
|
|
SetDParam(0, v->unitnumber);
|
|
|
AddNewsItem(
|
|
|
STR_A014_AIRCRAFT_IS_WAITING_IN,
|
|
|
NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0),
|
|
|
v->index,
|
|
|
0
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void AircraftLand(Vehicle *v)
|
|
|
{
|
|
|
v->sprite_width = v->sprite_height = 2;
|
|
|
}
|
|
|
|
|
|
static void AircraftLandAirplane(Vehicle *v)
|
|
|
{
|
|
|
AircraftLand(v);
|
|
|
if (!PlayVehicleSound(v, VSE_TOUCHDOWN)) {
|
|
|
SndPlayVehicleFx(SND_17_SKID_PLANE, v);
|
|
|
}
|
|
|
MaybeCrashAirplane(v);
|
|
|
}
|
|
|
|
|
|
// set the right pos when heading to other airports after takeoff
|
|
|
static void AircraftNextAirportPos_and_Order(Vehicle *v)
|
|
|
{
|
|
|
const Station* st;
|
|
|
const AirportFTAClass *Airport;
|
|
|
|
|
|
if (v->current_order.type == OT_GOTO_STATION ||
|
|
|
v->current_order.type == OT_GOTO_DEPOT)
|
|
|
v->u.air.targetairport = v->current_order.dest;
|
|
|
|
|
@@ -1472,49 +1429,49 @@ static void AircraftLeaveHangar(Vehicle
|
|
|
if (u != NULL) {
|
|
|
u->vehstatus &= ~VS_HIDDEN;
|
|
|
u->cur_speed = 80;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
VehicleServiceInDepot(v);
|
|
|
SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
|
|
|
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
|
|
|
InvalidateWindowClasses(WC_AIRCRAFT_LIST);
|
|
|
}
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
/////////////////// AIRCRAFT MOVEMENT SCHEME ////////////////////////////////
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
static void AircraftEventHandler_EnterTerminal(Vehicle *v, const AirportFTAClass *Airport)
|
|
|
{
|
|
|
AircraftEntersTerminal(v);
|
|
|
v->u.air.state = Airport->layout[v->u.air.pos].heading;
|
|
|
}
|
|
|
|
|
|
static void AircraftEventHandler_EnterHangar(Vehicle *v, const AirportFTAClass *Airport)
|
|
|
{
|
|
|
AircraftEnterHangar(v);
|
|
|
VehicleEnterDepot(v);
|
|
|
v->u.air.state = Airport->layout[v->u.air.pos].heading;
|
|
|
}
|
|
|
|
|
|
// In an Airport Hangar
|
|
|
static void AircraftEventHandler_InHangar(Vehicle *v, const AirportFTAClass *Airport)
|
|
|
{
|
|
|
// if we just arrived, execute EnterHangar first
|
|
|
if (v->u.air.previous_pos != v->u.air.pos) {
|
|
|
AircraftEventHandler_EnterHangar(v, Airport);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// if we were sent to the depot, stay there
|
|
|
if (v->current_order.type == OT_GOTO_DEPOT && (v->vehstatus & VS_STOPPED)) {
|
|
|
v->current_order.type = OT_NOTHING;
|
|
|
v->current_order.flags = 0;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (v->current_order.type != OT_GOTO_STATION &&
|
|
|
v->current_order.type != OT_GOTO_DEPOT)
|
|
|
return;
|
|
|
|
|
|
// if the block of the next position is busy, stay put
|