diff --git a/bin/ai/CMakeLists.txt b/bin/ai/CMakeLists.txt
index 8b54f74973..5920bc7c1c 100644
--- a/bin/ai/CMakeLists.txt
+++ b/bin/ai/CMakeLists.txt
@@ -1,4 +1,5 @@
set(AI_COMPAT_SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/compat.nut
${CMAKE_CURRENT_SOURCE_DIR}/compat_0.7.nut
${CMAKE_CURRENT_SOURCE_DIR}/compat_1.0.nut
${CMAKE_CURRENT_SOURCE_DIR}/compat_1.1.nut
diff --git a/bin/ai/compat.nut b/bin/ai/compat.nut
new file mode 100644
index 0000000000..3ec2837450
--- /dev/null
+++ b/bin/ai/compat.nut
@@ -0,0 +1,418 @@
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+class AICompatibility {}
+
+function AICompatibility::Add(major, minor)
+{
+ if (major < 1) {
+ /* 1.0 refactors many things */
+ AISign.GetMaxSignID <- function()
+ {
+ local list = AISignList();
+ local max_id = 0;
+ foreach (id, d in list) {
+ if (id > max_id) max_id = id;
+ }
+ return max_id;
+ }
+
+ AITile.GetHeight <- function(tile)
+ {
+ if (!AIMap.IsValidTile(tile)) return -1;
+
+ return AITile.GetCornerHeight(tile, AITile.CORNER_N);
+ }
+
+ AIOrder.ChangeOrder <- function(vehicle_id, order_position, order_flags)
+ {
+ return AIOrder.SetOrderFlags(vehicle_id, order_position, order_flags);
+ }
+
+ AIWaypoint.WAYPOINT_INVALID <- 0xFFFF;
+
+ AISubsidy.SourceIsTown <- function(subsidy_id)
+ {
+ if (!AISubsidy.IsValidSubsidy(subsidy_id) || AISubsidy.IsAwarded(subsidy_id)) return false;
+
+ return AISubsidy.GetSourceType(subsidy_id) == AISubsidy.SPT_TOWN;
+ }
+
+ AISubsidy.GetSource <- function(subsidy_id)
+ {
+ if (!AISubsidy.IsValidSubsidy(subsidy_id)) return AIBaseStation.STATION_INVALID;
+
+ if (AISubsidy.IsAwarded(subsidy_id)) {
+ return AIBaseStation.STATION_INVALID;
+ }
+
+ return AISubsidy.GetSourceIndex(subsidy_id);
+ }
+
+ AISubsidy.DestinationIsTown <- function(subsidy_id)
+ {
+ if (!AISubsidy.IsValidSubsidy(subsidy_id) || AISubsidy.IsAwarded(subsidy_id)) return false;
+
+ return AISubsidy.GetDestinationType(subsidy_id) == AISubsidy.SPT_TOWN;
+ }
+
+ AISubsidy.GetDestination <- function(subsidy_id)
+ {
+ if (!AISubsidy.IsValidSubsidy(subsidy_id)) return AIBaseStation.STATION_INVALID;
+
+ if (AISubsidy.IsAwarded(subsidy_id)) {
+ return AIBaseStation.STATION_INVALID;
+ }
+
+ return AISubsidy.GetDestinationIndex(subsidy_id);
+ }
+
+ AITown.GetMaxProduction <- function(town_id, cargo_id)
+ {
+ return AITown.GetLastMonthProduction(town_id, cargo_id);
+ }
+
+ AIRail.RemoveRailWaypoint <- function(tile)
+ {
+ return AIRail.RemoveRailWaypointTileRect(tile, tile, true);
+ }
+
+ AIRail.RemoveRailStationTileRect <- function(tile, tile2)
+ {
+ return AIRail.RemoveRailStationTileRectangle(tile, tile2, false);
+ }
+
+ AIVehicle.SkipToVehicleOrder <- function(vehicle_id, order_position)
+ {
+ return AIOrder.SkipToOrder(vehicle_id, order_position);
+ }
+
+ AIEngine.IsValidEngine <- function(engine_id)
+ {
+ return AIEngine.IsBuildable(engine_id);
+ }
+
+ AIEngine._GetName <- AIEngine.GetName;
+ AIEngine.GetName <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return null;
+ return AIEngine._GetName(engine_id);
+ }
+
+ AIEngine._GetCargoType <- AIEngine.GetCargoType;
+ AIEngine.GetCargoType <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return 255;
+ return AIEngine._GetCargoType(engine_id);
+ }
+
+ AIEngine._CanRefitCargo <- AIEngine.CanRefitCargo;
+ AIEngine.CanRefitCargo <- function(engine_id, cargo_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return false;
+ return AIEngine._CanRefitCargo(engine_id, cargo_id);
+ }
+
+ AIEngine._CanPullCargo <- AIEngine.CanPullCargo;
+ AIEngine.CanPullCargo <- function(engine_id, cargo_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return false;
+ return AIEngine._CanPullCargo(engine_id, cargo_id);
+ }
+
+ AIEngine._GetCapacity <- AIEngine.GetCapacity;
+ AIEngine.GetCapacity <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetCapacity(engine_id);
+ }
+
+ AIEngine._GetReliability <- AIEngine.GetReliability;
+ AIEngine.GetReliability <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetReliability(engine_id);
+ }
+
+ AIEngine._GetMaxSpeed <- AIEngine.GetMaxSpeed;
+ AIEngine.GetMaxSpeed <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetMaxSpeed(engine_id);
+ }
+
+ AIEngine._GetPrice <- AIEngine.GetPrice;
+ AIEngine.GetPrice <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetPrice(engine_id);
+ }
+
+ AIEngine._GetMaxAge <- AIEngine.GetMaxAge;
+ AIEngine.GetMaxAge <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetMaxAge(engine_id);
+ }
+
+ AIEngine._GetRunningCost <- AIEngine.GetRunningCost;
+ AIEngine.GetRunningCost <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetRunningCost(engine_id);
+ }
+
+ AIEngine._GetPower <- AIEngine.GetPower;
+ AIEngine.GetPower <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetPower(engine_id);
+ }
+
+ AIEngine._GetWeight <- AIEngine.GetWeight;
+ AIEngine.GetWeight <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetWeight(engine_id);
+ }
+
+ AIEngine._GetMaxTractiveEffort <- AIEngine.GetMaxTractiveEffort;
+ AIEngine.GetMaxTractiveEffort <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetMaxTractiveEffort(engine_id);
+ }
+
+ AIEngine._GetDesignDate <- AIEngine.GetDesignDate;
+ AIEngine.GetDesignDate <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetDesignDate(engine_id);
+ }
+
+ AIEngine._GetVehicleType <- AIEngine.GetVehicleType;
+ AIEngine.GetVehicleType <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return AIVehicle.VT_INVALID;
+ return AIEngine._GetVehicleType(engine_id);
+ }
+
+ AIEngine._IsWagon <- AIEngine.IsWagon;
+ AIEngine.IsWagon <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return false;
+ return AIEngine._IsWagon(engine_id);
+ }
+
+ AIEngine._CanRunOnRail <- AIEngine.CanRunOnRail;
+ AIEngine.CanRunOnRail <- function(engine_id, track_rail_type)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return false;
+ return AIEngine._CanRunOnRail(engine_id, track_rail_type);
+ }
+
+ AIEngine._HasPowerOnRail <- AIEngine.HasPowerOnRail;
+ AIEngine.HasPowerOnRail <- function(engine_id, track_rail_type)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return false;
+ return AIEngine._HasPowerOnRail(engine_id, track_rail_type);
+ }
+
+ AIEngine._GetRoadType <- AIEngine.GetRoadType;
+ AIEngine.GetRoadType <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return AIRoad.ROADTYPE_INVALID;
+ return AIEngine._GetRoadType(engine_id);
+ }
+
+ AIEngine._GetRailType <- AIEngine.GetRailType;
+ AIEngine.GetRailType <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return AIRail.RAILTYPE_INVALID;
+ return AIEngine._GetRailType(engine_id);
+ }
+
+ AIEngine._IsArticulated <- AIEngine.IsArticulated;
+ AIEngine.IsArticulated <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return false;
+ return AIEngine._IsArticulated(engine_id);
+ }
+
+ AIEngine._GetPlaneType <- AIEngine.GetPlaneType;
+ AIEngine.GetPlaneType <- function(engine_id)
+ {
+ if (!AIEngine.IsBuildable(engine_id)) return -1;
+ return AIEngine._GetPlaneType(engine_id);
+ }
+
+ _AIWaypointList <- AIWaypointList;
+ class AIWaypointList extends _AIWaypointList {
+ constructor()
+ {
+ ::_AIWaypointList.constructor(AIWaypoint.WAYPOINT_RAIL);
+ }
+ }
+
+ }
+ if (major < 1 || major == 1 && minor < 1) {
+ /* 1.1 allows overbuilding stations. */
+ AIRoad._BuildRoadStation <- AIRoad.BuildRoadStation;
+ AIRoad.BuildRoadStation <- function(tile, front, road_veh_type, station_id)
+ {
+ if (AIRoad.IsRoadStationTile(tile) && AICompany.IsMine(AITile.GetOwner(tile))) return false;
+
+ return AIRoad._BuildRoadStation(tile, front, road_veh_type, station_id);
+ }
+
+ AIRoad._BuildDriveThroughRoadStation <- AIRoad.BuildDriveThroughRoadStation;
+ AIRoad.BuildDriveThroughRoadStation <- function(tile, front, road_veh_type, station_id)
+ {
+ if (AIRoad.IsRoadStationTile(tile) && AICompany.IsMine(AITile.GetOwner(tile))) return false;
+
+ return AIRoad._BuildDriveThroughRoadStation(tile, front, road_veh_type, station_id);
+ }
+
+ /* 1.1 removed HasNext from lists in favour of IsEnd */
+ AIBridgeList.HasNext <-
+ AIBridgeList_Length.HasNext <-
+ AICargoList.HasNext <-
+ AICargoList_IndustryAccepting.HasNext <-
+ AICargoList_IndustryProducing.HasNext <-
+ AIDepotList.HasNext <-
+ AIEngineList.HasNext <-
+ AIGroupList.HasNext <-
+ AIIndustryList.HasNext <-
+ AIIndustryList_CargoAccepting.HasNext <-
+ AIIndustryList_CargoProducing.HasNext <-
+ AIIndustryTypeList.HasNext <-
+ AIList.HasNext <-
+ AIRailTypeList.HasNext <-
+ AISignList.HasNext <-
+ AIStationList.HasNext <-
+ AIStationList_Vehicle.HasNext <-
+ AISubsidyList.HasNext <-
+ AITileList.HasNext <-
+ AITileList_IndustryAccepting.HasNext <-
+ AITileList_IndustryProducing.HasNext <-
+ AITileList_StationType.HasNext <-
+ AITownList.HasNext <-
+ AIVehicleList.HasNext <-
+ AIVehicleList_DefaultGroup.HasNext <-
+ AIVehicleList_Depot.HasNext <-
+ AIVehicleList_Group.HasNext <-
+ AIVehicleList_SharedOrders.HasNext <-
+ AIVehicleList_Station.HasNext <-
+ AIWaypointList.HasNext <-
+ AIWaypointList_Vehicle.HasNext <-
+ function()
+ {
+ return !this.IsEnd();
+ }
+
+ /* 1.1 does not return a boolean anymore */
+ AIIndustry._IsCargoAccepted <- AIIndustry.IsCargoAccepted;
+ AIIndustry.IsCargoAccepted <- function(industry_id, cargo_id)
+ {
+ return AIIndustry._IsCargoAccepted(industry_id, cargo_id) != AIIndustry.CAS_NOT_ACCEPTED;
+ }
+
+ /* 1.1 renames some classes/functions */
+ AIAbstractList <- AIList;
+ AIList.ChangeItem <- AIList.SetValue;
+
+ /* 1.1 removes an unused error */
+ AIRail.ERR_NONUNIFORM_STATIONS_DISABLED <- 0xFFFF;
+ }
+
+ if (major < 1 || major == 1 && minor < 2) {
+ /* 1.2 replaces GetCompanyValue, and renames a lot of constants */
+ AICompany.GetCompanyValue <- function(company)
+ {
+ return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
+ }
+
+ AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
+
+ AIEvent.AI_ET_INVALID <- AIEvent.ET_INVALID;
+ AIEvent.AI_ET_TEST <- AIEvent.ET_TEST;
+ AIEvent.AI_ET_SUBSIDY_OFFER <- AIEvent.ET_SUBSIDY_OFFER;
+ AIEvent.AI_ET_SUBSIDY_OFFER_EXPIRED <- AIEvent.ET_SUBSIDY_OFFER_EXPIRED;
+ AIEvent.AI_ET_SUBSIDY_AWARDED <- AIEvent.ET_SUBSIDY_AWARDED;
+ AIEvent.AI_ET_SUBSIDY_EXPIRED <- AIEvent.ET_SUBSIDY_EXPIRED;
+ AIEvent.AI_ET_ENGINE_PREVIEW <- AIEvent.ET_ENGINE_PREVIEW;
+ AIEvent.AI_ET_COMPANY_NEW <- AIEvent.ET_COMPANY_NEW;
+ AIEvent.AI_ET_COMPANY_IN_TROUBLE <- AIEvent.ET_COMPANY_IN_TROUBLE;
+ AIEvent.AI_ET_COMPANY_ASK_MERGER <- AIEvent.ET_COMPANY_ASK_MERGER;
+ AIEvent.AI_ET_COMPANY_MERGER <- AIEvent.ET_COMPANY_MERGER;
+ AIEvent.AI_ET_COMPANY_BANKRUPT <- AIEvent.ET_COMPANY_BANKRUPT;
+ AIEvent.AI_ET_VEHICLE_CRASHED <- AIEvent.ET_VEHICLE_CRASHED;
+ AIEvent.AI_ET_VEHICLE_LOST <- AIEvent.ET_VEHICLE_LOST;
+ AIEvent.AI_ET_VEHICLE_WAITING_IN_DEPOT <- AIEvent.ET_VEHICLE_WAITING_IN_DEPOT;
+ AIEvent.AI_ET_VEHICLE_UNPROFITABLE <- AIEvent.ET_VEHICLE_UNPROFITABLE;
+ AIEvent.AI_ET_INDUSTRY_OPEN <- AIEvent.ET_INDUSTRY_OPEN;
+ AIEvent.AI_ET_INDUSTRY_CLOSE <- AIEvent.ET_INDUSTRY_CLOSE;
+ AIEvent.AI_ET_ENGINE_AVAILABLE <- AIEvent.ET_ENGINE_AVAILABLE;
+ AIEvent.AI_ET_STATION_FIRST_VEHICLE <- AIEvent.ET_STATION_FIRST_VEHICLE;
+ AIEvent.AI_ET_DISASTER_ZEPPELINER_CRASHED <- AIEvent.ET_DISASTER_ZEPPELINER_CRASHED;
+ AIEvent.AI_ET_DISASTER_ZEPPELINER_CLEARED <- AIEvent.ET_DISASTER_ZEPPELINER_CLEARED;
+ AIEvent.AI_ET_TOWN_FOUNDED <- AIEvent.ET_TOWN_FOUNDED;
+ AIOrder.AIOF_NONE <- AIOrder.OF_NONE
+ AIOrder.AIOF_NON_STOP_INTERMEDIATE <- AIOrder.OF_NON_STOP_INTERMEDIATE
+ AIOrder.AIOF_NON_STOP_DESTINATION <- AIOrder.OF_NON_STOP_DESTINATION
+ AIOrder.AIOF_UNLOAD <- AIOrder.OF_UNLOAD
+ AIOrder.AIOF_TRANSFER <- AIOrder.OF_TRANSFER
+ AIOrder.AIOF_NO_UNLOAD <- AIOrder.OF_NO_UNLOAD
+ AIOrder.AIOF_FULL_LOAD <- AIOrder.OF_FULL_LOAD
+ AIOrder.AIOF_FULL_LOAD_ANY <- AIOrder.OF_FULL_LOAD_ANY
+ AIOrder.AIOF_NO_LOAD <- AIOrder.OF_NO_LOAD
+ AIOrder.AIOF_SERVICE_IF_NEEDED <- AIOrder.OF_SERVICE_IF_NEEDED
+ AIOrder.AIOF_STOP_IN_DEPOT <- AIOrder.OF_STOP_IN_DEPOT
+ AIOrder.AIOF_GOTO_NEAREST_DEPOT <- AIOrder.OF_GOTO_NEAREST_DEPOT
+ AIOrder.AIOF_NON_STOP_FLAGS <- AIOrder.OF_NON_STOP_FLAGS
+ AIOrder.AIOF_UNLOAD_FLAGS <- AIOrder.OF_UNLOAD_FLAGS
+ AIOrder.AIOF_LOAD_FLAGS <- AIOrder.OF_LOAD_FLAGS
+ AIOrder.AIOF_DEPOT_FLAGS <- AIOrder.OF_DEPOT_FLAGS
+ AIOrder.AIOF_INVALID <- AIOrder.OF_INVALID
+ }
+
+ if (major < 1 || (major == 1 && minor < 9)) {
+ /* 1.9 adds a vehicle type parameter. */
+ AIBridge._GetName <- AIBridge.GetName;
+ AIBridge.GetName <- function(bridge_id)
+ {
+ return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
+ }
+
+ /* 1.9 adds parent_group_id to CreateGroup function */
+ AIGroup._CreateGroup <- AIGroup.CreateGroup;
+ AIGroup.CreateGroup <- function(vehicle_type)
+ {
+ return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
+ }
+ }
+
+ if (major < 13) {
+ /* 13 really checks RoadType against RoadType */
+ AIRoad._HasRoadType <- AIRoad.HasRoadType;
+ AIRoad.HasRoadType <- function(tile, road_type)
+ {
+ local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
+ foreach (rt, _ in list) {
+ if (AIRoad._HasRoadType(tile, rt)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ if (major < 15) {
+ /* 15 renames GetBridgeID */
+ AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+ }
+}
diff --git a/bin/ai/compat_0.7.nut b/bin/ai/compat_0.7.nut
index 0b2fa1f243..035c4975df 100644
--- a/bin/ai/compat_0.7.nut
+++ b/bin/ai/compat_0.7.nut
@@ -10,388 +10,5 @@ AILog.Info(" - AITown::GetLastMonthProduction's behaviour has slightly changed."
AILog.Info(" - AISubsidy::GetDestination returns STATION_INVALID for awarded subsidies.");
AILog.Info(" - AISubsidy::GetSource returns STATION_INVALID for awarded subsidies.");
-AISign.GetMaxSignID <- function()
-{
- local list = AISignList();
- local max_id = 0;
- foreach (id, d in list) {
- if (id > max_id) max_id = id;
- }
- return max_id;
-}
-
-AITile.GetHeight <- function(tile)
-{
- if (!AIMap.IsValidTile(tile)) return -1;
-
- return AITile.GetCornerHeight(tile, AITile.CORNER_N);
-}
-
-AIOrder.ChangeOrder <- function(vehicle_id, order_position, order_flags)
-{
- return AIOrder.SetOrderFlags(vehicle_id, order_position, order_flags);
-}
-
-AIWaypoint.WAYPOINT_INVALID <- 0xFFFF;
-
-AISubsidy.SourceIsTown <- function(subsidy_id)
-{
- if (!AISubsidy.IsValidSubsidy(subsidy_id) || AISubsidy.IsAwarded(subsidy_id)) return false;
-
- return AISubsidy.GetSourceType(subsidy_id) == AISubsidy.SPT_TOWN;
-}
-
-AISubsidy.GetSource <- function(subsidy_id)
-{
- if (!AISubsidy.IsValidSubsidy(subsidy_id)) return AIBaseStation.STATION_INVALID;
-
- if (AISubsidy.IsAwarded(subsidy_id)) {
- return AIBaseStation.STATION_INVALID;
- }
-
- return AISubsidy.GetSourceIndex(subsidy_id);
-}
-
-AISubsidy.DestinationIsTown <- function(subsidy_id)
-{
- if (!AISubsidy.IsValidSubsidy(subsidy_id) || AISubsidy.IsAwarded(subsidy_id)) return false;
-
- return AISubsidy.GetDestinationType(subsidy_id) == AISubsidy.SPT_TOWN;
-}
-
-AISubsidy.GetDestination <- function(subsidy_id)
-{
- if (!AISubsidy.IsValidSubsidy(subsidy_id)) return AIBaseStation.STATION_INVALID;
-
- if (AISubsidy.IsAwarded(subsidy_id)) {
- return AIBaseStation.STATION_INVALID;
- }
-
- return AISubsidy.GetDestinationIndex(subsidy_id);
-}
-
-AITown.GetMaxProduction <- function(town_id, cargo_id)
-{
- return AITown.GetLastMonthProduction(town_id, cargo_id);
-}
-
-AIRail.RemoveRailWaypoint <- function(tile)
-{
- return AIRail.RemoveRailWaypointTileRect(tile, tile, true);
-}
-
-AIRail.RemoveRailStationTileRect <- function(tile, tile2)
-{
- return AIRail.RemoveRailStationTileRectangle(tile, tile2, false);
-}
-
-AIVehicle.SkipToVehicleOrder <- function(vehicle_id, order_position)
-{
- return AIOrder.SkipToOrder(vehicle_id, order_position);
-}
-
-AIEngine.IsValidEngine <- function(engine_id)
-{
- return AIEngine.IsBuildable(engine_id);
-}
-
-AIEngine._GetName <- AIEngine.GetName;
-AIEngine.GetName <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return null;
- return AIEngine._GetName(engine_id);
-}
-
-AIEngine._GetCargoType <- AIEngine.GetCargoType;
-AIEngine.GetCargoType <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return 255;
- return AIEngine._GetCargoType(engine_id);
-}
-
-AIEngine._CanRefitCargo <- AIEngine.CanRefitCargo;
-AIEngine.CanRefitCargo <- function(engine_id, cargo_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return false;
- return AIEngine._CanRefitCargo(engine_id, cargo_id);
-}
-
-AIEngine._CanPullCargo <- AIEngine.CanPullCargo;
-AIEngine.CanPullCargo <- function(engine_id, cargo_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return false;
- return AIEngine._CanPullCargo(engine_id, cargo_id);
-}
-
-AIEngine._GetCapacity <- AIEngine.GetCapacity;
-AIEngine.GetCapacity <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetCapacity(engine_id);
-}
-
-AIEngine._GetReliability <- AIEngine.GetReliability;
-AIEngine.GetReliability <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetReliability(engine_id);
-}
-
-AIEngine._GetMaxSpeed <- AIEngine.GetMaxSpeed;
-AIEngine.GetMaxSpeed <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetMaxSpeed(engine_id);
-}
-
-AIEngine._GetPrice <- AIEngine.GetPrice;
-AIEngine.GetPrice <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetPrice(engine_id);
-}
-
-AIEngine._GetMaxAge <- AIEngine.GetMaxAge;
-AIEngine.GetMaxAge <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetMaxAge(engine_id);
-}
-
-AIEngine._GetRunningCost <- AIEngine.GetRunningCost;
-AIEngine.GetRunningCost <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetRunningCost(engine_id);
-}
-
-AIEngine._GetPower <- AIEngine.GetPower;
-AIEngine.GetPower <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetPower(engine_id);
-}
-
-AIEngine._GetWeight <- AIEngine.GetWeight;
-AIEngine.GetWeight <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetWeight(engine_id);
-}
-
-AIEngine._GetMaxTractiveEffort <- AIEngine.GetMaxTractiveEffort;
-AIEngine.GetMaxTractiveEffort <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetMaxTractiveEffort(engine_id);
-}
-
-AIEngine._GetDesignDate <- AIEngine.GetDesignDate;
-AIEngine.GetDesignDate <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetDesignDate(engine_id);
-}
-
-AIEngine._GetVehicleType <- AIEngine.GetVehicleType;
-AIEngine.GetVehicleType <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return AIVehicle.VT_INVALID;
- return AIEngine._GetVehicleType(engine_id);
-}
-
-AIEngine._IsWagon <- AIEngine.IsWagon;
-AIEngine.IsWagon <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return false;
- return AIEngine._IsWagon(engine_id);
-}
-
-AIEngine._CanRunOnRail <- AIEngine.CanRunOnRail;
-AIEngine.CanRunOnRail <- function(engine_id, track_rail_type)
-{
- if (!AIEngine.IsBuildable(engine_id)) return false;
- return AIEngine._CanRunOnRail(engine_id, track_rail_type);
-}
-
-AIEngine._HasPowerOnRail <- AIEngine.HasPowerOnRail;
-AIEngine.HasPowerOnRail <- function(engine_id, track_rail_type)
-{
- if (!AIEngine.IsBuildable(engine_id)) return false;
- return AIEngine._HasPowerOnRail(engine_id, track_rail_type);
-}
-
-AIEngine._GetRoadType <- AIEngine.GetRoadType;
-AIEngine.GetRoadType <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return AIRoad.ROADTYPE_INVALID;
- return AIEngine._GetRoadType(engine_id);
-}
-
-AIEngine._GetRailType <- AIEngine.GetRailType;
-AIEngine.GetRailType <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return AIRail.RAILTYPE_INVALID;
- return AIEngine._GetRailType(engine_id);
-}
-
-AIEngine._IsArticulated <- AIEngine.IsArticulated;
-AIEngine.IsArticulated <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return false;
- return AIEngine._IsArticulated(engine_id);
-}
-
-AIEngine._GetPlaneType <- AIEngine.GetPlaneType;
-AIEngine.GetPlaneType <- function(engine_id)
-{
- if (!AIEngine.IsBuildable(engine_id)) return -1;
- return AIEngine._GetPlaneType(engine_id);
-}
-
-_AIWaypointList <- AIWaypointList;
-class AIWaypointList extends _AIWaypointList {
- constructor()
- {
- ::_AIWaypointList.constructor(AIWaypoint.WAYPOINT_RAIL);
- }
-}
-
-AIRoad._BuildRoadStation <- AIRoad.BuildRoadStation;
-AIRoad.BuildRoadStation <- function(tile, front, road_veh_type, station_id)
-{
- if (AIRoad.IsRoadStationTile(tile) && AICompany.IsMine(AITile.GetOwner(tile))) return false;
-
- return AIRoad._BuildRoadStation(tile, front, road_veh_type, station_id);
-}
-
-AIRoad._BuildDriveThroughRoadStation <- AIRoad.BuildDriveThroughRoadStation;
-AIRoad.BuildDriveThroughRoadStation <- function(tile, front, road_veh_type, station_id)
-{
- if (AIRoad.IsRoadStationTile(tile) && AICompany.IsMine(AITile.GetOwner(tile))) return false;
-
- return AIRoad._BuildDriveThroughRoadStation(tile, front, road_veh_type, station_id);
-}
-
-AIBridgeList.HasNext <-
-AIBridgeList_Length.HasNext <-
-AICargoList.HasNext <-
-AICargoList_IndustryAccepting.HasNext <-
-AICargoList_IndustryProducing.HasNext <-
-AIDepotList.HasNext <-
-AIEngineList.HasNext <-
-AIGroupList.HasNext <-
-AIIndustryList.HasNext <-
-AIIndustryList_CargoAccepting.HasNext <-
-AIIndustryList_CargoProducing.HasNext <-
-AIIndustryTypeList.HasNext <-
-AIList.HasNext <-
-AIRailTypeList.HasNext <-
-AISignList.HasNext <-
-AIStationList.HasNext <-
-AIStationList_Vehicle.HasNext <-
-AISubsidyList.HasNext <-
-AITileList.HasNext <-
-AITileList_IndustryAccepting.HasNext <-
-AITileList_IndustryProducing.HasNext <-
-AITileList_StationType.HasNext <-
-AITownList.HasNext <-
-AIVehicleList.HasNext <-
-AIVehicleList_DefaultGroup.HasNext <-
-AIVehicleList_Group.HasNext <-
-AIVehicleList_SharedOrders.HasNext <-
-AIVehicleList_Station.HasNext <-
-AIWaypointList.HasNext <-
-AIWaypointList_Vehicle.HasNext <-
-function()
-{
- return !this.IsEnd();
-}
-
-AIIndustry._IsCargoAccepted <- AIIndustry.IsCargoAccepted;
-AIIndustry.IsCargoAccepted <- function(industry_id, cargo_id)
-{
- return AIIndustry._IsCargoAccepted(industry_id, cargo_id) != AIIndustry.CAS_NOT_ACCEPTED;
-}
-
-AIAbstractList <- AIList;
-
-AIList.ChangeItem <- AIList.SetValue;
-
-AIRail.ERR_NONUNIFORM_STATIONS_DISABLED <- 0xFFFF;
-
-AICompany.GetCompanyValue <- function(company)
-{
- return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
-}
-
-AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
-
-AIEvent.AI_ET_INVALID <- AIEvent.ET_INVALID;
-AIEvent.AI_ET_TEST <- AIEvent.ET_TEST;
-AIEvent.AI_ET_SUBSIDY_OFFER <- AIEvent.ET_SUBSIDY_OFFER;
-AIEvent.AI_ET_SUBSIDY_OFFER_EXPIRED <- AIEvent.ET_SUBSIDY_OFFER_EXPIRED;
-AIEvent.AI_ET_SUBSIDY_AWARDED <- AIEvent.ET_SUBSIDY_AWARDED;
-AIEvent.AI_ET_SUBSIDY_EXPIRED <- AIEvent.ET_SUBSIDY_EXPIRED;
-AIEvent.AI_ET_ENGINE_PREVIEW <- AIEvent.ET_ENGINE_PREVIEW;
-AIEvent.AI_ET_COMPANY_NEW <- AIEvent.ET_COMPANY_NEW;
-AIEvent.AI_ET_COMPANY_IN_TROUBLE <- AIEvent.ET_COMPANY_IN_TROUBLE;
-AIEvent.AI_ET_COMPANY_MERGER <- AIEvent.ET_COMPANY_MERGER;
-AIEvent.AI_ET_COMPANY_BANKRUPT <- AIEvent.ET_COMPANY_BANKRUPT;
-AIEvent.AI_ET_VEHICLE_CRASHED <- AIEvent.ET_VEHICLE_CRASHED;
-AIEvent.AI_ET_VEHICLE_LOST <- AIEvent.ET_VEHICLE_LOST;
-AIEvent.AI_ET_VEHICLE_WAITING_IN_DEPOT <- AIEvent.ET_VEHICLE_WAITING_IN_DEPOT;
-AIEvent.AI_ET_VEHICLE_UNPROFITABLE <- AIEvent.ET_VEHICLE_UNPROFITABLE;
-AIEvent.AI_ET_INDUSTRY_OPEN <- AIEvent.ET_INDUSTRY_OPEN;
-AIEvent.AI_ET_INDUSTRY_CLOSE <- AIEvent.ET_INDUSTRY_CLOSE;
-AIEvent.AI_ET_ENGINE_AVAILABLE <- AIEvent.ET_ENGINE_AVAILABLE;
-AIEvent.AI_ET_STATION_FIRST_VEHICLE <- AIEvent.ET_STATION_FIRST_VEHICLE;
-AIEvent.AI_ET_DISASTER_ZEPPELINER_CRASHED <- AIEvent.ET_DISASTER_ZEPPELINER_CRASHED;
-AIEvent.AI_ET_DISASTER_ZEPPELINER_CLEARED <- AIEvent.ET_DISASTER_ZEPPELINER_CLEARED;
-AIOrder.AIOF_NONE <- AIOrder.OF_NONE
-AIOrder.AIOF_NON_STOP_INTERMEDIATE <- AIOrder.OF_NON_STOP_INTERMEDIATE
-AIOrder.AIOF_NON_STOP_DESTINATION <- AIOrder.OF_NON_STOP_DESTINATION
-AIOrder.AIOF_UNLOAD <- AIOrder.OF_UNLOAD
-AIOrder.AIOF_TRANSFER <- AIOrder.OF_TRANSFER
-AIOrder.AIOF_NO_UNLOAD <- AIOrder.OF_NO_UNLOAD
-AIOrder.AIOF_FULL_LOAD <- AIOrder.OF_FULL_LOAD
-AIOrder.AIOF_FULL_LOAD_ANY <- AIOrder.OF_FULL_LOAD_ANY
-AIOrder.AIOF_NO_LOAD <- AIOrder.OF_NO_LOAD
-AIOrder.AIOF_SERVICE_IF_NEEDED <- AIOrder.OF_SERVICE_IF_NEEDED
-AIOrder.AIOF_STOP_IN_DEPOT <- AIOrder.OF_STOP_IN_DEPOT
-AIOrder.AIOF_GOTO_NEAREST_DEPOT <- AIOrder.OF_GOTO_NEAREST_DEPOT
-AIOrder.AIOF_NON_STOP_FLAGS <- AIOrder.OF_NON_STOP_FLAGS
-AIOrder.AIOF_UNLOAD_FLAGS <- AIOrder.OF_UNLOAD_FLAGS
-AIOrder.AIOF_LOAD_FLAGS <- AIOrder.OF_LOAD_FLAGS
-AIOrder.AIOF_DEPOT_FLAGS <- AIOrder.OF_DEPOT_FLAGS
-AIOrder.AIOF_INVALID <- AIOrder.OF_INVALID
-
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(0, 7)
diff --git a/bin/ai/compat_1.0.nut b/bin/ai/compat_1.0.nut
index bf3b8334e6..598bdde9b6 100644
--- a/bin/ai/compat_1.0.nut
+++ b/bin/ai/compat_1.0.nut
@@ -7,143 +7,5 @@
AILog.Info("1.0 API compatibility in effect.");
-AIRoad._BuildRoadStation <- AIRoad.BuildRoadStation;
-AIRoad.BuildRoadStation <- function(tile, front, road_veh_type, station_id)
-{
- if (AIRoad.IsRoadStationTile(tile) && AICompany.IsMine(AITile.GetOwner(tile))) return false;
-
- return AIRoad._BuildRoadStation(tile, front, road_veh_type, station_id);
-}
-
-AIRoad._BuildDriveThroughRoadStation <- AIRoad.BuildDriveThroughRoadStation;
-AIRoad.BuildDriveThroughRoadStation <- function(tile, front, road_veh_type, station_id)
-{
- if (AIRoad.IsRoadStationTile(tile) && AICompany.IsMine(AITile.GetOwner(tile))) return false;
-
- return AIRoad._BuildDriveThroughRoadStation(tile, front, road_veh_type, station_id);
-}
-
-AIBridgeList.HasNext <-
-AIBridgeList_Length.HasNext <-
-AICargoList.HasNext <-
-AICargoList_IndustryAccepting.HasNext <-
-AICargoList_IndustryProducing.HasNext <-
-AIDepotList.HasNext <-
-AIEngineList.HasNext <-
-AIGroupList.HasNext <-
-AIIndustryList.HasNext <-
-AIIndustryList_CargoAccepting.HasNext <-
-AIIndustryList_CargoProducing.HasNext <-
-AIIndustryTypeList.HasNext <-
-AIList.HasNext <-
-AIRailTypeList.HasNext <-
-AISignList.HasNext <-
-AIStationList.HasNext <-
-AIStationList_Vehicle.HasNext <-
-AISubsidyList.HasNext <-
-AITileList.HasNext <-
-AITileList_IndustryAccepting.HasNext <-
-AITileList_IndustryProducing.HasNext <-
-AITileList_StationType.HasNext <-
-AITownList.HasNext <-
-AIVehicleList.HasNext <-
-AIVehicleList_DefaultGroup.HasNext <-
-AIVehicleList_Depot.HasNext <-
-AIVehicleList_Group.HasNext <-
-AIVehicleList_SharedOrders.HasNext <-
-AIVehicleList_Station.HasNext <-
-AIWaypointList.HasNext <-
-AIWaypointList_Vehicle.HasNext <-
-function()
-{
- return !this.IsEnd();
-}
-
-AIIndustry._IsCargoAccepted <- AIIndustry.IsCargoAccepted;
-AIIndustry.IsCargoAccepted <- function(industry_id, cargo_id)
-{
- return AIIndustry._IsCargoAccepted(industry_id, cargo_id) != AIIndustry.CAS_NOT_ACCEPTED;
-}
-
-AIAbstractList <- AIList;
-
-AIList.ChangeItem <- AIList.SetValue;
-
-AIRail.ERR_NONUNIFORM_STATIONS_DISABLED <- 0xFFFF;
-
-AICompany.GetCompanyValue <- function(company)
-{
- return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
-}
-
-AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
-
-AIEvent.AI_ET_INVALID <- AIEvent.ET_INVALID;
-AIEvent.AI_ET_TEST <- AIEvent.ET_TEST;
-AIEvent.AI_ET_SUBSIDY_OFFER <- AIEvent.ET_SUBSIDY_OFFER;
-AIEvent.AI_ET_SUBSIDY_OFFER_EXPIRED <- AIEvent.ET_SUBSIDY_OFFER_EXPIRED;
-AIEvent.AI_ET_SUBSIDY_AWARDED <- AIEvent.ET_SUBSIDY_AWARDED;
-AIEvent.AI_ET_SUBSIDY_EXPIRED <- AIEvent.ET_SUBSIDY_EXPIRED;
-AIEvent.AI_ET_ENGINE_PREVIEW <- AIEvent.ET_ENGINE_PREVIEW;
-AIEvent.AI_ET_COMPANY_NEW <- AIEvent.ET_COMPANY_NEW;
-AIEvent.AI_ET_COMPANY_IN_TROUBLE <- AIEvent.ET_COMPANY_IN_TROUBLE;
-AIEvent.AI_ET_COMPANY_ASK_MERGER <- AIEvent.ET_COMPANY_ASK_MERGER;
-AIEvent.AI_ET_COMPANY_MERGER <- AIEvent.ET_COMPANY_MERGER;
-AIEvent.AI_ET_COMPANY_BANKRUPT <- AIEvent.ET_COMPANY_BANKRUPT;
-AIEvent.AI_ET_VEHICLE_CRASHED <- AIEvent.ET_VEHICLE_CRASHED;
-AIEvent.AI_ET_VEHICLE_LOST <- AIEvent.ET_VEHICLE_LOST;
-AIEvent.AI_ET_VEHICLE_WAITING_IN_DEPOT <- AIEvent.ET_VEHICLE_WAITING_IN_DEPOT;
-AIEvent.AI_ET_VEHICLE_UNPROFITABLE <- AIEvent.ET_VEHICLE_UNPROFITABLE;
-AIEvent.AI_ET_INDUSTRY_OPEN <- AIEvent.ET_INDUSTRY_OPEN;
-AIEvent.AI_ET_INDUSTRY_CLOSE <- AIEvent.ET_INDUSTRY_CLOSE;
-AIEvent.AI_ET_ENGINE_AVAILABLE <- AIEvent.ET_ENGINE_AVAILABLE;
-AIEvent.AI_ET_STATION_FIRST_VEHICLE <- AIEvent.ET_STATION_FIRST_VEHICLE;
-AIEvent.AI_ET_DISASTER_ZEPPELINER_CRASHED <- AIEvent.ET_DISASTER_ZEPPELINER_CRASHED;
-AIEvent.AI_ET_DISASTER_ZEPPELINER_CLEARED <- AIEvent.ET_DISASTER_ZEPPELINER_CLEARED;
-AIOrder.AIOF_NONE <- AIOrder.OF_NONE
-AIOrder.AIOF_NON_STOP_INTERMEDIATE <- AIOrder.OF_NON_STOP_INTERMEDIATE
-AIOrder.AIOF_NON_STOP_DESTINATION <- AIOrder.OF_NON_STOP_DESTINATION
-AIOrder.AIOF_UNLOAD <- AIOrder.OF_UNLOAD
-AIOrder.AIOF_TRANSFER <- AIOrder.OF_TRANSFER
-AIOrder.AIOF_NO_UNLOAD <- AIOrder.OF_NO_UNLOAD
-AIOrder.AIOF_FULL_LOAD <- AIOrder.OF_FULL_LOAD
-AIOrder.AIOF_FULL_LOAD_ANY <- AIOrder.OF_FULL_LOAD_ANY
-AIOrder.AIOF_NO_LOAD <- AIOrder.OF_NO_LOAD
-AIOrder.AIOF_SERVICE_IF_NEEDED <- AIOrder.OF_SERVICE_IF_NEEDED
-AIOrder.AIOF_STOP_IN_DEPOT <- AIOrder.OF_STOP_IN_DEPOT
-AIOrder.AIOF_GOTO_NEAREST_DEPOT <- AIOrder.OF_GOTO_NEAREST_DEPOT
-AIOrder.AIOF_NON_STOP_FLAGS <- AIOrder.OF_NON_STOP_FLAGS
-AIOrder.AIOF_UNLOAD_FLAGS <- AIOrder.OF_UNLOAD_FLAGS
-AIOrder.AIOF_LOAD_FLAGS <- AIOrder.OF_LOAD_FLAGS
-AIOrder.AIOF_DEPOT_FLAGS <- AIOrder.OF_DEPOT_FLAGS
-AIOrder.AIOF_INVALID <- AIOrder.OF_INVALID
-
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 0)
diff --git a/bin/ai/compat_1.1.nut b/bin/ai/compat_1.1.nut
index 456b054aba..ce5b00c0cd 100644
--- a/bin/ai/compat_1.1.nut
+++ b/bin/ai/compat_1.1.nut
@@ -7,80 +7,5 @@
AILog.Info("1.1 API compatibility in effect.");
-AICompany.GetCompanyValue <- function(company)
-{
- return AICompany.GetQuarterlyCompanyValue(company, AICompany.CURRENT_QUARTER);
-}
-
-AITown.GetLastMonthTransported <- AITown.GetLastMonthSupplied;
-
-AIEvent.AI_ET_INVALID <- AIEvent.ET_INVALID;
-AIEvent.AI_ET_TEST <- AIEvent.ET_TEST;
-AIEvent.AI_ET_SUBSIDY_OFFER <- AIEvent.ET_SUBSIDY_OFFER;
-AIEvent.AI_ET_SUBSIDY_OFFER_EXPIRED <- AIEvent.ET_SUBSIDY_OFFER_EXPIRED;
-AIEvent.AI_ET_SUBSIDY_AWARDED <- AIEvent.ET_SUBSIDY_AWARDED;
-AIEvent.AI_ET_SUBSIDY_EXPIRED <- AIEvent.ET_SUBSIDY_EXPIRED;
-AIEvent.AI_ET_ENGINE_PREVIEW <- AIEvent.ET_ENGINE_PREVIEW;
-AIEvent.AI_ET_COMPANY_NEW <- AIEvent.ET_COMPANY_NEW;
-AIEvent.AI_ET_COMPANY_IN_TROUBLE <- AIEvent.ET_COMPANY_IN_TROUBLE;
-AIEvent.AI_ET_COMPANY_ASK_MERGER <- AIEvent.ET_COMPANY_ASK_MERGER;
-AIEvent.AI_ET_COMPANY_MERGER <- AIEvent.ET_COMPANY_MERGER;
-AIEvent.AI_ET_COMPANY_BANKRUPT <- AIEvent.ET_COMPANY_BANKRUPT;
-AIEvent.AI_ET_VEHICLE_CRASHED <- AIEvent.ET_VEHICLE_CRASHED;
-AIEvent.AI_ET_VEHICLE_LOST <- AIEvent.ET_VEHICLE_LOST;
-AIEvent.AI_ET_VEHICLE_WAITING_IN_DEPOT <- AIEvent.ET_VEHICLE_WAITING_IN_DEPOT;
-AIEvent.AI_ET_VEHICLE_UNPROFITABLE <- AIEvent.ET_VEHICLE_UNPROFITABLE;
-AIEvent.AI_ET_INDUSTRY_OPEN <- AIEvent.ET_INDUSTRY_OPEN;
-AIEvent.AI_ET_INDUSTRY_CLOSE <- AIEvent.ET_INDUSTRY_CLOSE;
-AIEvent.AI_ET_ENGINE_AVAILABLE <- AIEvent.ET_ENGINE_AVAILABLE;
-AIEvent.AI_ET_STATION_FIRST_VEHICLE <- AIEvent.ET_STATION_FIRST_VEHICLE;
-AIEvent.AI_ET_DISASTER_ZEPPELINER_CRASHED <- AIEvent.ET_DISASTER_ZEPPELINER_CRASHED;
-AIEvent.AI_ET_DISASTER_ZEPPELINER_CLEARED <- AIEvent.ET_DISASTER_ZEPPELINER_CLEARED;
-AIEvent.AI_ET_TOWN_FOUNDED <- AIEvent.ET_TOWN_FOUNDED;
-AIOrder.AIOF_NONE <- AIOrder.OF_NONE
-AIOrder.AIOF_NON_STOP_INTERMEDIATE <- AIOrder.OF_NON_STOP_INTERMEDIATE
-AIOrder.AIOF_NON_STOP_DESTINATION <- AIOrder.OF_NON_STOP_DESTINATION
-AIOrder.AIOF_UNLOAD <- AIOrder.OF_UNLOAD
-AIOrder.AIOF_TRANSFER <- AIOrder.OF_TRANSFER
-AIOrder.AIOF_NO_UNLOAD <- AIOrder.OF_NO_UNLOAD
-AIOrder.AIOF_FULL_LOAD <- AIOrder.OF_FULL_LOAD
-AIOrder.AIOF_FULL_LOAD_ANY <- AIOrder.OF_FULL_LOAD_ANY
-AIOrder.AIOF_NO_LOAD <- AIOrder.OF_NO_LOAD
-AIOrder.AIOF_SERVICE_IF_NEEDED <- AIOrder.OF_SERVICE_IF_NEEDED
-AIOrder.AIOF_STOP_IN_DEPOT <- AIOrder.OF_STOP_IN_DEPOT
-AIOrder.AIOF_GOTO_NEAREST_DEPOT <- AIOrder.OF_GOTO_NEAREST_DEPOT
-AIOrder.AIOF_NON_STOP_FLAGS <- AIOrder.OF_NON_STOP_FLAGS
-AIOrder.AIOF_UNLOAD_FLAGS <- AIOrder.OF_UNLOAD_FLAGS
-AIOrder.AIOF_LOAD_FLAGS <- AIOrder.OF_LOAD_FLAGS
-AIOrder.AIOF_DEPOT_FLAGS <- AIOrder.OF_DEPOT_FLAGS
-AIOrder.AIOF_INVALID <- AIOrder.OF_INVALID
-
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 1)
diff --git a/bin/ai/compat_1.10.nut b/bin/ai/compat_1.10.nut
index 9b82efdcb3..12bf455a21 100644
--- a/bin/ai/compat_1.10.nut
+++ b/bin/ai/compat_1.10.nut
@@ -7,18 +7,5 @@
AILog.Info("1.10 API compatibility in effect.");
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 10)
diff --git a/bin/ai/compat_1.11.nut b/bin/ai/compat_1.11.nut
index 1b6bc4da04..81879f00b2 100644
--- a/bin/ai/compat_1.11.nut
+++ b/bin/ai/compat_1.11.nut
@@ -7,18 +7,5 @@
AILog.Info("1.11 API compatibility in effect.");
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 11)
diff --git a/bin/ai/compat_1.2.nut b/bin/ai/compat_1.2.nut
index 75ffd93d66..51efc9c89d 100644
--- a/bin/ai/compat_1.2.nut
+++ b/bin/ai/compat_1.2.nut
@@ -7,32 +7,5 @@
AILog.Info("1.2 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 2)
diff --git a/bin/ai/compat_1.3.nut b/bin/ai/compat_1.3.nut
index 5bc97c2cb2..81f18e5e14 100644
--- a/bin/ai/compat_1.3.nut
+++ b/bin/ai/compat_1.3.nut
@@ -7,32 +7,5 @@
AILog.Info("1.3 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 3)
diff --git a/bin/ai/compat_1.4.nut b/bin/ai/compat_1.4.nut
index 5700c6bfb8..45f55de899 100644
--- a/bin/ai/compat_1.4.nut
+++ b/bin/ai/compat_1.4.nut
@@ -7,32 +7,5 @@
AILog.Info("1.4 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 5)
diff --git a/bin/ai/compat_1.5.nut b/bin/ai/compat_1.5.nut
index 88f4221b4e..6b3c4bedcd 100644
--- a/bin/ai/compat_1.5.nut
+++ b/bin/ai/compat_1.5.nut
@@ -7,32 +7,5 @@
AILog.Info("1.5 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 5)
diff --git a/bin/ai/compat_1.6.nut b/bin/ai/compat_1.6.nut
index 4ddb4c5bcb..b143b7924c 100644
--- a/bin/ai/compat_1.6.nut
+++ b/bin/ai/compat_1.6.nut
@@ -7,32 +7,5 @@
AILog.Info("1.6 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 6)
diff --git a/bin/ai/compat_1.7.nut b/bin/ai/compat_1.7.nut
index 557f13bdc3..43a96a4160 100644
--- a/bin/ai/compat_1.7.nut
+++ b/bin/ai/compat_1.7.nut
@@ -7,32 +7,5 @@
AILog.Info("1.7 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 7)
diff --git a/bin/ai/compat_1.8.nut b/bin/ai/compat_1.8.nut
index 8e99a2c0c1..9b4938218a 100644
--- a/bin/ai/compat_1.8.nut
+++ b/bin/ai/compat_1.8.nut
@@ -7,32 +7,5 @@
AILog.Info("1.8 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-AIBridge._GetName <- AIBridge.GetName;
-AIBridge.GetName <- function(bridge_id)
-{
- return AIBridge._GetName(bridge_id, AIVehicle.VT_RAIL);
-}
-
-/* 1.9 adds parent_group_id to CreateGroup function */
-AIGroup._CreateGroup <- AIGroup.CreateGroup;
-AIGroup.CreateGroup <- function(vehicle_type)
-{
- return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 8)
diff --git a/bin/ai/compat_1.9.nut b/bin/ai/compat_1.9.nut
index 8301ebb4b8..54356eb5f6 100644
--- a/bin/ai/compat_1.9.nut
+++ b/bin/ai/compat_1.9.nut
@@ -7,18 +7,5 @@
AILog.Info("1.9 API compatibility in effect.");
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(1, 9)
diff --git a/bin/ai/compat_12.nut b/bin/ai/compat_12.nut
index 3ac3c66cb7..de3542fe2e 100644
--- a/bin/ai/compat_12.nut
+++ b/bin/ai/compat_12.nut
@@ -7,18 +7,5 @@
AILog.Info("12 API compatibility in effect.");
-/* 13 really checks RoadType against RoadType */
-AIRoad._HasRoadType <- AIRoad.HasRoadType;
-AIRoad.HasRoadType <- function(tile, road_type)
-{
- local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (AIRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(12, 0)
diff --git a/bin/ai/compat_13.nut b/bin/ai/compat_13.nut
index 42311e8001..efcee6441e 100644
--- a/bin/ai/compat_13.nut
+++ b/bin/ai/compat_13.nut
@@ -7,5 +7,5 @@
AILog.Info("13 API compatibility in effect.");
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(13, 0)
diff --git a/bin/ai/compat_14.nut b/bin/ai/compat_14.nut
index a303139a69..013d274d95 100644
--- a/bin/ai/compat_14.nut
+++ b/bin/ai/compat_14.nut
@@ -7,5 +7,5 @@
AILog.Info("14 API compatibility in effect.");
-/* 15 renames GetBridgeID */
-AIBridge.GetBridgeID <- AIBridge.GetBridgeType;
+require("compat.nut")
+AICompatibility.Add(14, 0)
diff --git a/bin/game/CMakeLists.txt b/bin/game/CMakeLists.txt
index d0b5448997..d8591d4534 100644
--- a/bin/game/CMakeLists.txt
+++ b/bin/game/CMakeLists.txt
@@ -1,4 +1,5 @@
set(GS_COMPAT_SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/compat.nut
${CMAKE_CURRENT_SOURCE_DIR}/compat_1.2.nut
${CMAKE_CURRENT_SOURCE_DIR}/compat_1.3.nut
${CMAKE_CURRENT_SOURCE_DIR}/compat_1.4.nut
diff --git a/bin/game/compat.nut b/bin/game/compat.nut
new file mode 100644
index 0000000000..1cb4bc3612
--- /dev/null
+++ b/bin/game/compat.nut
@@ -0,0 +1,70 @@
+/*
+ * This file is part of OpenTTD.
+ * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
+ * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
+ */
+
+class GSCompatibility {}
+
+function GSCompatibility::Add(major, minor)
+{
+ if (major == 1 && minor < 4) {
+ /* 1.4 codified resetting custom growth rate in a different way */
+ GSTown._SetGrowthRate <- GSTown.SetGrowthRate;
+ GSTown.SetGrowthRate <- function(town_id, days_between_town_growth)
+ {
+ /* Growth rate 0 caused resetting the custom growth rate. While this was undocumented, it was used nevertheless (ofc). */
+ if (days_between_town_growth == 0) days_between_town_growth = GSTown.TOWN_GROWTH_NORMAL;
+ return GSTown._SetGrowthRate(town_id, days_between_town_growth);
+ }
+ }
+
+ if (major == 1 && minor < 5) {
+ /* 1.5 adds a game element reference to the news. */
+ GSNews._Create <- GSNews.Create;
+ GSNews.Create <- function(type, text, company)
+ {
+ return GSNews._Create(type, text, company, GSNews.NR_NONE, 0);
+ }
+ }
+
+ if (major == 1 && minor < 9) {
+ /* 1.9 adds a vehicle type parameter. */
+ GSBridge._GetName <- GSBridge.GetName;
+ GSBridge.GetName <- function(bridge_id)
+ {
+ return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
+ }
+ }
+
+
+ if (major == 1 && minor < 11) {
+ /* 1.11 adds a tile parameter. */
+ GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
+ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
+ {
+ return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
+ }
+ }
+
+ if (major < 13) {
+ /* 13 really checks RoadType against RoadType */
+ GSRoad._HasRoadType <- GSRoad.HasRoadType;
+ GSRoad.HasRoadType <- function(tile, road_type)
+ {
+ local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
+ foreach (rt, _ in list) {
+ if (GSRoad._HasRoadType(tile, rt)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ if (major < 15) {
+ /* 15 renames GetBridgeID */
+ GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+ }
+}
diff --git a/bin/game/compat_1.10.nut b/bin/game/compat_1.10.nut
index 01a611075a..ff616d146e 100644
--- a/bin/game/compat_1.10.nut
+++ b/bin/game/compat_1.10.nut
@@ -7,25 +7,5 @@
GSLog.Info("1.10 API compatibility in effect.");
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 10)
diff --git a/bin/game/compat_1.11.nut b/bin/game/compat_1.11.nut
index 9cee3efe3b..8d7442005a 100644
--- a/bin/game/compat_1.11.nut
+++ b/bin/game/compat_1.11.nut
@@ -7,18 +7,5 @@
GSLog.Info("1.11 API compatibility in effect.");
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 11)
diff --git a/bin/game/compat_1.2.nut b/bin/game/compat_1.2.nut
index 662b8a8602..a52efedce3 100644
--- a/bin/game/compat_1.2.nut
+++ b/bin/game/compat_1.2.nut
@@ -7,47 +7,5 @@
GSLog.Info("1.2 API compatibility in effect.");
-GSTown._SetGrowthRate <- GSTown.SetGrowthRate;
-GSTown.SetGrowthRate <- function(town_id, days_between_town_growth)
-{
- /* Growth rate 0 caused resetting the custom growth rate. While this was undocumented, it was used nevertheless (ofc). */
- if (days_between_town_growth == 0) days_between_town_growth = GSTown.TOWN_GROWTH_NORMAL;
- return GSTown._SetGrowthRate(town_id, days_between_town_growth);
-}
-
-/* 1.5 adds a game element reference to the news. */
-GSNews._Create <- GSNews.Create;
-GSNews.Create <- function(type, text, company)
-{
- return GSNews._Create(type, text, company, GSNews.NR_NONE, 0);
-}
-
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 2)
diff --git a/bin/game/compat_1.3.nut b/bin/game/compat_1.3.nut
index 6dd74c008d..27604d1f76 100644
--- a/bin/game/compat_1.3.nut
+++ b/bin/game/compat_1.3.nut
@@ -7,47 +7,5 @@
GSLog.Info("1.3 API compatibility in effect.");
-GSTown._SetGrowthRate <- GSTown.SetGrowthRate;
-GSTown.SetGrowthRate <- function(town_id, days_between_town_growth)
-{
- /* Growth rate 0 caused resetting the custom growth rate. While this was undocumented, it was used nevertheless (ofc). */
- if (days_between_town_growth == 0) days_between_town_growth = GSTown.TOWN_GROWTH_NORMAL;
- return GSTown._SetGrowthRate(town_id, days_between_town_growth);
-}
-
-/* 1.5 adds a game element reference to the news. */
-GSNews._Create <- GSNews.Create;
-GSNews.Create <- function(type, text, company)
-{
- return GSNews._Create(type, text, company, GSNews.NR_NONE, 0);
-}
-
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 3)
diff --git a/bin/game/compat_1.4.nut b/bin/game/compat_1.4.nut
index 1d53a60642..9938c522ff 100644
--- a/bin/game/compat_1.4.nut
+++ b/bin/game/compat_1.4.nut
@@ -7,39 +7,5 @@
GSLog.Info("1.4 API compatibility in effect.");
-/* 1.5 adds a game element reference to the news. */
-GSNews._Create <- GSNews.Create;
-GSNews.Create <- function(type, text, company)
-{
- return GSNews._Create(type, text, company, GSNews.NR_NONE, 0);
-}
-
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 4)
diff --git a/bin/game/compat_1.5.nut b/bin/game/compat_1.5.nut
index 05fb05253b..71c1acde93 100644
--- a/bin/game/compat_1.5.nut
+++ b/bin/game/compat_1.5.nut
@@ -7,32 +7,5 @@
GSLog.Info("1.5 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 5)
diff --git a/bin/game/compat_1.6.nut b/bin/game/compat_1.6.nut
index 0ee37890d5..cda669d400 100644
--- a/bin/game/compat_1.6.nut
+++ b/bin/game/compat_1.6.nut
@@ -7,32 +7,5 @@
GSLog.Info("1.6 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 6)
diff --git a/bin/game/compat_1.7.nut b/bin/game/compat_1.7.nut
index 33f607b7f0..72891cbb77 100644
--- a/bin/game/compat_1.7.nut
+++ b/bin/game/compat_1.7.nut
@@ -7,32 +7,5 @@
GSLog.Info("1.7 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 7)
diff --git a/bin/game/compat_1.8.nut b/bin/game/compat_1.8.nut
index 9723add99a..fab758befc 100644
--- a/bin/game/compat_1.8.nut
+++ b/bin/game/compat_1.8.nut
@@ -7,32 +7,5 @@
GSLog.Info("1.8 API compatibility in effect.");
-/* 1.9 adds a vehicle type parameter. */
-GSBridge._GetName <- GSBridge.GetName;
-GSBridge.GetName <- function(bridge_id)
-{
- return GSBridge._GetName(bridge_id, GSVehicle.VT_RAIL);
-}
-
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 8)
diff --git a/bin/game/compat_1.9.nut b/bin/game/compat_1.9.nut
index f9e3b42797..f5b904bd28 100644
--- a/bin/game/compat_1.9.nut
+++ b/bin/game/compat_1.9.nut
@@ -7,25 +7,5 @@
GSLog.Info("1.9 API compatibility in effect.");
-/* 1.11 adds a tile parameter. */
-GSCompany._ChangeBankBalance <- GSCompany.ChangeBankBalance;
-GSCompany.ChangeBankBalance <- function(company, delta, expenses_type)
-{
- return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID);
-}
-
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(1, 9)
diff --git a/bin/game/compat_12.nut b/bin/game/compat_12.nut
index e2e263bd49..9d90e7a3f0 100644
--- a/bin/game/compat_12.nut
+++ b/bin/game/compat_12.nut
@@ -7,18 +7,5 @@
GSLog.Info("12 API compatibility in effect.");
-/* 13 really checks RoadType against RoadType */
-GSRoad._HasRoadType <- GSRoad.HasRoadType;
-GSRoad.HasRoadType <- function(tile, road_type)
-{
- local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type));
- foreach (rt, _ in list) {
- if (GSRoad._HasRoadType(tile, rt)) {
- return true;
- }
- }
- return false;
-}
-
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(12, 0)
diff --git a/bin/game/compat_13.nut b/bin/game/compat_13.nut
index a9dc9cd87d..dbaf7fb98c 100644
--- a/bin/game/compat_13.nut
+++ b/bin/game/compat_13.nut
@@ -7,5 +7,5 @@
GSLog.Info("13 API compatibility in effect.");
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(13, 0)
diff --git a/bin/game/compat_14.nut b/bin/game/compat_14.nut
index 9115d8bcfa..9b94ff9ad5 100644
--- a/bin/game/compat_14.nut
+++ b/bin/game/compat_14.nut
@@ -7,5 +7,5 @@
GSLog.Info("14 API compatibility in effect.");
-/* 15 renames GetBridgeID */
-GSBridge.GetBridgeID <- GSBridge.GetBridgeType;
+require("compat.nut")
+GSCompatibility.Add(14, 0)