summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aircraft_cmd.c10
-rw-r--r--newgrf_callbacks.h4
-rw-r--r--roadveh_cmd.c10
-rw-r--r--ship_cmd.c10
-rw-r--r--train_cmd.c9
5 files changed, 43 insertions, 0 deletions
diff --git a/aircraft_cmd.c b/aircraft_cmd.c
index 3136865e5..4493940ed 100644
--- a/aircraft_cmd.c
+++ b/aircraft_cmd.c
@@ -22,6 +22,7 @@
#include "table/sprites.h"
#include "newgrf_engine.h"
#include "newgrf_callbacks.h"
+#include "newgrf_text.h"
static bool AirportMove(Vehicle *v, const AirportFTAClass *Airport);
static bool AirportSetBlocks(Vehicle *v, AirportFTA *current_pos, const AirportFTAClass *Airport);
@@ -420,6 +421,7 @@ static void DoDeleteAircraft(Vehicle *v)
int32 CmdSellAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
+ uint16 callback;
if (!IsVehicleIndex(p1)) return CMD_ERROR;
@@ -430,6 +432,14 @@ int32 CmdSellAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
+ /* Check if this aircraft can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
if (flags & DC_EXEC) {
// Invalidate depot
InvalidateWindow(WC_VEHICLE_DEPOT, v->tile);
diff --git a/newgrf_callbacks.h b/newgrf_callbacks.h
index 62ce8ac96..d7a91c04b 100644
--- a/newgrf_callbacks.h
+++ b/newgrf_callbacks.h
@@ -41,6 +41,10 @@ enum CallbackID {
/* Called when building a station to customize the tile layout */
CBID_STATION_TILE_LAYOUT = 0x24,
+
+ /* Called when the player (or AI) tries to start or stop a vehicle. Mainly
+ * used for preventing a vehicle from leaving the depot. */
+ CBID_VEHICLE_START_STOP_CHECK = 0x31,
};
/**
diff --git a/roadveh_cmd.c b/roadveh_cmd.c
index 875ef6241..e36e0ec5f 100644
--- a/roadveh_cmd.c
+++ b/roadveh_cmd.c
@@ -25,6 +25,7 @@
#include "vehicle_gui.h"
#include "newgrf_callbacks.h"
#include "newgrf_engine.h"
+#include "newgrf_text.h"
#include "yapf/yapf.h"
static const uint16 _roadveh_images[63] = {
@@ -208,6 +209,7 @@ int32 CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
int32 CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
+ uint16 callback;
if (!IsVehicleIndex(p1)) return CMD_ERROR;
@@ -215,6 +217,14 @@ int32 CmdStartStopRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
+ /* Check if this road veh can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
if (flags & DC_EXEC) {
if (IsRoadVehInDepotStopped(v)) {
DeleteVehicleNews(p1, STR_9016_ROAD_VEHICLE_IS_WAITING);
diff --git a/ship_cmd.c b/ship_cmd.c
index a47882f11..7b5737559 100644
--- a/ship_cmd.c
+++ b/ship_cmd.c
@@ -24,6 +24,7 @@
#include "yapf/yapf.h"
#include "debug.h"
#include "newgrf_callbacks.h"
+#include "newgrf_text.h"
static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D};
static const byte _ship_sometracks[4] = {0x19, 0x16, 0x25, 0x2A};
@@ -958,6 +959,7 @@ int32 CmdSellShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
int32 CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
+ uint16 callback;
if (!IsVehicleIndex(p1)) return CMD_ERROR;
@@ -965,6 +967,14 @@ int32 CmdStartStopShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (v->type != VEH_Ship || !CheckOwnership(v->owner)) return CMD_ERROR;
+ /* Check if this ship can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
if (flags & DC_EXEC) {
if (IsShipInDepotStopped(v)) {
DeleteVehicleNews(p1, STR_981C_SHIP_IS_WAITING_IN_DEPOT);
diff --git a/train_cmd.c b/train_cmd.c
index 1bcc1bffa..8afe5d75b 100644
--- a/train_cmd.c
+++ b/train_cmd.c
@@ -1227,6 +1227,7 @@ int32 CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
{
Vehicle *v;
+ uint16 callback;
if (!IsVehicleIndex(p1)) return CMD_ERROR;
@@ -1234,6 +1235,14 @@ int32 CmdStartStopTrain(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
+ /* Check if this train can be started/stopped. The callback will fail or
+ * return 0xFF if it can. */
+ callback = GetVehicleCallback(CBID_VEHICLE_START_STOP_CHECK, 0, 0, v->engine_type, v);
+ if (callback != CALLBACK_FAILED && callback != 0xFF) {
+ StringID error = GetGRFStringID(GetEngineGRFID(v->engine_type), 0xD000 + callback);
+ return_cmd_error(error);
+ }
+
if (flags & DC_EXEC) {
if (v->vehstatus & VS_STOPPED && v->u.rail.track == 0x80) {
DeleteVehicleNews(p1, STR_8814_TRAIN_IS_WAITING_IN_DEPOT);