载入中...
搜索中...
未找到
PlacementSystem.h
浏览该文件的文档.
1#pragma once
2
3// 放置操作静态入口 + 可插拔校验 / 吸附 / 变更钩子。
4//
5// C++ 侧通过 register* 扩展;脚本侧通过定义/世界上的策略名字符串选用已注册规则。
6
8
9#include <functional>
10#include <string>
11#include <unordered_map>
12#include <vector>
13
14namespace eve::building {
15
16class PlacementWorld;
17class Ghost;
18
20public:
21 using ValidateFn = std::function<bool(const PlacementWorld &world, const PlacementQuery &q,
22 std::string *reason)>;
23 using SnapFn =
24 std::function<SnapResult(const PlacementWorld &world, float worldX, float worldY)>;
25 using ChangeHook = std::function<void(const BuildingChangeEvent &ev)>;
26
28 struct PlacementHit {
29 float worldX = 0.f;
30 float worldY = 0.f;
31 float worldZ = 0.f;
32 };
39 using SurfaceFn = std::function<bool(const PlacementWorld &world, float x, float y,
40 PlacementHit *hit)>;
41
50 static PlacementSystem &inst();
51
52 static void registerValidateRule(const std::string &name, ValidateFn fn);
53 static void unregisterValidateRule(const std::string &name);
54 static bool hasValidateRule(const std::string &name);
55
56 static void registerSnapRule(const std::string &name, SnapFn fn);
57 static void unregisterSnapRule(const std::string &name);
58 static bool hasSnapRule(const std::string &name);
59
60 static void registerChangeHook(const std::string &name, ChangeHook fn);
61 static void unregisterChangeHook(const std::string &name);
62 static bool hasChangeHook(const std::string &name);
63
64 static void registerSurface(const std::string &name, SurfaceFn fn);
65 static void unregisterSurface(const std::string &name);
66 static bool hasSurface(const std::string &name);
67 static bool surfaceHit(const PlacementWorld &world, const std::string &name, float x,
68 float y, PlacementHit *hit);
69 static std::vector<std::string> surfaceNames();
71 static void setPlaneSurfaceHeight(float h);
72 static float getPlaneSurfaceHeight();
73
75 static void ensureBuiltins();
76
77 static SnapResult snap(const PlacementWorld &world, const std::string &buildingId, float worldX,
78 float worldY);
80 static SnapResult snap3D(const PlacementWorld &world, const std::string &buildingId,
81 float worldX, float worldY, float worldZ);
82 static SnapResult snapWithMode(const PlacementWorld &world, const std::string &mode,
83 float worldX, float worldY);
84
86 static float normalizeRotation(const std::string &buildingId, float rotationDeg);
87
89 static void effectiveFootprint(const BuildingDefinition &def, float rotationDeg, int *outW,
90 int *outH);
91
93 static bool foreachFootprintCell(const BuildingDefinition &def, int originCellX,
94 int originCellY, float rotationDeg,
95 const std::function<bool(int cx, int cy)> &fn);
96
97 static bool canPlace(PlacementWorld *world, const std::string &buildingId, int cellX, int cellY,
98 float rotationDeg = 0.f, int excludeInstanceId = 0,
99 std::string *reason = nullptr);
101 static bool canPlaceElev(PlacementWorld *world, const std::string &buildingId, int cellX,
102 int cellY, float elevation, float rotationDeg = 0.f,
103 int excludeInstanceId = 0, std::string *reason = nullptr);
104
106 static int placeAt(PlacementWorld *world, const std::string &buildingId, int cellX, int cellY,
107 float rotationDeg = 0.f);
109 static int placeAtWorld(PlacementWorld *world, const std::string &buildingId, float worldX,
110 float worldY, float rotationDeg = 0.f);
112 static int placeAtWorld3D(PlacementWorld *world, const std::string &buildingId, float worldX,
113 float worldY, float worldZ, float rotationDeg = 0.f);
114 static int placeGhost(PlacementWorld *world, Ghost *ghost);
115
116 static bool removeBuilding(PlacementWorld *world, int instanceId);
117 static bool moveBuilding(PlacementWorld *world, int instanceId, int cellX, int cellY,
118 float rotationDeg = -1.f);
119 static void clearBuildings(PlacementWorld *world);
120
121 static void pushEvent(BuildingChangeEvent ev);
122 static void pollEvents(std::vector<BuildingChangeEvent> &out);
123 static void clearEvents();
124 static const std::vector<BuildingChangeEvent> &events();
125
126 static int nextInstanceId();
127
128private:
129 static bool runValidate(const PlacementWorld &world, const BuildingDefinition &def,
130 const PlacementQuery &q, std::string *reason);
131 static bool checkBoundsAndOccupancy(const PlacementWorld &world, const BuildingDefinition &def,
132 const PlacementQuery &q, bool checkOccupancy,
133 std::string *reason);
134 static bool checkTerrain(const PlacementWorld &world, const BuildingDefinition &def,
135 const PlacementQuery &q, std::string *reason);
136 static bool checkAdjacency(const PlacementWorld &world, const BuildingDefinition &def,
137 const PlacementQuery &q, std::string *reason);
138 static void writeOccupancy(PlacementWorld &world, const BuildingDefinition &def,
139 const PlacedBuilding &placed, int instanceId);
140 static void clearOccupancy(PlacementWorld &world, int instanceId);
141 static void emit(BuildingChangeEvent ev);
142
143 static std::unordered_map<std::string, ValidateFn> &validateRules();
144 static std::unordered_map<std::string, SnapFn> &snapRules();
145 static std::unordered_map<std::string, ChangeHook> &changeHooks();
146 static std::unordered_map<std::string, SurfaceFn> &surfaces();
147 static float &planeSurfaceHeight();
148 static std::vector<BuildingChangeEvent> &eventQueue();
149 static int &instanceCounter();
150 static bool &builtinsReady();
151
152 PlacementSystem() = default;
153 ~PlacementSystem() = default;
154 PlacementSystem(const PlacementSystem &) = delete;
155 PlacementSystem &operator=(const PlacementSystem &) = delete;
156
157 std::unordered_map<std::string, ValidateFn> validateRules_;
158 std::unordered_map<std::string, SnapFn> snapRules_;
159 std::unordered_map<std::string, ChangeHook> changeHooks_;
160 std::unordered_map<std::string, SurfaceFn> surfaces_;
161 std::vector<BuildingChangeEvent> eventQueue_;
162 int instanceCounter_ = 0;
163 bool builtinsReady_ = false;
164 float planeSurfaceHeight_ = 0.f;
165};
166
167} // namespace eve::building
float cx
Definition CardTypes.cpp:31
float cy
Definition CardTypes.cpp:32
int y
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
int h
const char * name
Definition RockMesh.cpp:21
SettlementPipeline::Stage fn
std::function< bool(const PlacementWorld &world, const PlacementQuery &q, std::string *reason)> ValidateFn
static SnapResult snap(const PlacementWorld &world, const std::string &buildingId, float worldX, float worldY)
static void effectiveFootprint(const BuildingDefinition &def, float rotationDeg, int *outW, int *outH)
旋转后的占地宽高(cardinal 90/270 交换)。
static int placeAt(PlacementWorld *world, const std::string &buildingId, int cellX, int cellY, float rotationDeg=0.f)
成功返回 instanceId;失败返回 0。
std::function< bool(const PlacementWorld &world, float x, float y, PlacementHit *hit)> SurfaceFn
static std::vector< std::string > surfaceNames()
static void registerSurface(const std::string &name, SurfaceFn fn)
static int placeAtWorld3D(PlacementWorld *world, const std::string &buildingId, float worldX, float worldY, float worldZ, float rotationDeg=0.f)
static SnapResult snap3D(const PlacementWorld &world, const std::string &buildingId, float worldX, float worldY, float worldZ)
static PlacementSystem & inst()
Process singleton holding all PlacementSystem state.
static const std::vector< BuildingChangeEvent > & events()
static bool surfaceHit(const PlacementWorld &world, const std::string &name, float x, float y, PlacementHit *hit)
static void clearBuildings(PlacementWorld *world)
std::function< SnapResult(const PlacementWorld &world, float worldX, float worldY)> SnapFn
static void unregisterChangeHook(const std::string &name)
static void setPlaneSurfaceHeight(float h)
static void ensureBuiltins()
确保内置规则已注册(模块首次使用时自动调用)。
static bool hasSurface(const std::string &name)
std::function< void(const BuildingChangeEvent &ev)> ChangeHook
static void pushEvent(BuildingChangeEvent ev)
static bool foreachFootprintCell(const BuildingDefinition &def, int originCellX, int originCellY, float rotationDeg, const std::function< bool(int cx, int cy)> &fn)
枚举占地格子(旋转后局部 → 世界格子)。返回 false 若定义未知。
static float normalizeRotation(const std::string &buildingId, float rotationDeg)
规范化旋转角(cardinal → 0/90/180/270;none → 0)。
static bool removeBuilding(PlacementWorld *world, int instanceId)
static bool hasSnapRule(const std::string &name)
static void unregisterSurface(const std::string &name)
static bool moveBuilding(PlacementWorld *world, int instanceId, int cellX, int cellY, float rotationDeg=-1.f)
static bool hasChangeHook(const std::string &name)
static int placeAtWorld(PlacementWorld *world, const std::string &buildingId, float worldX, float worldY, float rotationDeg=0.f)
先吸附再放置;free/自定义 snap 会保留吸附后的世界坐标。
static void registerSnapRule(const std::string &name, SnapFn fn)
static bool hasValidateRule(const std::string &name)
static int placeGhost(PlacementWorld *world, Ghost *ghost)
static bool canPlaceElev(PlacementWorld *world, const std::string &buildingId, int cellX, int cellY, float elevation, float rotationDeg=0.f, int excludeInstanceId=0, std::string *reason=nullptr)
static void pollEvents(std::vector< BuildingChangeEvent > &out)
static void unregisterValidateRule(const std::string &name)
static void unregisterSnapRule(const std::string &name)
static bool canPlace(PlacementWorld *world, const std::string &buildingId, int cellX, int cellY, float rotationDeg=0.f, int excludeInstanceId=0, std::string *reason=nullptr)
static void registerChangeHook(const std::string &name, ChangeHook fn)
static SnapResult snapWithMode(const PlacementWorld &world, const std::string &mode, float worldX, float worldY)
static void registerValidateRule(const std::string &name, ValidateFn fn)
格子型建筑放置世界(脚本可直接操作)。
建筑放置模块入口:定义 / 放置世界 / 鬼影 / 变更事件的脚本绑定点。 设计文档:docs/dev/建筑放置系统设计.md
Definition Building.cpp:7
一次成功放置变更的事件(供脚本 poll / C++ hook)。
建筑模板(进程级注册表中的定义)。
已放置的建筑实例。
校验上下文:传给可插拔规则。