changeset 19238:6081468bb39e draft

(svn r24127) -Feature [FS#1497]: Allow closing airports for incoming aircraft. (Based on patch by cirdan)
author michi_cc <michi_cc@openttd.org>
date Tue, 17 Apr 2012 19:43:18 +0000
parents ac215e4838cf
children f8c2a425a11b
files src/aircraft_cmd.cpp src/airport.h src/command.cpp src/command_type.h src/lang/english.txt src/script/api/ai/ai_station.hpp.sq src/script/api/ai_changelog.hpp src/script/api/game/game_station.hpp.sq src/script/api/game/game_window.hpp.sq src/script/api/game_changelog.hpp src/script/api/script_station.cpp src/script/api/script_station.hpp src/script/api/script_window.hpp src/station_cmd.cpp src/station_gui.cpp src/widgets/station_widget.h
diffstat 16 files changed, 126 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -1461,8 +1461,8 @@
 {
 	Station *st = Station::Get(v->targetairport);
 
-	/* runway busy or not allowed to use this airstation, circle */
-	if (CanVehicleUseStation(v, st) && (st->owner == OWNER_NONE || st->owner == v->owner)) {
+	/* Runway busy, not allowed to use this airstation or closed, circle. */
+	if (CanVehicleUseStation(v, st) && (st->owner == OWNER_NONE || st->owner == v->owner) && !(st->airport.flags & AIRPORT_CLOSED_block)) {
 		/* {32,FLYING,NOTHING_block,37}, {32,LANDING,N,33}, {32,HELILANDING,N,41},
 		 * if it is an airplane, look for LANDING, for helicopter HELILANDING
 		 * it is possible to choose from multiple landing runways, so loop until a free one is found */
--- a/src/airport.h
+++ b/src/airport.h
@@ -122,7 +122,8 @@
 	OUT_WAY_block2           = 1ULL << 31,
 	/* end of new blocks */
 
-	NOTHING_block            = 1ULL << 30;
+	NOTHING_block            = 1ULL << 30,
+	AIRPORT_CLOSED_block     = 1ULL << 63; ///< Dummy block for indicating a closed airport.
 
 /** A single location on an airport where aircraft can move to. */
 struct AirportMovingData {
--- a/src/command.cpp
+++ b/src/command.cpp
@@ -181,6 +181,8 @@
 CommandProc CmdAutofillTimetable;
 CommandProc CmdSetTimetableStart;
 
+CommandProc CmdOpenCloseAirport;
+
 #define DEF_CMD(proc, flags, type) {proc, #proc, (CommandFlags)flags, type}
 
 /**
@@ -322,6 +324,8 @@
 	DEF_CMD(CmdSetVehicleOnTime,                               0, CMDT_ROUTE_MANAGEMENT      ), // CMD_SET_VEHICLE_ON_TIME
 	DEF_CMD(CmdAutofillTimetable,                              0, CMDT_ROUTE_MANAGEMENT      ), // CMD_AUTOFILL_TIMETABLE
 	DEF_CMD(CmdSetTimetableStart,                              0, CMDT_ROUTE_MANAGEMENT      ), // CMD_SET_TIMETABLE_START
+
+	DEF_CMD(CmdOpenCloseAirport,                               0, CMDT_ROUTE_MANAGEMENT      ), // CMD_OPEN_CLOSE_AIRPORT
 };
 
 /*!
--- a/src/command_type.h
+++ b/src/command_type.h
@@ -302,6 +302,8 @@
 	CMD_AUTOFILL_TIMETABLE,           ///< autofill the timetable
 	CMD_SET_TIMETABLE_START,          ///< set the date that a timetable should start
 
+	CMD_OPEN_CLOSE_AIRPORT,           ///< open/close an airport to incoming aircraft
+
 	CMD_END,                          ///< Must ALWAYS be on the end of this list!! (period)
 };
 
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2751,6 +2751,9 @@
 
 STR_STATION_VIEW_RENAME_STATION_CAPTION                         :Rename station/loading area
 
+STR_STATION_VIEW_CLOSE_AIRPORT                                  :{BLACK}Close airport
+STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP                          :{BLACK}Prevent aircraft from landing on this airport
+
 # Waypoint/buoy view window
 STR_WAYPOINT_VIEW_CAPTION                                       :{WHITE}{WAYPOINT}
 STR_WAYPOINT_VIEW_CENTER_TOOLTIP                                :{BLACK}Centre main view on waypoint location. Ctrl+Click opens a new viewport on waypoint location
--- a/src/script/api/ai/ai_station.hpp.sq
+++ b/src/script/api/ai/ai_station.hpp.sq
@@ -56,6 +56,8 @@
 	SQAIStation.DefSQStaticMethod(engine, &ScriptStation::HasStationType,             "HasStationType",             3, ".ii");
 	SQAIStation.DefSQStaticMethod(engine, &ScriptStation::HasRoadType,                "HasRoadType",                3, ".ii");
 	SQAIStation.DefSQStaticMethod(engine, &ScriptStation::GetNearestTown,             "GetNearestTown",             2, ".i");
+	SQAIStation.DefSQStaticMethod(engine, &ScriptStation::IsAirportClosed,            "IsAirportClosed",            2, ".i");
+	SQAIStation.DefSQStaticMethod(engine, &ScriptStation::OpenCloseAirport,           "OpenCloseAirport",           2, ".i");
 
 	SQAIStation.PostRegister(engine);
 }
--- a/src/script/api/ai_changelog.hpp
+++ b/src/script/api/ai_changelog.hpp
@@ -19,6 +19,10 @@
  *
  * 1.3.0 is not yet released. The following changes are not set in stone yet.
  *
+ * API additions:
+ * \li AIStation::IsAirportClosed
+ * \li AIStation::OpenCloseAirport
+ *
  * \b 1.2.0
  *
  * API additions:
--- a/src/script/api/game/game_station.hpp.sq
+++ b/src/script/api/game/game_station.hpp.sq
@@ -57,6 +57,8 @@
 	SQGSStation.DefSQStaticMethod(engine, &ScriptStation::HasStationType,             "HasStationType",             3, ".ii");
 	SQGSStation.DefSQStaticMethod(engine, &ScriptStation::HasRoadType,                "HasRoadType",                3, ".ii");
 	SQGSStation.DefSQStaticMethod(engine, &ScriptStation::GetNearestTown,             "GetNearestTown",             2, ".i");
+	SQGSStation.DefSQStaticMethod(engine, &ScriptStation::IsAirportClosed,            "IsAirportClosed",            2, ".i");
+	SQGSStation.DefSQStaticMethod(engine, &ScriptStation::OpenCloseAirport,           "OpenCloseAirport",           2, ".i");
 
 	SQGSStation.PostRegister(engine);
 }
--- a/src/script/api/game/game_window.hpp.sq
+++ b/src/script/api/game/game_window.hpp.sq
@@ -1040,6 +1040,7 @@
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_LOCATION,                           "WID_SV_LOCATION");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_ACCEPTS_RATINGS,                    "WID_SV_ACCEPTS_RATINGS");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_RENAME,                             "WID_SV_RENAME");
+	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_CLOSE_AIRPORT,                      "WID_SV_CLOSE_AIRPORT");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_TRAINS,                             "WID_SV_TRAINS");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_ROADVEHS,                           "WID_SV_ROADVEHS");
 	SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_SHIPS,                              "WID_SV_SHIPS");
--- a/src/script/api/game_changelog.hpp
+++ b/src/script/api/game_changelog.hpp
@@ -19,6 +19,10 @@
  *
  * 1.3.0 is not yet released. The following changes are not set in stone yet.
  *
+ * API additions:
+ * \li GSStation::IsAirportClosed
+ * \li GSStation::OpenCloseAirport
+ *
  * \b 1.2.0
  * \li First stable release with the NoGo framework.
  */
--- a/src/script/api/script_station.cpp
+++ b/src/script/api/script_station.cpp
@@ -127,3 +127,19 @@
 
 	return ::Station::Get(station_id)->town->index;
 }
+
+/*static */ bool ScriptStation::IsAirportClosed(StationID station_id)
+{
+	EnforcePrecondition(false, IsValidStation(station_id));
+	EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT));
+
+	return (::Station::Get(station_id)->airport.flags & AIRPORT_CLOSED_block) != 0;
+}
+
+/*static */ bool ScriptStation::OpenCloseAirport(StationID station_id)
+{
+	EnforcePrecondition(false, IsValidStation(station_id));
+	EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT));
+
+	return ScriptObject::DoCommand(0, station_id, 0, CMD_OPEN_CLOSE_AIRPORT);
+}
--- a/src/script/api/script_station.hpp
+++ b/src/script/api/script_station.hpp
@@ -172,6 +172,24 @@
 	 *  towns grow, towns change. So don't depend on this value too much.
 	 */
 	static TownID GetNearestTown(StationID station_id);
