Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change: simplified water region evaluation, removed savegame data #11750

Merged
merged 1 commit into from Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/genworld.cpp
Expand Up @@ -35,7 +35,6 @@
#include "string_func.h"
#include "thread.h"
#include "tgp.h"
#include "pathfinder/water_regions.h"

#include "safeguards.h"

Expand Down Expand Up @@ -173,8 +172,6 @@ static void _GenerateWorld()
}
}

InitializeWaterRegions();

BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP);

ResetObjectToPlace();
Expand Down
3 changes: 3 additions & 0 deletions src/landscape.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -538,6 +539,8 @@ void DoClearSquare(TileIndex tile)
MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
MarkTileDirtyByTile(tile);
if (remove) RemoveDockingTile(tile);

InvalidateWaterRegion(tile);
PeterN marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/map.cpp
Expand Up @@ -13,6 +13,7 @@
#include "water_map.h"
#include "error_func.h"
#include "string_func.h"
#include "pathfinder/water_regions.h"

#include "safeguards.h"

Expand Down Expand Up @@ -62,6 +63,8 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned);

Tile::base_tiles = CallocT<Tile::TileBase>(Map::size);
Tile::extended_tiles = CallocT<Tile::TileExtended>(Map::size);

AllocateWaterRegions();
}


Expand Down
2 changes: 2 additions & 0 deletions src/object_cmd.cpp
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down
34 changes: 9 additions & 25 deletions src/pathfinder/water_regions.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -114,6 +115,7 @@ class WaterRegion
*/
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);
Expand Down Expand Up @@ -267,8 +269,9 @@ WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
void InvalidateWaterRegion(TileIndex tile)
{
const int index = GetWaterRegionIndex(tile);
if (index > static_cast<int>(_water_regions.size())) return;
_water_regions[index].Invalidate();

Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(tile), GetWaterRegionY(tile));
}

/**
Expand Down Expand Up @@ -342,38 +345,19 @@ void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_pat
}
}

std::vector<WaterRegionSaveLoadInfo> GetWaterRegionSaveLoadInfo()
{
std::vector<WaterRegionSaveLoadInfo> result;
for (WaterRegion &region : _water_regions) result.push_back({ region.IsInitialized() });
return result;
}

void LoadWaterRegions(const std::vector<WaterRegionSaveLoadInfo> &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 &region = _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<size_t>(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);
}
}
}
10 changes: 1 addition & 9 deletions src/pathfinder/water_regions.h
Expand Up @@ -60,14 +60,6 @@ void InvalidateWaterRegion(TileIndex tile);
using TVisitWaterRegionPatchCallBack = std::function<void(const WaterRegionPatchDesc &)>;
void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback);

void InitializeWaterRegions();

struct WaterRegionSaveLoadInfo
{
bool initialized;
};

std::vector<WaterRegionSaveLoadInfo> GetWaterRegionSaveLoadInfo();
void LoadWaterRegions(const std::vector<WaterRegionSaveLoadInfo> &save_load_info);
void AllocateWaterRegions();

#endif /* WATER_REGIONS_H */
3 changes: 0 additions & 3 deletions src/saveload/afterload.cpp
Expand Up @@ -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"

Expand Down Expand Up @@ -3297,8 +3296,6 @@ bool AfterLoadGame()
}
}

if (IsSavegameVersionBefore(SLV_WATER_REGIONS)) InitializeWaterRegions();

return true;
}

Expand Down
2 changes: 2 additions & 0 deletions src/saveload/saveload.h
Expand Up @@ -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.
TrueBrain marked this conversation as resolved.
Show resolved Hide resolved

SLV_WATER_REGION_EVAL_SIMPLIFIED, ///< 325 PR#11750 Simplified Water Region evaluation.

SL_MAX_VERSION, ///< Highest possible saveload version
};

Expand Down
40 changes: 9 additions & 31 deletions src/saveload/water_regions_sl.cpp
Expand Up @@ -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),
};

struct WRGNChunkHandler : ChunkHandler {
WRGNChunkHandler() : ChunkHandler('WRGN', CH_TABLE) {}

void Save() const override
{
SlTableHeader(_water_region_desc);
extern void SlSkipArray();

int index = 0;
for (WaterRegionSaveLoadInfo &region : GetWaterRegionSaveLoadInfo()) {
SlSetArrayIndex(index++);
SlObject(&region, _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<SaveLoad> slt = SlTableHeader(_water_region_desc);

int index;

std::vector<WaterRegionSaveLoadInfo> loaded_info;
while ((index = SlIterateArray()) != -1) {
WaterRegionSaveLoadInfo region_info;
SlObject(&region_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);
2 changes: 0 additions & 2 deletions src/tunnelbridge_cmd.cpp
Expand Up @@ -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:
Expand Down
14 changes: 0 additions & 14 deletions src/water_cmd.cpp
Expand Up @@ -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;

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1175,8 +1163,6 @@ void DoFloodTile(TileIndex target)
}

if (flooded) {
InvalidateWaterRegion(target);

/* Mark surrounding canal tiles dirty too to avoid glitches */
MarkCanalsAndRiversAroundDirty(target);

Expand Down
1 change: 0 additions & 1 deletion src/waypoint_cmd.cpp
Expand Up @@ -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);

Expand Down