From e17a8989cf87ee7b94199873429b238e9c0c8d62 Mon Sep 17 00:00:00 2001 From: celestar Date: Sun, 9 Jan 2005 08:49:40 +0000 Subject: (svn r1440) -Feature: Allows more flexible airport layouts now, as the number of terminals in every group can be freely chosen -Codechange: AT_OILRIG is now 15, so that new airports can be added easily. --- aircraft_cmd.c | 94 +++++++++++++++++++++++++++++++---------- airport.c | 120 +++++++++++++++++++++++++++++++++++++++++++---------- airport.h | 8 ++-- airport_movement.h | 18 +++++++- saveload.c | 2 +- ttd.c | 10 ++++- 6 files changed, 200 insertions(+), 52 deletions(-) diff --git a/aircraft_cmd.c b/aircraft_cmd.c index 0009078ef..5ea991379 100644 --- a/aircraft_cmd.c +++ b/aircraft_cmd.c @@ -373,7 +373,7 @@ int32 CmdSendAircraftToHangar(int x, int y, uint32 flags, uint32 p1, uint32 p2) st = GetStation(v->u.air.targetairport); // If an airport doesn't have terminals (so no landing space for airports), // it surely doesn't have any hangars - if (st->xy == 0 || st->airport_tile == 0 || GetAirport(st->airport_type)->nofterminals == 0) + if (st->xy == 0 || st->airport_tile == 0 || GetAirport(st->airport_type)->terminals == NULL) return CMD_ERROR; if (flags & DC_EXEC) { @@ -495,7 +495,7 @@ static void CheckIfAircraftNeedsService(Vehicle *v) st = GetStation(v->current_order.station); // only goto depot if the target airport has terminals (eg. it is airport) - if (st->xy != 0 && st->airport_tile != 0 && GetAirport(st->airport_type)->nofterminals != 0) { + if (st->xy != 0 && st->airport_tile != 0 && GetAirport(st->airport_type)->terminals != NULL) { // printf("targetairport = %d, st->index = %d\n", v->u.air.targetairport, st->index); // v->u.air.targetairport = st->index; v->current_order.type = OT_GOTO_DEPOT; @@ -1356,7 +1356,7 @@ static void AircraftEventHandler_AtTerminal(Vehicle *v, const AirportFTAClass *A // on an airport with helipads, a helicopter will always land there // and get serviced at the same time - patch setting if (_patches.serviceathelipad) { - if (v->subtype == 0 && Airport->nofhelipads > 0) { + if (v->subtype == 0 && Airport->helipads != NULL) { // an exerpt of ServiceAircraft, without the invisibility stuff v->date_of_last_service = _date; v->breakdowns_since_last_service = 0; @@ -1518,7 +1518,7 @@ static void AircraftEventHandler_HeliEndLanding(Vehicle *v, const AirportFTAClas if (v->current_order.type == OT_GOTO_STATION) { if (AirportFindFreeHelipad(v, Airport)) {return;} } - v->u.air.state = (Airport->nofterminals != 0) ? HANGAR : HELITAKEOFF; + v->u.air.state = (Airport->terminals != NULL) ? HANGAR : HELITAKEOFF; } typedef void AircraftStateHandler(Vehicle *v, const AirportFTAClass *Airport); @@ -1696,9 +1696,18 @@ static bool FreeTerminal(Vehicle *v, byte i, byte last_terminal) return false; } +static int GetNumTerminals(const AirportFTAClass *Airport) +{ + int i, num = 0; + + for (i = Airport->terminals[0]; i > 0; i--) + num += Airport->terminals[i]; + + return num; +} + static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *Airport) { - byte nofterminalspergroup, i; AirportFTA *temp; Station *st; @@ -1712,18 +1721,29 @@ static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *Airport) possible groups are checked (in this case group 1, since that is after group 0). If that fails, then attempt fails and plane waits */ - if (Airport->nofterminalgroups > 1) { + if (Airport->terminals[0] > 1) { st = GetStation(v->u.air.targetairport); - nofterminalspergroup = Airport->nofterminals / Airport->nofterminalgroups; temp = Airport->layout[v->u.air.pos].next_in_chain; while (temp != NULL) { if (temp->heading == 255) { if (!HASBITS(st->airport_flags, temp->block)) { - i = temp->next_position * nofterminalspergroup; // next_position denotes the group to check - // only that group will be checked (eg 6 terms, 2 groups) - // with i = 0 terms 1 - 3 and - // with i = 1 terms 4 - 6 - if (FreeTerminal(v, i, i + nofterminalspergroup)) {return true;} + int target_group; + int i; + int group_start = 0; + int group_end; + + //read which group do we want to go to? + //(the first free group) + target_group = temp->next_position + 1; + + //at what terminal does the group start? + //that means, sum up all terminals of + //groups with lower number + for(i = 1; i < target_group; i++) + group_start += Airport->terminals[i]; + + group_end = group_start + Airport->terminals[target_group]; + if (FreeTerminal(v, group_start, group_end)) {return true;} } } else {return false;} // once the heading isn't 255, we've exhausted the possible blocks. So we cannot move @@ -1732,29 +1752,52 @@ static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *Airport) } // if there is only 1 terminalgroup, all terminals are checked (starting from 0 to max) - return FreeTerminal(v, 0, Airport->nofterminals); + return FreeTerminal(v, 0, GetNumTerminals(Airport)); } +static int GetNumHelipads(const AirportFTAClass *Airport) +{ + int i, num = 0; + + for (i = Airport->helipads[0]; i > 0; i--) + num += Airport->helipads[i]; + + return num; +} + + static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *Airport) { Station *st; - byte nofhelipadspergroup, i; AirportFTA *temp; // if an airport doesn't have helipads, use terminals - if (Airport->nofhelipads == 0) {return AirportFindFreeTerminal(v, Airport);} + if (Airport->helipads == NULL) {return AirportFindFreeTerminal(v, Airport);} // if there are more helicoptergroups, pick one, just as in AirportFindFreeTerminal() - if (Airport->nofhelipadgroups > 1) { + if (Airport->helipads[0] > 1) { st = GetStation(v->u.air.targetairport); - nofhelipadspergroup = Airport->nofhelipads / Airport->nofhelipadgroups; temp = Airport->layout[v->u.air.pos].next_in_chain; while (temp != NULL) { if (temp->heading == 255) { if (!HASBITS(st->airport_flags, temp->block)) { - i = temp->next_position * nofhelipadspergroup; // next position is the group to check - // heliports start from after TERMINALS, so MAX_TERMINALS needs to be added - if (FreeTerminal(v, i + MAX_TERMINALS, i + MAX_TERMINALS + nofhelipadspergroup)) {return true;} + int target_group; + int i; + int group_start = 0; + int group_end; + + //read which group do we want to go to? + //(the first free group) + target_group = temp->next_position + 1; + + //at what terminal does the group start? + //that means, sum up all terminals of + //groups with lower number + for(i = 1; i < target_group; i++) + group_start += Airport->helipads[i]; + + group_end = group_start + Airport->helipads[target_group]; + if (FreeTerminal(v, group_start, group_end)) {return true;} } } else {return false;} // once the heading isn't 255, we've exhausted the possible blocks. So we cannot move @@ -1763,7 +1806,7 @@ static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *Airport) } // only 1 helicoptergroup, check all helipads // The blocks for helipads start after the last terminal (MAX_TERMINALS) - else {return FreeTerminal(v, MAX_TERMINALS, Airport->nofhelipads + MAX_TERMINALS);} + else {return FreeTerminal(v, MAX_TERMINALS, GetNumHelipads(Airport) + MAX_TERMINALS);} return false; // it shouldn't get here anytime, but just to be sure } @@ -1821,6 +1864,15 @@ void Aircraft_Tick(Vehicle *v) } } +void UpdateOilRig( void ) +{ + Station *st; + + FOR_ALL_STATIONS(st) { + if (st->airport_type == 5) st->airport_type = AT_OILRIG; + } +} + // need to be called to load aircraft from old version void UpdateOldAircraft() { diff --git a/airport.c b/airport.c index 63a1c633a..e94ed2daa 100644 --- a/airport.c +++ b/airport.c @@ -10,8 +10,7 @@ AirportFTAClass *MetropolitanAirport; AirportFTAClass *InternationalAirport; static void AirportFTAClass_Constructor(AirportFTAClass *Airport, - const byte nofterminals, const byte nofterminalgroups, - const byte nofhelipads, const byte nofhelipadgroups, + const byte *terminals, const byte *helipads, const byte entry_point, const byte acc_planes, const AirportFTAbuildup *FA, const TileIndexDiffC *depots, const byte nof_depots); @@ -26,24 +25,75 @@ static byte AirportBlockToString(uint32 block);*/ void InitializeAirports() { // country airport - CountryAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass)); - AirportFTAClass_Constructor(CountryAirport, 2, 1, 0, 0, 16, ALL, _airport_fta_country, _airport_depots_country, lengthof(_airport_depots_country)); + CountryAirport = malloc(sizeof(AirportFTAClass)); + + AirportFTAClass_Constructor( + CountryAirport, + _airport_terminal_country, + NULL, + 16, + ALL, + _airport_fta_country, + _airport_depots_country, + lengthof(_airport_depots_country) + ); // city airport - CityAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass)); - AirportFTAClass_Constructor(CityAirport, 3, 1, 0, 0, 19, ALL, _airport_fta_city, _airport_depots_city, lengthof(_airport_depots_city)); + CityAirport = malloc(sizeof(AirportFTAClass)); + + AirportFTAClass_Constructor( + CityAirport, + _airport_terminal_city, + NULL, + 19, + ALL, + _airport_fta_city, + _airport_depots_city, + lengthof(_airport_depots_city) + ); // metropolitan airport - MetropolitanAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass)); - AirportFTAClass_Constructor(MetropolitanAirport, 3, 1, 0, 0, 20, ALL, _airport_fta_metropolitan, _airport_depots_metropolitan, lengthof(_airport_depots_metropolitan)); + MetropolitanAirport = malloc(sizeof(AirportFTAClass)); + + AirportFTAClass_Constructor( + MetropolitanAirport, + _airport_terminal_metropolitan, + NULL, + 20, + ALL, + _airport_fta_metropolitan, + _airport_depots_metropolitan, + lengthof(_airport_depots_metropolitan) + ); // international airport InternationalAirport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass)); - AirportFTAClass_Constructor(InternationalAirport, 6, 2, 2, 1, 37, ALL, _airport_fta_international, _airport_depots_international, lengthof(_airport_depots_international)); + + AirportFTAClass_Constructor( + InternationalAirport, + _airport_terminal_international, + _airport_helipad_international, + 37, + ALL, + _airport_fta_international, + _airport_depots_international, + lengthof(_airport_depots_international) + ); // heliport, oilrig Heliport = (AirportFTAClass *)malloc(sizeof(AirportFTAClass)); - AirportFTAClass_Constructor(Heliport, 0, 0, 1, 1, 7, HELICOPTERS_ONLY, _airport_fta_heliport_oilrig, NULL, 0); + + AirportFTAClass_Constructor( + Heliport, + NULL, + _airport_helipad_heliport_oilrig, + 7, + HELICOPTERS_ONLY, + _airport_fta_heliport_oilrig, + NULL, + 0 + ); + Oilrig = Heliport; // exactly the same structure for heliport/oilrig, so share state machine } @@ -57,12 +107,46 @@ void UnInitializeAirports() } static void AirportFTAClass_Constructor(AirportFTAClass *Airport, - const byte nofterminals, const byte nofterminalgroups, - const byte nofhelipads, const byte nofhelipadgroups, + const byte *terminals, const byte *helipads, const byte entry_point, const byte acc_planes, const AirportFTAbuildup *FA, const TileIndexDiffC *depots, const byte nof_depots) { + byte nofterminals, nofhelipads; + byte nofterminalgroups = 0; + byte nofhelipadgroups = 0; + const byte * curr; + int i; + nofterminals = nofhelipads = 0; + + //now we read the number of terminals we have + if (terminals != NULL) { + i = terminals[0]; + nofterminalgroups = i; + curr = terminals; + while (i-- > 0) { + curr++; + assert(*curr != 0); //we don't want to have an empty group + nofterminals += *curr; + } + + } + Airport->terminals = terminals; + + //read helipads + if (helipads != NULL) { + i = helipads[0]; + nofhelipadgroups = i; + curr = helipads; + while (i-- > 0) { + curr++; + assert(*curr != 0); //no empty groups please + nofhelipads += *curr; + } + + } + Airport->helipads = helipads; + // if there are more terminals than 6, internal variables have to be changed, so don't allow that // same goes for helipads if (nofterminals > MAX_TERMINALS) { printf("Currently only maximum of %2d terminals are supported (you wanted %2d)\n", MAX_TERMINALS, nofterminals);} @@ -70,23 +154,15 @@ static void AirportFTAClass_Constructor(AirportFTAClass *Airport, // terminals/helipads are divided into groups. Groups are computed by dividing the number // of terminals by the number of groups. Half in half. If #terminals is uneven, first group // will get the less # of terminals - if (nofterminalgroups > nofterminals) { printf("# of terminalgroups (%2d) must be less or equal to terminals (%2d)", nofterminals, nofterminalgroups);} - if (nofhelipadgroups > nofhelipads) { printf("# of helipadgroups (%2d) must be less or equal to helipads (%2d)", nofhelipads, nofhelipadgroups);} assert(nofterminals <= MAX_TERMINALS); assert(nofhelipads <= MAX_HELIPADS); - assert(nofterminalgroups <= nofterminals); - assert(nofhelipadgroups <= nofhelipads); Airport->nofelements = AirportGetNofElements(FA); // check if (entry_point >= Airport->nofelements) {printf("Entry point (%2d) must be within the airport positions (which is max %2d)\n", entry_point, Airport->nofelements);} assert(entry_point < Airport->nofelements); - Airport->nofterminals = nofterminals; - Airport->nofterminalgroups = nofterminalgroups; - Airport->nofhelipads = nofhelipads; - Airport->nofhelipadgroups = nofhelipadgroups; Airport->acc_planes = acc_planes; Airport->entry_point = entry_point; Airport->airport_depots = depots; @@ -95,8 +171,8 @@ static void AirportFTAClass_Constructor(AirportFTAClass *Airport, // build the state machine AirportBuildAutomata(Airport, FA); - DEBUG(misc, 1) ("#Elements %2d; #Terminals %2d in %d group(s); #Helipads %2d in %d group(s)", Airport->nofelements, - Airport->nofterminals, Airport->nofterminalgroups, Airport->nofhelipads, Airport->nofhelipadgroups); + DEBUG(misc, 1) ("#Elements %2d; #Terminals %2d in %d group(s); #Helipads %2d in %d group(s); Entry Point %d", Airport->nofelements, + nofterminals, nofterminalgroups, nofhelipads, nofhelipadgroups, Airport->entry_point); { diff --git a/airport.h b/airport.h index f3204a152..5242f995a 100644 --- a/airport.h +++ b/airport.h @@ -13,7 +13,7 @@ enum { AT_HELIPORT = 2, AT_METROPOLITAN = 3, AT_INTERNATIONAL = 4, - AT_OILRIG = 5 + AT_OILRIG = 15 }; // do not change unless you change v->subtype too. This aligns perfectly with its current setting @@ -26,10 +26,8 @@ enum { // Finite sTate mAchine --> FTA typedef struct AirportFTAClass { byte nofelements; // number of positions the airport consists of - byte nofterminals; // number of terminals this airport has - byte nofterminalgroups; // terminals belong to so many groups (MAX is the nofterminals) - byte nofhelipads; // number of helipads this airport has - byte nofhelipadgroups; // helipads belong to so many groups (MAX is the nofhelipads) + const byte *terminals; + const byte *helipads; byte entry_point; // when an airplane arrives at this airport, enter it at position entry_point byte acc_planes; // accept airplanes or helicopters or both const TileIndexDiffC *airport_depots; // gives the position of the depots on the airports diff --git a/airport_movement.h b/airport_movement.h index 652017e0a..fdc8c2292 100644 --- a/airport_movement.h +++ b/airport_movement.h @@ -264,6 +264,7 @@ static const AirportMovingData _airport_moving_data_oilrig[9] = { // first element of depots array tells us how many depots there are (to know size of array) // this may be changed later when airports are moved to external file static const TileIndexDiffC _airport_depots_country[] = {{3, 0}}; +static const byte _airport_terminal_country[] = {1, 2}; static const AirportFTAbuildup _airport_fta_country[] = { { 0,HANGAR,NOTHING_block,1}, { 1,255,AIRPORT_BUSY_block,0}, {1,HANGAR,0,0}, {1,TERM1,TERM1_block,2}, {1,TERM2,0,4}, {1,HELITAKEOFF,0,19}, {1,0,0,6}, @@ -294,6 +295,7 @@ static const AirportFTAbuildup _airport_fta_country[] = { }; static const TileIndexDiffC _airport_depots_city[] = {{5, 0}}; +static const byte _airport_terminal_city[] = {1, 3}; 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 @@ -328,6 +330,7 @@ static const AirportFTAbuildup _airport_fta_city[] = { }; static const TileIndexDiffC _airport_depots_metropolitan[] = {{5, 0}}; +static const byte _airport_terminal_metropolitan[] = {1, 3}; static const AirportFTAbuildup _airport_fta_metropolitan[] = { { 0,HANGAR,NOTHING_block,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 @@ -364,6 +367,8 @@ static const AirportFTAbuildup _airport_fta_metropolitan[] = { }; static const TileIndexDiffC _airport_depots_international[] = {{0, 3}, {6, 1}}; +static const byte _airport_terminal_international[] = {2, 3, 3}; +static const byte _airport_helipad_international[] = {1, 2}; static const AirportFTAbuildup _airport_fta_international[] = { { 0,HANGAR,NOTHING_block,2}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER1_block,1}, {0,HELITAKEOFF,HELIPAD1_block,2}, {0,0,0,2}, { 1,HANGAR,NOTHING_block,3}, {1,255,HANGAR2_AREA_block,1}, {1,HELITAKEOFF,HELIPAD2_block,3}, {1,0,0,3}, @@ -426,6 +431,7 @@ static const AirportFTAbuildup _airport_fta_international[] = { }; // heliports, oilrigs don't have depots +static const byte _airport_helipad_heliport_oilrig[] = {1, 1}; static const AirportFTAbuildup _airport_fta_heliport_oilrig[] = { {0,HELIPAD1,HELIPAD1_block,1}, {1,HELITAKEOFF,NOTHING_block,0}, // takeoff @@ -440,12 +446,22 @@ static const AirportFTAbuildup _airport_fta_heliport_oilrig[] = { {MAX_ELEMENTS,0,0,0} // end marker. DO NOT REMOVE }; -static const AirportMovingData * const _airport_moving_datas[6] = { +static const AirportMovingData * const _airport_moving_datas[] = { _airport_moving_data_country, // Country Airfield (small) 4x3 _airport_moving_data_town, // City Airport (large) 6x6 _airport_moving_data_heliport, // Heliport _airport_moving_data_metropolitan, // Metropolitain Airport (large) - 2 runways _airport_moving_data_international, // International Airport (xlarge) - 2 runways + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, _airport_moving_data_oilrig // Oilrig }; diff --git a/saveload.c b/saveload.c index 328ac91be..bfba0ff7b 100644 --- a/saveload.c +++ b/saveload.c @@ -8,7 +8,7 @@ enum { SAVEGAME_MAJOR_VERSION = 5, - SAVEGAME_MINOR_VERSION = 0, + SAVEGAME_MINOR_VERSION = 1, SAVEGAME_LOADABLE_VERSION = (SAVEGAME_MAJOR_VERSION << 8) + SAVEGAME_MINOR_VERSION }; diff --git a/ttd.c b/ttd.c index 1a26dbfb3..266ca8571 100644 --- a/ttd.c +++ b/ttd.c @@ -1250,13 +1250,14 @@ void UpdateVoidTiles() memset(_map_type_and_height + MapMaxY() * MapSizeX(), MP_VOID << 4, MapSizeX()); } -extern void UpdateOldAircraft(); +extern void UpdateOldAircraft( void ); +extern void UpdateOilRig( void ); bool AfterLoadGame(uint version) { Window *w; ViewPort *vp; - + // in version 2.1 of the savegame, town owner was unified. if (version <= 0x200) { ConvertTownOwner(); @@ -1354,6 +1355,11 @@ bool AfterLoadGame(uint version) DoZoomInOutWindow(ZOOM_NONE, w); // update button status MarkWholeScreenDirty(); + //In 5.1, Oilrigs have been moved (again) + if (version <= 0x500) { + UpdateOilRig(); + } + return true; } -- cgit v1.2.3-70-g09d2