+
+	/**
+	 * Get the open/closed state of an airport.
+	 * @param station_id The airport to look at.
+	 * @pre IsValidStation(station_id).
+	 * @pre HasStationType(station_id, STATION_AIRPORT).
+	 * @return True if the airport is currently closed to incoming traffic.
+	 */
+	static bool IsAirportClosed(StationID station_id);
+
+	/**
+	 * Toggle the open/closed state of an airport.
+	 * @param station_id The airport to modify.
+	 * @pre IsValidStation(station_id).
+	 * @pre HasStationType(station_id, STATION_AIRPORT).
+	 * @return True if the state could be toggled.
+	 */
+	static bool OpenCloseAirport(StationID station_id);
 };
 
 DECLARE_ENUM_AS_BIT_SET(ScriptStation::StationType)
--- a/src/script/api/script_window.hpp
+++ b/src/script/api/script_window.hpp
@@ -2059,6 +2059,7 @@
 		WID_SV_LOCATION                      = ::WID_SV_LOCATION,                      ///< 'Location' button.
 		WID_SV_ACCEPTS_RATINGS               = ::WID_SV_ACCEPTS_RATINGS,               ///< 'Accepts' / 'Ratings' button.
 		WID_SV_RENAME                        = ::WID_SV_RENAME,                        ///< 'Rename' button.
