From b38d3c22087608bc75b40462245ddb23d7951325 Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Sun, 21 Jan 2024 21:56:50 +0100 Subject: [PATCH] Change: simplified water region evaluation, removed savegame data (#11750) --- src/genworld.cpp | 3 --- src/landscape.cpp | 3 +++ src/map.cpp | 3 +++ src/object_cmd.cpp | 2 ++ src/pathfinder/water_regions.cpp | 34 +++++++------------------- src/pathfinder/water_regions.h | 10 +------- src/saveload/afterload.cpp | 3 --- src/saveload/saveload.h | 2 ++ src/saveload/water_regions_sl.cpp | 40 +++++++------------------------ src/tunnelbridge_cmd.cpp | 2 -- src/water_cmd.cpp | 14 ----------- src/waypoint_cmd.cpp | 1 - 12 files changed, 29 insertions(+), 88 deletions(-) diff --git a/src/genworld.cpp b/src/genworld.cpp index 9c78403777..762cc9a69e 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -35,7 +35,6 @@ #include "string_func.h" #include "thread.h" #include "tgp.h" -#include "pathfinder/water_regions.h" #include "safeguards.h" @@ -173,8 +172,6 @@ static void _GenerateWorld() } } - InitializeWaterRegions(); - BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP); ResetObjectToPlace(); diff --git a/src/landscape.cpp b/src/landscape.cpp index 880c77b576..5437995a4d 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -36,6 +36,7 @@ #include "landscape_cmd.h" #include "terraform_cmd.h" #include "station_func.h" +#include "pathfinder/water_regions.h" #include "table/strings.h" #include "table/sprites.h" @@ -538,6 +539,8 @@ void DoClearSquare(TileIndex tile) MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0); MarkTileDirtyByTile(tile); if (remove) RemoveDockingTile(tile); + + InvalidateWaterRegion(tile); } /** diff --git a/src/map.cpp b/src/map.cpp index 77e510d498..91d02b3f9d 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -13,6 +13,7 @@ #include "water_map.h" #include "error_func.h" #include "string_func.h" +#include "pathfinder/water_regions.h" #include "safeguards.h" @@ -62,6 +63,8 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); Tile::base_tiles = CallocT(Map::size); Tile::extended_tiles = CallocT(Map::size); + + AllocateWaterRegions(); } diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index f8c503499b..066e4a2f55 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -35,6 +35,7 @@ #include "station_func.h" #include "object_cmd.h" #include "landscape_cmd.h" +#include "pathfinder/water_regions.h" #include "table/strings.h" #include "table/object_land.h" @@ -362,6 +363,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, if (flags & DC_EXEC) { BuildObject(type, tile, _current_company == OWNER_DEITY ? OWNER_NONE : _current_company, nullptr, view); + for (TileIndex t : ta) InvalidateWaterRegion(t); /* Make sure the HQ starts at the right size. */ if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score); diff --git a/src/pathfinder/water_regions.cpp b/src/pathfinder/water_regions.cpp index 2bda5aa1cf..477e3edfd3 100644 --- a/src/pathfinder/water_regions.cpp +++ b/src/pathfinder/water_regions.cpp @@ -18,6 +18,7 @@ #include "tunnelbridge_map.h" #include "follow_track.hpp" #include "ship.h" +#include "debug.h" using TWaterRegionTraversabilityBits = uint16_t; constexpr TWaterRegionPatchLabel FIRST_REGION_LABEL = 1; @@ -114,6 +115,7 @@ public: */ void ForceUpdate() { + Debug(map, 3, "Updating water region ({},{})", GetWaterRegionX(this->tile_area.tile), GetWaterRegionY(this->tile_area.tile)); this->has_cross_region_aqueducts = false; this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH); @@ -267,8 +269,9 @@ WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile) void InvalidateWaterRegion(TileIndex tile) { const int index = GetWaterRegionIndex(tile); - if (index > static_cast(_water_regions.size())) return; _water_regions[index].Invalidate(); + + Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(tile), GetWaterRegionY(tile)); } /** @@ -342,38 +345,19 @@ void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_pat } } -std::vector GetWaterRegionSaveLoadInfo() -{ - std::vector result; - for (WaterRegion ®ion : _water_regions) result.push_back({ region.IsInitialized() }); - return result; -} - -void LoadWaterRegions(const std::vector &save_load_info) -{ - _water_regions.clear(); - _water_regions.reserve(save_load_info.size()); - TWaterRegionIndex index = 0; - for (const auto &loaded_region_info : save_load_info) { - const int region_x = index % GetWaterRegionMapSizeX(); - const int region_y = index / GetWaterRegionMapSizeX(); - WaterRegion ®ion = _water_regions.emplace_back(region_x, region_y); - if (loaded_region_info.initialized) region.ForceUpdate(); - index++; - } -} - /** - * Initializes all water regions. All water tiles will be scanned and interconnected water patches within regions will be identified. + * Allocates the appropriate amount of water regions for the current map size */ -void InitializeWaterRegions() +void AllocateWaterRegions() { _water_regions.clear(); _water_regions.reserve(static_cast(GetWaterRegionMapSizeX()) * GetWaterRegionMapSizeY()); + Debug(map, 2, "Allocating {} x {} water regions", GetWaterRegionMapSizeX(), GetWaterRegionMapSizeY()); + for (int region_y = 0; region_y < GetWaterRegionMapSizeY(); region_y++) { for (int region_x = 0; region_x < GetWaterRegionMapSizeX(); region_x++) { - _water_regions.emplace_back(region_x, region_y).ForceUpdate(); + _water_regions.emplace_back(region_x, region_y); } } } diff --git a/src/pathfinder/water_regions.h b/src/pathfinder/water_regions.h index 801c83b563..8cbb6e6ee9 100644 --- a/src/pathfinder/water_regions.h +++ b/src/pathfinder/water_regions.h @@ -60,14 +60,6 @@ void InvalidateWaterRegion(TileIndex tile); using TVisitWaterRegionPatchCallBack = std::function; void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback); -void InitializeWaterRegions(); - -struct WaterRegionSaveLoadInfo -{ - bool initialized; -}; - -std::vector GetWaterRegionSaveLoadInfo(); -void LoadWaterRegions(const std::vector &save_load_info); +void AllocateWaterRegions(); #endif /* WATER_REGIONS_H */ diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 33d12648b5..e6fd1c7ba1 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -61,7 +61,6 @@ #include "../timer/timer.h" #include "../timer/timer_game_calendar.h" #include "../timer/timer_game_tick.h" -#include "../pathfinder/water_regions.h" #include "saveload_internal.h" @@ -3297,8 +3296,6 @@ bool AfterLoadGame() } } - if (IsSavegameVersionBefore(SLV_WATER_REGIONS)) InitializeWaterRegions(); - return true; } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index be139df5ab..4c784ba70d 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -367,6 +367,8 @@ enum SaveLoadVersion : uint16_t { SLV_TIMETABLE_TICKS_TYPE, ///< 323 PR#11435 Convert timetable current order time to ticks. SLV_WATER_REGIONS, ///< 324 PR#10543 Water Regions for ship pathfinder. + SLV_WATER_REGION_EVAL_SIMPLIFIED, ///< 325 PR#11750 Simplified Water Region evaluation. + SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/saveload/water_regions_sl.cpp b/src/saveload/water_regions_sl.cpp index ae872ccfd9..92e601dca3 100644 --- a/src/saveload/water_regions_sl.cpp +++ b/src/saveload/water_regions_sl.cpp @@ -10,45 +10,23 @@ #include "../stdafx.h" #include "saveload.h" -#include "pathfinder/water_regions.h" #include "../safeguards.h" -static const SaveLoad _water_region_desc[] = { - SLE_VAR(WaterRegionSaveLoadInfo, initialized, SLE_BOOL), -}; +extern void SlSkipArray(); -struct WRGNChunkHandler : ChunkHandler { - WRGNChunkHandler() : ChunkHandler('WRGN', CH_TABLE) {} - - void Save() const override - { - SlTableHeader(_water_region_desc); - - int index = 0; - for (WaterRegionSaveLoadInfo ®ion : GetWaterRegionSaveLoadInfo()) { - SlSetArrayIndex(index++); - SlObject(®ion, _water_region_desc); - } - } +/* Water Region savegame data is no longer used, but still needed for old savegames to load without errors. */ +struct WaterRegionChunkHandler : ChunkHandler { + WaterRegionChunkHandler() : ChunkHandler('WRGN', CH_READONLY) + {} void Load() const override { - const std::vector slt = SlTableHeader(_water_region_desc); - - int index; - - std::vector loaded_info; - while ((index = SlIterateArray()) != -1) { - WaterRegionSaveLoadInfo region_info; - SlObject(®ion_info, slt); - loaded_info.push_back(std::move(region_info)); - } - - LoadWaterRegions(loaded_info); - } + SlTableHeader({}); + SlSkipArray(); + }; }; -static const WRGNChunkHandler WRGN; +static const WaterRegionChunkHandler WRGN; static const ChunkHandlerRef water_region_chunk_handlers[] = { WRGN }; extern const ChunkHandlerTable _water_region_chunk_handlers(water_region_chunk_handlers); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 1805f476df..a2e9d67f1c 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -562,8 +562,6 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir)); CheckForDockingTile(tile_start); CheckForDockingTile(tile_end); - InvalidateWaterRegion(tile_start); - InvalidateWaterRegion(tile_end); break; default: diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index aec29645a3..8325c4da19 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -134,9 +134,6 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis) } if (flags & DC_EXEC) { - InvalidateWaterRegion(tile); - InvalidateWaterRegion(tile2); - Depot *depot = new Depot(tile); depot->build_date = TimerGameCalendar::date; @@ -247,7 +244,6 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o) /* Zero map array and terminate animation */ DoClearSquare(tile); - InvalidateWaterRegion(tile); /* Maybe change to water */ switch (wc) { @@ -345,10 +341,6 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag } if (flags & DC_EXEC) { - InvalidateWaterRegion(tile); - InvalidateWaterRegion(tile + delta); - InvalidateWaterRegion(tile - delta); - /* Update company infrastructure counts. */ Company *c = Company::GetIfValid(_current_company); if (c != nullptr) { @@ -491,8 +483,6 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t if (!water) cost.AddCost(ret); if (flags & DC_EXEC) { - InvalidateWaterRegion(current_tile); - if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) { Owner owner = GetTileOwner(current_tile); if (Company::IsValidID(owner)) { @@ -543,8 +533,6 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags) { - if (flags & DC_EXEC) InvalidateWaterRegion(tile); - switch (GetWaterTileType(tile)) { case WATER_TILE_CLEAR: { if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); @@ -1175,8 +1163,6 @@ void DoFloodTile(TileIndex target) } if (flooded) { - InvalidateWaterRegion(target); - /* Mark surrounding canal tiles dirty too to avoid glitches */ MarkCanalsAndRiversAroundDirty(target); diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 11e16b9a41..38165a62c8 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -347,7 +347,6 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile) if (wp->town == nullptr) MakeDefaultName(wp); MakeBuoy(tile, wp->index, GetWaterClass(tile)); - InvalidateWaterRegion(tile); CheckForDockingTile(tile); MarkTileDirtyByTile(tile);