mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-07 06:39:08 +00:00
(svn r20366) -Codechange: store the rotation of the airport layout in the station struct and use it to rotate hangar tiles
This commit is contained in:
parent
330c2f979e
commit
d2f9b87ccd
@ -803,9 +803,10 @@ byte GetAircraftFlyingAltitude(const Aircraft *v)
|
||||
*
|
||||
* @param v The vehicle that is approaching the airport
|
||||
* @param apc The Airport Class being approached.
|
||||
* @param rotation The rotation of the airport.
|
||||
* @returns The index of the entry point
|
||||
*/
|
||||
static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc)
|
||||
static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation)
|
||||
{
|
||||
assert(v != NULL);
|
||||
assert(apc != NULL);
|
||||
@ -832,6 +833,7 @@ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc)
|
||||
/* We are northwest or southeast of the airport */
|
||||
dir = delta_y < 0 ? DIAGDIR_NW : DIAGDIR_SE;
|
||||
}
|
||||
dir = ChangeDiagDir(dir, (DiagDirDiff)ReverseDiagDir(DirToDiagDir(rotation)));
|
||||
return apc->entry_points[dir];
|
||||
}
|
||||
|
||||
@ -863,7 +865,7 @@ static bool AircraftController(Aircraft *v)
|
||||
if (st == NULL || st->airport.tile == INVALID_TILE) {
|
||||
/* Jump into our "holding pattern" state machine if possible */
|
||||
if (v->pos >= afc->nofelements) {
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, afc);
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, afc, DIR_N);
|
||||
} else if (v->targetairport != v->current_order.GetDestination()) {
|
||||
/* If not possible, just get out of here fast */
|
||||
v->state = FLYING;
|
||||
@ -1358,7 +1360,8 @@ void AircraftNextAirportPos_and_Order(Aircraft *v)
|
||||
|
||||
const Station *st = GetTargetAirportIfValid(v);
|
||||
const AirportFTAClass *apc = st == NULL ? GetAirport(AT_DUMMY) : st->airport.GetFTA();
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, apc);
|
||||
Direction rotation = st == NULL ? DIR_N : st->airport.rotation;
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, apc, rotation);
|
||||
}
|
||||
|
||||
void AircraftLeaveHangar(Aircraft *v)
|
||||
@ -1997,7 +2000,8 @@ void UpdateAirplanesOnNewStation(const Station *st)
|
||||
/* update position of airplane. If plane is not flying, landing, or taking off
|
||||
* you cannot delete airport, so it doesn't matter */
|
||||
if (v->state >= FLYING) { // circle around
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, ap);
|
||||
Direction rotation = st->airport.tile == INVALID_TILE ? DIR_N : st->airport.rotation;
|
||||
v->pos = v->previous_pos = AircraftGetEntryPoint(v, ap, rotation);
|
||||
v->state = FLYING;
|
||||
UpdateAircraftCache(v);
|
||||
/* landing plane needs to be reset to flying height (only if in pause mode upgrade,
|
||||
|
@ -356,7 +356,11 @@ public:
|
||||
this->DisableWidget(BAIRW_LAYOUT_INCREASE);
|
||||
} else {
|
||||
const AirportSpec *as = GetAirportSpecFromClass(_selected_airport_class, _selected_airport_index);
|
||||
SetTileSelectSize(as->size_x, as->size_y);
|
||||
int w = as->size_x;
|
||||
int h = as->size_y;
|
||||
Direction rotation = as->rotation[_selected_airport_layout];
|
||||
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
|
||||
SetTileSelectSize(w, h);
|
||||
|
||||
this->SetWidgetDisabledState(BAIRW_LAYOUT_DECREASE, _selected_airport_layout == 0);
|
||||
this->SetWidgetDisabledState(BAIRW_LAYOUT_INCREASE, _selected_airport_layout + 1 >= as->num_table);
|
||||
|
@ -59,6 +59,7 @@ struct HangarTileTable {
|
||||
struct AirportSpec {
|
||||
const struct AirportFTAClass *fsm; ///< the finite statemachine for the default airports
|
||||
const AirportTileTable * const *table; ///< list of the tiles composing the airport
|
||||
Direction *rotation; ///< the rotation of each tiletable
|
||||
byte num_table; ///< number of elements in the table
|
||||
const HangarTileTable *depot_table; ///< gives the position of the depots on the airports
|
||||
byte nof_depots; ///< the number of hangar tiles in this airport
|
||||
|
@ -337,6 +337,7 @@ static const SaveLoad _station_desc[] = {
|
||||
SLE_VAR(Station, airport.type, SLE_UINT8),
|
||||
SLE_CONDVAR(Station, airport.layout, SLE_UINT8, 145, SL_MAX_VERSION),
|
||||
SLE_VAR(Station, airport.flags, SLE_UINT64),
|
||||
SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, 145, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Station, indtype, SLE_UINT8),
|
||||
|
||||
|
@ -49,9 +49,10 @@ struct GoodsEntry {
|
||||
struct Airport : public TileArea {
|
||||
Airport() : TileArea(INVALID_TILE, 0, 0) {}
|
||||
|
||||
uint64 flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
|
||||
byte type; ///< Type of this airport, @see AirportTypes.
|
||||
byte layout; ///< Airport layout number.
|
||||
uint64 flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
|
||||
byte type; ///< Type of this airport, @see AirportTypes.
|
||||
byte layout; ///< Airport layout number.
|
||||
Direction rotation; ///< How this airport is rotated.
|
||||
|
||||
/**
|
||||
* Get the AirportSpec that from the airport type of this airport. If there
|
||||
@ -81,6 +82,30 @@ struct Airport : public TileArea {
|
||||
return this->GetSpec()->nof_depots > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the tileoffset to the base tile of this airport but rotate it first.
|
||||
* The base tile is the northernmost tile of this airport. This function
|
||||
* helps to make sure that getting the tile of a hangar works even for
|
||||
* rotated airport layouts without requiring a rotated array of hangar tiles.
|
||||
* @param tidc The tilediff to add to the airport tile.
|
||||
* @return The tile of this airport plus the rotated offset.
|
||||
*/
|
||||
FORCEINLINE TileIndex GetRotatedTileFromOffset(TileIndexDiffC tidc) const
|
||||
{
|
||||
const AirportSpec *as = this->GetSpec();
|
||||
switch (this->rotation) {
|
||||
case DIR_N: return this->tile + ToTileIndexDiff(tidc);
|
||||
|
||||
case DIR_E: return this->tile + TileDiffXY(tidc.y, as->size_x - 1 - tidc.x);
|
||||
|
||||
case DIR_S: return this->tile + TileDiffXY(as->size_x - 1 - tidc.x, as->size_y - 1 - tidc.y);
|
||||
|
||||
case DIR_W: return this->tile + TileDiffXY(as->size_y - 1 - tidc.y, tidc.x);
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first tile of the given hangar.
|
||||
* @param hangar_num The hangar to get the location of.
|
||||
@ -92,7 +117,7 @@ struct Airport : public TileArea {
|
||||
const AirportSpec *as = this->GetSpec();
|
||||
for (uint i = 0; i < as->nof_depots; i++) {
|
||||
if (as->depot_table[i].hangar_num == hangar_num) {
|
||||
return this->tile + ToTileIndexDiff(as->depot_table[i].ti);
|
||||
return this->GetRotatedTileFromOffset(as->depot_table[i].ti);
|
||||
}
|
||||
}
|
||||
NOT_REACHED();
|
||||
@ -108,7 +133,7 @@ struct Airport : public TileArea {
|
||||
{
|
||||
const AirportSpec *as = this->GetSpec();
|
||||
for (uint i = 0; i < as->nof_depots; i++) {
|
||||
if (this->tile + ToTileIndexDiff(as->depot_table[i].ti) == tile) {
|
||||
if (this->GetRotatedTileFromOffset(as->depot_table[i].ti) == tile) {
|
||||
return as->depot_table[i].hangar_num;
|
||||
}
|
||||
}
|
||||
|
@ -2125,9 +2125,11 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
const AirportSpec *as = AirportSpec::Get(airport_type);
|
||||
if (!as->IsAvailable() || layout >= as->num_table) return CMD_ERROR;
|
||||
|
||||
Direction rotation = as->rotation[layout];
|
||||
Town *t = ClosestTownFromTile(tile, UINT_MAX);
|
||||
int w = as->size_x;
|
||||
int h = as->size_y;
|
||||
if (rotation == DIR_E || rotation == DIR_W) Swap(w, h);
|
||||
|
||||
if (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread) {
|
||||
return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT);
|
||||
@ -2216,6 +2218,7 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||
st->airport.type = airport_type;
|
||||
st->airport.layout = layout;
|
||||
st->airport.flags = 0;
|
||||
st->airport.rotation = rotation;
|
||||
|
||||
st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
|
||||
|
||||
|
@ -373,21 +373,25 @@ static AirportTileTable *_tile_table_helistation[] = {
|
||||
_tile_table_helistation_0,
|
||||
};
|
||||
|
||||
static Direction _default_airports_rotation[] = {
|
||||
DIR_N,
|
||||
};
|
||||
|
||||
#undef MK
|
||||
#undef MKEND
|
||||
|
||||
/** General AirportSpec definition. */
|
||||
#define AS_GENERIC(fsm, att, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, enabled) \
|
||||
{fsm, att, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, enabled, {AT_INVALID, 0, NULL, NULL, AT_INVALID}}
|
||||
#define AS_GENERIC(fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, enabled) \
|
||||
{fsm, att, rot, att_len, depot_tbl, num_depots, size_x, size_y, noise, catchment, min_year, max_year, name, ttdpatch_type, class_id, enabled, {AT_INVALID, 0, NULL, NULL, AT_INVALID}}
|
||||
|
||||
/** AirportSpec definition for airports without any depot. */
|
||||
#define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, ttdpatch_type, class_id, name) \
|
||||
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, lengthof(_tile_table_##ap_name), NULL, 0, \
|
||||
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), NULL, 0, \
|
||||
size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, true)
|
||||
|
||||
/** AirportSpec definition for airports with at least one depot. */
|
||||
#define AS(ap_name, size_x, size_y, min_year, max_year, catchment, noise, ttdpatch_type, class_id, name) \
|
||||
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, lengthof(_tile_table_##ap_name), _airport_depots_##ap_name, lengthof(_airport_depots_##ap_name), \
|
||||
AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), _airport_depots_##ap_name, lengthof(_airport_depots_##ap_name), \
|
||||
size_x, size_y, noise, catchment, min_year, max_year, ttdpatch_type, class_id, name, true)
|
||||
|
||||
/* The helidepot and helistation have ATP_TTDP_SMALL because they are at ground level */
|
||||
@ -401,12 +405,12 @@ extern const AirportSpec _origin_airport_specs[] = {
|
||||
AS(helidepot, 2, 2, 1976, MAX_YEAR, 4, 2, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT),
|
||||
AS(intercontinental, 9, 11, 2002, MAX_YEAR, 10, 25, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL),
|
||||
AS(helistation, 4, 2, 1980, MAX_YEAR, 4, 3, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION),
|
||||
AS_GENERIC(&_airportfta_oilrig, NULL, 0, NULL, 0, 1, 1, 0, 4, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, false),
|
||||
AS_GENERIC(&_airportfta_oilrig, NULL, _default_airports_rotation, 0, NULL, 0, 1, 1, 0, 4, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, false),
|
||||
};
|
||||
|
||||
assert_compile(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs));
|
||||
|
||||
AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, NULL, 0, NULL, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, false);
|
||||
AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, NULL, _default_airports_rotation, 0, NULL, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, false);
|
||||
|
||||
#undef AS
|
||||
#undef AS_ND
|
||||
|
Loading…
Reference in New Issue
Block a user