+		WID_SV_CLOSE_AIRPORT                 = ::WID_SV_CLOSE_AIRPORT,                 ///< 'Close airport' button.
 		WID_SV_TRAINS                        = ::WID_SV_TRAINS,                        ///< List of scheduled trains button.
 		WID_SV_ROADVEHS                      = ::WID_SV_ROADVEHS,                      ///< List of scheduled road vehs button.
 		WID_SV_SHIPS                         = ::WID_SV_SHIPS,                         ///< List of scheduled ships button.
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2263,7 +2263,7 @@
 		st->RecomputeIndustriesNear();
 		InvalidateWindowData(WC_SELECT_STATION, 0, 0);
 		InvalidateWindowData(WC_STATION_LIST, st->owner, 0);
-		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_PLANES);
+		InvalidateWindowData(WC_STATION_VIEW, st->index);
 
 		if (_settings_game.economy.station_noise_level) {
 			SetWindowDirty(WC_TOWN_VIEW, st->town->index);
@@ -2339,7 +2339,7 @@
 		st->airport.Clear();
 		st->facilities &= ~FACIL_AIRPORT;
 
-		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_PLANES);
+		InvalidateWindowData(WC_STATION_VIEW, st->index);
 
 		if (_settings_game.economy.station_noise_level) {
 			SetWindowDirty(WC_TOWN_VIEW, st->town->index);
@@ -2358,6 +2358,32 @@
 }
 
 /**
+ * Open/close an airport to incoming aircraft.
+ * @param tile Unused.
+ * @param flags Operation to perform.
+ * @param p1 Station ID of the airport.
+ * @param p2 Unused.
+ * @param text unused
+ * @return the cost of this operation or an error
+ */
+CommandCost CmdOpenCloseAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
+{
+	if (!Station::IsValidID(p1)) return CMD_ERROR;
+	Station *st = Station::Get(p1);
+
+	if (!(st->facilities & FACIL_AIRPORT)) return CMD_ERROR;
+
+	CommandCost ret = CheckOwnership(st->owner);
+	if (ret.Failed()) return ret;
+
+	if (flags & DC_EXEC) {
+		st->airport.flags ^= AIRPORT_CLOSED_block;
+		SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_CLOSE_AIRPORT);
+	}
+	return CommandCost();
+}
+
+/**
  * Tests whether the company's vehicles have this station in orders
  * @param station station ID
  * @param include_company If true only check vehicles of \a company, if false only check vehicles of other companies
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -762,13 +762,17 @@
 		NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SV_SCROLLBAR),
 	EndContainer(),
 	NWidget(WWT_PANEL, COLOUR_GREY, WID_SV_ACCEPT_RATING_LIST), SetMinimalSize(249, 32), SetResize(1, 0), EndContainer(),
-	NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
-		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_LOCATION), SetMinimalSize(60, 12), SetResize(1, 0), SetFill(1, 1),
-				SetDataTip(STR_BUTTON_LOCATION, STR_STATION_VIEW_CENTER_TOOLTIP),
-		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_ACCEPTS_RATINGS), SetMinimalSize(61, 12), SetResize(1, 0), SetFill(1, 1),
-				SetDataTip(STR_STATION_VIEW_RATINGS_BUTTON, STR_STATION_VIEW_RATINGS_TOOLTIP),
-		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_RENAME), SetMinimalSize(60, 12), SetResize(1, 0), SetFill(1, 1),
-				SetDataTip(STR_BUTTON_RENAME, STR_STATION_VIEW_RENAME_TOOLTIP),
+	NWidget(NWID_HORIZONTAL),
+		NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
+			NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_LOCATION), SetMinimalSize(45, 12), SetResize(1, 0), SetFill(1, 1),
+					SetDataTip(STR_BUTTON_LOCATION, STR_STATION_VIEW_CENTER_TOOLTIP),
+			NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_ACCEPTS_RATINGS), SetMinimalSize(46, 12), SetResize(1, 0), SetFill(1, 1),
+					SetDataTip(STR_STATION_VIEW_RATINGS_BUTTON, STR_STATION_VIEW_RATINGS_TOOLTIP),
+			NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_RENAME), SetMinimalSize(45, 12), SetResize(1, 0), SetFill(1, 1),
+					SetDataTip(STR_BUTTON_RENAME, STR_STATION_VIEW_RENAME_TOOLTIP),
+		EndContainer(),
+		NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_CLOSE_AIRPORT), SetMinimalSize(45, 12), SetResize(1, 0), SetFill(1, 1),
+				SetDataTip(STR_STATION_VIEW_CLOSE_AIRPORT, STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP),
 		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_TRAINS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_TRAIN, STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP),
 		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_ROADVEHS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_LORRY, STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP),
 		NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SHIPS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_SHIP, STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP),
@@ -869,6 +873,15 @@
 			case WID_SV_ACCEPT_RATING_LIST:
 				size->height = WD_FRAMERECT_TOP + ((this->GetWidget<NWidgetCore>(WID_SV_ACCEPTS_RATINGS)->widget_data == STR_STATION_VIEW_RATINGS_BUTTON) ? this->accepts_lines : this->rating_lines) * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
 				break;
+
+			case WID_SV_CLOSE_AIRPORT:
+				if (!(Station::Get(this->window_number)->facilities & FACIL_AIRPORT)) {
+					/* Hide 'Close Airport' button if no airport present. */
+					size->width = 0;
+					resize->width = 0;
+					fill->width = 0;
+				}
+				break;
 		}
 	}
 
