mirror of https://github.com/OpenTTD/OpenTTD
Change: simplified water region evaluation, removed savegame data (#11750)
parent
1985e7415b
commit
b38d3c2208
|
@ -35,7 +35,6 @@
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "tgp.h"
|
#include "tgp.h"
|
||||||
#include "pathfinder/water_regions.h"
|
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
@ -173,8 +172,6 @@ static void _GenerateWorld()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeWaterRegions();
|
|
||||||
|
|
||||||
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP);
|
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP);
|
||||||
|
|
||||||
ResetObjectToPlace();
|
ResetObjectToPlace();
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "landscape_cmd.h"
|
#include "landscape_cmd.h"
|
||||||
#include "terraform_cmd.h"
|
#include "terraform_cmd.h"
|
||||||
#include "station_func.h"
|
#include "station_func.h"
|
||||||
|
#include "pathfinder/water_regions.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
|
@ -538,6 +539,8 @@ void DoClearSquare(TileIndex tile)
|
||||||
MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
|
MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
if (remove) RemoveDockingTile(tile);
|
if (remove) RemoveDockingTile(tile);
|
||||||
|
|
||||||
|
InvalidateWaterRegion(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
#include "error_func.h"
|
#include "error_func.h"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
|
#include "pathfinder/water_regions.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
@ -62,6 +63,8 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned);
|
||||||
|
|
||||||
Tile::base_tiles = CallocT<Tile::TileBase>(Map::size);
|
Tile::base_tiles = CallocT<Tile::TileBase>(Map::size);
|
||||||
Tile::extended_tiles = CallocT<Tile::TileExtended>(Map::size);
|
Tile::extended_tiles = CallocT<Tile::TileExtended>(Map::size);
|
||||||
|
|
||||||
|
AllocateWaterRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "station_func.h"
|
#include "station_func.h"
|
||||||
#include "object_cmd.h"
|
#include "object_cmd.h"
|
||||||
#include "landscape_cmd.h"
|
#include "landscape_cmd.h"
|
||||||
|
#include "pathfinder/water_regions.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/object_land.h"
|
#include "table/object_land.h"
|
||||||
|
@ -362,6 +363,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type,
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
BuildObject(type, tile, _current_company == OWNER_DEITY ? OWNER_NONE : _current_company, nullptr, view);
|
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. */
|
/* Make sure the HQ starts at the right size. */
|
||||||
if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score);
|
if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "tunnelbridge_map.h"
|
#include "tunnelbridge_map.h"
|
||||||
#include "follow_track.hpp"
|
#include "follow_track.hpp"
|
||||||
#include "ship.h"
|
#include "ship.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
using TWaterRegionTraversabilityBits = uint16_t;
|
using TWaterRegionTraversabilityBits = uint16_t;
|
||||||
constexpr TWaterRegionPatchLabel FIRST_REGION_LABEL = 1;
|
constexpr TWaterRegionPatchLabel FIRST_REGION_LABEL = 1;
|
||||||
|
@ -114,6 +115,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void ForceUpdate()
|
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->has_cross_region_aqueducts = false;
|
||||||
|
|
||||||
this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH);
|
this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH);
|
||||||
|
@ -267,8 +269,9 @@ WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
|
||||||
void InvalidateWaterRegion(TileIndex tile)
|
void InvalidateWaterRegion(TileIndex tile)
|
||||||
{
|
{
|
||||||
const int index = GetWaterRegionIndex(tile);
|
const int index = GetWaterRegionIndex(tile);
|
||||||
if (index > static_cast<int>(_water_regions.size())) return;
|
|
||||||
_water_regions[index].Invalidate();
|
_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<WaterRegionSaveLoadInfo> GetWaterRegionSaveLoadInfo()
|
|
||||||
{
|
|
||||||
std::vector<WaterRegionSaveLoadInfo> result;
|
|
||||||
for (WaterRegion ®ion : _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 ®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.clear();
|
||||||
_water_regions.reserve(static_cast<size_t>(GetWaterRegionMapSizeX()) * GetWaterRegionMapSizeY());
|
_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_y = 0; region_y < GetWaterRegionMapSizeY(); region_y++) {
|
||||||
for (int region_x = 0; region_x < GetWaterRegionMapSizeX(); region_x++) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,14 +60,6 @@ void InvalidateWaterRegion(TileIndex tile);
|
||||||
using TVisitWaterRegionPatchCallBack = std::function<void(const WaterRegionPatchDesc &)>;
|
using TVisitWaterRegionPatchCallBack = std::function<void(const WaterRegionPatchDesc &)>;
|
||||||
void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback);
|
void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback);
|
||||||
|
|
||||||
void InitializeWaterRegions();
|
void AllocateWaterRegions();
|
||||||
|
|
||||||
struct WaterRegionSaveLoadInfo
|
|
||||||
{
|
|
||||||
bool initialized;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<WaterRegionSaveLoadInfo> GetWaterRegionSaveLoadInfo();
|
|
||||||
void LoadWaterRegions(const std::vector<WaterRegionSaveLoadInfo> &save_load_info);
|
|
||||||
|
|
||||||
#endif /* WATER_REGIONS_H */
|
#endif /* WATER_REGIONS_H */
|
||||||
|
|
|
@ -61,7 +61,6 @@
|
||||||
#include "../timer/timer.h"
|
#include "../timer/timer.h"
|
||||||
#include "../timer/timer_game_calendar.h"
|
#include "../timer/timer_game_calendar.h"
|
||||||
#include "../timer/timer_game_tick.h"
|
#include "../timer/timer_game_tick.h"
|
||||||
#include "../pathfinder/water_regions.h"
|
|
||||||
|
|
||||||
#include "saveload_internal.h"
|
#include "saveload_internal.h"
|
||||||
|
|
||||||
|
@ -3297,8 +3296,6 @@ bool AfterLoadGame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsSavegameVersionBefore(SLV_WATER_REGIONS)) InitializeWaterRegions();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -367,6 +367,8 @@ enum SaveLoadVersion : uint16_t {
|
||||||
SLV_TIMETABLE_TICKS_TYPE, ///< 323 PR#11435 Convert timetable current order time to ticks.
|
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_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
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,45 +10,23 @@
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
|
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
#include "pathfinder/water_regions.h"
|
|
||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
static const SaveLoad _water_region_desc[] = {
|
extern void SlSkipArray();
|
||||||
SLE_VAR(WaterRegionSaveLoadInfo, initialized, SLE_BOOL),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WRGNChunkHandler : ChunkHandler {
|
/* Water Region savegame data is no longer used, but still needed for old savegames to load without errors. */
|
||||||
WRGNChunkHandler() : ChunkHandler('WRGN', CH_TABLE) {}
|
struct WaterRegionChunkHandler : ChunkHandler {
|
||||||
|
WaterRegionChunkHandler() : ChunkHandler('WRGN', CH_READONLY)
|
||||||
void Save() const override
|
{}
|
||||||
{
|
|
||||||
SlTableHeader(_water_region_desc);
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (WaterRegionSaveLoadInfo ®ion : GetWaterRegionSaveLoadInfo()) {
|
|
||||||
SlSetArrayIndex(index++);
|
|
||||||
SlObject(®ion, _water_region_desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Load() const override
|
void Load() const override
|
||||||
{
|
{
|
||||||
const std::vector<SaveLoad> slt = SlTableHeader(_water_region_desc);
|
SlTableHeader({});
|
||||||
|
SlSkipArray();
|
||||||
int index;
|
};
|
||||||
|
|
||||||
std::vector<WaterRegionSaveLoadInfo> loaded_info;
|
|
||||||
while ((index = SlIterateArray()) != -1) {
|
|
||||||
WaterRegionSaveLoadInfo region_info;
|
|
||||||
SlObject(®ion_info, slt);
|
|
||||||
loaded_info.push_back(std::move(region_info));
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadWaterRegions(loaded_info);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const WRGNChunkHandler WRGN;
|
static const WaterRegionChunkHandler WRGN;
|
||||||
static const ChunkHandlerRef water_region_chunk_handlers[] = { WRGN };
|
static const ChunkHandlerRef water_region_chunk_handlers[] = { WRGN };
|
||||||
extern const ChunkHandlerTable _water_region_chunk_handlers(water_region_chunk_handlers);
|
extern const ChunkHandlerTable _water_region_chunk_handlers(water_region_chunk_handlers);
|
||||||
|
|
|
@ -562,8 +562,6 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti
|
||||||
MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir));
|
MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir));
|
||||||
CheckForDockingTile(tile_start);
|
CheckForDockingTile(tile_start);
|
||||||
CheckForDockingTile(tile_end);
|
CheckForDockingTile(tile_end);
|
||||||
InvalidateWaterRegion(tile_start);
|
|
||||||
InvalidateWaterRegion(tile_end);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -134,9 +134,6 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
InvalidateWaterRegion(tile);
|
|
||||||
InvalidateWaterRegion(tile2);
|
|
||||||
|
|
||||||
Depot *depot = new Depot(tile);
|
Depot *depot = new Depot(tile);
|
||||||
depot->build_date = TimerGameCalendar::date;
|
depot->build_date = TimerGameCalendar::date;
|
||||||
|
|
||||||
|
@ -247,7 +244,6 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o)
|
||||||
|
|
||||||
/* Zero map array and terminate animation */
|
/* Zero map array and terminate animation */
|
||||||
DoClearSquare(tile);
|
DoClearSquare(tile);
|
||||||
InvalidateWaterRegion(tile);
|
|
||||||
|
|
||||||
/* Maybe change to water */
|
/* Maybe change to water */
|
||||||
switch (wc) {
|
switch (wc) {
|
||||||
|
@ -345,10 +341,6 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
InvalidateWaterRegion(tile);
|
|
||||||
InvalidateWaterRegion(tile + delta);
|
|
||||||
InvalidateWaterRegion(tile - delta);
|
|
||||||
|
|
||||||
/* Update company infrastructure counts. */
|
/* Update company infrastructure counts. */
|
||||||
Company *c = Company::GetIfValid(_current_company);
|
Company *c = Company::GetIfValid(_current_company);
|
||||||
if (c != nullptr) {
|
if (c != nullptr) {
|
||||||
|
@ -491,8 +483,6 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t
|
||||||
if (!water) cost.AddCost(ret);
|
if (!water) cost.AddCost(ret);
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
InvalidateWaterRegion(current_tile);
|
|
||||||
|
|
||||||
if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) {
|
if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) {
|
||||||
Owner owner = GetTileOwner(current_tile);
|
Owner owner = GetTileOwner(current_tile);
|
||||||
if (Company::IsValidID(owner)) {
|
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)
|
static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
|
||||||
{
|
{
|
||||||
if (flags & DC_EXEC) InvalidateWaterRegion(tile);
|
|
||||||
|
|
||||||
switch (GetWaterTileType(tile)) {
|
switch (GetWaterTileType(tile)) {
|
||||||
case WATER_TILE_CLEAR: {
|
case WATER_TILE_CLEAR: {
|
||||||
if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
|
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) {
|
if (flooded) {
|
||||||
InvalidateWaterRegion(target);
|
|
||||||
|
|
||||||
/* Mark surrounding canal tiles dirty too to avoid glitches */
|
/* Mark surrounding canal tiles dirty too to avoid glitches */
|
||||||
MarkCanalsAndRiversAroundDirty(target);
|
MarkCanalsAndRiversAroundDirty(target);
|
||||||
|
|
||||||
|
|
|
@ -347,7 +347,6 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile)
|
||||||
if (wp->town == nullptr) MakeDefaultName(wp);
|
if (wp->town == nullptr) MakeDefaultName(wp);
|
||||||
|
|
||||||
MakeBuoy(tile, wp->index, GetWaterClass(tile));
|
MakeBuoy(tile, wp->index, GetWaterClass(tile));
|
||||||
InvalidateWaterRegion(tile);
|
|
||||||
CheckForDockingTile(tile);
|
CheckForDockingTile(tile);
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue