载入中...
搜索中...
未找到
TileLayer.cpp
浏览该文件的文档.
1#include "map/TileLayer.h"
2#include "map/TileConfig.h"
4
5#include "graphics/Canvas.h"
6#include "graphics/Texture.h"
7
8#include <algorithm>
9#include <cstdlib>
10#include <sstream>
11
12namespace eve::map {
13
14TileLayer *TileLayer::createLayer(int mapW, int mapH, float tileW, float tileH) {
15 TileLayer *e = TileLayer::create();
16 e->config()->entity = e;
17 e->resize(mapW, mapH);
19 auto ts = e->tileset();
20 ts->tileW = int(tileW > 0.f ? tileW : 32.f);
21 ts->tileH = int(tileH > 0.f ? tileH : 32.f);
22 (void)e->draw();
23 (void)e->resource();
24 return e;
25}
26
27void TileLayer::setOrigin(float x, float y) {
28 config()->originX = x;
29 config()->originY = y;
30}
31
32float TileLayer::getX() { return config()->originX; }
33float TileLayer::getY() { return config()->originY; }
34
35int TileLayer::getMapWidth() { return config()->mapW; }
36int TileLayer::getMapHeight() { return config()->mapH; }
37float TileLayer::getTileWidth() { return config()->tileW; }
38float TileLayer::getTileHeight() { return config()->tileH; }
39
41 auto c = config();
42 c->tileW = tileW > 0.f ? tileW : 1.f;
43 c->tileH = tileH > 0.f ? tileH : 1.f;
44}
45
46void TileLayer::resize(int mapW, int mapH) {
47 auto c = config();
48 c->mapW = mapW > 0 ? mapW : 0;
49 c->mapH = mapH > 0 ? mapH : 0;
50 const size_t n = size_t(std::max(0, c->mapW) * std::max(0, c->mapH));
51 tiles()->gids.assign(n, 0u);
52 tiles()->terrainIds.assign(n, -1);
54}
55
56void TileLayer::setTile(int tx, int ty, int gid) {
57 auto c = config();
58 if (tx < 0 || ty < 0 || tx >= c->mapW || ty >= c->mapH) return;
59 auto t = tiles();
60 const size_t index = size_t(ty * c->mapW + tx);
61 const uint32_t next = uint32_t(gid);
62 const bool wasEmpty = tileGid(t->gids[index]) == 0;
63 const bool isEmpty = tileGid(next) == 0;
64 if (t->gids[index] == next) return;
65 t->gids[index] = next;
66 const int chunkIndex = (ty / Tiles::kChunkSize) * t->chunkColumns + tx / Tiles::kChunkSize;
67 if (chunkIndex >= 0 && chunkIndex < int(t->chunks.size()) && wasEmpty != isEmpty)
68 t->chunks[size_t(chunkIndex)].nonEmpty += isEmpty ? -1 : 1;
69 ++t->revision;
70}
71
72int TileLayer::getTile(int tx, int ty) {
73 auto c = config();
74 if (tx < 0 || ty < 0 || tx >= c->mapW || ty >= c->mapH) return 0;
75 return int(tiles()->gids[size_t(ty * c->mapW + tx)]);
76}
77
78void TileLayer::fillRect(int x, int y, int width, int height, int gid) {
79 auto c = config();
80 if (width <= 0 || height <= 0 || c->mapW <= 0 || c->mapH <= 0) return;
81 const int x0 = std::max(0, x);
82 const int y0 = std::max(0, y);
83 const int x1 = std::min(c->mapW, x + width);
84 const int y1 = std::min(c->mapH, y + height);
85 if (x0 >= x1 || y0 >= y1) return;
86 const uint32_t next = uint32_t(gid);
87 bool changed = false;
88 auto t = tiles();
89 for (int ty = y0; ty < y1; ++ty) {
90 for (int tx = x0; tx < x1; ++tx) {
91 const size_t index = size_t(ty * c->mapW + tx);
92 if (t->gids[index] == next) continue;
93 t->gids[index] = next;
94 changed = true;
95 }
96 }
97 if (changed) {
99 }
100}
101
102void TileLayer::fill(int gid) {
103 const uint32_t g = uint32_t(gid);
104 auto t = tiles();
105 bool changed = false;
106 for (auto &v : t->gids) {
107 if (v != g) changed = true;
108 v = g;
109 }
110 if (changed) {
112 }
113}
114
115void TileLayer::clear() { fill(0); }
116
117int TileLayer::getRevision() { return int(tiles()->revision & 0x7fffffffu); }
119int TileLayer::getChunkCount() { return int(tiles()->chunks.size()); }
121 int count = 0;
122 for (const auto &chunk : tiles()->chunks)
123 if (chunk.nonEmpty > 0) ++count;
124 return count;
125}
126
128 auto c = config();
129 auto t = tiles();
130 t->chunkColumns = (c->mapW + Tiles::kChunkSize - 1) / Tiles::kChunkSize;
131 t->chunkRows = (c->mapH + Tiles::kChunkSize - 1) / Tiles::kChunkSize;
132 t->chunks.assign(size_t(t->chunkColumns * t->chunkRows), {});
133 for (int y = 0; y < c->mapH; ++y) {
134 for (int x = 0; x < c->mapW; ++x) {
135 const size_t index = size_t(y * c->mapW + x);
136 if (index >= t->gids.size() || tileGid(t->gids[index]) == 0) continue;
137 const int chunkIndex = (y / Tiles::kChunkSize) * t->chunkColumns + x / Tiles::kChunkSize;
138 ++t->chunks[size_t(chunkIndex)].nonEmpty;
139 }
140 }
141 ++t->revision;
142}
143
145 auto &animations = tileset()->animations;
146 animations.erase(std::remove_if(animations.begin(), animations.end(),
147 [gid](const Tileset::Animation &a) { return a.gid == gid; }),
148 animations.end());
149}
150
151void TileLayer::addTileAnimationFrame(int gid, int frameGid, int durationMs) {
152 if (gid <= 0 || frameGid <= 0) return;
153 auto &animations = tileset()->animations;
154 auto it = std::find_if(animations.begin(), animations.end(),
155 [gid](const Tileset::Animation &a) { return a.gid == gid; });
156 if (it == animations.end()) {
157 animations.push_back({});
158 it = animations.end() - 1;
159 it->gid = gid;
160 }
161 it->frames.push_back({frameGid, std::max(1, durationMs)});
162}
163
165 for (const auto &animation : tileset()->animations)
166 if (animation.gid == gid) return int(animation.frames.size());
167 return 0;
168}
169
170namespace {
171TileLayer::Tileset::CustomData *findCustomData(TileLayer::Tileset &tileset, int gid,
172 const std::string &name) {
173 for (auto &entry : tileset.customData)
174 if (entry.gid == gid && entry.name == name) return &entry;
175 tileset.customData.push_back({gid, name, {}, {}});
176 return &tileset.customData.back();
177}
178
179const TileLayer::Tileset::CustomData *findCustomData(const TileLayer::Tileset &tileset, int gid,
180 const std::string &name) {
181 for (const auto &entry : tileset.customData)
182 if (entry.gid == gid && entry.name == name) return &entry;
183 return nullptr;
184}
185} // namespace
186
187void TileLayer::setTileDataString(int gid, const std::string &name, const std::string &value) {
188 if (gid <= 0 || name.empty()) return;
189 auto *entry = findCustomData(*tileset(), gid, name);
190 entry->type = "string";
191 entry->value = value;
192}
193
194void TileLayer::setTileDataNumber(int gid, const std::string &name, float value) {
195 if (gid <= 0 || name.empty()) return;
196 auto *entry = findCustomData(*tileset(), gid, name);
197 entry->type = "number";
198 std::ostringstream out;
199 out << value;
200 entry->value = out.str();
201}
202
203void TileLayer::setTileDataBool(int gid, const std::string &name, bool value) {
204 if (gid <= 0 || name.empty()) return;
205 auto *entry = findCustomData(*tileset(), gid, name);
206 entry->type = "bool";
207 entry->value = value ? "true" : "false";
208}
209
210std::string TileLayer::getTileDataType(int gid, const std::string &name) {
211 const auto *entry = findCustomData(*tileset(), gid, name);
212 return entry ? entry->type : std::string();
213}
214
215std::string TileLayer::getTileDataString(int gid, const std::string &name) {
216 const auto *entry = findCustomData(*tileset(), gid, name);
217 return entry ? entry->value : std::string();
218}
219
220float TileLayer::getTileDataNumber(int gid, const std::string &name) {
221 const auto *entry = findCustomData(*tileset(), gid, name);
222 return entry && (entry->type == "number" || entry->type == "float" || entry->type == "int")
223 ? std::strtof(entry->value.c_str(), nullptr)
224 : 0.f;
225}
226
227bool TileLayer::getTileDataBool(int gid, const std::string &name) {
228 const auto *entry = findCustomData(*tileset(), gid, name);
229 return entry && entry->type == "bool" && entry->value == "true";
230}
231
232void TileLayer::setTerrainRule(int gid, int terrain, int neighborMask) {
233 setAutotileRule(gid, terrain, neighborMask, 1);
234}
235
236void TileLayer::defineAutotileFamily(int terrain, const std::string &kind, int seed) {
237 if (terrain < 0) return;
238 const std::string normalized = (kind == "shore" || kind == "wall" || kind == "waterfall") ? kind : "terrain";
239 auto ts = tileset();
240 auto it = std::find_if(ts->terrainFamilies.begin(), ts->terrainFamilies.end(),
241 [terrain](const Tileset::TerrainFamily &family) { return family.terrain == terrain; });
242 if (it == ts->terrainFamilies.end())
243 ts->terrainFamilies.push_back({terrain, normalized, uint32_t(seed)});
244 else {
245 it->kind = normalized;
246 it->seed = uint32_t(seed);
247 }
248 ++tiles()->revision;
249}
250
251void TileLayer::setAutotileRule(int gid, int terrain, int neighborMask, int weight) {
252 if (gid <= 0 || terrain < 0) return;
253 auto &rules = tileset()->terrainRules;
254 auto it = std::find_if(rules.begin(), rules.end(), [=](const Tileset::TerrainRule &rule) {
255 return rule.gid == gid && rule.terrain == terrain && rule.neighborMask == (neighborMask & 0xff);
256 });
257 if (it == rules.end())
258 rules.push_back({gid, terrain, neighborMask & 0xff, std::max(1, weight)});
259 else
260 it->weight = std::max(1, weight);
261 ++tiles()->revision;
262}
263
265 tileset()->terrainRules.clear();
266 tileset()->terrainFamilies.clear();
267 ++tiles()->revision;
268}
269
270int TileLayer::getTerrain(int x, int y) {
271 auto c = config();
272 auto t = tiles();
273 if (x < 0 || y < 0 || x >= c->mapW || y >= c->mapH) return -1;
274 const size_t index = size_t(y * c->mapW + x);
275 return index < t->terrainIds.size() ? t->terrainIds[index] : -1;
276}
277
278namespace {
279uint32_t autotileHash(uint32_t seed, int terrain, int x, int y) {
280 uint32_t value = seed ^ uint32_t(terrain) * 0x9e3779b9u;
281 value ^= uint32_t(x) * 0x85ebca6bu;
282 value ^= uint32_t(y) * 0xc2b2ae35u;
283 value ^= value >> 16;
284 value *= 0x7feb352du;
285 value ^= value >> 15;
286 return value;
287}
288
289void resolveTerrainRegion(TileLayer *layer, int x0, int y0, int x1, int y1) {
290 auto c = layer->config();
291 auto t = layer->tiles();
292 auto ts = layer->tileset();
293 constexpr int dx[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
294 constexpr int dy[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
295 for (int cy = std::max(0, y0); cy <= std::min(c->mapH - 1, y1); ++cy) {
296 for (int cx = std::max(0, x0); cx <= std::min(c->mapW - 1, x1); ++cx) {
297 const size_t cell = size_t(cy * c->mapW + cx);
298 const int terrain = cell < t->terrainIds.size() ? t->terrainIds[cell] : -1;
299 // Manual tiles have no terrain owner. Only explicit terrain erasure
300 // may clear them; resolving a neighbor must preserve their GID.
301 if (terrain < 0) continue;
302 int mask = 0;
303 for (int i = 0; i < 8; ++i) {
304 const int nx = cx + dx[i], ny = cy + dy[i];
305 if (nx < 0 || ny < 0 || nx >= c->mapW || ny >= c->mapH) continue;
306 if (t->terrainIds[size_t(ny * c->mapW + nx)] == terrain) mask |= 1 << i;
307 }
308 uint32_t seed = 0;
309 int relevantMask = 0xff;
310 const auto family = std::find_if(
311 ts->terrainFamilies.begin(), ts->terrainFamilies.end(),
312 [terrain](const TileLayer::Tileset::TerrainFamily &candidate) { return candidate.terrain == terrain; });
313 if (family != ts->terrainFamilies.end()) {
314 seed = family->seed;
315 if (family->kind == "wall")
316 relevantMask = 0xaa;
317 else if (family->kind == "waterfall")
318 relevantMask = 0x22;
319 }
320 const int exactMask = mask & relevantMask;
321 int totalWeight = 0;
322 for (const auto &rule : ts->terrainRules)
323 if (rule.terrain == terrain && (rule.neighborMask & relevantMask) == exactMask)
324 totalWeight += std::max(1, rule.weight);
325 if (totalWeight <= 0) continue;
326 int pick = int(autotileHash(seed, terrain, cx, cy) % uint32_t(totalWeight));
327 for (const auto &rule : ts->terrainRules) {
328 if (rule.terrain != terrain || (rule.neighborMask & relevantMask) != exactMask) continue;
329 pick -= std::max(1, rule.weight);
330 if (pick < 0) {
331 t->gids[cell] = uint32_t(rule.gid);
332 break;
333 }
334 }
335 }
336 }
338}
339} // namespace
340
341void TileLayer::paintTerrain(int x, int y, int terrain) {
342 auto c = config();
343 auto t = tiles();
344 if (x < 0 || y < 0 || x >= c->mapW || y >= c->mapH || terrain < 0) return;
345 if (t->terrainIds.size() != t->gids.size()) t->terrainIds.assign(t->gids.size(), -1);
346 t->terrainIds[size_t(y * c->mapW + x)] = terrain;
347 resolveTerrainRegion(this, x - 1, y - 1, x + 1, y + 1);
348}
349
350void TileLayer::paintTerrainRect(int x, int y, int width, int height, int terrain) {
351 auto c = config();
352 auto t = tiles();
353 if (width <= 0 || height <= 0 || terrain < 0) return;
354 if (t->terrainIds.size() != t->gids.size()) t->terrainIds.assign(t->gids.size(), -1);
355 const int x0 = std::max(0, x), y0 = std::max(0, y);
356 const int x1 = std::min(c->mapW, x + width), y1 = std::min(c->mapH, y + height);
357 if (x0 >= x1 || y0 >= y1) return;
358 for (int cy = y0; cy < y1; ++cy)
359 for (int cx = x0; cx < x1; ++cx) t->terrainIds[size_t(cy * c->mapW + cx)] = terrain;
360 resolveTerrainRegion(this, x0 - 1, y0 - 1, x1, y1);
361}
362
364 if (terrain < 0) return;
365 auto t = tiles();
366 t->terrainIds.assign(t->gids.size(), terrain);
367 resolveTerrainRegion(this, 0, 0, config()->mapW - 1, config()->mapH - 1);
368}
369
370void TileLayer::eraseTerrainRect(int x, int y, int width, int height) {
371 auto c = config();
372 auto t = tiles();
373 if (width <= 0 || height <= 0) return;
374 if (t->terrainIds.size() != t->gids.size()) t->terrainIds.assign(t->gids.size(), -1);
375 const int x0 = std::max(0, x), y0 = std::max(0, y);
376 const int x1 = std::min(c->mapW, x + width), y1 = std::min(c->mapH, y + height);
377 if (x0 >= x1 || y0 >= y1) return;
378 for (int cy = y0; cy < y1; ++cy)
379 for (int cx = x0; cx < x1; ++cx) {
380 const size_t cell = size_t(cy * c->mapW + cx);
381 t->terrainIds[cell] = -1;
382 t->gids[cell] = 0;
383 }
384 resolveTerrainRegion(this, x0 - 1, y0 - 1, x1, y1);
385}
386
388 int spacing) {
389 auto ts = tileset();
390 ts->visuals.clear();
391 ts->animations.clear();
392 ts->terrainRules.clear();
393 ts->terrainFamilies.clear();
394 ts->customData.clear();
395 ts->atlases.clear();
396 ts->texture = texture;
397 ts->firstGid = firstGid > 0 ? firstGid : 1;
398 ts->columns = columns > 0 ? columns : 1;
399 ts->margin = margin > 0 ? margin : 0;
400 ts->spacing = spacing > 0 ? spacing : 0;
401 ts->atlases.push_back(
402 {texture, ts->firstGid, ts->columns, ts->tileW, ts->tileH, ts->margin, ts->spacing, resource()->texturePath});
403 if (texture) {
404 // Default atlas tile size from Config when not set yet.
405 if (ts->tileW <= 0) ts->tileW = int(config()->tileW);
406 if (ts->tileH <= 0) ts->tileH = int(config()->tileH);
407 }
408}
409
411 auto ts = tileset();
412 ts->tileW = tileW > 0 ? tileW : 1;
413 ts->tileH = tileH > 0 ? tileH : 1;
414 if (!ts->atlases.empty()) {
415 ts->atlases.front().tileW = ts->tileW;
416 ts->atlases.front().tileH = ts->tileH;
417 }
418}
419
420void TileLayer::setCellGap(float gapX, float gapY) {
421 config()->cellGapX = std::max(gapX, -config()->tileW + 0.001f);
422 config()->cellGapY = std::max(gapY, -config()->tileH + 0.001f);
423}
424
425void TileLayer::setRenderSpacing(float spacingX, float spacingY) {
426 config()->cellGapX = config()->tileW * (std::max(spacingX, 0.001f) - 1.f);
427 config()->cellGapY = config()->tileH * (std::max(spacingY, 0.001f) - 1.f);
428}
429
430float TileLayer::getCellGapX() { return config()->cellGapX; }
431float TileLayer::getCellGapY() { return config()->cellGapY; }
433 return config()->tileW != 0.f ? 1.f + config()->cellGapX / config()->tileW : 1.f;
434}
436 return config()->tileH != 0.f ? 1.f + config()->cellGapY / config()->tileH : 1.f;
437}
438
439void TileLayer::setVisualScale(float scaleX, float scaleY) {
440 draw()->visualScaleX = scaleX > 0.f ? scaleX : 1.f;
441 draw()->visualScaleY = scaleY > 0.f ? scaleY : 1.f;
442}
443
444float TileLayer::getVisualScaleX() { return draw()->visualScaleX; }
445float TileLayer::getVisualScaleY() { return draw()->visualScaleY; }
446
447void TileLayer::setTileVisual(int gid, int x, int y, int width, int height, float pivotX,
448 float pivotY, float sortBias) {
449 if (gid <= 0 || width <= 0 || height <= 0) return;
450 auto &visuals = tileset()->visuals;
451 auto it = std::find_if(visuals.begin(), visuals.end(),
452 [gid](const Tileset::Visual &v) { return v.gid == gid; });
453 if (it == visuals.end()) {
454 visuals.push_back({});
455 it = visuals.end() - 1;
456 it->gid = gid;
457 }
458 it->x = x;
459 it->y = y;
460 it->width = width;
461 it->height = height;
462 it->pivotX = pivotX;
463 it->pivotY = pivotY;
464 it->sortBias = sortBias;
465}
466
468 tileset()->visuals.clear();
469 ++tiles()->revision;
470}
471
472int TileLayer::getTileVisualCount() { return int(tileset()->visuals.size()); }
473
474void TileLayer::setTileMetadata(int gid, int footprintW, int footprintH, bool walkable,
475 float cost) {
476 if (gid <= 0) return;
477 auto &visuals = tileset()->visuals;
478 auto it = std::find_if(visuals.begin(), visuals.end(),
479 [gid](const Tileset::Visual &v) { return v.gid == gid; });
480 if (it == visuals.end()) {
481 visuals.push_back({});
482 it = visuals.end() - 1;
483 it->gid = gid;
484 }
485 it->footprintW = std::max(1, footprintW);
486 it->footprintH = std::max(1, footprintH);
487 it->walkable = walkable;
488 it->cost = cost > 0.f ? cost : 1.f;
489 ++tiles()->revision;
490}
491
492void TileLayer::setTileNavigationProfile(int gid, bool walkable, float cost, int enterMask, int exitMask, bool opaque,
493 int semanticFlags) {
494 if (gid <= 0) return;
495 auto ts = tileset();
496 auto it = std::find_if(ts->visuals.begin(), ts->visuals.end(),
497 [gid](const Tileset::Visual &visual) { return visual.gid == gid; });
498 if (it == ts->visuals.end()) {
499 ts->visuals.push_back({});
500 it = ts->visuals.end() - 1;
501 it->gid = gid;
502 }
503 it->walkable = walkable;
504 it->cost = std::max(0.001f, cost);
505 it->enterMask = uint8_t(enterMask & 0xff);
506 it->exitMask = uint8_t(exitMask & 0xff);
507 it->opaque = opaque;
508 it->semanticFlags = uint32_t(semanticFlags);
509 ++tiles()->revision;
510}
511
512bool TileLayer::loadTilesetManifest(const std::string &path) {
513 return loadTilesetManifestFile(this, path, nullptr);
514}
515
517int TileLayer::getTilesetFirstGid() { return tileset()->firstGid; }
518int TileLayer::getTilesetColumns() { return tileset()->columns; }
519
520void TileLayer::setCanvas(graphics::Canvas *canvas) { draw()->canvas = canvas; }
522
523void TileLayer::setLayer(int layer) { draw()->layer = layer; }
524int TileLayer::getLayer() { return draw()->layer; }
525
526void TileLayer::setVisible(bool visible) { draw()->visible = visible; }
527bool TileLayer::isVisible() { return draw()->visible; }
528
529void TileLayer::setReceiveLight(bool receive) { draw()->receiveLight = receive; }
530bool TileLayer::getReceiveLight() { return draw()->receiveLight; }
531
532void TileLayer::setTint(float r, float g, float b, float a) {
533 draw()->tint = Color{r, g, b, a};
534}
535
536bool TileLayer::applyConfig(const std::string &json) { return applyConfigText(this, json, nullptr); }
537
538bool TileLayer::loadConfig(const std::string &path) { return loadConfigFile(this, path, nullptr); }
539
540bool TileLayer::reloadConfig() { return reloadConfigFile(this, nullptr); }
541
542void TileLayer::setAutoReload(bool enable) { resource()->autoReload = enable; }
543bool TileLayer::getAutoReload() { return resource()->autoReload; }
544std::string TileLayer::getConfigPath() { return resource()->path; }
545
546void TileLayer::tileToWorld(int tx, int ty, float &wx, float &wy) {
547 eve::map::tileToWorld(*config(), tx, ty, wx, wy);
548}
549
550float TileLayer::depthY(int tx, int ty) { return tileToDepthY(*config(), tx, ty); }
551
552void TileLayer::worldToTile(float wx, float wy, int &tx, int &ty) {
553 eve::map::worldToTile(*config(), wx, wy, tx, ty);
554}
555
556float TileLayer::tileToWorldX(int tx, int ty) {
557 float wx = 0.f, wy = 0.f;
558 tileToWorld(tx, ty, wx, wy);
559 return wx;
560}
561
562float TileLayer::tileToWorldY(int tx, int ty) {
563 float wx = 0.f, wy = 0.f;
564 tileToWorld(tx, ty, wx, wy);
565 return wy;
566}
567
568float TileLayer::depthYAt(int tx, int ty) { return depthY(tx, ty); }
569
570int TileLayer::worldToTileX(float wx, float wy) {
571 int tx = 0, ty = 0;
572 worldToTile(wx, wy, tx, ty);
573 return tx;
574}
575
576int TileLayer::worldToTileY(float wx, float wy) {
577 int tx = 0, ty = 0;
578 worldToTile(wx, wy, tx, ty);
579 return ty;
580}
581
582} // namespace eve::map
double value
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
std::string terrain
int mask
float cx
Definition CardTypes.cpp:33
float cy
Definition CardTypes.cpp:34
float nx
float ny
eve::resource::CostSpec cost
tensor::Graph g
Definition GpuGraph.cpp:7
float camera[2]
float u
Definition Grass.cpp:233
glm::vec3 n
Definition Grass.cpp:63
double r
float v
std::int32_t c
std::uint32_t height
std::uint32_t width
TokenKind kind
std::string name
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
MeshVfxBatchedDraw draw
std::vector< uint8_t > exitMask
TileLayer * layer
std::vector< uint8_t > enterMask
std::uint64_t revision
std::string path
Definition PlayHost.cpp:110
std::uint32_t seed
Definition PointSet.cpp:807
float t
std::string resource
float dy
float dx
std::uint32_t count
Cell cell
double spacingX
int spacing
int firstGid
std::vector< TileLayer::Tileset::TerrainRule > terrainRules
int columns
std::vector< TileLayer::Tileset::CustomData > customData
std::vector< TileLayer::Tileset::Visual > visuals
int tileW
int margin
int tileH
bool visible
std::vector< TileLayer::Tileset::Animation > animations
uint32_t index
std::vector< WfcTile > tiles
Definition WfcSimple.cpp:22
float wx
float wy
Declarative 2D camera (viewport center + zoom).
Canvas public API.
Definition Canvas.h:17
GPU texture created via Graphics::newTexture. Owns GPU resources through an opaque backend handle.
Definition Texture.h:18
ECS tile layer entity. Script mutates tile GIDs / tileset / draw; TileRenderSystem batch-draws atlas ...
Definition TileLayer.h:32
void setVisualScale(float scaleX, float scaleY)
Scales atlas-pixel tile visuals into world units when drawing.
std::string getConfigPath()
Path of the bound config file.
void clearTileAnimation(int gid)
TileSet v2 animation authoring; frames are selected during map update/render.
int getTileVisualCount()
Number of irregular visual records.
void setTileDataBool(int gid, const std::string &name, bool value)
void clear()
Clears the layer to empty.
void setReceiveLight(bool receive)
Enable Light2D shading for this layer's tiles.
float getTileWidth()
Tile size in pixels.
Definition TileLayer.cpp:37
void eraseTerrainRect(int x, int y, int width, int height)
Erases logical terrain and visual GIDs in a clipped rectangle.
std::string getTileDataString(int gid, const std::string &name)
void setCellGap(float gapX, float gapY)
Sets extra world-space distance between projected cells.
void setTileDataNumber(int gid, const std::string &name, float value)
graphics::Texture * getTilesetTexture()
Bound tileset accessors.
float getTileDataNumber(int gid, const std::string &name)
void rebuildSpatialIndex()
Rebuild chunk occupancy after bulk loader writes directly to gids.
void setOrigin(float x, float y)
World origin of the layer (pixels).
Definition TileLayer.cpp:27
float getVisualScaleX()
Current horizontal visual-to-world scale.
void setTileVisual(int gid, int x, int y, int width, int height, float pivotX, float pivotY, float sortBias=0.f)
Defines or replaces one irregular atlas region.
bool loadConfig(const std::string &path)
Loads a config file and binds it for hot reload.
int worldToTileX(float wx, float wy)
void setTile(int tx, int ty, int gid)
Tile GID access; 0 = empty.
Definition TileLayer.cpp:56
void setAutoReload(bool enable)
Enables/disables automatic config hot reload.
void clearTileVisuals()
Removes all irregular per-GID visual metadata.
float getVisualScaleY()
Current vertical visual-to-world scale.
void setTileset(graphics::Texture *texture, int firstGid, int columns, int margin=0, int spacing=0)
Binds the atlas texture and tile table.
void setTileNavigationProfile(int gid, bool walkable, float cost, int enterMask, int exitMask, bool opaque, int semanticFlags=0)
Sets canonical navigation, collision and visibility metadata for one GID.
void addTileAnimationFrame(int gid, int frameGid, int durationMs)
void resize(int mapW, int mapH)
Resizes the tile grid (existing GIDs preserved where possible).
Definition TileLayer.cpp:46
bool getTileDataBool(int gid, const std::string &name)
void setRenderSpacing(float spacingX, float spacingY)
Sets projected cell pitch as a multiple of the logical tile size.
bool applyConfig(const std::string &json)
Applies a map JSON config (Config + Tiles + Tileset + Draw).
void setTilesetTileSize(int tileW, int tileH)
Tile size in pixels of the bound tileset.
void setLayer(int layer)
Draw order layer / visibility / tint.
int worldToTileY(float wx, float wy)
bool loadTilesetManifest(const std::string &path)
Loads an extensible TileSet manifest without changing map cell data.
void setCamera(graphics::Camera2D *camera)
int getChunkSize()
Runtime spatial-index diagnostics.
void paintTerrain(int x, int y, int terrain)
int getTile(int tx, int ty)
Definition TileLayer.cpp:72
bool reloadConfig()
Re-reads the bound config file (hot reload).
static TileLayer * createLayer(int mapW, int mapH, float tileW=32.f, float tileH=32.f)
Definition TileLayer.cpp:14
int getRevision()
Monotonic tile-data revision used by derived navigation/FOV caches.
void setTileMetadata(int gid, int footprintW, int footprintH, bool walkable, float cost=1.f)
Configures gameplay metadata kept beside a visual record.
void paintTerrainRect(int x, int y, int width, int height, int terrain)
Paints a clipped rectangle and resolves one dirty-region revision.
int getTerrain(int x, int y)
float getCellGapX()
Horizontal and vertical world-space gaps between projected cells.
float tileToWorldX(int tx, int ty)
Scalar conversion helpers.
float depthY(int tx, int ty)
Painter's-algorithm depth for 2.5D draw ordering.
void worldToTile(float wx, float wy, int &tx, int &ty)
int getTileAnimationFrameCount(int gid)
void fillTerrain(int terrain)
Replaces every logical terrain cell and resolves the whole layer.
float depthYAt(int tx, int ty)
void setTileSize(float tileW, float tileH)
Definition TileLayer.cpp:40
void tileToWorld(int tx, int ty, float &wx, float &wy)
Tile-index ↔ world-pixel conversions (per layer orientation).
void setCanvas(graphics::Canvas *canvas)
Draw target canvas / camera.
bool getReceiveLight()
Whether this layer's tiles receive Light2D.
void defineAutotileFamily(int terrain, const std::string &kind, int seed=0)
Defines a deterministic resolver family: terrain, shore, wall or waterfall.
float getRenderSpacingX()
Horizontal and vertical projected pitch multipliers.
void setVisible(bool visible)
float tileToWorldY(int tx, int ty)
std::string getTileDataType(int gid, const std::string &name)
void fill(int gid)
Fills the whole layer with one GID.
void setTileDataString(int gid, const std::string &name, const std::string &value)
TileSet v2 typed custom data (stored losslessly as canonical text).
void setAutotileRule(int gid, int terrain, int neighborMask, int weight=1)
Adds an exact eight-neighbor rule with deterministic variant weight.
int getMapWidth()
Map dimensions in tiles.
Definition TileLayer.cpp:35
void setTint(float r, float g, float b, float a=1.f)
void setTerrainRule(int gid, int terrain, int neighborMask)
Register an 8-neighbor terrain rule and paint with local re-resolution.
void fillRect(int x, int y, int width, int height, int gid)
Fill a clipped rectangular region and publish one tile revision.
Definition TileLayer.cpp:78
放置世界:格子占用(多通道)+ 地形语义 + 已放置建筑实例。 行为由 PlacementSystem 提供;本类暴露便于脚本绑定的薄封装方法。 坐标换算统一走 eve::grid(支持 rectang...
bool loadTilesetManifestFile(TileLayer *layer, const std::string &path, std::string *error)
Load a composable TileSet manifest onto an existing layer.
bool reloadConfigFile(TileLayer *layer, std::string *error)
Reloads config file.
void worldToTile(const TileLayer::Config &cfg, float wx, float wy, int &tx, int &ty)
Converts world pixels back to the containing tile index.
bool applyConfigText(TileLayer *layer, const std::string &json, std::string *error)
Parse JSON text and apply onto one layer.
uint32_t tileGid(uint32_t raw)
Strip Tiled flip / rotate flags; keep low 28 bits.
Definition TileLayer.h:383
void tileToWorld(const TileLayer::Config &cfg, int tx, int ty, float &wx, float &wy)
Converts a tile index to world pixels using the layer's projection.
float tileToDepthY(const TileLayer::Config &cfg, int tx, int ty)
Painter's-algorithm depth for the tile under the layer's projection.
bool loadConfigFile(TileLayer *layer, const std::string &path, std::string *error)
Read path via Filesystem, apply onto layer, bind Resource.path + modtime for hot reload....
glm::vec4 Color
Render-neutral RGBA color shared by graphics-facing modules.
Definition RenderTypes.h:8
static constexpr int kChunkSize
Definition TileLayer.h:63
Versioned logical terrain family consumed by the canonical resolver.
Definition TileLayer.h:94
Per-GID visual metadata emitted by a project-defined asset pipeline.
Definition TileLayer.h:109
std::vector< TerrainFamily > terrainFamilies
Definition TileLayer.h:176
graphics::Texture * texture
Definition TileLayer.h:166
std::vector< TerrainRule > terrainRules
Definition TileLayer.h:175
std::vector< CustomData > customData
Definition TileLayer.h:177
std::vector< Visual > visuals
Definition TileLayer.h:173