From dc663d7b0a217b4aa847c335d17391a9afd4cb91 Mon Sep 17 00:00:00 2001 From: Rito12 Date: Thu, 25 Dec 2025 19:51:31 +0100 Subject: [PATCH] Feature: Allow to build buoys at (0x0). --- src/order_cmd.cpp | 12 ++++++------ src/pathfinder/yapf/yapf_destrail.hpp | 4 ++-- src/pathfinder/yapf/yapf_road.cpp | 4 ++-- src/pathfinder/yapf/yapf_ship.cpp | 4 ++-- src/pathfinder/yapf/yapf_ship_regions.cpp | 2 +- src/roadveh_cmd.cpp | 4 +--- src/saveload/afterload.cpp | 7 +++++++ src/saveload/saveload.h | 1 + src/ship_cmd.cpp | 6 +++--- src/waypoint_cmd.cpp | 2 +- 10 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 8ceac01fc8..5ecfdde68f 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1951,7 +1951,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool { if (conditional_depth > v->GetNumOrders()) { v->current_order.Free(); - v->SetDestTile(TileIndex{}); + v->SetDestTile(INVALID_TILE); return false; } @@ -1971,7 +1971,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) { /* If the vehicle can't find its destination, delay its next search. * In case many vehicles are in this state, use the vehicle index to spread out pathfinder calls. */ - if (v->dest_tile == 0 && TimerGameEconomy::date_fract != (v->index % Ticks::DAY_TICKS)) break; + if (v->dest_tile == INVALID_TILE && TimerGameEconomy::date_fract != (v->index % Ticks::DAY_TICKS)) break; /* We need to search for the nearest depot (hangar). */ ClosestDepot closest_depot = v->FindClosestDepot(); @@ -2045,7 +2045,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool } default: - v->SetDestTile(TileIndex{}); + v->SetDestTile(INVALID_TILE); return false; } @@ -2061,7 +2061,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool if (order == nullptr) { v->current_order.Free(); - v->SetDestTile(TileIndex{}); + v->SetDestTile(INVALID_TILE); return false; } @@ -2136,12 +2136,12 @@ bool ProcessOrders(Vehicle *v) } v->current_order.Free(); - v->SetDestTile(TileIndex{}); + v->SetDestTile(INVALID_TILE); return false; } /* If it is unchanged, keep it. */ - if (order->Equals(v->current_order) && (v->type == VEH_AIRCRAFT || v->dest_tile != 0) && + if (order->Equals(v->current_order) && (v->type == VEH_AIRCRAFT || v->dest_tile != INVALID_TILE) && (v->type != VEH_SHIP || !order->IsType(OT_GOTO_STATION) || Station::Get(order->GetDestination().ToStationID())->ship_station.tile != INVALID_TILE)) { return false; } diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 34900ccf50..1d3f44ade2 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.hpp @@ -158,9 +158,9 @@ public: [[fallthrough]]; default: - this->dest_tile = v->dest_tile; + this->dest_tile = v->dest_tile == INVALID_TILE ? TileIndex{} : v->dest_tile; this->dest_station_id = StationID::Invalid(); - this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0)); + this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(this->dest_tile, TRANSPORT_RAIL, 0)); break; } this->CYapfDestinationRailBase::SetDestination(v); diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 031212eb99..c5a1964298 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -251,8 +251,8 @@ public: this->dest_trackdirs = INVALID_TRACKDIR_BIT; } else { this->dest_station = StationID::Invalid(); - this->dest_tile = v->dest_tile; - this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); + this->dest_tile = v->dest_tile == INVALID_TILE ? TileIndex{} : v->dest_tile; + this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(this->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); } } diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index b024edb722..fd4466fcb0 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -49,8 +49,8 @@ public: this->dest_trackdirs = INVALID_TRACKDIR_BIT; } else { this->dest_station = StationID::Invalid(); - this->dest_tile = v->dest_tile; - this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0)); + this->dest_tile = v->dest_tile == INVALID_TILE ? TileIndex{} : v->dest_tile; + this->dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(this->dest_tile, TRANSPORT_WATER, 0)); } } diff --git a/src/pathfinder/yapf/yapf_ship_regions.cpp b/src/pathfinder/yapf/yapf_ship_regions.cpp index 0a7c9fd0d3..c0a2c282f8 100644 --- a/src/pathfinder/yapf/yapf_ship_regions.cpp +++ b/src/pathfinder/yapf/yapf_ship_regions.cpp @@ -193,7 +193,7 @@ public: } } } else { - TileIndex tile = v->dest_tile; + TileIndex tile = v->dest_tile == INVALID_TILE ? TileIndex{} : v->dest_tile; pf.AddOrigin(GetWaterRegionPatchInfo(tile)); } diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 4325fb70a1..a6eafb56d6 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -889,7 +889,6 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection { #define return_track(x) { best_track = (Trackdir)x; goto found_best_track; } - TileIndex desttile; Trackdir best_track; bool path_found = true; @@ -957,8 +956,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection } } - desttile = v->dest_tile; - if (desttile == 0) { + if (v->dest_tile == INVALID_TILE) { /* We've got no destination, pick a random track */ return_track(PickRandomBit(trackdirs)); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 138ff5aa86..5b8acc9cf8 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2228,6 +2228,13 @@ bool AfterLoadGame() } } + if (IsSavegameVersionBefore(SLV_BUOYS_AT_0_0)) { + /* Tile for no orders is now INVALID_TILE instead of 0. */ + for (Vehicle *v : Vehicle::Iterate()) { + if (v->dest_tile == 0) v->SetDestTile(INVALID_TILE); + } + } + if (IsSavegameVersionBefore(SLV_121)) { /* Delete small ufos heading for non-existing vehicles */ for (DisasterVehicle *v : DisasterVehicle::Iterate()) { diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 589b549ba8..c08fb1f6fe 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -413,6 +413,7 @@ enum SaveLoadVersion : uint16_t { SLV_LOCKS_UNDER_BRIDGES, ///< 361 PR#14595 Allow locks under bridges. SLV_ENGINE_MULTI_RAILTYPE, ///< 362 PR#14357 v15.0 Train engines can have multiple railtypes. SLV_SIGN_TEXT_COLOURS, ///< 363 PR#14743 Configurable sign text colors in scenario editor. + SLV_BUOYS_AT_0_0, ///< 364 PR#14983 Allow to build buoys at (0x0). SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index b47ee9ceaf..4ddb3c6b4f 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -378,7 +378,7 @@ static bool CheckShipStayInDepot(Ship *v) } /* Don't leave depot if no destination set */ - if (v->dest_tile == 0) return true; + if (v->dest_tile == INVALID_TILE) return true; /* Don't leave depot if another vehicle is already entering/leaving */ /* This helps avoid CPU load if many ships are set to start at the same time */ @@ -467,7 +467,7 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, TrackBits tracks) bool path_found = true; Track track; - if (v->dest_tile == 0) { + if (v->dest_tile == INVALID_TILE) { /* No destination, don't invoke pathfinder. */ track = TrackBitsToTrack(v->state); if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track); @@ -725,7 +725,7 @@ static void ShipController(Ship *v) const DiagDirection exitdir = VehicleExitDir(v->direction, v->state); const TileIndex tile = TileAddByDiagDir(v->tile, exitdir); if (TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, exitdir)) == TRACK_BIT_NONE) return ReverseShip(v); - } else if (v->dest_tile != 0) { + } else if (v->dest_tile != INVALID_TILE) { /* We have a target, let's see if we reached it... */ if (v->current_order.IsType(OT_GOTO_WAYPOINT) && DistanceManhattan(v->dest_tile, gp.new_tile) <= 3) { diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 863ca13230..60221228e8 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -474,7 +474,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi */ CommandCost CmdBuildBuoy(DoCommandFlags flags, TileIndex tile) { - if (tile == 0 || !HasTileWaterGround(tile)) return CommandCost(STR_ERROR_SITE_UNSUITABLE); + if (!HasTileWaterGround(tile)) return CommandCost(STR_ERROR_SITE_UNSUITABLE); if (CommandCost ret = IsBuoyBridgeAboveOk(tile); ret.Failed()) return ret; if (!IsTileFlat(tile)) return CommandCost(STR_ERROR_SITE_UNSUITABLE);