@@ -887,6 +900,8 @@
 		this->SetWidgetDisabledState(WID_SV_ROADVEHS, !(st->facilities & FACIL_TRUCK_STOP) && !(st->facilities & FACIL_BUS_STOP));
 		this->SetWidgetDisabledState(WID_SV_SHIPS,    !(st->facilities & FACIL_DOCK));
 		this->SetWidgetDisabledState(WID_SV_PLANES,   !(st->facilities & FACIL_AIRPORT));
+		this->SetWidgetDisabledState(WID_SV_CLOSE_AIRPORT, !(st->facilities & FACIL_AIRPORT) || st->owner != _local_company);
+		this->SetWidgetLoweredState(WID_SV_CLOSE_AIRPORT, (st->facilities & FACIL_AIRPORT) && (st->airport.flags & AIRPORT_CLOSED_block) != 0);
 
 		this->DrawWidgets();
 
@@ -1133,6 +1148,10 @@
 						this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
 				break;
 
+			case WID_SV_CLOSE_AIRPORT:
+				DoCommandP(0, this->window_number, 0, CMD_OPEN_CLOSE_AIRPORT);
+				break;
+
 			case WID_SV_TRAINS:   // Show list of scheduled trains to this station
 			case WID_SV_ROADVEHS: // Show list of scheduled road-vehicles to this station
 			case WID_SV_SHIPS:    // Show list of scheduled ships to this station
@@ -1153,6 +1172,16 @@
 	{
 		this->vscroll->SetCapacityFromWidget(this, WID_SV_WAITING, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM);
 	}
+
+	/**
+	 * Some data on this window has become invalid.
+	 * @param data Information about the changed data.
+	 * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
+	 */
+	virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
+	{
+		if (gui_scope) this->ReInit();
+	}
 };
 
 
--- a/src/widgets/station_widget.h
+++ b/src/widgets/station_widget.h
@@ -21,6 +21,7 @@
 	WID_SV_LOCATION,           ///< 'Location' button.
 	WID_SV_ACCEPTS_RATINGS,    ///< 'Accepts' / 'Ratings' button.
 	WID_SV_RENAME,             ///< 'Rename' button.
+	WID_SV_CLOSE_AIRPORT,      ///< 'Close airport' button.
 	WID_SV_TRAINS,             ///< List of scheduled trains button.
 	WID_SV_ROADVEHS,           ///< List of scheduled road vehs button.
 	WID_SV_SHIPS,              ///< List of scheduled ships button.