diff options
-rw-r--r-- | src/aircraft.h | 7 | ||||
-rw-r--r-- | src/aircraft_cmd.cpp | 208 | ||||
-rw-r--r-- | src/newgrf_engine.cpp | 10 | ||||
-rw-r--r-- | src/openttd.cpp | 4 | ||||
-rw-r--r-- | src/order_cmd.cpp | 11 | ||||
-rw-r--r-- | src/saveload/oldloader_sl.cpp | 10 | ||||
-rw-r--r-- | src/saveload/vehicle_sl.cpp | 39 | ||||
-rw-r--r-- | src/station.cpp | 7 | ||||
-rw-r--r-- | src/station_cmd.cpp | 3 | ||||
-rw-r--r-- | src/vehicle.cpp | 13 | ||||
-rw-r--r-- | src/vehicle_base.h | 10 | ||||
-rw-r--r-- | src/vehicle_cmd.cpp | 8 | ||||
-rw-r--r-- | src/water_cmd.cpp | 2 |
13 files changed, 170 insertions, 162 deletions
diff --git a/src/aircraft.h b/src/aircraft.h index 7f3c8bff7..d4e11f206 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -92,6 +92,13 @@ byte GetAircraftFlyingAltitude(const Aircraft *v); * As side-effect the vehicle type is set correctly. */ struct Aircraft : public Vehicle { + uint16 crashed_counter; + uint16 cached_max_speed; + byte pos; + byte previous_pos; + StationID targetairport; + byte state; + /** Initializes the Vehicle to an aircraft */ Aircraft() { this->type = VEH_AIRCRAFT; } diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 1a0469819..c06e3e64b 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -40,7 +40,7 @@ void Aircraft::UpdateDeltaXY(Direction direction) default: NOT_REACHED(); case AIR_AIRCRAFT: case AIR_HELICOPTER: - switch (this->u.air.state) { + switch (this->state) { case ENDTAKEOFF: case LANDING: case HELILANDING: @@ -173,7 +173,7 @@ SpriteID GetRotorImage(const Aircraft *v) } /* Return standard rotor sprites if there are no custom sprites for this helicopter */ - return SPR_ROTOR_STOPPED + w->u.air.state; + return SPR_ROTOR_STOPPED + w->state; } static SpriteID GetAircraftIcon(EngineID engine) @@ -368,14 +368,14 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin assert(i != apc->nof_depots); if (st->airport_tile + ToTileIndexDiff(apc->airport_depots[i]) == tile) { assert(apc->layout[i].heading == HANGAR); - v->u.air.pos = apc->layout[i].position; + v->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->state = HANGAR; + v->previous_pos = v->pos; + v->targetairport = GetStationIndex(tile); v->SetNext(u); v->service_interval = _settings_game.vehicle.servint_aircraft; @@ -411,7 +411,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, uint32 p1, uin w->cur_image = SPR_ROTOR_STOPPED; w->random_bits = VehicleRandomBits(); /* Use rotor's air.state to store the rotor animation frame */ - w->u.air.state = HRS_ROTOR_STOPPED; + w->state = HRS_ROTOR_STOPPED; w->UpdateDeltaXY(INVALID_DIR); u->SetNext(w); @@ -594,8 +594,8 @@ static void CheckIfAircraftNeedsService(Aircraft *v) /* only goto depot if the target airport has terminals (eg. it is airport) */ if (st->airport_tile != INVALID_TILE && st->Airport()->terminals != NULL) { -// printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index); -// v->u.air.targetairport = st->index; +// printf("targetairport = %d, st->index = %d\n", v->targetairport, st->index); +// v->targetairport = st->index; v->current_order.MakeGoToDepot(st->index, ODTFB_SERVICE); InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH); } else if (v->current_order.IsType(OT_GOTO_DEPOT)) { @@ -655,7 +655,7 @@ static void HelicopterTickHandler(Aircraft *v) if (v->current_order.IsType(OT_LOADING) || (v->vehstatus & VS_STOPPED)) { if (u->cur_speed != 0) { u->cur_speed++; - if (u->cur_speed >= 0x80 && u->u.air.state == HRS_ROTOR_MOVING_3) { + if (u->cur_speed >= 0x80 && u->state == HRS_ROTOR_MOVING_3) { u->cur_speed = 0; } } @@ -672,13 +672,13 @@ static void HelicopterTickHandler(Aircraft *v) SpriteID img; if (spd == 0) { - u->u.air.state = HRS_ROTOR_STOPPED; + u->state = HRS_ROTOR_STOPPED; img = GetRotorImage(v); if (u->cur_image == img) return; } else if (tick >= spd) { u->tick_counter = 0; - u->u.air.state++; - if (u->u.air.state > HRS_ROTOR_MOVING_3) u->u.air.state = HRS_ROTOR_MOVING_1; + u->state++; + if (u->state > HRS_ROTOR_MOVING_3) u->state = HRS_ROTOR_MOVING_1; img = GetRotorImage(v); } else { return; @@ -757,9 +757,9 @@ void UpdateAircraftCache(Aircraft *v) /* Convert from original units to (approx) km/h */ max_speed = (max_speed * 129) / 10; - v->u.air.cached_max_speed = max_speed; + v->cached_max_speed = max_speed; } else { - v->u.air.cached_max_speed = 0xFFFF; + v->cached_max_speed = 0xFFFF; } } @@ -791,9 +791,9 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, * and take-off speeds being too low. */ speed_limit *= _settings_game.vehicle.plane_speed; - if (v->u.air.cached_max_speed < speed_limit) { + if (v->cached_max_speed < speed_limit) { if (v->cur_speed < speed_limit) hard_limit = false; - speed_limit = v->u.air.cached_max_speed; + speed_limit = v->cached_max_speed; } speed_limit = min(speed_limit, v->max_speed); @@ -889,7 +889,7 @@ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc) * or it will simply crash in next tick */ TileIndex tile = 0; - const Station *st = Station::GetIfValid(v->u.air.targetairport); + const Station *st = Station::GetIfValid(v->targetairport); if (st != NULL) { /* Make sure we don't go to INVALID_TILE if the airport has been removed. */ tile = (st->airport_tile != INVALID_TILE) ? st->airport_tile : st->xy; @@ -921,7 +921,7 @@ static bool AircraftController(Aircraft *v) int count; /* NULL if station is invalid */ - const Station *st = Station::GetIfValid(v->u.air.targetairport); + const Station *st = Station::GetIfValid(v->targetairport); /* INVALID_TILE if there is no station */ TileIndex tile = INVALID_TILE; if (st != NULL) { @@ -933,11 +933,11 @@ static bool AircraftController(Aircraft *v) /* prevent going to INVALID_TILE if airport is deleted. */ if (st == NULL || st->airport_tile == INVALID_TILE) { /* Jump into our "holding pattern" state machine if possible */ - if (v->u.air.pos >= afc->nofelements) { - v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, afc); - } else if (v->u.air.targetairport != v->current_order.GetDestination()) { + if (v->pos >= afc->nofelements) { + v->pos = v->previous_pos = AircraftGetEntryPoint(v, afc); + } else if (v->targetairport != v->current_order.GetDestination()) { /* If not possible, just get out of here fast */ - v->u.air.state = FLYING; + v->state = FLYING; UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); /* get aircraft back on running altitude */ @@ -947,7 +947,7 @@ static bool AircraftController(Aircraft *v) } /* get airport moving data */ - const AirportMovingData *amd = afc->MovingData(v->u.air.pos); + const AirportMovingData *amd = afc->MovingData(v->pos); int x = TileX(tile) * TILE_SIZE; int y = TileY(tile) * TILE_SIZE; @@ -983,7 +983,7 @@ static bool AircraftController(Aircraft *v) /* FIXME - AircraftController -> if station no longer exists, do not land * helicopter will circle until sign disappears, then go to next order * what to do when it is the only order left, right now it just stays in 1 place */ - v->u.air.state = FLYING; + v->state = FLYING; UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); return false; @@ -1102,7 +1102,7 @@ static bool AircraftController(Aircraft *v) if (amd->flag & AMED_LAND) { if (st->airport_tile == INVALID_TILE) { /* Airport has been removed, abort the landing procedure */ - v->u.air.state = FLYING; + v->state = FLYING; UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); /* get aircraft back on running altitude */ @@ -1142,21 +1142,21 @@ static bool AircraftController(Aircraft *v) static bool HandleCrashedAircraft(Aircraft *v) { - v->u.air.crashed_counter += 3; + v->crashed_counter += 3; Station *st = GetTargetAirportIfValid(v); /* make aircraft crash down to the ground */ - if (v->u.air.crashed_counter < 500 && st == NULL && ((v->u.air.crashed_counter % 3) == 0) ) { + if (v->crashed_counter < 500 && st == NULL && ((v->crashed_counter % 3) == 0) ) { uint z = GetSlopeZ(v->x_pos, v->y_pos); v->z_pos -= 1; if (v->z_pos == z) { - v->u.air.crashed_counter = 500; + v->crashed_counter = 500; v->z_pos++; } } - if (v->u.air.crashed_counter < 650) { + if (v->crashed_counter < 650) { uint32 r; if (Chance16R(1,32,r)) { static const DirDiff delta[] = { @@ -1172,7 +1172,7 @@ static bool HandleCrashedAircraft(Aircraft *v) GB(r, 8, 4), EV_EXPLOSION_SMALL); } - } else if (v->u.air.crashed_counter >= 10000) { + } else if (v->crashed_counter >= 10000) { /* remove rubble of crashed airplane */ /* clear runway-in on all airports, set by crashing plane @@ -1276,7 +1276,7 @@ void HandleMissingAircraftOrders(Aircraft *v) TileIndex Aircraft::GetOrderStationLocation(StationID station) { /* Orders are changed in flight, ensure going to the right station. */ - if (this->u.air.state == FLYING) { + if (this->state == FLYING) { AircraftNextAirportPos_and_Order(this); } @@ -1294,7 +1294,7 @@ void Aircraft::MarkDirty() static void CrashAirplane(Aircraft *v) { v->vehstatus |= VS_CRASHED; - v->u.air.crashed_counter = 0; + v->crashed_counter = 0; CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); @@ -1330,7 +1330,7 @@ static void CrashAirplane(Aircraft *v) static void MaybeCrashAirplane(Aircraft *v) { - Station *st = Station::Get(v->u.air.targetairport); + Station *st = Station::Get(v->targetairport); /* FIXME -- MaybeCrashAirplane -> increase crashing chances of very modern airplanes on smaller than AT_METROPOLITAN airports */ uint16 prob = 0x10000 / 1500; @@ -1356,8 +1356,8 @@ static void AircraftEntersTerminal(Aircraft *v) { if (v->current_order.IsType(OT_GOTO_DEPOT)) return; - Station *st = Station::Get(v->u.air.targetairport); - v->last_station_visited = v->u.air.targetairport; + Station *st = Station::Get(v->targetairport); + v->last_station_visited = v->targetairport; /* Check if station was ever visited before */ if (!(st->had_vehicle_of_type & HVOT_AIRCRAFT)) { @@ -1391,12 +1391,12 @@ static void AircraftLandAirplane(Aircraft *v) void AircraftNextAirportPos_and_Order(Aircraft *v) { if (v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_DEPOT)) { - v->u.air.targetairport = v->current_order.GetDestination(); + v->targetairport = v->current_order.GetDestination(); } const Station *st = GetTargetAirportIfValid(v); const AirportFTAClass *apc = st == NULL ? GetAirport(AT_DUMMY) : st->Airport(); - v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc); + v->pos = v->previous_pos = AircraftGetEntryPoint(v, apc); } void AircraftLeaveHangar(Aircraft *v) @@ -1470,20 +1470,20 @@ static inline bool CheckSendAircraftToHangarForReplacement(const Vehicle *v) static void AircraftEventHandler_EnterTerminal(Aircraft *v, const AirportFTAClass *apc) { AircraftEntersTerminal(v); - v->u.air.state = apc->layout[v->u.air.pos].heading; + v->state = apc->layout[v->pos].heading; } static void AircraftEventHandler_EnterHangar(Aircraft *v, const AirportFTAClass *apc) { VehicleEnterDepot(v); - v->u.air.state = apc->layout[v->u.air.pos].heading; + v->state = apc->layout[v->pos].heading; } /** In an Airport Hangar */ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *apc) { /* if we just arrived, execute EnterHangar first */ - if (v->u.air.previous_pos != v->u.air.pos) { + if (v->previous_pos != v->pos) { AircraftEventHandler_EnterHangar(v, apc); return; } @@ -1499,10 +1499,10 @@ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *ap return; /* if the block of the next position is busy, stay put */ - if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return; + if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return; /* We are already at the target airport, we need to find a terminal */ - if (v->current_order.GetDestination() == v->u.air.targetairport) { + if (v->current_order.GetDestination() == v->targetairport) { /* FindFreeTerminal: * 1. Find a free terminal, 2. Occupy it, 3. Set the vehicle's state to that terminal */ if (v->subtype == AIR_HELICOPTER) { @@ -1512,7 +1512,7 @@ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *ap } } else { // Else prepare for launch. /* airplane goto state takeoff, helicopter to helitakeoff */ - v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF; + v->state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF; } AircraftLeaveHangar(v); AirportMove(v, apc); @@ -1522,7 +1522,7 @@ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *ap static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass *apc) { /* if we just arrived, execute EnterTerminal first */ - if (v->u.air.previous_pos != v->u.air.pos) { + if (v->previous_pos != v->pos) { AircraftEventHandler_EnterTerminal(v, apc); /* on an airport with helipads, a helicopter will always land there * and get serviced at the same time - setting */ @@ -1541,7 +1541,7 @@ static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass * if (v->current_order.IsType(OT_NOTHING)) return; /* if the block of the next position is busy, stay put */ - if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return; + if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return; /* airport-road is free. We either have to go to another airport, or to the hangar * ---> start moving */ @@ -1551,7 +1551,7 @@ static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass * case OT_GOTO_STATION: // ready to fly to another airport break; case OT_GOTO_DEPOT: // visit hangar for serivicing, sale, etc. - go_to_hangar = v->current_order.GetDestination() == v->u.air.targetairport; + go_to_hangar = v->current_order.GetDestination() == v->targetairport; break; case OT_CONDITIONAL: /* In case of a conditional order we just have to wait a tick @@ -1560,14 +1560,14 @@ static void AircraftEventHandler_AtTerminal(Aircraft *v, const AirportFTAClass * return; default: // orders have been deleted (no orders), goto depot and don't bother us v->current_order.Free(); - go_to_hangar = Station::Get(v->u.air.targetairport)->Airport()->nof_depots != 0; + go_to_hangar = Station::Get(v->targetairport)->Airport()->nof_depots != 0; } if (go_to_hangar) { - v->u.air.state = HANGAR; + v->state = HANGAR; } else { /* airplane goto state takeoff, helicopter to helitakeoff */ - v->u.air.state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF; + v->state = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : TAKEOFF; } AirportMove(v, apc); } @@ -1580,25 +1580,25 @@ static void AircraftEventHandler_General(Aircraft *v, const AirportFTAClass *apc static void AircraftEventHandler_TakeOff(Aircraft *v, const AirportFTAClass *apc) { PlayAircraftSound(v); // play takeoffsound for airplanes - v->u.air.state = STARTTAKEOFF; + v->state = STARTTAKEOFF; } static void AircraftEventHandler_StartTakeOff(Aircraft *v, const AirportFTAClass *apc) { - v->u.air.state = ENDTAKEOFF; + v->state = ENDTAKEOFF; v->UpdateDeltaXY(INVALID_DIR); } static void AircraftEventHandler_EndTakeOff(Aircraft *v, const AirportFTAClass *apc) { - v->u.air.state = FLYING; + v->state = FLYING; /* get the next position to go to, differs per airport */ AircraftNextAirportPos_and_Order(v); } static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass *apc) { - v->u.air.state = FLYING; + v->state = FLYING; v->UpdateDeltaXY(INVALID_DIR); /* get the next position to go to, differs per airport */ @@ -1614,7 +1614,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) { - Station *st = Station::Get(v->u.air.targetairport); + Station *st = Station::Get(v->targetairport); /* runway busy or not allowed to use this airstation, circle */ if (apc->flags & (v->subtype == AIR_HELICOPTER ? AirportFTAClass::HELICOPTERS : AirportFTAClass::AIRPLANES) && @@ -1624,7 +1624,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) * if it is an airplane, look for LANDING, for helicopter HELILANDING * it is possible to choose from multiple landing runways, so loop until a free one is found */ byte landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING; - const AirportFTA *current = apc->layout[v->u.air.pos].next; + const AirportFTA *current = apc->layout[v->pos].next; while (current != NULL) { if (current->heading == landingtype) { /* save speed before, since if AirportHasBlock is false, it resets them to 0 @@ -1633,12 +1633,12 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) uint16 tcur_speed = v->cur_speed; uint16 tsubspeed = v->subspeed; if (!AirportHasBlock(v, current, apc)) { - v->u.air.state = landingtype; // LANDING / HELILANDING + v->state = landingtype; // LANDING / HELILANDING /* it's a bit dirty, but I need to set position to next position, otherwise * if there are multiple runways, plane won't know which one it took (because * they all have heading LANDING). And also occupy that block! */ - v->u.air.pos = current->next_position; - SETBITS(st->airport_flags, apc->layout[v->u.air.pos].block); + v->pos = current->next_position; + SETBITS(st->airport_flags, apc->layout[v->pos].block); return; } v->cur_speed = tcur_speed; @@ -1647,13 +1647,13 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) current = current->next; } } - v->u.air.state = FLYING; - v->u.air.pos = apc->layout[v->u.air.pos].next_position; + v->state = FLYING; + v->pos = apc->layout[v->pos].next_position; } static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc) { - v->u.air.state = ENDLANDING; + v->state = ENDLANDING; AircraftLandAirplane(v); // maybe crash airplane /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ @@ -1666,14 +1666,14 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc static void AircraftEventHandler_HeliLanding(Aircraft *v, const AirportFTAClass *apc) { - v->u.air.state = HELIENDLANDING; + v->state = HELIENDLANDING; v->UpdateDeltaXY(INVALID_DIR); } static void AircraftEventHandler_EndLanding(Aircraft *v, const AirportFTAClass *apc) { /* next block busy, don't do a thing, just wait */ - if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return; + if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return; /* if going to terminal (OT_GOTO_STATION) choose one * 1. in case all terminals are busy AirportFindFreeTerminal() returns false or @@ -1682,14 +1682,14 @@ static void AircraftEventHandler_EndLanding(Aircraft *v, const AirportFTAClass * if (v->current_order.IsType(OT_GOTO_STATION)) { if (AirportFindFreeTerminal(v, apc)) return; } - v->u.air.state = HANGAR; + v->state = HANGAR; } static void AircraftEventHandler_HeliEndLanding(Aircraft *v, const AirportFTAClass *apc) { /* next block busy, don't do a thing, just wait */ - if (AirportHasBlock(v, &apc->layout[v->u.air.pos], apc)) return; + if (AirportHasBlock(v, &apc->layout[v->pos], apc)) return; /* if going to helipad (OT_GOTO_STATION) choose one. If airport doesn't have helipads, choose terminal * 1. in case all terminals/helipads are busy (AirportFindFreeHelipad() returns false) or @@ -1701,7 +1701,7 @@ static void AircraftEventHandler_HeliEndLanding(Aircraft *v, const AirportFTACla if (v->current_order.IsType(OT_GOTO_STATION)) { if (AirportFindFreeHelipad(v, apc)) return; } - v->u.air.state = (apc->nof_depots != 0) ? HANGAR : HELITAKEOFF; + v->state = (apc->nof_depots != 0) ? HANGAR : HELITAKEOFF; } typedef void AircraftStateHandler(Aircraft *v, const AirportFTAClass *apc); @@ -1734,10 +1734,10 @@ static AircraftStateHandler * const _aircraft_state_handlers[] = { static void AirportClearBlock(const Aircraft *v, const AirportFTAClass *apc) { /* we have left the previous block, and entered the new one. Free the previous block */ - if (apc->layout[v->u.air.previous_pos].block != apc->layout[v->u.air.pos].block) { - Station *st = Station::Get(v->u.air.targetairport); + if (apc->layout[v->previous_pos].block != apc->layout[v->pos].block) { + Station *st = Station::Get(v->targetairport); - CLRBITS(st->airport_flags, apc->layout[v->u.air.previous_pos].block); + CLRBITS(st->airport_flags, apc->layout[v->previous_pos].block); } } @@ -1746,7 +1746,7 @@ static void AirportGoToNextPosition(Aircraft *v) /* if aircraft is not in position, wait until it is */ if (!AircraftController(v)) return; - const AirportFTAClass *apc = Station::Get(v->u.air.targetairport)->Airport(); + const AirportFTAClass *apc = Station::Get(v->targetairport)->Airport(); AirportClearBlock(v, apc); AirportMove(v, apc); // move aircraft to next position @@ -1756,28 +1756,28 @@ static void AirportGoToNextPosition(Aircraft *v) static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) { /* error handling */ - if (v->u.air.pos >= apc->nofelements) { - DEBUG(misc, 0, "[Ap] position %d is not valid for current airport. Max position is %d", v->u.air.pos, apc->nofelements-1); - assert(v->u.air.pos < apc->nofelements); + if (v->pos >= apc->nofelements) { + DEBUG(misc, 0, "[Ap] position %d is not valid for current airport. Max position is %d", v->pos, apc->nofelements-1); + assert(v->pos < apc->nofelements); } - const AirportFTA *current = &apc->layout[v->u.air.pos]; + const AirportFTA *current = &apc->layout[v->pos]; /* we have arrived in an important state (eg terminal, hangar, etc.) */ - if (current->heading == v->u.air.state) { - byte prev_pos = v->u.air.pos; // location could be changed in state, so save it before-hand - byte prev_state = v->u.air.state; - _aircraft_state_handlers[v->u.air.state](v, apc); - if (v->u.air.state != FLYING) v->u.air.previous_pos = prev_pos; - if (v->u.air.state != prev_state || v->u.air.pos != prev_pos) UpdateAircraftCache(v); + if (current->heading == v->state) { + byte prev_pos = v->pos; // location could be changed in state, so save it before-hand + byte prev_state = v->state; + _aircraft_state_handlers[v->state](v, apc); + if (v->state != FLYING) v->previous_pos = prev_pos; + if (v->state != prev_state || v->pos != prev_pos) UpdateAircraftCache(v); return true; } - v->u.air.previous_pos = v->u.air.pos; // save previous location + v->previous_pos = v->pos; // save previous location /* there is only one choice to move to */ if (current->next == NULL) { if (AirportSetBlocks(v, current, apc)) { - v->u.air.pos = current->next_position; + v->pos = current->next_position; UpdateAircraftCache(v); } // move to next position return false; @@ -1786,9 +1786,9 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) /* there are more choices to choose from, choose the one that * matches our heading */ do { - if (v->u.air.state == current->heading || current->heading == TO_ALL) { + if (v->state == current->heading || current->heading == TO_ALL) { if (AirportSetBlocks(v, current, apc)) { - v->u.air.pos = current->next_position; + v->pos = current->next_position; UpdateAircraftCache(v); } // move to next position return false; @@ -1796,7 +1796,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) current = current->next; } while (current != NULL); - DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->u.air.pos, v->u.air.state, v->index); + DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->pos, v->state, v->index); assert(0); return false; } @@ -1804,12 +1804,12 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) /* returns true if the road ahead is busy, eg. you must wait before proceeding */ static bool AirportHasBlock(Aircraft *v, const AirportFTA *current_pos, const AirportFTAClass *apc) { - const AirportFTA *reference = &apc->layout[v->u.air.pos]; + const AirportFTA *reference = &apc->layout[v->pos]; const AirportFTA *next = &apc->layout[current_pos->next_position]; /* same block, then of course we can move */ if (apc->layout[current_pos->position].block != next->block) { - const Station *st = Station::Get(v->u.air.targetairport); + const Station *st = Station::Get(v->targetairport); uint64 airport_flags = next->block; /* check additional possible extra blocks */ @@ -1836,7 +1836,7 @@ static bool AirportHasBlock(Aircraft *v, const AirportFTA *current_pos, const Ai static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const AirportFTAClass *apc) { const AirportFTA *next = &apc->layout[current_pos->next_position]; - const AirportFTA *reference = &apc->layout[v->u.air.pos]; + const AirportFTA *reference = &apc->layout[v->pos]; /* if the next position is in another block, check it and wait until it is free */ if ((apc->layout[current_pos->position].block & next->block) != next->block) { @@ -1857,7 +1857,7 @@ static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const A * checking, because it has been set by the airplane before */ if (current_pos->block == next->block) airport_flags ^= next->block; - Station *st = Station::Get(v->u.air.targetairport); + Station *st = Station::Get(v->targetairport); if (HASBITS(st->airport_flags, airport_flags)) { v->cur_speed = 0; v->subspeed = 0; @@ -1873,11 +1873,11 @@ static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const A static bool FreeTerminal(Aircraft *v, byte i, byte last_terminal) { - Station *st = Station::Get(v->u.air.targetairport); + Station *st = Station::Get(v->targetairport); for (; i < last_terminal; i++) { if (!HasBit(st->airport_flags, _airport_terminal_flag[i])) { /* TERMINAL# HELIPAD# */ - v->u.air.state = _airport_terminal_state[i]; // start moving to that terminal/helipad + v->state = _airport_terminal_state[i]; // start moving to that terminal/helipad SetBit(st->airport_flags, _airport_terminal_flag[i]); // occupy terminal/helipad return true; } @@ -1907,8 +1907,8 @@ static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc) * fails, then attempt fails and plane waits */ if (apc->terminals[0] > 1) { - const Station *st = Station::Get(v->u.air.targetairport); - const AirportFTA *temp = apc->layout[v->u.air.pos].next; + const Station *st = Station::Get(v->targetairport); + const AirportFTA *temp = apc->layout[v->pos].next; while (temp != NULL) { if (temp->heading == 255) { @@ -1958,8 +1958,8 @@ static bool AirportFindFreeHelipad(Aircraft *v, const AirportFTAClass *apc) /* if there are more helicoptergroups, pick one, just as in AirportFindFreeTerminal() */ if (apc->helipads[0] > 1) { - const Station *st = Station::Get(v->u.air.targetairport); - const AirportFTA *temp = apc->layout[v->u.air.pos].next; + const Station *st = Station::Get(v->targetairport); + const AirportFTA *temp = apc->layout[v->pos].next; while (temp != NULL) { if (temp->heading == 255) { @@ -2049,7 +2049,7 @@ bool Aircraft::Tick() } -/** Returns aircraft's target station if v->u.air.target_airport +/** Returns aircraft's target station if v->target_airport * is a valid station with airport. * @param v vehicle to get target airport for * @return pointer to target station, NULL if invalid @@ -2058,7 +2058,7 @@ Station *GetTargetAirportIfValid(const Aircraft *v) { assert(v->type == VEH_AIRCRAFT); - Station *st = Station::GetIfValid(v->u.air.targetairport); + Station *st = Station::GetIfValid(v->targetairport); if (st == NULL) return NULL; return st->airport_tile == INVALID_TILE ? NULL : st; @@ -2077,12 +2077,12 @@ void UpdateAirplanesOnNewStation(const Station *st) FOR_ALL_VEHICLES(u) { if (u->type == VEH_AIRCRAFT && IsNormalAircraft(u)) { Aircraft *v = (Aircraft *)u; - if (v->u.air.targetairport == st->index) { // if heading to this airport + if (v->targetairport == st->index) { // if heading to this airport /* update position of airplane. If plane is not flying, landing, or taking off * you cannot delete airport, so it doesn't matter */ - if (v->u.air.state >= FLYING) { // circle around - v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, ap); - v->u.air.state = FLYING; + if (v->state >= FLYING) { // circle around + v->pos = v->previous_pos = AircraftGetEntryPoint(v, ap); + v->state = FLYING; UpdateAircraftCache(v); /* landing plane needs to be reset to flying height (only if in pause mode upgrade, * in normal mode, plane is reset in AircraftController. It doesn't hurt for FLYING */ @@ -2090,13 +2090,13 @@ void UpdateAirplanesOnNewStation(const Station *st) /* set new position x,y,z */ SetAircraftPosition(v, gp.x, gp.y, GetAircraftFlyingAltitude(v)); } else { - assert(v->u.air.state == ENDTAKEOFF || v->u.air.state == HELITAKEOFF); + assert(v->state == ENDTAKEOFF || v->state == HELITAKEOFF); byte takeofftype = (v->subtype == AIR_HELICOPTER) ? HELITAKEOFF : ENDTAKEOFF; /* search in airportdata for that heading * easiest to do, since this doesn't happen a lot */ for (uint cnt = 0; cnt < ap->nofelements; cnt++) { if (ap->layout[cnt].heading == takeofftype) { - v->u.air.pos = ap->layout[cnt].position; + v->pos = ap->layout[cnt].position; UpdateAircraftCache(v); break; } diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index a3bd84c2d..993ff00f9 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -180,9 +180,9 @@ static byte MapAircraftMovementState(const Aircraft *v) if (st == NULL) return AMS_TTDP_FLIGHT_TO_TOWER; const AirportFTAClass *afc = st->Airport(); - uint16 amdflag = afc->MovingData(v->u.air.pos)->flag; + uint16 amdflag = afc->MovingData(v->pos)->flag; - switch (v->u.air.state) { + switch (v->state) { case HANGAR: /* The international airport is a special case as helicopters can land in * front of the hanger. Helicopters also change their air.state to @@ -303,7 +303,7 @@ enum { */ static byte MapAircraftMovementAction(const Aircraft *v) { - switch (v->u.air.state) { + switch (v->state) { case HANGAR: return (v->cur_speed > 0) ? AMA_TTDP_LANDING_TO_HANGAR : AMA_TTDP_IN_HANGAR; @@ -796,7 +796,7 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by Aircraft *a = (Aircraft *)v; switch (variable - 0x80) { case 0x62: return MapAircraftMovementState(a); // Current movement state - case 0x63: return v->u.air.targetairport; // Airport to which the action refers + case 0x63: return a->targetairport; // Airport to which the action refers case 0x66: return MapAircraftMovementAction(a); // Current movement action } } break; @@ -936,7 +936,7 @@ SpriteID GetRotorOverrideSprite(EngineID engine, const Aircraft *v, bool info_vi if (v == NULL) return group->g.result.sprite; - return group->g.result.sprite + (info_view ? 0 : (v->Next()->Next()->u.air.state % group->g.result.num_sprites)); + return group->g.result.sprite + (info_view ? 0 : (v->Next()->Next()->state % group->g.result.num_sprites)); } diff --git a/src/openttd.cpp b/src/openttd.cpp index ba4a96cce..e22cbea01 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1146,9 +1146,9 @@ void StateGameLoop() case VEH_AIRCRAFT: { Aircraft *a = (Aircraft *)v; - uint speed = a->u.air.cached_max_speed; + uint speed = a->cached_max_speed; UpdateAircraftCache(a); - if (speed != a->u.air.cached_max_speed) { + if (speed != a->cached_max_speed) { DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber); } } break; diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index cf527e39a..3dfe2a1eb 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1620,10 +1620,13 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth) /* If there is no depot in front, reverse automatically (trains only) */ if (v->type == VEH_TRAIN && reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); - if (v->type == VEH_AIRCRAFT && v->u.air.state == FLYING && v->u.air.targetairport != destination) { - /* The aircraft is now heading for a different hangar than the next in the orders */ - extern void AircraftNextAirportPos_and_Order(Aircraft *a); - AircraftNextAirportPos_and_Order((Aircraft *)v); + if (v->type == VEH_AIRCRAFT) { + Aircraft *a = (Aircraft *)v; + if (a->state == FLYING && a->targetairport != destination) { + /* The aircraft is now heading for a different hangar than the next in the orders */ + extern void AircraftNextAirportPos_and_Order(Aircraft *a); + AircraftNextAirportPos_and_Order(a); + } } } else { UpdateVehicleTimetable(v, true); diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index eaa488fa1..d1186559c 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -1111,10 +1111,10 @@ static const OldChunks vehicle_ship_chunk[] = { }; static const OldChunks vehicle_air_chunk[] = { - OCL_SVAR( OC_UINT8, VehicleAir, pos ), - OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, VehicleAir, targetairport ), - OCL_SVAR( OC_UINT16, VehicleAir, crashed_counter ), - OCL_SVAR( OC_UINT8, VehicleAir, state ), + OCL_SVAR( OC_UINT8, Aircraft, pos ), + OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Aircraft, targetairport ), + OCL_SVAR( OC_UINT16, Aircraft, crashed_counter ), + OCL_SVAR( OC_UINT8, Aircraft, state ), OCL_NULL( 5 ), ///< Junk @@ -1159,7 +1159,7 @@ static bool LoadOldVehicleUnion(LoadgameState *ls, int num) case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break; case VEH_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break; - case VEH_AIRCRAFT: res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break; + case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break; case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break; case VEH_DISASTER: res = LoadChunk(ls, v, vehicle_disaster_chunk); break; } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 727b2d35b..d7e2c136d 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -173,29 +173,30 @@ void UpdateOldAircraft() * skip those */ if (v->type == VEH_AIRCRAFT && IsNormalAircraft(v)) { Aircraft *v_oldstyle = (Aircraft *)v; + Aircraft *a = (Aircraft *)v_oldstyle; /* airplane in terminal stopped doesn't hurt anyone, so goto next */ - if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) { - v_oldstyle->u.air.state = HANGAR; + if (a->vehstatus & VS_STOPPED && a->state == 0) { + a->state = HANGAR; continue; } - AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example - v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving - v_oldstyle->cur_speed = v_oldstyle->max_speed; // so aircraft don't have zero speed while in air - if (!v_oldstyle->current_order.IsType(OT_GOTO_STATION) && !v_oldstyle->current_order.IsType(OT_GOTO_DEPOT)) { + AircraftLeaveHangar(a); // make airplane visible if it was in a depot for example + a->vehstatus &= ~VS_STOPPED; // make airplane moving + a->cur_speed = v_oldstyle->max_speed; // so aircraft don't have zero speed while in air + if (!a->current_order.IsType(OT_GOTO_STATION) && !a->current_order.IsType(OT_GOTO_DEPOT)) { /* reset current order so aircraft doesn't have invalid "station-only" order */ - v_oldstyle->current_order.MakeDummy(); + a->current_order.MakeDummy(); } - v_oldstyle->u.air.state = FLYING; - AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport - GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle); - v_oldstyle->tile = 0; // aircraft in air is tile=0 + a->state = FLYING; + AircraftNextAirportPos_and_Order(a); // move it to the entry point of the airport + GetNewVehiclePosResult gp = GetNewVehiclePos(a); + a->tile = 0; // aircraft in air is tile=0 /* correct speed of helicopter-rotors */ - if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32; + if (a->subtype == AIR_HELICOPTER) a->Next()->Next()->cur_speed = 32; /* set new position x,y,z */ - SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle)); + SetAircraftPosition(a, gp.x, gp.y, GetAircraftFlyingAltitude(a)); } } } @@ -572,15 +573,15 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) static const SaveLoad _aircraft_desc[] = { SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT), SLE_VEH_INCLUDEX(), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8), + SLE_VAR(Aircraft, crashed_counter, SLE_UINT16), + SLE_VAR(Aircraft, pos, SLE_UINT8), - SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4), - SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION), + SLE_CONDVAR(Aircraft, targetairport, SLE_FILE_U8 | SLE_VAR_U16, 0, 4), + SLE_CONDVAR(Aircraft, targetairport, SLE_UINT16, 5, SL_MAX_VERSION), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8), + SLE_VAR(Aircraft, state, SLE_UINT8), - SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION), + SLE_CONDVAR(Aircraft, previous_pos, SLE_UINT8, 2, SL_MAX_VERSION), /* reserve extra space in savegame here. (currently 15 bytes) */ SLE_CONDNULL(15, 2, SL_MAX_VERSION), diff --git a/src/station.cpp b/src/station.cpp index 03d7a9db8..97713dfbf 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -70,9 +70,10 @@ Station::~Station() Vehicle *v; FOR_ALL_VEHICLES(v) { - if (v->type == VEH_AIRCRAFT && IsNormalAircraft(v) && v->u.air.targetairport == this->index) { - v->u.air.targetairport = INVALID_STATION; - } + if (v->type != VEH_AIRCRAFT || !IsNormalAircraft(v)) continue; + + Aircraft *a = (Aircraft *)v; + if (a->targetairport == this->index) a->targetairport = INVALID_STATION; } MarkDirty(); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 14718a45d..8076b95a2 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1968,7 +1968,8 @@ static CommandCost RemoveAirport(Station *st, DoCommandFlag flags) FOR_ALL_VEHICLES(v) { if (!(v->type == VEH_AIRCRAFT && IsNormalAircraft(v))) continue; - if (v->u.air.targetairport == st->index && v->u.air.state != FLYING) return CMD_ERROR; + Aircraft *a = (Aircraft *)v; + if (a->targetairport == st->index && a->state != FLYING) return CMD_ERROR; } BEGIN_TILE_LOOP(tile_cur, w, h, tile) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 28d026feb..857c4df8a 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -530,7 +530,7 @@ void Vehicle::PreDestructor() Station *st = GetTargetAirportIfValid(a); if (st != NULL) { const AirportFTA *layout = st->Airport()->layout; - CLRBITS(st->airport_flags, layout[this->u.air.previous_pos].block | layout[this->u.air.pos].block); + CLRBITS(st->airport_flags, layout[a->previous_pos].block | layout[a->pos].block); } } @@ -1571,10 +1571,13 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) /* If there is no depot in front, reverse automatically (trains only) */ if (this->type == VEH_TRAIN && reverse) DoCommand(this->tile, this->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); - if (this->type == VEH_AIRCRAFT && this->u.air.state == FLYING && this->u.air.targetairport != destination) { - /* The aircraft is now heading for a different hangar than the next in the orders */ - extern void AircraftNextAirportPos_and_Order(Aircraft *a); - AircraftNextAirportPos_and_Order((Aircraft *)this); + if (this->type == VEH_AIRCRAFT) { + Aircraft *a = (Aircraft *)this; + if (a->state == FLYING && a->targetairport != destination) { + /* The aircraft is now heading for a different hangar than the next in the orders */ + extern void AircraftNextAirportPos_and_Order(Aircraft *a); + AircraftNextAirportPos_and_Order(a); + } } } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 9434cd596..4719dd7af 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -149,15 +149,6 @@ enum VehicleRailFlags { VRF_TRAIN_STUCK = 8, }; -struct VehicleAir { - uint16 crashed_counter; - uint16 cached_max_speed; - byte pos; - byte previous_pos; - StationID targetairport; - byte state; -}; - struct VehicleRoad { byte state; ///< @see RoadVehicleStates byte frame; @@ -304,7 +295,6 @@ public: union { VehicleRail rail; - VehicleAir air; VehicleRoad road; } u; diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 5a78c747c..6dd38a346 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -10,6 +10,7 @@ #include "company_func.h" #include "vehicle_gui.h" #include "train.h" +#include "aircraft.h" #include "newgrf_engine.h" #include "newgrf_text.h" #include "functions.h" @@ -73,10 +74,11 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, case VEH_ROAD: break; - case VEH_AIRCRAFT: + case VEH_AIRCRAFT: { + Aircraft *a = (Aircraft *)v; /* cannot stop airplane when in flight, or when taking off / landing */ - if (v->u.air.state >= STARTTAKEOFF && v->u.air.state < TERM7) return_cmd_error(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT); - break; + if (a->state >= STARTTAKEOFF && a->state < TERM7) return_cmd_error(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT); + } break; default: return CMD_ERROR; } diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index b4a67024a..48f4bdb76 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -828,7 +828,7 @@ static void FloodVehicle(Vehicle *v) case VEH_AIRCRAFT: pass += 2; // driver - v->u.air.crashed_counter = 9000; // max 10000, disappear pretty fast + ((Aircraft *)v)->crashed_counter = 9000; // max 10000, disappear pretty fast InvalidateWindowClassesData(WC_AIRCRAFT_LIST, 0); break; } |