载入中...
搜索中...
未找到
HexMap.cpp
浏览该文件的文档.
13[[nodiscard]] std::int32_t clampInt(std::int32_t value, std::int32_t low, std::int32_t high) noexcept {
17[[nodiscard]] std::int32_t layerIndex(std::int32_t feature) noexcept { return clampInt(feature, 0, 2); }
28 if (sum < std::numeric_limits<std::int32_t>::min()) return std::numeric_limits<std::int32_t>::min();
29 if (sum > std::numeric_limits<std::int32_t>::max()) return std::numeric_limits<std::int32_t>::max();
37Result<void> HexMap::reset(std::int32_t cellCountX, std::int32_t cellCountZ, std::uint32_t seed) {
38 if (cellCountX <= 0 || cellCountZ <= 0) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "hex map size must be positive", "hexmap"));
40 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "hex map size must be a multiple of the 5x5 chunk size", "hexmap"));
79const HexCellData* HexMap::cell(HexCoordinates coordinates) const noexcept { return cellAt(indexOf(coordinates)); }
87bool HexMap::getNeighbor(HexCoordinates coordinates, HexDirection direction, HexCoordinates& out) const noexcept {
115HexCoordinates HexMap::chunkCell(std::int32_t chunkIndex, std::int32_t column, std::int32_t row) const noexcept {
124 const HexVec3 b = cellPosition(chunkCell(chunkIndex, HexMetrics::kChunkSizeX - 1, HexMetrics::kChunkSizeZ - 1));
177Result<HexCoordinates> HexMap::pickCell(HexVec3 rayOrigin, HexVec3 rayDirection) const noexcept {
183 std::sqrt(rayDirection.x * rayDirection.x + rayDirection.y * rayDirection.y + rayDirection.z * rayDirection.z);
186 Diagnostic::error(DiagnosticCode::InvalidArgument, "ray direction must be non-zero", "hexmap.pick"));
193 HexVec3 high = cellGroundPosition(HexCoordinates::fromOffset(cellCountX_ - 1, cellCountZ_ - 1));
246 Diagnostic::error(DiagnosticCode::NotFound, "ray never reached the hex surface", "hexmap.pick"));
295 Diagnostic::error(DiagnosticCode::NotFound, "ray never reached the hex surface", "hexmap.pick"));
394 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
395 const std::int32_t clamped = clampInt(value, HexMetrics::kMinElevation, HexMetrics::kMaxElevation);
421 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
432 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
442 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
450 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
458 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
466 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
476 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
484 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
496 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
507 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
516 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
518 if (!getNeighbor(c, direction, neighbour)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "river direction leaves the hex map", "hexmap"));
519 if (data->flags.hasAnyRiverOut() && data->flags.hasRiverOut(direction)) return Result<void>::success();
521 return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "a river cannot flow uphill", "hexmap"));
560 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
571 other->flags = other->flags.withoutRiverIn(opposite(direction)).withoutRiverOut(opposite(direction));
580 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
582 if (!getNeighbor(c, direction, neighbour)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "road direction leaves the hex map", "hexmap"));
590 if (other->values.specialIndex() != 0 || data->values.specialIndex() != 0) return Result<void>::success();
604 if (!data) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "cell is outside the hex map", "hexmap"));
621void HexMap::collectBrush(HexCoordinates center, std::int32_t radius, std::vector<std::int32_t>& out) const {
628 const std::int64_t diameter = static_cast<std::int64_t>(cellCountX_) + static_cast<std::int64_t>(cellCountZ_);
633 static_cast<std::int32_t>(std::max<std::int64_t>(0, static_cast<std::int64_t>(centerColumn) - spread));
637 static_cast<std::int32_t>(std::max<std::int64_t>(0, static_cast<std::int64_t>(center.z) - reach));
639 static_cast<std::int32_t>(std::min<std::int64_t>(cellCountZ_ - 1, static_cast<std::int64_t>(center.z) + reach));
648Result<void> HexMap::editElevation(HexCoordinates center, std::int32_t radius, std::int32_t delta) {
649 if (!contains(center)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush centre is outside the hex map", "hexmap"));
650 if (radius < 0) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush radius must be non-negative", "hexmap"));
661Result<void> HexMap::editWaterLevel(HexCoordinates center, std::int32_t radius, std::int32_t delta) {
662 if (!contains(center)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush centre is outside the hex map", "hexmap"));
663 if (radius < 0) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush radius must be non-negative", "hexmap"));
674Result<void> HexMap::editTerrainType(HexCoordinates center, std::int32_t radius, std::int32_t terrainType) {
675 if (!contains(center)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush centre is outside the hex map", "hexmap"));
676 if (radius < 0) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush radius must be non-negative", "hexmap"));
686Result<void> HexMap::editFeatureLevel(HexCoordinates center, std::int32_t radius, std::int32_t feature,
688 if (!contains(center)) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush centre is outside the hex map", "hexmap"));
689 if (radius < 0) return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument, "brush radius must be non-negative", "hexmap"));
Stable, structured diagnostics shared by engine modules.
Editable hex cell grid: topology, queries, picking and authoring.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
void ignore(std::string_view reason={}) const noexcept
Explicitly discard this result after documenting the reason.
Definition Result.h:537
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Packed boolean cell state (roads, rivers, walls, exploration).
Definition HexCell.h:123
constexpr bool hasRiverThrough(HexDirection d) const noexcept
Whether a river enters and/or leaves through d.
Definition HexCell.h:172
constexpr HexFlags withoutRiverIn(HexDirection d) const noexcept
Without river in.
Definition HexCell.h:207
constexpr HexFlags withoutRiverOut(HexDirection d) const noexcept
Without river out.
Definition HexCell.h:217
Result< void > removeRiver(HexCoordinates c)
Removes every river connection of the cell and its neighbours.
Definition HexMap.cpp:558
Result< void > setSpecialIndex(HexCoordinates c, std::int32_t index)
Sets a cell's special-feature index; ignored while the cell carries a river.
Definition HexMap.cpp:464
HexVec3 chunkCenter(std::int32_t chunkIndex) const noexcept
World-space centre of a chunk, at the first cell's elevation.
Definition HexMap.cpp:121
Result< void > editFeatureLevel(HexCoordinates center, std::int32_t radius, std::int32_t feature, std::int32_t delta)
Applies additive change to one feature level (0 urban, 1 farm, 2 plant).
Definition HexMap.cpp:686
Result< void > setWalled(HexCoordinates c, bool walled)
Sets whether a cell is walled.
Definition HexMap.cpp:474
std::int32_t waterLevel(HexCoordinates c) const noexcept
Definition HexMap.cpp:304
HexCoordinates coordinatesAt(std::int32_t index) const noexcept
Coordinates of a linear cell index; out-of-range indices return (0, 0).
Definition HexMap.cpp:69
std::int32_t chunkRowOf(std::int32_t chunkIndex) const noexcept
Chunk row of a chunk index.
Definition HexMap.cpp:111
std::int32_t indexOf(HexCoordinates coordinates) const noexcept
Linear cell index of coordinates (offset order), or -1 when outside the grid.
Definition HexMap.cpp:64
Result< void > editTerrainType(HexCoordinates center, std::int32_t radius, std::int32_t terrainType)
Paints a terrain palette index over a hex brush.
Definition HexMap.cpp:674
std::int32_t chunkColumnOf(std::int32_t chunkIndex) const noexcept
Chunk column of a chunk index.
Definition HexMap.cpp:107
Result< void > setUrbanLevel(HexCoordinates c, std::int32_t level)
Sets a cell's urban level, clamped to [0, 3].
Definition HexMap.cpp:440
Result< void > setTerrainType(HexCoordinates c, std::int32_t terrainType)
Sets a cell's terrain palette index, clamped to the palette range.
Definition HexMap.cpp:430
Result< void > removeRoads(HexCoordinates c)
Removes every road of the cell and its neighbours.
Definition HexMap.cpp:602
HexVec3 cellPosition(HexCoordinates coordinates) const noexcept
Cell centre including elevation and vertical perturbation.
Definition HexMap.cpp:170
std::int32_t terrainType(HexCoordinates c) const noexcept
Definition HexMap.cpp:308
Result< void > setCellState(HexCoordinates c, HexValues values, HexFlags flags)
Writes a complete cell record verbatim.
Definition HexMap.cpp:505
HexValues values(HexCoordinates c) const noexcept
Full packed value record of a cell (zero when outside the grid).
Definition HexMap.cpp:356
bool contains(HexCoordinates coordinates) const noexcept
Whether coordinates address a cell inside the grid.
Definition HexMap.h:122
Result< void > setPlantLevel(HexCoordinates c, std::int32_t level)
Sets a cell's plant level, clamped to [0, 3].
Definition HexMap.cpp:456
Result< void > editWaterLevel(HexCoordinates center, std::int32_t radius, std::int32_t delta)
Applies additive water-level change over a hex brush.
Definition HexMap.cpp:661
Result< HexCoordinates > pickCell(HexVec3 rayOrigin, HexVec3 rayDirection) const noexcept
Finds the cell under a world-space ray.
Definition HexMap.cpp:177
bool getNeighbor(HexCoordinates coordinates, HexDirection direction, HexCoordinates &out) const noexcept
Neighbour of coordinates in direction; false when it is off-grid.
Definition HexMap.cpp:87
std::int32_t specialIndex(HexCoordinates c) const noexcept
Definition HexMap.cpp:324
bool isExplorable(HexCoordinates c) const noexcept
Whether a cell may ever be revealed by a viewer.
Definition HexMap.cpp:352
bool isWalled(HexCoordinates c) const noexcept
Definition HexMap.cpp:344
Result< void > setWaterLevel(HexCoordinates c, std::int32_t waterLevel)
Sets a cell's water level, clamped to [0, maxElevation].
Definition HexMap.cpp:419
Result< void > setOutgoingRiver(HexCoordinates c, HexDirection direction)
Forces a river to leave the cell through direction, mirroring the neighbour.
Definition HexMap.cpp:514
bool isUnderwater(HexCoordinates c) const noexcept
Definition HexMap.cpp:328
bool isExplored(HexCoordinates c) const noexcept
Whether a cell has ever been seen by a viewer (the fog-of-war latch).
Definition HexMap.cpp:348
std::int32_t chunkIndexOf(HexCoordinates coordinates) const noexcept
Chunk index owning coordinates, or -1 when outside the grid.
Definition HexMap.cpp:102
Result< void > reset(std::int32_t cellCountX, std::int32_t cellCountZ, std::uint32_t seed)
Replaces the grid with a new cellCountX * cellCountZ map.
Definition HexMap.cpp:37
HexFlags flags(HexCoordinates c) const noexcept
Full packed flag record of a cell (zero when outside the grid).
Definition HexMap.cpp:360
Result< void > setElevation(HexCoordinates c, std::int32_t elevation)
Sets a cell's elevation, clamped to the editable range, and refreshes dependents.
Definition HexMap.cpp:392
bool hasRiver(HexCoordinates c) const noexcept
Definition HexMap.cpp:332
Result< void > setExplored(HexCoordinates c, bool explored)
Sets the explored (fog-of-war) latch of a cell.
Definition HexMap.cpp:482
std::int32_t elevation(HexCoordinates c) const noexcept
Definition HexMap.cpp:300
const HexCellData * cell(HexCoordinates coordinates) const noexcept
Cell record, or null when outside the grid. @ownership Borrowed; the map owns the record....
Definition HexMap.cpp:79
Result< void > setFarmLevel(HexCoordinates c, std::int32_t level)
Sets a cell's farm level, clamped to [0, 3].
Definition HexMap.cpp:448
void collectBrush(HexCoordinates center, std::int32_t radius, std::vector< std::int32_t > &out) const
Enumerates the cells of a hex brush into out (cleared first).
Definition HexMap.cpp:621
HexEdgeType edgeTypeTo(HexCoordinates a, HexCoordinates b) const noexcept
Relationship between two adjacent cells; Flat when not adjacent or out of range.
Definition HexMap.cpp:94
bool hasRiverThrough(HexCoordinates c, HexDirection d) const noexcept
Definition HexMap.cpp:340
void markChunkDirtyAndNeighbors(std::int32_t chunkIndex) noexcept
Marks one chunk and its direct chunk neighbours dirty.
Definition HexMap.cpp:136
Result< void > addRoad(HexCoordinates c, HexDirection direction)
Adds a road through direction when both cells can carry one.
Definition HexMap.cpp:578
std::int32_t urbanLevel(HexCoordinates c) const noexcept
Definition HexMap.cpp:312
const HexCellData * cellAt(std::int32_t index) const noexcept
Cell record by linear index, or null when out of range. @ownership Borrowed; the map owns the record....
Definition HexMap.cpp:74
std::int32_t plantLevel(HexCoordinates c) const noexcept
Definition HexMap.cpp:320
std::int32_t farmLevel(HexCoordinates c) const noexcept
Definition HexMap.cpp:316
Result< void > setExplorable(HexCoordinates c, bool explorable)
Sets whether a cell may ever be explored.
Definition HexMap.cpp:494
Result< void > editElevation(HexCoordinates center, std::int32_t radius, std::int32_t delta)
Raises or lowers every cell within radius steps of center.
Definition HexMap.cpp:648
HexCoordinates chunkCell(std::int32_t chunkIndex, std::int32_t column, std::int32_t row) const noexcept
Coordinates of the cell at (column, row) inside a chunk.
Definition HexMap.cpp:115
static constexpr float kElevationStep
Vertical distance between two elevation levels.
Definition HexMetrics.h:120
static constexpr float kOuterRadius
Outer (corner) radius of one hex cell in world units.
Definition HexMetrics.h:165
static float elevationY(int elevation) noexcept
Y coordinate of a cell's elevation surface.
Definition HexMetrics.h:265
constexpr HexValues withSpecialIndex(std::int32_t value) const noexcept
With special index.
Definition HexCell.h:96
constexpr HexValues withElevation(std::int32_t value) const noexcept
Definition HexCell.h:76
constexpr HexValues withWaterLevel(std::int32_t value) const noexcept
With water level.
Definition HexCell.h:80
Definition HexCell.h:9
constexpr HexDirection opposite(HexDirection d) noexcept
The direction opposite to d.
Definition HexMetrics.h:65
constexpr std::int32_t kHexDirectionCount
Number of hex edges / facing directions.
Definition HexMetrics.h:62
constexpr HexEdgeType edgeType(int elevation1, int elevation2) noexcept
The relationship between two elevations (single-step changes are slopes).
Definition HexMetrics.h:96
HexEdgeType
Relationship between two neighbouring cells of different elevation.
Definition HexMetrics.h:93
constexpr HexDirection next(HexDirection d) noexcept
The next direction clockwise (NW wraps to NE).
Definition HexMetrics.h:76
constexpr std::int32_t clampTerrainType(std::int32_t index) noexcept
Terrain type index clamped into the supported palette range.
Definition HexCell.h:24
@ InvalidArgument
@ NotFound
One cell of the hex map: packed values plus packed flags.
Definition HexCell.h:244
static HexVec3 toWorldPosition(HexCoordinates coordinates) noexcept
World-space centre of a cell before elevation and perturbation.
Definition HexCoordinates.h:105
static constexpr HexCoordinates fromOffset(std::int32_t offsetX, std::int32_t offsetZ) noexcept
Converts an odd-row offset pair into axial coordinates.
Definition HexCoordinates.h:84
constexpr HexCoordinates step(HexDirection direction, std::int32_t distance=1) const noexcept
Returns the neighbouring coordinates one step in direction.
Definition HexCoordinates.h:45
static HexCoordinates fromWorldPosition(HexVec3 position) noexcept
Converts a world-space XZ position back to cell coordinates.
Definition HexCoordinates.cpp:5
Minimal 3-component float vector used by the hex mesh builders.
Definition HexMetrics.h:18