载入中...
搜索中...
未找到
PlacementWorld.h
浏览该文件的文档.
1#pragma once
2#include "common/Export.h"
3
4
12#include "common/Result.h"
13
14#include <memory>
15#include <string>
16#include <unordered_map>
17#include <vector>
18
19namespace eve::map {
20class TileLayer;
21}
22
23namespace eve::grid {
24struct GridConfig;
25}
26
27namespace eve::building {
28
29class Ghost;
30
33public:
34 using ChannelMap = std::unordered_map<std::string, std::vector<int>>;
36 PlacementWorld(int width, int height, float cellSize = 32.f);
39
40 PlacementWorld(const PlacementWorld &) = delete;
42
44 void destroy();
45
47 std::string getId() const { return id_; }
49 void setId(const std::string &id) { id_ = id; }
50
52 int getWidth() const { return width_; }
54 int getHeight() const { return height_; }
56 float getCellSize() const;
58 void setCellSize(float s);
59
61 float getOriginX() const;
63 float getOriginY() const;
65 void setOrigin(float x, float y);
66
68 float getFloorHeight() const { return floorHeight_; }
70 void setFloorHeight(float height);
72 int getActiveLevel() const { return activeLevel_; }
74 void setActiveLevel(int level) { activeLevel_ = level; }
75
77 std::string getSnapMode() const { return snapMode_; }
79 void setSnapMode(const std::string &mode) { snapMode_ = mode; }
81 std::string getValidateRule() const { return validateRule_; }
83 void setValidateRule(const std::string &rule) { validateRule_ = rule; }
84
86 void setExtra(const std::string &key, const std::string &value);
88 std::string getExtra(const std::string &key, const std::string &fallback = {}) const;
89
90 // ---- Grid 配置(默认正交 2D,等价旧行为)----
92 const grid::GridConfig &getGrid() const;
94 grid::GridConfig &getGrid();
96 void setGridLayout(const std::string &layout);
98 std::string getGridLayoutName() const;
100 void setGridPlane(const std::string &plane);
102 std::string getGridPlaneName() const;
104 void setCellGap(float gapX, float gapY);
106 void setHexSideLength(float s);
108 void setStagger(const std::string &axis, const std::string &index);
111 void setGridFromLayer(map::TileLayer *layer);
113 bool hasGridFromLayer() const { return tileLayer_ != nullptr; }
114
115 // ---- 坐标换算 ----
119 int worldToCellX(float worldX) const;
122 int worldToCellY(float worldY) const;
124 float cellToWorldX(int cellX) const;
126 float cellToWorldY(int cellY) const;
129 void cellToWorldPlane(int cellX, int cellY, float &px, float &py) const;
132 void cellToWorld3D(int cellX, int cellY, float elevation, float &worldX, float &worldY,
133 float &worldZ) const;
135 float cellToWorld3DX(int cellX, int cellY, float elevation) const;
137 float cellToWorld3DY(int cellX, int cellY, float elevation) const;
139 float cellToWorld3DZ(int cellX, int cellY, float elevation) const;
142 void worldToCell3D(float worldX, float worldY, float worldZ, int &cellX, int &cellY) const;
144 int worldToCell3DX(float worldX, float worldY, float worldZ) const;
146 int worldToCell3DY(float worldX, float worldY, float worldZ) const;
147
149 void fillTerrain(int semantic);
151 void setTerrain(int cellX, int cellY, int semantic);
154 int getTerrain(int cellX, int cellY) const;
156 bool inBounds(int cellX, int cellY) const;
157
158 // ---- Tilemap 绑定 ----
160 void bindTileLayer(map::TileLayer *layer);
162 map::TileLayer *getTileLayer() const { return tileLayer_; }
164 void clearTileLayer();
166 void setTerrainGidMapJson(const std::string &json);
168 void setTerrainGid(int gid, int semantic);
170 void clearTerrainGidMap();
171
172 // ---- 占用查询 ----
176 int getOccupant(int cellX, int cellY) const;
178 int getOccupantInChannel(const std::string &channel, int cellX, int cellY) const;
180 int getOccupantAtLevel(const std::string &channel, int cellX, int cellY, int level) const;
183 int getAnyOccupant(int cellX, int cellY) const;
185 int getAnyOccupantAtLevel(int cellX, int cellY, int level) const;
187 bool isCellEmpty(int cellX, int cellY) const;
189 bool isCellEmptyInChannel(const std::string &channel, int cellX, int cellY) const;
191 int getEdgeOccupant(const std::string &channel, int cellX, int cellY,
192 const std::string &direction) const;
194 int getEdgeOccupantAtLevel(const std::string &channel, int cellX, int cellY,
195 const std::string &direction, int level) const;
197 bool isEdgeEmpty(const std::string &channel, int cellX, int cellY,
198 const std::string &direction) const;
200 int getCornerOccupant(const std::string &channel, int vertexX, int vertexY) const;
202 int getCornerOccupantAtLevel(const std::string &channel, int vertexX, int vertexY,
203 int level) const;
205 int getAnyCornerOccupantAtLevel(int vertexX, int vertexY, int level) const;
207 bool isCornerEmpty(const std::string &channel, int vertexX, int vertexY) const;
209 int getFreeOccupant(const std::string &channel, float worldX, float worldY) const;
211 int getFreeOccupantAtLevel(const std::string &channel, float worldX, float worldY,
212 int level) const;
214 int getEdgeConnectionMask(int instanceId) const;
216 std::string getEdgeVariant(int instanceId) const;
218 int getBuildingCount() const;
220 bool hasBuilding(int instanceId) const;
222 std::string getBuildingId(int instanceId) const;
224 int getBuildingCellX(int instanceId) const;
226 int getBuildingCellY(int instanceId) const;
228 float getBuildingWorldX(int instanceId) const;
230 float getBuildingWorldY(int instanceId) const;
233 float getBuildingWorldZ(int instanceId) const;
236 float getBuildingElevation(int instanceId) const;
238 int getBuildingLevel(int instanceId) const;
240 int getBuildingSupportCount(int instanceId) const;
242 int getBuildingSupportAt(int instanceId, int index) const;
244 int getBuildingDependentCount(int instanceId) const;
246 std::string getBuildingSurfaceId(int instanceId) const;
248 int64_t getBuildingSurfaceRevision(int instanceId) const;
250 float getBuildingSurfaceNormalX(int instanceId) const;
252 float getBuildingSurfaceNormalY(int instanceId) const;
254 float getBuildingSurfaceNormalZ(int instanceId) const;
256 std::string getBuildingChannel(int instanceId) const;
258 float getBuildingRotation(int instanceId) const;
260 std::string getBuildingProp(int instanceId, const std::string &key,
261 const std::string &fallback = {}) const;
263 void setBuildingProp(int instanceId, const std::string &key, const std::string &value);
265 bool buildingHasTag(int instanceId, const std::string &tag) const;
267 int getBuildingInstanceAt(int index) const;
269 int getEdgeCurveGroupCount() const { return static_cast<int>(edgeCurveGroups_.size()); }
271 EdgeCurveGroupId nextEdgeCurveGroupId() const { return {nextEdgeCurveGroupId_}; }
273 std::vector<EdgeCurveGroupId> edgeCurveGroupIds() const;
279 [[nodiscard]] eve::Result<EdgeCurveGroup> edgeCurveGroup(EdgeCurveGroupId id) const;
281 [[nodiscard]] eve::Result<EdgeCurveGroup> edgeCurveGroupForInstance(int instanceId) const;
282
284 bool canPlace(const std::string &buildingId, int cellX, int cellY, float rotationDeg = 0.f);
286 std::string canPlaceReason(const std::string &buildingId, int cellX, int cellY,
287 float rotationDeg = 0.f);
289 int placeAt(const std::string &buildingId, int cellX, int cellY, float rotationDeg = 0.f);
291 int placeAtWorld(const std::string &buildingId, float worldX, float worldY,
292 float rotationDeg = 0.f);
294 int placeAtWorld3D(const std::string &buildingId, float worldX, float worldY, float worldZ,
295 float rotationDeg = 0.f);
297 int placeGhost(Ghost *ghost);
299 int placeEdge(const std::string &buildingId, int cellX, int cellY,
300 const std::string &direction);
302 bool canPlaceEdge(const std::string &buildingId, int cellX, int cellY,
303 const std::string &direction);
305 std::string canPlaceEdgeReason(const std::string &buildingId, int cellX, int cellY,
306 const std::string &direction);
308 int placeCorner(const std::string &buildingId, int vertexX, int vertexY);
310 bool canPlaceCorner(const std::string &buildingId, int vertexX, int vertexY);
312 std::string canPlaceCornerReason(const std::string &buildingId, int vertexX, int vertexY);
314 int placeFree(const std::string &buildingId, float worldX, float worldY,
315 float elevation = 0.f, float rotationDeg = 0.f);
317 bool canPlaceFree(const std::string &buildingId, float worldX, float worldY);
319 std::string canPlaceFreeReason(const std::string &buildingId, float worldX, float worldY);
321 bool removeBuilding(int instanceId);
323 std::string canRemoveBuildingReason(int instanceId) const;
328 int removeBuildingCascade(int instanceId);
330 bool moveBuilding(int instanceId, int cellX, int cellY, float rotationDeg = -1.f);
332 void clearBuildings();
333
335 [[nodiscard]] std::unique_ptr<PlacementWorld> cloneState() const;
337 void swapState(PlacementWorld& candidate) noexcept;
338
339 // ---- 供 System 直接访问 ----
341 const std::vector<int> &occupancy() const { return occupancy_; }
343 std::vector<int> &occupancy() { return occupancy_; }
345 const std::vector<int> &terrain() const { return terrain_; }
347 std::vector<int> &terrain() { return terrain_; }
348 const std::unordered_map<std::string, std::vector<int>> &allChannels() const {
349 return allChannels_;
350 }
351 std::unordered_map<std::string, std::vector<int>> &allChannels() { return allChannels_; }
354 std::vector<int> &channelOccupancy(const std::string &channel);
356 std::vector<int> &channelOccupancy(const std::string &channel, int level);
357 const std::unordered_map<int, PlacedBuilding> &buildings() const { return buildings_; }
358 std::unordered_map<int, PlacedBuilding> &buildings() { return buildings_; }
359
360private:
361 friend class PlacementSystem;
362
363 int terrainFromGid(int cellX, int cellY) const;
364 ChannelMap &edgeChannels(EdgeAxis axis, int level);
370 const ChannelMap *findEdgeChannels(EdgeAxis axis, int level) const;
371 ChannelMap &cornerChannels(int level);
377 const ChannelMap *findCornerChannels(int level) const;
378
379 std::string id_;
380 int width_ = 0;
381 int height_ = 0;
382 float floorHeight_ = 3.f;
383 int activeLevel_ = 0;
384 std::unique_ptr<grid::GridConfig> grid_;
385 std::string snapMode_ = "grid";
386 std::string validateRule_ = "default";
387 std::vector<int> occupancy_;
388 std::vector<int> terrain_;
389 std::vector<uint8_t> terrainOverrides_;
390 std::unordered_map<std::string, std::vector<int>> allChannels_;
391 std::unordered_map<std::string, std::vector<int>> horizontalEdgeChannels_;
392 std::unordered_map<std::string, std::vector<int>> verticalEdgeChannels_;
393 std::unordered_map<std::string, std::vector<int>> cornerChannels_;
394 std::unordered_map<int, ChannelMap> cellChannelsByLevel_;
395 std::unordered_map<int, ChannelMap> horizontalEdgesByLevel_;
396 std::unordered_map<int, ChannelMap> verticalEdgesByLevel_;
397 std::unordered_map<int, ChannelMap> cornersByLevel_;
398 std::unordered_map<int, PlacedBuilding> buildings_;
399 std::unordered_map<uint64_t, EdgeCurveGroup> edgeCurveGroups_;
400 uint64_t nextEdgeCurveGroupId_ = 1;
401 bool publishEvents_ = true;
402 std::unordered_map<std::string, std::string> extra_;
403 std::vector<int> instanceOrder_;
404
405 // tilemap 绑定(可空)
406 map::TileLayer *tileLayer_ = nullptr;
407 bool terrainBound_ = false;
408 std::unordered_map<int, int> terrainGidMap_;
409};
410
411} // namespace eve::building
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
const std::string & s
float py
#define EVENGINE_API_WORLD
Definition Export.h:109
std::string layout
std::uint32_t key
float elevation
std::vector< Colorf > px
std::uint32_t height
std::uint32_t width
void(* destroy)(void *)
int level
const std::string * tag
TileLayer * layer
std::string id
Definition PlayHost.cpp:108
Move-only, checked operation results for the common layer.
RoadLaneDirection direction
uint32_t index
uint32_t semantic
Definition WfcSimple.cpp:15
Move-only operation result carrying either a value or Status.
Definition Result.h:155
EVENGINE_API_WORLD public API.
Definition Ghost.h:16
EVENGINE_API_WORLD public API.
格子型建筑放置世界(脚本可直接操作)。
int getWidth() const
尺寸 / 格子大小 / 原点。
int getActiveLevel() const
Floor used by compatibility placement/query APIs.
std::unordered_map< std::string, std::vector< int > > ChannelMap
~PlacementWorld()
Placement world.
void setValidateRule(const std::string &rule)
Sets the validate rule.
PlacementWorld(const PlacementWorld &)=delete
float getFloorHeight() const
Height between discrete floors along the grid plane normal.
const std::unordered_map< int, PlacedBuilding > & buildings() const
const std::vector< int > & terrain() const
Terrain.
const std::vector< int > & occupancy() const
Occupancy.
std::string getSnapMode() const
放置策略:吸附模式 / 校验规则。
std::string getId() const
世界 id(用于变更事件定位)。
std::string getValidateRule() const
Returns the validate rule.
bool hasGridFromLayer() const
True when grid from layer.
int getEdgeCurveGroupCount() const
Number of complete authoritative edge-curve groups in this world.
void setActiveLevel(int level)
Select the floor used by compatibility placement/query APIs.
map::TileLayer * getTileLayer() const
Returns the tile layer.
std::unordered_map< int, PlacedBuilding > & buildings()
void setId(const std::string &id)
Sets the id.
EdgeCurveGroupId nextEdgeCurveGroupId() const
Return the next monotonic curve-group identity without reserving it.
std::vector< int > & occupancy()
Occupancy.
void setSnapMode(const std::string &mode)
Sets the snap mode.
const std::unordered_map< std::string, std::vector< int > > & allChannels() const
int getHeight() const
Returns the height.
std::unordered_map< std::string, std::vector< int > > & allChannels()
std::vector< int > & terrain()
Terrain.
PlacementWorld & operator=(const PlacementWorld &)=delete
ECS tile layer entity. Script mutates tile GIDs / tileset / draw; TileRenderSystem batch-draws atlas ...
Definition TileLayer.h:32
建筑放置模块入口:定义 / 放置世界 / 鬼影 / 变更事件的脚本绑定点。 设计文档:docs/dev/建筑放置系统设计.md
Definition Building.cpp:7
EdgeAxis
Canonical orientation of an edge in logical grid coordinates.
放置世界:格子占用(多通道)+ 地形语义 + 已放置建筑实例。 行为由 PlacementSystem 提供;本类暴露便于脚本绑定的薄封装方法。 坐标换算统一走 eve::grid(支持 rectang...
Strong world-local identity of one authoritative edge-curve group.
Grid shape, cell metrics, origin, and placement plane. Pure data; use GridProjection helpers for worl...
Definition GridConfig.h:34