# HG changeset patch # User rubidium # Date 2009-09-08 10:12:13 # Node ID be92c1cb71c87d4ba7b9e7ab33157703fe4e8a35 # Parent ecbe762e1011d4fae3c6c3f973310d78cc505c1a (svn r17471) -Change: when removing a station or waypoint keep the rail unless Ctrl is pressed. This makes the behaviour consistent between the two. diff --git a/bin/ai/compat_0.7.nut b/bin/ai/compat_0.7.nut --- a/bin/ai/compat_0.7.nut +++ b/bin/ai/compat_0.7.nut @@ -76,3 +76,13 @@ AITown.GetMaxProduction <- function(town { 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); +} diff --git a/bin/ai/regression/regression.nut b/bin/ai/regression/regression.nut --- a/bin/ai/regression/regression.nut +++ b/bin/ai/regression/regression.nut @@ -964,7 +964,7 @@ function Regression::Rail() print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7957)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7958)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7959)); - print(" RemoveRailStationTileRect(): " + AIRail.RemoveRailStationTileRect(7959, 7959)); + print(" RemoveRailStationTileRectangle():" + AIRail.RemoveRailStationTileRectangle(7959, 7959, false)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7957)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7958)); print(" IsRailStationTile(): " + AIRail.IsRailStationTile(7959)); diff --git a/bin/ai/regression/regression.txt b/bin/ai/regression/regression.txt --- a/bin/ai/regression/regression.txt +++ b/bin/ai/regression/regression.txt @@ -7137,7 +7137,7 @@ IsRailStationTile(): false IsRailStationTile(): true IsRailStationTile(): true - RemoveRailStationTileRect(): true + RemoveRailStationTileRectangle():true IsRailStationTile(): false IsRailStationTile(): true IsRailStationTile(): false diff --git a/src/ai/api/ai_changelog.hpp b/src/ai/api/ai_changelog.hpp --- a/src/ai/api/ai_changelog.hpp +++ b/src/ai/api/ai_changelog.hpp @@ -16,11 +16,14 @@ * * \b 0.8.0 * + * 0.8.0 is not yet released. The following changes are not set in stone yet. + * * API additions: * \li AIBaseStation * \li AIBuoyList * \li AIEventCompanyAskMerger - * \li AIRail::RemoveRailWaypointTileRect + * \li AIRail::RemoveRailStationTileRectangle + * \li AIRail::RemoveRailWaypointTileRectangle * \li AISubsidy::SubsidyParticipantType * \li AISubsidy::GetSourceType * \li AISubsidy::GetSourceIndex @@ -31,12 +34,14 @@ * * API removals: * \li AIOrder::ChangeOrder, use AIOrder::SetOrderFlags instead + * \li AIRail::RemoveRailStationTileRect, use AIRail::RemoveRailStationTileRectangle instead + * \li AIRail::RemoveRailWaypoint, use AIRail::RemoveRailWaypointTileRectangle instead * \li AISign::GetMaxSignID, use AISignList instead - * \li AITile::GetHeight, use AITile::GetMinHeight/GetMaxHeight/GetCornerHeight instead * \li AISubsidy::SourceIsTown, use AISubsidy::GetSourceType instead * \li AISubsidy::GetSource, use AISubsidy::GetSourceIndex instead * \li AISubsidy::DestinationIsTown, use AISubsidy::GetDestinationType instead * \li AISubsidy::GetDestination, use AISubsidy::GetDestinationIndex instead + * \li AITile::GetHeight, use AITile::GetMinHeight/GetMaxHeight/GetCornerHeight instead * \li AITown::GetMaxProduction, use AITown::GetLastMonthProduction instead * \li AIWaypoint::WAYPOINT_INVALID, use AIBaseStation::STATION_INVALID instead * @@ -49,6 +54,13 @@ * \li WaypointID was replaced by StationID. All WaypointIDs from previous * savegames are invalid. Use STATION_INVALID instead of WAYPOINT_INVALID * \li AIVehicleList_Station now also works for waypoints + * \li Stations can be build over rail without signals that is in the right + * direction for the to-be built station. It will also convert the rail if + * the station's rail type supports the old type. + * \li GetAPIVersion() was added as function to info.nut. If it does not exist + * API version 0.7 is assumed. This function should return the major and + * minor number of the stable version of the API the AI is written against. + * For 0.7.2 that would be 0.7, for 1.1.3 it would be 1.1, etc. * * \b 0.7.3 * diff --git a/src/ai/api/ai_rail.cpp b/src/ai/api/ai_rail.cpp --- a/src/ai/api/ai_rail.cpp +++ b/src/ai/api/ai_rail.cpp @@ -187,28 +187,20 @@ return AIObject::DoCommand(tile, GetCurrentRailType() | (GetRailTracks(tile) == RAILTRACK_NE_SW ? AXIS_X : AXIS_Y) << 4 | 1 << 8 | 1 << 16, STAT_CLASS_WAYP | INVALID_STATION << 16, CMD_BUILD_RAIL_WAYPOINT); } -/* static */ bool AIRail::RemoveRailWaypoint(TileIndex tile) -{ - EnforcePrecondition(false, ::IsValidTile(tile)); - EnforcePrecondition(false, IsRailWaypointTile(tile)); - - return AIObject::DoCommand(tile, 0, 0, CMD_REMOVE_FROM_RAIL_WAYPOINT); -} - -/* static */ bool AIRail::RemoveRailWaypointTileRect(TileIndex tile, TileIndex tile2) +/* static */ bool AIRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); - return AIObject::DoCommand(tile, tile2, 0, CMD_REMOVE_FROM_RAIL_WAYPOINT); + return AIObject::DoCommand(tile, tile2, keep_rail ? 1 : 0, CMD_REMOVE_FROM_RAIL_WAYPOINT); } -/* static */ bool AIRail::RemoveRailStationTileRect(TileIndex tile, TileIndex tile2) +/* static */ bool AIRail::RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) { EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); - return AIObject::DoCommand(tile, tile2, 0, CMD_REMOVE_FROM_RAIL_STATION); + return AIObject::DoCommand(tile, tile2, keep_rail ? 1 : 0, CMD_REMOVE_FROM_RAIL_STATION); } /* static */ uint AIRail::GetRailTracks(TileIndex tile) diff --git a/src/ai/api/ai_rail.hpp b/src/ai/api/ai_rail.hpp --- a/src/ai/api/ai_rail.hpp +++ b/src/ai/api/ai_rail.hpp @@ -280,33 +280,26 @@ public: static bool BuildRailWaypoint(TileIndex tile); /** - * Remove a rail waypoint. - * @param tile Place to remove the waypoint from. - * @pre AIMap::IsValidTile(tile). - * @pre IsRailWaypointTile(tile). - * @return Whether the rail waypoint has been/can be removed or not. - */ - static bool RemoveRailWaypoint(TileIndex tile); - - /** * Remove all rail waypoint pieces within a rectangle on the map. * @param tile One corner of the rectangle to clear. * @param tile2 The oppposite corner. + * @param keep_rail Whether to keep the rail after removal. * @pre IsValidTile(tile). * @pre IsValidTile(tile2). * @return Whether at least one tile has been/can be cleared or not. */ - static bool RemoveRailWaypointTileRect(TileIndex tile, TileIndex tile2); + static bool RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail); /** * Remove all rail station platform pieces within a rectangle on the map. * @param tile One corner of the rectangle to clear. * @param tile2 The oppposite corner. + * @param keep_rail Whether to keep the rail after removal. * @pre IsValidTile(tile). * @pre IsValidTile(tile2). * @return Whether at least one tile has been/can be cleared or not. */ - static bool RemoveRailStationTileRect(TileIndex tile, TileIndex tile2); + static bool RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail); /** * Get all RailTracks on the given tile. diff --git a/src/ai/api/ai_rail.hpp.sq b/src/ai/api/ai_rail.hpp.sq --- a/src/ai/api/ai_rail.hpp.sq +++ b/src/ai/api/ai_rail.hpp.sq @@ -68,36 +68,35 @@ void SQAIRail_Register(Squirrel *engine) AIError::RegisterErrorMapString(AIRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK"); AIError::RegisterErrorMapString(AIRail::ERR_NONUNIFORM_STATIONS_DISABLED, "ERR_NONUNIFORM_STATIONS_DISABLED"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTile, "IsRailTile", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::IsLevelCrossingTile, "IsLevelCrossingTile", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailDepotTile, "IsRailDepotTile", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailStationTile, "IsRailStationTile", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailWaypointTile, "IsRailWaypointTile", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTypeAvailable, "IsRailTypeAvailable", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::GetCurrentRailType, "GetCurrentRailType", 1, "."); - SQAIRail.DefSQStaticMethod(engine, &AIRail::SetCurrentRailType, "SetCurrentRailType", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::TrainCanRunOnRail, "TrainCanRunOnRail", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::TrainHasPowerOnRail, "TrainHasPowerOnRail", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailType, "GetRailType", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::ConvertRailType, "ConvertRailType", 4, ".iii"); - 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, ".iiiii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildNewGRFRailStation, "BuildNewGRFRailStation", 11, ".iiiiiiiiib"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailWaypoint, "BuildRailWaypoint", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailWaypoint, "RemoveRailWaypoint", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailWaypointTileRect, "RemoveRailWaypointTileRect", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailStationTileRect, "RemoveRailStationTileRect", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailTracks, "GetRailTracks", 2, ".i"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailTrack, "BuildRailTrack", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailTrack, "RemoveRailTrack", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::AreTilesConnected, "AreTilesConnected", 4, ".iii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRail, "BuildRail", 4, ".iii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRail, "RemoveRail", 4, ".iii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::GetSignalType, "GetSignalType", 3, ".ii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildSignal, "BuildSignal", 4, ".iii"); - SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveSignal, "RemoveSignal", 3, ".ii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTile, "IsRailTile", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::IsLevelCrossingTile, "IsLevelCrossingTile", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailDepotTile, "IsRailDepotTile", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailStationTile, "IsRailStationTile", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailWaypointTile, "IsRailWaypointTile", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::IsRailTypeAvailable, "IsRailTypeAvailable", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::GetCurrentRailType, "GetCurrentRailType", 1, "."); + SQAIRail.DefSQStaticMethod(engine, &AIRail::SetCurrentRailType, "SetCurrentRailType", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::TrainCanRunOnRail, "TrainCanRunOnRail", 3, ".ii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::TrainHasPowerOnRail, "TrainHasPowerOnRail", 3, ".ii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailType, "GetRailType", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::ConvertRailType, "ConvertRailType", 4, ".iii"); + 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, ".iiiii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildNewGRFRailStation, "BuildNewGRFRailStation", 11, ".iiiiiiiiib"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailWaypoint, "BuildRailWaypoint", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailWaypointTileRectangle, "RemoveRailWaypointTileRectangle", 4, ".iib"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailStationTileRectangle, "RemoveRailStationTileRectangle", 4, ".iib"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::GetRailTracks, "GetRailTracks", 2, ".i"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRailTrack, "BuildRailTrack", 3, ".ii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRailTrack, "RemoveRailTrack", 3, ".ii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::AreTilesConnected, "AreTilesConnected", 4, ".iii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildRail, "BuildRail", 4, ".iii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveRail, "RemoveRail", 4, ".iii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::GetSignalType, "GetSignalType", 3, ".ii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::BuildSignal, "BuildSignal", 4, ".iii"); + SQAIRail.DefSQStaticMethod(engine, &AIRail::RemoveSignal, "RemoveSignal", 3, ".ii"); SQAIRail.PostRegister(engine); } diff --git a/src/lang/english.txt b/src/lang/english.txt --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1847,7 +1847,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Build railway signals. Ctrl toggles semaphore/light signals{}Dragging builds signals along a straight stretch of rail. Ctrl builds signals till the next junction{}Ctrl+Click toggles opening the signal selection window STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Build railway bridge STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Build railway tunnel -STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track and signals +STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track, signals, waypoints and stations. Ctrl+Click will leave track when removing waypoints and stations STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Convert/Upgrade the type of rail # Rail depot construction window diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -769,14 +769,14 @@ struct BuildRailToolbarWindow : Window { if (this->IsWidgetLowered(RTW_BUILD_STATION)) { /* Station */ if (_remove_button_clicked) { - DoCommandP(end_tile, start_tile, 0, CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound1E); + DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_REMOVE_PART_OF_STATION), CcPlaySound1E); } else { HandleStationPlacement(start_tile, end_tile); } } else { /* Waypoint */ if (_remove_button_clicked) { - DoCommandP(end_tile, start_tile, 0, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E); + DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound1E); } else { TileArea ta(start_tile, end_tile); uint32 p1 = _cur_railtype | (select_method == VPM_FIX_X ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1217,14 +1217,16 @@ restart: * @param affected_stations the stations affected * @param flags the command flags * @param removal_cost the cost for removing the tile + * @param keep_rail whether to keep the rail of the station * @tparam T the type of station to remove * @return the number of cleared tiles or an error */ template -CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector &affected_stations, DoCommandFlag flags, Money removal_cost) +CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector &affected_stations, DoCommandFlag flags, Money removal_cost, bool keep_rail) { /* Count of the number of tiles removed */ int quantity = 0; + CommandCost total_cost(EXPENSES_CONSTRUCTION); /* Do the action for every tile into the area */ TILE_LOOP(tile, ta.w, ta.h, ta.tile) { @@ -1267,7 +1269,7 @@ CommandCost RemoveFromRailBaseStation(Ti } } - if (st->facilities & FACIL_WAYPOINT) { + if (keep_rail) { MakeRailNormal(tile, owner, TrackToTrackBits(track), rt); } else { DoClearSquare(tile); @@ -1288,6 +1290,10 @@ CommandCost RemoveFromRailBaseStation(Ti if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), true); } } + if (keep_rail) { + /* Don't refund the 'steel' of the track! */ + total_cost.AddCost(-_price.remove_rail); + } } if (quantity == 0) return CMD_ERROR; @@ -1310,7 +1316,8 @@ CommandCost RemoveFromRailBaseStation(Ti } } - return CommandCost(EXPENSES_CONSTRUCTION, quantity * removal_cost); + total_cost.AddCost(quantity * removal_cost); + return total_cost; } /** Remove a single tile from a rail station. @@ -1318,7 +1325,8 @@ CommandCost RemoveFromRailBaseStation(Ti * @param start tile of station piece to remove * @param flags operation to perform * @param p1 start_tile - * @param p2 unused + * @param p2 various bitstuffed elements + * - p2 = bit 0 - if set keep the rail * @param text unused * @return cost of operation or error */ @@ -1330,7 +1338,7 @@ CommandCost CmdRemoveFromRailStation(Til TileArea ta(start, end); SmallVector affected_stations; - CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price.remove_rail_station); + CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price.remove_rail_station, HasBit(p2, 0)); if (ret.Failed()) return ret; /* Do all station specific functions here. */ @@ -1351,7 +1359,8 @@ CommandCost CmdRemoveFromRailStation(Til * @param start tile of waypoint piece to remove * @param flags operation to perform * @param p1 start_tile - * @param p2 unused + * @param p2 various bitstuffed elements + * - p2 = bit 0 - if set keep the rail * @param text unused * @return cost of operation or error */ @@ -1363,7 +1372,7 @@ CommandCost CmdRemoveFromRailWaypoint(Ti TileArea ta(start, end); SmallVector affected_stations; - return RemoveFromRailBaseStation(ta, affected_stations, flags, _price.remove_train_depot); + return RemoveFromRailBaseStation(ta, affected_stations, flags, _price.remove_train_depot, HasBit(p2, 0)); }