(svn r10977) [NewGRF_ports] -Feature: Added multi-tile depot support. NewGRF_ports
authorrichk
Fri, 24 Aug 2007 22:53:07 +0000
branchNewGRF_ports
changeset 6863 13335bf10adb
parent 6862 0b2c0e2b5356
child 6864 2c66eda48c11
(svn r10977) [NewGRF_ports] -Feature: Added multi-tile depot support.
In the newgrf depot list, each depot is defined as x, y, FSMposition. The FSMposition is the location in the state machine that has the moving data that defines where the hangar is. Thus, you can enter a depot at several locations, but you always exit at the same location (unless you define it as a separate depot).
All state machines updated to use new depot definitions.
bin/data/airportsbasic.grf
bin/data/airportsextended.grf
bin/data/realworldairports.grf
bin/data/seaplaneport.grf
bin/data/sprites/airportsbasic.nfo
bin/data/sprites/airportsextended.nfo
bin/data/sprites/seaplaneport.nfo
src/ai/default/default.cpp
src/aircraft_cmd.cpp
src/fsmport.h
src/newgrf.cpp
src/station_cmd.cpp
Binary file bin/data/airportsbasic.grf has changed
Binary file bin/data/airportsextended.grf has changed
Binary file bin/data/realworldairports.grf has changed
Binary file bin/data/seaplaneport.grf has changed
--- a/bin/data/sprites/airportsbasic.nfo	Fri Aug 24 20:14:22 2007 +0000
+++ b/bin/data/sprites/airportsbasic.nfo	Fri Aug 24 22:53:07 2007 +0000
@@ -252,7 +252,7 @@
 		1C 10 10 10 10
 
 // Prop1D Hangar/Depot Locations
-		1D 01 03 00 01
+		1D 01 03 00 00
 
 // Prop1E Terminal Groups
 		1E 01 02
@@ -638,7 +638,7 @@
 		1C 1A 1D 1B 1C
 
 // Prop1D Hangar/Depot Locations
-		1D 01 05 00 01
+		1D 01 05 00 00
 
 // Prop1E Terminal Groups
 		1E 01 03
--- a/bin/data/sprites/airportsextended.nfo	Fri Aug 24 20:14:22 2007 +0000
+++ b/bin/data/sprites/airportsextended.nfo	Fri Aug 24 22:53:07 2007 +0000
@@ -535,7 +535,7 @@
 		1C 15 15 15 15
 
 // Prop1D Hangar/Depot Locations
-		1D 01 04 00 01
+		1D 01 04 00 00
 
 // Prop1E Terminal Groups
 		1E 01 03
@@ -882,7 +882,7 @@
 		1C 14 14 14 14
 
 // Prop1D Hangar/Depot Locations
-		1D 01 05 00 01
+		1D 01 05 00 00
 
 // Prop1E Terminal Groups
 		1E 01 03
@@ -1400,7 +1400,7 @@
 		1C 25 25 25 25
 
 // Prop1D Hangar/Depot Locations
-		1D 02 00 03 01 06 01 02
+		1D 02 00 03 00 06 01 01
 
 // Prop1E Terminal Groups
 		1E 02 03 03
@@ -1676,7 +1676,7 @@
 		1C 04 04 04 04
 
 // Prop1D Hangar/Depot Locations
-		1D 01 01 00 01
+		1D 01 01 00 00
 
 // Prop1F Helipad Groups
 		1F 01 01
@@ -2409,7 +2409,7 @@
 		1C 2B 2C 2D 2E
 
 // Prop1D Hangar/Depot Locations
-		1D 02 00 05 01 08 04 02
+		1D 02 00 05 00 08 04 01
 
 // Prop1E Terminal Groups
 		1E 02 04 04
@@ -2722,7 +2722,7 @@
 		1C 19 19 19 19
 
 // Prop1D Hangar/Depot Locations
-		1D 01 00 00 01
+		1D 01 00 00 00
 
 // Prop1F Helipad Groups
 		1F 01 03
--- a/bin/data/sprites/seaplaneport.nfo	Fri Aug 24 20:14:22 2007 +0000
+++ b/bin/data/sprites/seaplaneport.nfo	Fri Aug 24 22:53:07 2007 +0000
@@ -246,7 +246,7 @@
 		1C 10 10 10 10
 
 // Prop1D Hangar/Depot Locations
-		1D 01 03 00 01
+		1D 01 03 00 00
 
 // Prop1E Terminal Groups
 		1E 01 02
--- a/src/ai/default/default.cpp	Fri Aug 24 20:14:22 2007 +0000
+++ b/src/ai/default/default.cpp	Fri Aug 24 22:53:07 2007 +0000
@@ -3511,7 +3511,7 @@
 
 	/* XXX - Have the AI pick the hangar terminal in an airport. Eg get airport-type
 	 * and offset to the FIRST depot because the AI picks the st->xy tile */
-	tile += ToTileIndexDiff(GetStationByTile(tile)->Airport()->depots[0]);
+	tile += ToTileIndexDiff(GetStationByTile(tile)->Airport()->depots[0].tile_pos);
 	if (CmdFailed(DoCommand(tile, veh, 0, DC_EXEC, CMD_BUILD_AIRCRAFT))) return;
 	loco_id = _new_vehicle_id;
 
--- a/src/aircraft_cmd.cpp	Fri Aug 24 20:14:22 2007 +0000
+++ b/src/aircraft_cmd.cpp	Fri Aug 24 22:53:07 2007 +0000
@@ -417,16 +417,16 @@
 			TileIndexDiffC depots;
 			if (IsCustomFSMportsSpecIndex(tile)) {
 				apc = st->fsmportsspeclist[1].spec->portFSM;
-				depots = RotateFSMPosition(apc->depots[i], st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
+				depots = RotateFSMPosition(apc->depots[i].tile_pos, st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
 										   st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set], st->FSMport_orientation);
 			} else {
 				apc = st->Airport();
-				depots = apc->depots[i];
+				depots = apc->depots[i].tile_pos;
 			}
 
 			assert(i != apc->num_depots);  //asserts if depot not found
 			if (st->airport_tile + ToTileIndexDiff(depots) == tile) {
-
+//TODO: update this to work with multi tile depots
 				/* adjust all the initial position data by the orientation of the airport */
 				AirportMovingData amd = RotateAMDbyOrientation(v, *apc->MovingData(i), st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
 											 st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set], st->FSMport_orientation);
@@ -903,11 +903,24 @@
 	}
 }
 
+extern FSMDepots GetKeyDepotByTile(TileIndex t);
+extern TileIndex GetKeyDepotTile(TileIndex t);
+
+AirportMovingData GetMovingDataKeyDepotTile(Vehicle *v, TileIndex t)
+{
+	Station *st = GetStationByTile(t);
+	const FSMPortMovingData *md = st->fsmportsspeclist[1].spec->portFSM->MovingData(GetKeyDepotByTile(t).FSMposition);
+	AirportMovingData amd = RotateAMDbyOrientation(v, *md, st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
+									st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set], st->FSMport_orientation);
+	return amd;
+}
+
 /** Handle Aircraft specific tasks when a an Aircraft enters a hangar
  * @param *v Vehicle that enters the hangar
  */
 void HandleAircraftEnterHangar(Vehicle *v)
 {
+	Station *st = GetStationByTile(v->tile);
 	v->subspeed = 0;
 	v->progress = 0;
 
@@ -919,7 +932,11 @@
 		u->cur_speed = 0;
 	}
 
-	SetAircraftPosition(v, v->x_pos, v->y_pos, v->z_pos);
+	AirportMovingData md = GetMovingDataKeyDepotTile(v, v->tile);
+	v->u.air.previous_pos = v->u.air.pos = GetKeyDepotByTile(v->tile).FSMposition;
+	v->tile = GetKeyDepotTile(v->tile);
+	SetAircraftPosition(v, (TILE_SIZE * TileX(st->airport_tile)) + md.x, (TILE_SIZE * TileY(st->airport_tile)) + md.y,
+							GetTileMaxZ(st->airport_tile) + md.z + 1);
 }
 
 static void PlayAircraftSound(const Vehicle* v)
--- a/src/fsmport.h	Fri Aug 24 20:14:22 2007 +0000
+++ b/src/fsmport.h	Fri Aug 24 22:53:07 2007 +0000
@@ -19,7 +19,7 @@
 };
 
 struct FSMCommand {
-	FSMCommand *next;           ///< Possible extra movement choices from this position
+	FSMCommand *next;         ///< Possible extra movement choices from this position
 	FSMblockmap reserveblock; ///< The blocks to reserve at this state
 	FSMblockmap releaseblock; ///< The blocks to release at this state
 	byte position;            ///< The position that a vehicle is at
@@ -28,6 +28,12 @@
 	byte special;             ///< Used as extra data for special orders 7B, 7C, 7D, 7E
 };
 
+struct FSMDepots {
+	TileIndexDiffC tile_pos;  ///< position of depot on port
+	byte FSMposition;         ///< position of main depot location in state machine
+							  ///< (used to identify location from which vehicles emerge in multi tile depots)
+};
+
 /** Forward declaration, as we need a circular dependancy */
 struct FSMportsSpec;
 
@@ -46,9 +52,9 @@
 
 	FSMPortMovingData *moving_data;
 	FSMCommand *layout;
-	byte num_positions;                     // number of positions the airport consists of
+	byte num_positions;                   // number of positions the airport consists of
 
-	TileIndexDiffC *depots; // gives the position of the depots on the airports
+	FSMDepots *depots;                    // gives the position of the depots on the airports
 	byte num_depots;                      // number of depots this airport has
 
 	byte size_x;
--- a/src/newgrf.cpp	Fri Aug 24 20:14:22 2007 +0000
+++ b/src/newgrf.cpp	Fri Aug 24 22:53:07 2007 +0000
@@ -2315,13 +2315,13 @@
 
 			case 0x1D: // Hangar locations
 				fsmportspec->portFSM->num_depots = grf_load_byte(&buf);
-				fsmportspec->portFSM->depots = MallocT<TileIndexDiffC>(fsmportspec->portFSM->num_depots);
+				fsmportspec->portFSM->depots = MallocT<FSMDepots>(fsmportspec->portFSM->num_depots);
 				for (uint depot = 0; depot < fsmportspec->portFSM->num_depots; depot++) {
-					TileIndexDiffC depot_tile;
-					depot_tile.x = grf_load_byte(&buf);
-					depot_tile.y = grf_load_byte(&buf);
-					grf_load_byte(&buf);  //TODO: depot number. for the moment discard. will be used to allow multi-tile depots
-					fsmportspec->portFSM->depots[depot] = depot_tile;
+					FSMDepots fsmdepot;
+					fsmdepot.tile_pos.x = grf_load_byte(&buf);
+					fsmdepot.tile_pos.y = grf_load_byte(&buf);
+					fsmdepot.FSMposition = grf_load_byte(&buf);  //identifies position in FSM associated with main depot location for multi-tile depots
+					fsmportspec->portFSM->depots[depot] = fsmdepot;
 				}
 				break;
 
--- a/src/station_cmd.cpp	Fri Aug 24 20:14:22 2007 +0000
+++ b/src/station_cmd.cpp	Fri Aug 24 22:53:07 2007 +0000
@@ -59,7 +59,7 @@
 	assert(IsTileType(t, MP_STATION));
 
 	Station *st = GetStationByTile(t);
-	TileIndexDiffC *hangar_list;
+	FSMDepots *hangar_list;
 	byte num_depots;
 	if (IsCustomFSMportsSpecIndex(t)) {
 		hangar_list = st->fsmportsspeclist[1].spec->portFSM->depots;
@@ -69,7 +69,7 @@
 		num_depots = st->Airport()->num_depots;
 	}
 	for (uint i = 0; i < num_depots; i++) {
-		TileIndexDiffC depot = RotateFSMPosition(hangar_list[i],
+		TileIndexDiffC depot = RotateFSMPosition(hangar_list[i].tile_pos,
 												 st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
 												 st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set],
 												 st->FSMport_orientation);
@@ -80,6 +80,55 @@
 	return false;
 }
 
+
+FSMDepots GetKeyDepotByTile(TileIndex t)
+{
+	Station *st = GetStationByTile(t);
+
+	FSMDepots *hangar_list;
+	byte num_depots;
+	uint i;
+
+	if (IsCustomFSMportsSpecIndex(t)) {
+		hangar_list = st->fsmportsspeclist[1].spec->portFSM->depots;
+		num_depots = st->fsmportsspeclist[1].spec->portFSM->num_depots;
+	} else {
+		hangar_list = st->Airport()->depots;
+		num_depots = st->Airport()->num_depots;
+	}
+	for (i = 0; i < num_depots; i++) {
+		TileIndexDiffC depot = RotateFSMPosition(hangar_list[i].tile_pos,
+												 st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
+												 st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set],
+												 st->FSMport_orientation);
+		if (st->airport_tile + ToTileIndexDiff(depot) == t) {
+			break;
+		}
+	}
+	return hangar_list[i];
+}
+
+/**
+ * goes from a tile location, looks up the depot, finds the location of the key part of the depot in the state machine
+ * returns the tile location of that key part
+ * @param t: the tile to start from
+ * @pre IsHangar(t)
+ * @return tile of key part of hangar
+ */
+TileIndex GetKeyDepotTile(TileIndex t)
+{
+	Station *st = GetStationByTile(t);
+	const FSMPortMovingData *md = st->fsmportsspeclist[1].spec->portFSM->MovingData(GetKeyDepotByTile(t).FSMposition);
+	TileIndexDiffC keydepot;
+	keydepot.x = md->x / TILE_SIZE;
+	keydepot.y = md->y / TILE_SIZE;
+	keydepot = RotateFSMPosition(keydepot,
+												 st->fsmportsspeclist[1].spec->size_x[st->FSMport_layout_set],
+												 st->fsmportsspeclist[1].spec->size_y[st->FSMport_layout_set],
+												 st->FSMport_orientation);
+	return st->airport_tile + ToTileIndexDiff(keydepot);
+}
+
 RoadStop* GetRoadStopByTile(TileIndex tile, RoadStop::Type type)
 {
 	const Station* st = GetStationByTile(tile);
@@ -1762,7 +1811,7 @@
 	if (flags & DC_EXEC) {
 		for (uint i = 0; i < fsmportsspec->portFSM->num_depots; ++i) {
 			DeleteWindowById(
-				WC_VEHICLE_DEPOT, tile + ToTileIndexDiff(fsmportsspec->portFSM->depots[i])
+				WC_VEHICLE_DEPOT, tile + ToTileIndexDiff(fsmportsspec->portFSM->depots[i].tile_pos)
 			);
 		}
 
@@ -2317,7 +2366,8 @@
 static void ClickTile_Station(TileIndex tile)
 {
 	if (IsHangar(tile)) {
-		ShowDepotWindow(tile, VEH_AIRCRAFT);
+		//find the main tile for this depot
+		ShowDepotWindow(GetKeyDepotTile(tile), VEH_AIRCRAFT);
 	} else {
 		ShowStationViewWindow(GetStationIndex(tile));
 	}