载入中...
搜索中...
未找到
PlacementWorld.h
浏览该文件的文档.
1#pragma once
2
10#include "grid/GridConfig.h"
11
12#include <string>
13#include <unordered_map>
14#include <vector>
15
16namespace eve::map {
17class TileLayer;
18}
19
20namespace eve::building {
21
22class Ghost;
23
26public:
28 PlacementWorld(int width, int height, float cellSize = 32.f);
29 ~PlacementWorld() = default;
30
31 PlacementWorld(const PlacementWorld &) = delete;
33
35 void destroy();
36
38 std::string getId() const { return id_; }
39 void setId(const std::string &id) { id_ = id; }
40
42 int getWidth() const { return width_; }
43 int getHeight() const { return height_; }
44 float getCellSize() const { return grid_.cellW; }
45 void setCellSize(float s);
46
47 float getOriginX() const { return grid_.originX; }
48 float getOriginY() const { return grid_.originY; }
49 void setOrigin(float x, float y);
50
52 std::string getSnapMode() const { return snapMode_; }
53 void setSnapMode(const std::string &mode) { snapMode_ = mode; }
54 std::string getValidateRule() const { return validateRule_; }
55 void setValidateRule(const std::string &rule) { validateRule_ = rule; }
56
58 void setExtra(const std::string &key, const std::string &value);
59 std::string getExtra(const std::string &key, const std::string &fallback = {}) const;
60
61 // ---- Grid 配置(默认正交 2D,等价旧行为)----
62 const grid::GridConfig &getGrid() const { return grid_; }
63 grid::GridConfig &getGrid() { return grid_; }
64 void setGridLayout(const std::string &layout);
65 std::string getGridLayoutName() const;
66 void setGridPlane(const std::string &plane);
67 std::string getGridPlaneName() const;
68 void setCellGap(float gapX, float gapY);
69 void setHexSideLength(float s);
70 void setStagger(const std::string &axis, const std::string &index);
73 bool hasGridFromLayer() const { return tileLayer_ != nullptr; }
74
75 // ---- 坐标换算 ----
78 int worldToCellX(float worldX) const;
80 int worldToCellY(float worldY) const;
81 float cellToWorldX(int cellX) const;
82 float cellToWorldY(int cellY) const;
84 void cellToWorldPlane(int cellX, int cellY, float &px, float &py) const;
86 void cellToWorld3D(int cellX, int cellY, float elevation, float &worldX, float &worldY,
87 float &worldZ) const;
88 float cellToWorld3DX(int cellX, int cellY, float elevation) const;
89 float cellToWorld3DY(int cellX, int cellY, float elevation) const;
90 float cellToWorld3DZ(int cellX, int cellY, float elevation) const;
92 void worldToCell3D(float worldX, float worldY, float worldZ, int &cellX, int &cellY) const;
93 int worldToCell3DX(float worldX, float worldY, float worldZ) const;
94 int worldToCell3DY(float worldX, float worldY, float worldZ) const;
95
97 void fillTerrain(int semantic);
98 void setTerrain(int cellX, int cellY, int semantic);
100 int getTerrain(int cellX, int cellY) const;
101 bool inBounds(int cellX, int cellY) const;
102
103 // ---- Tilemap 绑定 ----
105 map::TileLayer *getTileLayer() const { return tileLayer_; }
106 void clearTileLayer();
107 void setTerrainGidMapJson(const std::string &json);
108 void setTerrainGid(int gid, int semantic);
109 void clearTerrainGidMap();
110
111 // ---- 占用查询 ----
114 int getOccupant(int cellX, int cellY) const;
115 int getOccupantInChannel(const std::string &channel, int cellX, int cellY) const;
117 int getAnyOccupant(int cellX, int cellY) const;
118 bool isCellEmpty(int cellX, int cellY) const;
120 bool isCellEmptyInChannel(const std::string &channel, int cellX, int cellY) const;
121 int getBuildingCount() const;
122 bool hasBuilding(int instanceId) const;
123 std::string getBuildingId(int instanceId) const;
124 int getBuildingCellX(int instanceId) const;
125 int getBuildingCellY(int instanceId) const;
126 float getBuildingWorldX(int instanceId) const;
127 float getBuildingWorldY(int instanceId) const;
129 float getBuildingWorldZ(int instanceId) const;
131 float getBuildingElevation(int instanceId) const;
132 std::string getBuildingChannel(int instanceId) const;
133 float getBuildingRotation(int instanceId) const;
134 std::string getBuildingProp(int instanceId, const std::string &key,
135 const std::string &fallback = {}) const;
136 void setBuildingProp(int instanceId, const std::string &key, const std::string &value);
137 bool buildingHasTag(int instanceId, const std::string &tag) const;
139 int getBuildingInstanceAt(int index) const;
140
142 bool canPlace(const std::string &buildingId, int cellX, int cellY, float rotationDeg = 0.f);
143 std::string canPlaceReason(const std::string &buildingId, int cellX, int cellY,
144 float rotationDeg = 0.f);
145 int placeAt(const std::string &buildingId, int cellX, int cellY, float rotationDeg = 0.f);
146 int placeAtWorld(const std::string &buildingId, float worldX, float worldY,
147 float rotationDeg = 0.f);
148 int placeAtWorld3D(const std::string &buildingId, float worldX, float worldY, float worldZ,
149 float rotationDeg = 0.f);
150 int placeGhost(Ghost *ghost);
151 bool removeBuilding(int instanceId);
152 bool moveBuilding(int instanceId, int cellX, int cellY, float rotationDeg = -1.f);
153 void clearBuildings();
154
155 // ---- 供 System 直接访问 ----
156 const std::vector<int> &occupancy() const { return occupancy_; }
157 std::vector<int> &occupancy() { return occupancy_; }
158 const std::vector<int> &terrain() const { return terrain_; }
159 std::vector<int> &terrain() { return terrain_; }
160 const std::unordered_map<std::string, std::vector<int>> &allChannels() const {
161 return allChannels_;
162 }
163 std::unordered_map<std::string, std::vector<int>> &allChannels() { return allChannels_; }
165 std::vector<int> &channelOccupancy(const std::string &channel);
166 const std::unordered_map<int, PlacedBuilding> &buildings() const { return buildings_; }
167 std::unordered_map<int, PlacedBuilding> &buildings() { return buildings_; }
168
169private:
170 friend class PlacementSystem;
171
172 int terrainFromGid(int cellX, int cellY) const;
173
174 std::string id_;
175 int width_ = 0;
176 int height_ = 0;
177 grid::GridConfig grid_;
178 std::string snapMode_ = "grid";
179 std::string validateRule_ = "default";
180 std::vector<int> occupancy_;
181 std::vector<int> terrain_;
182 std::vector<uint8_t> terrainOverrides_;
183 std::unordered_map<std::string, std::vector<int>> allChannels_;
184 std::unordered_map<int, PlacedBuilding> buildings_;
185 std::unordered_map<std::string, std::string> extra_;
186 std::vector<int> instanceOrder_;
187
188 // tilemap 绑定(可空)
189 map::TileLayer *tileLayer_ = nullptr;
190 bool terrainBound_ = false;
191 std::unordered_map<int, int> terrainGidMap_;
192};
193
194} // namespace eve::building
std::string value
std::string layout
std::string id
int y
Definition Grass.cpp:135
float height
Definition Grass.cpp:235
int x
Definition Grass.cpp:135
std::vector< Colorf > px
int width
TileLayer * layer
uint32_t s
Definition Weather.cpp:28
uint32_t semantic
Definition WfcSimple.cpp:15
格子型建筑放置世界(脚本可直接操作)。
std::string canPlaceReason(const std::string &buildingId, int cellX, int cellY, float rotationDeg=0.f)
bool inBounds(int cellX, int cellY) const
int worldToCellX(float worldX) const
世界像素 ↔ 格子坐标。
void destroy()
释放资源并使其失效。
int getTerrain(int cellX, int cellY) const
std::string getBuildingProp(int instanceId, const std::string &key, const std::string &fallback={}) const
int getWidth() const
尺寸 / 格子大小 / 原点。
float getBuildingWorldY(int instanceId) const
int getBuildingCellY(int instanceId) const
void setGridFromLayer(map::TileLayer *layer)
float getBuildingWorldX(int instanceId) const
bool moveBuilding(int instanceId, int cellX, int cellY, float rotationDeg=-1.f)
void setValidateRule(const std::string &rule)
std::string getGridLayoutName() const
float getBuildingElevation(int instanceId) const
PlacementWorld(const PlacementWorld &)=delete
int getOccupant(int cellX, int cellY) const
占用查询:格子上建筑实例 / 是否为空。
bool isCellEmptyInChannel(const std::string &channel, int cellX, int cellY) const
已放置建筑实例查询。
bool hasBuilding(int instanceId) const
void setOrigin(float x, float y)
const std::unordered_map< int, PlacedBuilding > & buildings() const
const grid::GridConfig & getGrid() const
int getBuildingInstanceAt(int index) const
按插入顺序取实例 id。
int getBuildingCellX(int instanceId) const
float cellToWorld3DX(int cellX, int cellY, float elevation) const
const std::vector< int > & terrain() const
bool buildingHasTag(int instanceId, const std::string &tag) const
const std::vector< int > & occupancy() const
std::string getSnapMode() const
放置策略:吸附模式 / 校验规则。
int placeAt(const std::string &buildingId, int cellX, int cellY, float rotationDeg=0.f)
std::string getId() const
世界 id(用于变更事件定位)。
void setGridLayout(const std::string &layout)
std::string getValidateRule() const
void setExtra(const std::string &key, const std::string &value)
世界级额外属性(键值)。
void setCellGap(float gapX, float gapY)
bool isCellEmpty(int cellX, int cellY) const
map::TileLayer * getTileLayer() const
void setTerrain(int cellX, int cellY, int semantic)
void setTerrainGid(int gid, int semantic)
bool removeBuilding(int instanceId)
float getBuildingRotation(int instanceId) const
int worldToCell3DX(float worldX, float worldY, float worldZ) const
float cellToWorldX(int cellX) const
int placeAtWorld3D(const std::string &buildingId, float worldX, float worldY, float worldZ, float rotationDeg=0.f)
std::string getGridPlaneName() const
std::unordered_map< int, PlacedBuilding > & buildings()
bool canPlace(const std::string &buildingId, int cellX, int cellY, float rotationDeg=0.f)
便捷操作(转发 PlacementSystem):放置 / 移除 / 移动。
float cellToWorldY(int cellY) const
void setId(const std::string &id)
int worldToCellY(float worldY) const
void cellToWorldPlane(int cellX, int cellY, float &px, float &py) const
void setBuildingProp(int instanceId, const std::string &key, const std::string &value)
std::string getBuildingId(int instanceId) const
std::vector< int > & occupancy()
grid::GridConfig & getGrid()
void setGridPlane(const std::string &plane)
void setSnapMode(const std::string &mode)
void bindTileLayer(map::TileLayer *layer)
std::string getExtra(const std::string &key, const std::string &fallback={}) const
int worldToCell3DY(float worldX, float worldY, float worldZ) const
const std::unordered_map< std::string, std::vector< int > > & allChannels() const
void setStagger(const std::string &axis, const std::string &index)
int placeAtWorld(const std::string &buildingId, float worldX, float worldY, float rotationDeg=0.f)
int getAnyOccupant(int cellX, int cellY) const
void worldToCell3D(float worldX, float worldY, float worldZ, int &cellX, int &cellY) const
float cellToWorld3DY(int cellX, int cellY, float elevation) const
std::unordered_map< std::string, std::vector< int > > & allChannels()
std::string getBuildingChannel(int instanceId) const
void setTerrainGidMapJson(const std::string &json)
float getBuildingWorldZ(int instanceId) const
int getOccupantInChannel(const std::string &channel, int cellX, int cellY) const
float cellToWorld3DZ(int cellX, int cellY, float elevation) const
std::vector< int > & channelOccupancy(const std::string &channel)
void fillTerrain(int semantic)
地形语义(占用检查用)。
void cellToWorld3D(int cellX, int cellY, float elevation, float &worldX, float &worldY, float &worldZ) const
std::vector< int > & terrain()
PlacementWorld & operator=(const PlacementWorld &)=delete
ECS tile layer entity. Script mutates tile GIDs / tileset / draw; TileRenderSystem batch-draws atlas ...
Definition TileLayer.h:30
建筑放置模块入口:定义 / 放置世界 / 鬼影 / 变更事件的脚本绑定点。 设计文档:docs/dev/建筑放置系统设计.md
Definition Building.cpp:7
放置世界:格子占用(多通道)+ 地形语义 + 已放置建筑实例。 行为由 PlacementSystem 提供;本类暴露便于脚本绑定的薄封装方法。 坐标换算统一走 eve::grid(支持 rectang...