(svn r20366) -Codechange: store the rotation of the airport layout in the station struct and use it to rotate hangar tiles

pull/155/head
yexo 14 years ago
parent 7f7e3d4a3a
commit 2743532ae5

@ -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…
Cancel
Save