--- a/src/station_cmd.cpp Mon Jul 16 00:31:25 2007 +0000
+++ b/src/station_cmd.cpp Mon Jul 16 00:39:06 2007 +0000
@@ -44,6 +44,7 @@
#include "strings.h"
#include "table/station_air.h"
#include "airport_states.h"
+#include "newgrf_fsmports.h"
/**
* Called if a new block is added to the station-pool
@@ -1470,21 +1471,43 @@
return ret;
}
+static void GetFSMportsLayout(byte *layout, int width, int length, const FSMportsSpec *fsmportspec)
+{
+ if (fsmportspec != NULL) {
+ /* Custom layout defined, follow it. */
+ memcpy(layout, fsmportspec->layouts[width - 1][length - 1],
+ length * width);
+ return;
+ }
+
+ while (--width >= 0) {
+ layout = CreateMulti(layout, length, 4);
+ layout = CreateMulti(layout, length, 6);
+ }
+}
+
/** Place an Airport.
* @param tile tile where airport will be built
* @param flags operation to perform
- * @param p1 airport type, @see airport.h
- * @param p2 (bit 0) - allow airports directly adjacent to other airports.
+ * @param p1 various bitstuffed elements
+ * - p1 = (bit 0) - orientation (Axis)
+ * - p1 = (bit 8-15) - length
+ * - p1 = (bit 16-23) - width
+ * - p1 = (bit 24) - allow stations directly adjacent to other stations.
+ * @param p2 various bitstuffed elements
+ * - p2 = (bit 0- 3) - airport type
+ * - p2 = (bit 8-15) - custom fsmport class
+ * - p2 = (bit 16-23) - custom fsmport id
*/
CommandCost CmdBuildAirport(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
bool airport_upgrade = true;
- const uint airport_type_for_flat_check = 0x80 | (p1 << 3);
+ const uint airport_type_for_flat_check = 0x80 | (GB(p2, 0, 4) << 3);
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
/* Check if a valid, buildable airport was chosen for construction */
- if (p1 > lengthof(_airport_sections) || !HASBIT(GetValidAirports(), p1)) return CMD_ERROR;
+ //if (p1 > lengthof(_airport_sections) || !HASBIT(GetValidAirports(), p1)) return CMD_ERROR;
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile))
return CMD_ERROR;
@@ -1505,17 +1528,30 @@
}
}
- const AirportFTAClass *afc = GetAirport(p1);
+ const AirportFTAClass *afc = GetAirport(GB(p2, 0, 4));
int w = afc->size_x;
int h = afc->size_y;
- CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, airport_type_for_flat_check, NULL);
- if (CmdFailed(ret)) return ret;
- CommandCost cost(ret.GetCost());
-
Station *st = NULL;
- if (!_patches.adjacent_stations || !HASBIT(p2, 0)) {
+ /* Check if the given station class is valid */
+ if (GB(p2, 8, 8) >= FSMPORTS_CLASS_MAX) return CMD_ERROR;
+
+ /* Check if we can allocate a custom stationspec to this station */
+ const FSMportsSpec *fsmportsspec = GetCustomFSMportsSpec((FSMportsClassID)GB(p2, 8, 8), GB(p2, 16, 8));
+
+ if (fsmportsspec != NULL) {
+ /* Perform NewStation checks */
+ w = fsmportsspec->width;
+ h = fsmportsspec->lengths;
+
+ /* Check if the station is buildable */
+ if (HASBIT(fsmportsspec->callbackmask, CBM_STATION_AVAIL) && GetFSMportsCallback(CBID_STATION_AVAILABILITY, 0, 0, fsmportsspec, NULL, INVALID_TILE) == 0) {
+ return CMD_ERROR;
+ }
+ }
+
+ if (!_patches.adjacent_stations || !HASBIT(p1, 24)) {
st = GetStationAround(tile, w, h, INVALID_STATION);
if (st == CHECK_STATIONS_ERR) return CMD_ERROR;
}
@@ -1565,9 +1601,16 @@
}
}
+
+ CommandCost ret = CheckFlatLandBelow(tile, w, h, flags, airport_type_for_flat_check, NULL);
+ if (CmdFailed(ret)) return ret;
+ CommandCost cost(ret.GetCost());
+
cost.AddCost(_price.build_airport * w * h);
if (flags & DC_EXEC) {
+ byte *layout_ptr;
+
st->airport_tile = tile;
st->AddFacility(FACIL_AIRPORT, tile);
st->airport_type = (byte)p1;
@@ -1584,11 +1627,17 @@
*/
if (airport_upgrade) UpdateAirplanesOnNewStation(st);
+ int fsmportspecindex = AllocateFSMportsSpecToStation(fsmportsspec, st, flags & DC_EXEC);
+ if (fsmportspecindex == -1) return CMD_ERROR;
+
+ layout_ptr = (byte*)alloca(w * h);
+ GetFSMportsLayout(layout_ptr, w, h, fsmportsspec);
+
{
- const byte *b = _airport_sections[p1];
-
BEGIN_TILE_LOOP(tile_cur, w, h, tile) {
- MakeAirport(tile_cur, st->owner, st->index, *b++);
+ byte layout = *layout_ptr++;
+ MakeAirport(tile_cur, st->owner, st->index, layout);
+ SetCustomFSMportsSpecIndex(tile_cur, fsmportspecindex); //set top bit of m6 to indicate an fsmportsspec
} END_TILE_LOOP(tile_cur, w, h, tile)
}
@@ -1926,6 +1975,8 @@
uint32 relocation = 0;
const Station *st = NULL;
const StationSpec *statspec = NULL;
+ const FSMportsSpec *fsmportspec = NULL;
+ bool FSMport = false;
PlayerID owner = GetTileOwner(ti->tile);
SpriteID palette;
@@ -1943,7 +1994,13 @@
if (IsCustomStationSpecIndex(ti->tile)) {
// look for customization
st = GetStationByTile(ti->tile);
- statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
+ int specindex = GetCustomStationSpecIndex(ti->tile);
+ FSMport = IsCustomFSMportsSpecIndex(ti->tile);
+ if (FSMport) {
+ fsmportspec = st->fsmportsspeclist[specindex].spec;
+ } else {
+ statspec = st->speclist[specindex].spec;
+ }
//debug("Cust-o-mized %p", statspec);
@@ -1962,13 +2019,28 @@
t = &statspec->renderdata[tile < statspec->tiles ? tile : (uint)GetRailStationAxis(ti->tile)];
}
}
+ if (fsmportspec != NULL) {
+ uint tile = GetStationGfx(ti->tile);
+
+ relocation = GetCustomFSMportsRelocation(fsmportspec, st, ti->tile);
+
+ //if (HASBIT(fsmportspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
+ // uint16 callback = GetFSMportsCallback(CBID_FSMPORTS_SPRITE_LAYOUT, 0, 0, fsmportspec, st, ti->tile);
+ // if (callback != CALLBACK_FAILED) tile = (callback & ~1) + GetRailStationAxis(ti->tile);
+ //}
+
+ /* Ensure the chosen tile layout is valid for this custom station */
+ if (fsmportspec->renderdata != NULL) {
+ t = &fsmportspec->renderdata[tile < fsmportspec->tiles ? tile : (uint)GetRailStationAxis(ti->tile)];
+ }
+ }
}
if (t == NULL || t->seq == NULL) t = &_station_display_datas[GetStationGfx(ti->tile)];
SpriteID image = t->ground_sprite;
if (HASBIT(image, SPRITE_MODIFIER_USE_OFFSET)) {
- image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
+ image += (FSMport)? GetCustomFSMportsGroundRelocation(fsmportspec, st, ti->tile) : GetCustomStationGroundRelocation(statspec, st, ti->tile);
image += rti->custom_ground_offset;
} else {
image += rti->total_offset;