src/station_cmd.cpp
branchNewGRF_ports
changeset 6722 72f280229ee1
parent 6720 35756db7e577
child 6724 cfa62b4744d4
--- 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;