From 8583274f183dd88c7488d35e36efe340033bed76 Mon Sep 17 00:00:00 2001 From: yexo Date: Sat, 14 Feb 2009 21:15:23 +0000 Subject: [PATCH] (svn r15488) -Change [API CHANGE]: Add support for distant-join stations. --- bin/ai/regression/regression.nut | 38 ++++++++++++++++---------------- src/ai/api/ai_airport.cpp | 7 ++++-- src/ai/api/ai_airport.hpp | 5 +++-- src/ai/api/ai_airport.hpp.sq | 2 +- src/ai/api/ai_marine.cpp | 8 +++++-- src/ai/api/ai_marine.hpp | 5 +++-- src/ai/api/ai_marine.hpp.sq | 2 +- src/ai/api/ai_rail.cpp | 15 ++++++++----- src/ai/api/ai_rail.hpp | 10 +++++---- src/ai/api/ai_rail.hpp.sq | 4 ++-- src/ai/api/ai_road.cpp | 11 +++++++-- src/ai/api/ai_road.hpp | 5 +++-- src/ai/api/ai_road.hpp.sq | 2 +- src/ai/api/ai_station.hpp | 6 +++++ src/ai/api/ai_station.hpp.sq | 5 +++++ 15 files changed, 79 insertions(+), 46 deletions(-) diff --git a/bin/ai/regression/regression.nut b/bin/ai/regression/regression.nut index de45d5250d..679aa0bec9 100644 --- a/bin/ai/regression/regression.nut +++ b/bin/ai/regression/regression.nut @@ -221,7 +221,7 @@ function Regression::Airport() } print(" GetBankBalance(): " + AICompany.GetBankBalance(AICompany.COMPANY_SELF)); - print(" BuildAirport(): " + AIAirport.BuildAirport(32116, 0, true)); + print(" BuildAirport(): " + AIAirport.BuildAirport(32116, 0, AIStation.STATION_JOIN_ADJACENT)); print(" IsHangarTile(): " + AIAirport.IsHangarTile(32116)); print(" IsAirportTile(): " + AIAirport.IsAirportTile(32116)); print(" GetAirportType(): " + AIAirport.GetAirportType(32119)); @@ -235,7 +235,7 @@ function Regression::Airport() print(" IsHangarTile(): " + AIAirport.IsHangarTile(32119)); print(" IsAirportTile(): " + AIAirport.IsAirportTile(32119)); print(" GetBankBalance(): " + AICompany.GetBankBalance(AICompany.COMPANY_SELF)); - print(" BuildAirport(): " + AIAirport.BuildAirport(32116, 0, true)); + print(" BuildAirport(): " + AIAirport.BuildAirport(32116, 0, AIStation.STATION_JOIN_ADJACENT)); } function Regression::Bridge() @@ -786,7 +786,7 @@ function Regression::Marine() print(" GetBankBalance(): " + AICompany.GetBankBalance(AICompany.COMPANY_SELF)); print(" BuildWaterDepot(): " + AIMarine.BuildWaterDepot(28479, false)); - print(" BuildDock(): " + AIMarine.BuildDock(29253, true)); + print(" BuildDock(): " + AIMarine.BuildDock(29253, AIStation.STATION_JOIN_ADJACENT)); print(" BuildBuoy(): " + AIMarine.BuildBuoy(28481)); print(" BuildLock(): " + AIMarine.BuildLock(28487)); print(" HasTransportType(): " + AITile.HasTransportType(32127, AITile.TRANSPORT_WATER)); @@ -812,7 +812,7 @@ function Regression::Marine() print(" GetBankBalance(): " + AICompany.GetBankBalance(AICompany.COMPANY_SELF)); print(" BuildWaterDepot(): " + AIMarine.BuildWaterDepot(28479, false)); - print(" BuildDock(): " + AIMarine.BuildDock(29253, true)); + print(" BuildDock(): " + AIMarine.BuildDock(29253, AIStation.STATION_JOIN_ADJACENT)); } function Regression::Order() @@ -944,8 +944,8 @@ function Regression::Rail() print(" RemoveDepot(): " + AITile.DemolishTile(33411)); print(" Station"); - print(" BuildRailStation(): " + AIRail.BuildRailStation(0, AIRail.RAILTRACK_NE_SW, 1, 1, false)); - print(" BuildRailStation(): " + AIRail.BuildRailStation(7958, AIRail.RAILTRACK_NE_SW, 4, 5, false)); + print(" BuildRailStation(): " + AIRail.BuildRailStation(0, AIRail.RAILTRACK_NE_SW, 1, 1, AIStation.STATION_NEW)); + print(" BuildRailStation(): " + AIRail.BuildRailStation(7958, AIRail.RAILTRACK_NE_SW, 4, 5, AIStation.STATION_NEW)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7957)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7958)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7959)); @@ -1023,10 +1023,10 @@ function Regression::Road() print(" Station"); print(" IsRoadTile(): " + AIRoad.IsRoadTile(33411)); - print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(0, 1, false, false, true)); - print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(33411, 33411, false, false, true)); - print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(33411, 33414, false, false, true)); - print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(33411, 33412, false, false, true)); + print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(0, 1, false, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(33411, 33411, false, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(33411, 33414, false, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(): " + AIRoad.BuildRoadStation(33411, 33412, false, false, AIStation.STATION_JOIN_ADJACENT)); print(" IsStationTile(): " + AITile.IsStationTile(33411)); print(" IsStationTile(): " + AITile.IsStationTile(33412)); print(" HasRoadType(Road): " + AIRoad.HasRoadType(33411, AIRoad.ROADTYPE_ROAD)); @@ -1040,15 +1040,15 @@ function Regression::Road() print(" RemoveRoadStation(): " + AIRoad.RemoveRoadStation(33411)); print(" Station Types"); - print(" BuildRoadStation(bus): " + AIRoad.BuildRoadStation(33411, 33410, false, false, true)); - print(" BuildRoadStation(truck): " + AIRoad.BuildRoadStation(33421, 33422, true, false, true)); - print(" BuildRoadStation(truck): " + AIRoad.BuildRoadStation(33412, 33413, true, false, true)); - print(" BuildRoadStation(bus): " + AIRoad.BuildRoadStation(33411 + 256, 33411, false, false, true)); - print(" BuildRoadStation(truck): " + AIRoad.BuildRoadStation(33412 + 256, 33412 + 256 + 256, true, false, true)); - print(" BuildRoadStation(bus-drive): " + AIRoad.BuildRoadStation(33413, 33412, false, true, true)); - print(" BuildRoadStation(truck-drive): " + AIRoad.BuildRoadStation(33414, 33413, true, true, true)); - print(" BuildRoadStation(bus-drive): " + AIRoad.BuildRoadStation(33415, 33414, false, true, true)); - print(" BuildRoadStation(truck-drive): " + AIRoad.BuildRoadStation(33416, 33415, true, true, true)); + print(" BuildRoadStation(bus): " + AIRoad.BuildRoadStation(33411, 33410, false, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(truck): " + AIRoad.BuildRoadStation(33421, 33422, true, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(truck): " + AIRoad.BuildRoadStation(33412, 33413, true, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(bus): " + AIRoad.BuildRoadStation(33411 + 256, 33411, false, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(truck): " + AIRoad.BuildRoadStation(33412 + 256, 33412 + 256 + 256, true, false, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(bus-drive): " + AIRoad.BuildRoadStation(33413, 33412, false, true, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(truck-drive): " + AIRoad.BuildRoadStation(33414, 33413, true, true, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(bus-drive): " + AIRoad.BuildRoadStation(33415, 33414, false, true, AIStation.STATION_JOIN_ADJACENT)); + print(" BuildRoadStation(truck-drive): " + AIRoad.BuildRoadStation(33416, 33415, true, true, AIStation.STATION_JOIN_ADJACENT)); print(" BuildRoadDepot(): " + AIRoad.BuildRoadDepot(33417, 33418)); print(" GetRoadStationFrontTile(): " + AIRoad.GetRoadStationFrontTile(33411 + 256)); print(" GetRoadStationFrontTile(): " + AIRoad.GetRoadStationFrontTile(33412 + 256)); diff --git a/src/ai/api/ai_airport.cpp b/src/ai/api/ai_airport.cpp index cfe4df0846..b2b969b82a 100644 --- a/src/ai/api/ai_airport.cpp +++ b/src/ai/api/ai_airport.cpp @@ -56,12 +56,15 @@ return _settings_game.station.modified_catchment ? ::GetAirport(type)->catchment : (uint)CA_UNMODIFIED; } -/* static */ bool AIAirport::BuildAirport(TileIndex tile, AirportType type, bool join_adjacent) +/* static */ bool AIAirport::BuildAirport(TileIndex tile, AirportType type, StationID station_id) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsValidAirportType(type)); + EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id)); - return AIObject::DoCommand(tile, type, (INVALID_STATION << 16) | (join_adjacent ? 0 : 1), CMD_BUILD_AIRPORT); + uint p2 = station_id == AIStation::STATION_JOIN_ADJACENT ? 0 : 1; + p2 |= (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; + return AIObject::DoCommand(tile, type, p2, CMD_BUILD_AIRPORT); } /* static */ bool AIAirport::RemoveAirport(TileIndex tile) diff --git a/src/ai/api/ai_airport.hpp b/src/ai/api/ai_airport.hpp index 7693774e62..559d9c6aea 100644 --- a/src/ai/api/ai_airport.hpp +++ b/src/ai/api/ai_airport.hpp @@ -120,9 +120,10 @@ public: * Builds a airport with tile at the topleft corner. * @param tile The topleft corner of the airport. * @param type The type of airport to build. - * @param join_adjacent When building next to an other station, don't create a new station when this flag is true. + * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT. * @pre AIMap::IsValidTile(tile). * @pre AirportAvailable(type). + * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id). * @exception AIError::ERR_AREA_NOT_CLEAR * @exception AIError::ERR_FLAT_LAND_REQUIRED * @exception AIError::ERR_LOCAL_AUTHORITY_REFUSES @@ -130,7 +131,7 @@ public: * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_OTHER_STATION * @return Whether the airport has been/can be build or not. */ - static bool BuildAirport(TileIndex tile, AirportType type, bool join_adjacent); + static bool BuildAirport(TileIndex tile, AirportType type, StationID station_id); /** * Removes a airport. diff --git a/src/ai/api/ai_airport.hpp.sq b/src/ai/api/ai_airport.hpp.sq index 3c56b6daef..f84412869d 100644 --- a/src/ai/api/ai_airport.hpp.sq +++ b/src/ai/api/ai_airport.hpp.sq @@ -47,7 +47,7 @@ void SQAIAirport_Register(Squirrel *engine) { SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportCoverageRadius, "GetAirportCoverageRadius", 2, "?i"); SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNumHangars, "GetNumHangars", 2, "?i"); SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetHangarOfAirport, "GetHangarOfAirport", 2, "?i"); - SQAIAirport.DefSQStaticMethod(engine, &AIAirport::BuildAirport, "BuildAirport", 4, "?iib"); + SQAIAirport.DefSQStaticMethod(engine, &AIAirport::BuildAirport, "BuildAirport", 4, "?iii"); SQAIAirport.DefSQStaticMethod(engine, &AIAirport::RemoveAirport, "RemoveAirport", 2, "?i"); SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetAirportType, "GetAirportType", 2, "?i"); SQAIAirport.DefSQStaticMethod(engine, &AIAirport::GetNoiseLevelIncrease, "GetNoiseLevelIncrease", 3, "?ii"); diff --git a/src/ai/api/ai_marine.cpp b/src/ai/api/ai_marine.cpp index e1712ab69e..f80c510e55 100644 --- a/src/ai/api/ai_marine.cpp +++ b/src/ai/api/ai_marine.cpp @@ -3,6 +3,7 @@ /** @file ai_marine.cpp Implementation of AIMarine. */ #include "ai_marine.hpp" +#include "ai_station.hpp" #include "../../station_map.h" #include "../../tile_cmd.h" @@ -70,11 +71,14 @@ return AIObject::DoCommand(tile, vertical, 0, CMD_BUILD_SHIP_DEPOT); } -/* static */ bool AIMarine::BuildDock(TileIndex tile, bool join_adjacent) +/* static */ bool AIMarine::BuildDock(TileIndex tile, StationID station_id) { EnforcePrecondition(false, ::IsValidTile(tile)); + EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id)); - return AIObject::DoCommand(tile, join_adjacent ? 0 : 1, INVALID_STATION << 16, CMD_BUILD_DOCK); + uint p1 = station_id == AIStation::STATION_JOIN_ADJACENT ? 0 : 1; + uint p2 = (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; + return AIObject::DoCommand(tile, p1, p2, CMD_BUILD_DOCK); } /* static */ bool AIMarine::BuildBuoy(TileIndex tile) diff --git a/src/ai/api/ai_marine.hpp b/src/ai/api/ai_marine.hpp index 9f871887db..0ff0660186 100644 --- a/src/ai/api/ai_marine.hpp +++ b/src/ai/api/ai_marine.hpp @@ -95,15 +95,16 @@ public: /** * Builds a dock where tile is the tile still on land. * @param tile The tile still on land of the dock. - * @param join_adjacent When building next to an other station, don't create a new station when this flag is true. + * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT. * @pre AIMap::IsValidTile(tile). + * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id). * @exception AIError::ERR_AREA_NOT_CLEAR * @exception AIError::ERR_SITE_UNSUITABLE * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS * @return Whether the dock has been/can be build or not. */ - static bool BuildDock(TileIndex tile, bool join_adjacent); + static bool BuildDock(TileIndex tile, StationID station_id); /** * Builds a buoy on tile. diff --git a/src/ai/api/ai_marine.hpp.sq b/src/ai/api/ai_marine.hpp.sq index 3c32431836..42c641b2a9 100644 --- a/src/ai/api/ai_marine.hpp.sq +++ b/src/ai/api/ai_marine.hpp.sq @@ -35,7 +35,7 @@ void SQAIMarine_Register(Squirrel *engine) { SQAIMarine.DefSQStaticMethod(engine, &AIMarine::IsCanalTile, "IsCanalTile", 2, "?i"); SQAIMarine.DefSQStaticMethod(engine, &AIMarine::AreWaterTilesConnected, "AreWaterTilesConnected", 3, "?ii"); SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildWaterDepot, "BuildWaterDepot", 3, "?ib"); - SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildDock, "BuildDock", 3, "?ib"); + SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildDock, "BuildDock", 3, "?ii"); SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildBuoy, "BuildBuoy", 2, "?i"); SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildLock, "BuildLock", 2, "?i"); SQAIMarine.DefSQStaticMethod(engine, &AIMarine::BuildCanal, "BuildCanal", 2, "?i"); diff --git a/src/ai/api/ai_rail.cpp b/src/ai/api/ai_rail.cpp index 9ef1c4f53a..f520fdb5c2 100644 --- a/src/ai/api/ai_rail.cpp +++ b/src/ai/api/ai_rail.cpp @@ -4,6 +4,7 @@ #include "ai_rail.hpp" #include "ai_map.hpp" +#include "ai_station.hpp" #include "../../debug.h" #include "../../station_map.h" #include "../../company_func.h" @@ -125,35 +126,37 @@ return AIObject::DoCommand(tile, AIObject::GetRailType(), entrance_dir, CMD_BUILD_TRAIN_DEPOT); } -/* static */ bool AIRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent) +/* static */ bool AIRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW); EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF); EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); + EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id)); uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); if (direction == RAILTRACK_NW_SE) p1 |= (1 << 4); - if (!join_adjacent) p1 |= (1 << 24); - return AIObject::DoCommand(tile, p1, INVALID_STATION << 16, CMD_BUILD_RAILROAD_STATION); + if (station_id != AIStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); + return AIObject::DoCommand(tile, p1, (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16, CMD_BUILD_RAILROAD_STATION); } -/* static */ bool AIRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station) +/* static */ bool AIRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW); EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF); EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF); EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType())); + EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id)); uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8); if (direction == RAILTRACK_NW_SE) p1 |= 1 << 4; - if (!join_adjacent) p1 |= (1 << 24); + if (station_id != AIStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24); const GRFFile *file; uint16 res = GetAiPurchaseCallbackResult(GSF_STATION, cargo_id, 0, source_industry, goal_industry, min(255, distance / 2), AICE_STATION_GET_STATION_ID, source_station ? 0 : 1, min(15, num_platforms) << 4 | min(15, platform_length), &file); - uint32 p2 = INVALID_STATION << 16; + uint32 p2 = (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; if (res != CALLBACK_FAILED) { int index = 0; const StationSpec *spec = GetCustomStationSpecByGrf(file->grfid, res, &index); diff --git a/src/ai/api/ai_rail.hpp b/src/ai/api/ai_rail.hpp index 5acb995ffd..7444907f29 100644 --- a/src/ai/api/ai_rail.hpp +++ b/src/ai/api/ai_rail.hpp @@ -213,12 +213,13 @@ public: * @param direction The direction to build the station. * @param num_platforms The number of platforms to build. * @param platform_length The length of each platform. - * @param join_adjacent When building next to an other station, don't create a new station when this flag is true. + * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT. * @pre IsRailTypeAvailable(GetCurrentRailType()). * @pre AIMap::IsValidTile(tile). * @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW. * @pre num_platforms > 0 && num_platforms <= 255. * @pre platform_length > 0 && platform_length <= 255. + * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id). * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception AIError::ERR_AREA_NOT_CLEAR * @exception AIError::ERR_FLAT_LAND_REQUIRED @@ -227,7 +228,7 @@ public: * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN * @return Whether the station has been/can be build or not. */ - static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent); + static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id); /** * Build a NewGRF rail station. This calls callback 18 to let a NewGRF @@ -237,7 +238,7 @@ public: * @param direction The direction to build the station. * @param num_platforms The number of platforms to build. * @param platform_length The length of each platform. - * @param join_adjacent When building next to an other station, don't create a new station when this flag is true. + * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT. * @param cargo_id The CargoID of the cargo that will be transported from / to this station. * @param source_industry The IndustryType of the industry you'll transport goods from. * @param goal_industry The IndustryType of the industry you'll transport goods to. @@ -248,6 +249,7 @@ public: * @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW. * @pre num_platforms > 0 && num_platforms <= 255. * @pre platform_length > 0 && platform_length <= 255. + * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id). * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception AIError::ERR_AREA_NOT_CLEAR * @exception AIError::ERR_FLAT_LAND_REQUIRED @@ -256,7 +258,7 @@ public: * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN * @return Whether the station has been/can be build or not. */ - static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, bool join_adjacent, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station); + static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station); /** * Remove a rectangle of platform pieces from a rail station. diff --git a/src/ai/api/ai_rail.hpp.sq b/src/ai/api/ai_rail.hpp.sq index 23979b227e..612551aa41 100644 --- a/src/ai/api/ai_rail.hpp.sq +++ b/src/ai/api/ai_rail.hpp.sq @@ -75,8 +75,8 @@ void SQAIRail_Register(Squirrel *engine) { SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailDepotFrontTile, "GetRailDepotFrontTile", 2, "?i"); SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailStationDirection, "GetRailStationDirection", 2, "?i"); SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailDepot, "BuildRailDepot", 3, "?ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailStation, "BuildRailStation", 6, "?iiiib"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildNewGRFRailStation, "BuildNewGRFRailStation", 11, "?iiiibiiiib"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailStation, "BuildRailStation", 6, "?iiiii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildNewGRFRailStation, "BuildNewGRFRailStation", 11, "?iiiiiiiiib"); SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailStationTileRect, "RemoveRailStationTileRect", 3, "?ii"); SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailTracks, "GetRailTracks", 2, "?i"); SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailTrack, "BuildRailTrack", 3, "?ii"); diff --git a/src/ai/api/ai_road.cpp b/src/ai/api/ai_road.cpp index be40caf4cb..c9e0f48880 100644 --- a/src/ai/api/ai_road.cpp +++ b/src/ai/api/ai_road.cpp @@ -4,6 +4,7 @@ #include "ai_road.hpp" #include "ai_map.hpp" +#include "ai_station.hpp" #include "../../station_map.h" #include "../../command_type.h" #include "../../settings_type.h" @@ -490,12 +491,13 @@ static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, Dia return AIObject::DoCommand(tile, entrance_dir | (AIObject::GetRoadType() << 2), 0, CMD_BUILD_ROAD_DEPOT); } -/* static */ bool AIRoad::BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through, bool join_adjacent) +/* static */ bool AIRoad::BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through, StationID station_id) { EnforcePrecondition(false, tile != front); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(front)); EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front)); + EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id)); uint entrance_dir; if (drive_through) { @@ -504,7 +506,12 @@ static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, Dia entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); } - return AIObject::DoCommand(tile, entrance_dir, (join_adjacent ? 0 : 32) | (drive_through ? 2 : 0) | (truck ? 1 : 0) | (::RoadTypeToRoadTypes(AIObject::GetRoadType()) << 2) | (INVALID_STATION << 16), CMD_BUILD_ROAD_STOP); + uint p2 = station_id == AIStation::STATION_JOIN_ADJACENT ? 0 : 32; + p2 |= drive_through ? 2 : 0; + p2 |= truck ? 1 : 0; + p2 |= ::RoadTypeToRoadTypes(AIObject::GetRoadType()) << 2; + p2 |= (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; + return AIObject::DoCommand(tile, entrance_dir, p2, CMD_BUILD_ROAD_STOP); } /* static */ bool AIRoad::RemoveRoad(TileIndex start, TileIndex end) diff --git a/src/ai/api/ai_road.hpp b/src/ai/api/ai_road.hpp index 875f935adf..4b828dde80 100644 --- a/src/ai/api/ai_road.hpp +++ b/src/ai/api/ai_road.hpp @@ -325,10 +325,11 @@ public: * For drive-through stations either entrance side can be used. * @param truck Whether to build a truck (true) or bus (false) station. * @param drive_through Whether to make the station drive through or not. - * @param join_adjacent When building next to an other station, don't create a new station when this flag is true. + * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT. * @pre AIMap::IsValidTile(tile). * @pre AIMap::IsValidTile(front). * @pre 'tile' is not equal to 'front', but in a straight line of it. + * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id). * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception AIError::ERR_AREA_NOT_CLEAR * @exception AIError::ERR_FLAT_LAND_REQUIRED @@ -340,7 +341,7 @@ public: * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN * @return Whether the station has been/can be build or not. */ - static bool BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through, bool join_adjacent); + static bool BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through, StationID station_id); /** * Removes a road from the center of tile start to the center of tile end. diff --git a/src/ai/api/ai_road.hpp.sq b/src/ai/api/ai_road.hpp.sq index 8cba4cfc79..101d0bcd69 100644 --- a/src/ai/api/ai_road.hpp.sq +++ b/src/ai/api/ai_road.hpp.sq @@ -62,7 +62,7 @@ void SQAIRoad_Register(Squirrel *engine) { SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadFull, "BuildRoadFull", 3, "?ii"); SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildOneWayRoadFull, "BuildOneWayRoadFull", 3, "?ii"); SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadDepot, "BuildRoadDepot", 3, "?ii"); - SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadStation, "BuildRoadStation", 6, "?iibbb"); + SQAIRoad.DefSQStaticMethod(engine, &AIRoad::BuildRoadStation, "BuildRoadStation", 6, "?iibbi"); SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoad, "RemoveRoad", 3, "?ii"); SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoadFull, "RemoveRoadFull", 3, "?ii"); SQAIRoad.DefSQStaticMethod(engine, &AIRoad::RemoveRoadDepot, "RemoveRoadDepot", 2, "?i"); diff --git a/src/ai/api/ai_station.hpp b/src/ai/api/ai_station.hpp index 5a25f16ed8..82cb6a5fed 100644 --- a/src/ai/api/ai_station.hpp +++ b/src/ai/api/ai_station.hpp @@ -49,6 +49,12 @@ public: STATION_ANY = 0x1F, //!< All station types }; + enum SpecialStationIDs { + STATION_NEW = 0xFFFD, //!< Build a new station + STATION_JOIN_ADJACENT = 0xFFFE, //!< Join an neighbouring station if one exists + STATION_INVALID = 0xFFFF, //!< Invalid station id. + }; + /** * Checks whether the given station is valid and owned by you. * @param station_id The station to check. diff --git a/src/ai/api/ai_station.hpp.sq b/src/ai/api/ai_station.hpp.sq index be83b9d209..d820f94dc3 100644 --- a/src/ai/api/ai_station.hpp.sq +++ b/src/ai/api/ai_station.hpp.sq @@ -9,6 +9,8 @@ namespace SQConvert { template <> int Return(HSQUIRRELVM vm, AIStation::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; } template <> AIStation::StationType GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIStation::StationType)tmp; } template <> int Return(HSQUIRRELVM vm, AIStation::StationType res) { sq_pushinteger(vm, (int32)res); return 1; } + template <> AIStation::SpecialStationIDs GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIStation::SpecialStationIDs)tmp; } + template <> int Return(HSQUIRRELVM vm, AIStation::SpecialStationIDs res) { sq_pushinteger(vm, (int32)res); return 1; } /* Allow AIStation to be used as Squirrel parameter */ template <> AIStation *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIStation *)instance; } @@ -34,6 +36,9 @@ void SQAIStation_Register(Squirrel *engine) { SQAIStation.DefSQConst(engine, AIStation::STATION_AIRPORT, "STATION_AIRPORT"); SQAIStation.DefSQConst(engine, AIStation::STATION_DOCK, "STATION_DOCK"); SQAIStation.DefSQConst(engine, AIStation::STATION_ANY, "STATION_ANY"); + SQAIStation.DefSQConst(engine, AIStation::STATION_NEW, "STATION_NEW"); + SQAIStation.DefSQConst(engine, AIStation::STATION_JOIN_ADJACENT, "STATION_JOIN_ADJACENT"); + SQAIStation.DefSQConst(engine, AIStation::STATION_INVALID, "STATION_INVALID"); AIError::RegisterErrorMap(STR_306C_STATION_TOO_SPREAD_OUT, AIStation::ERR_STATION_TOO_LARGE); AIError::RegisterErrorMap(STR_300D_TOO_CLOSE_TO_ANOTHER_AIRPORT, AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION);