18#include <simplesquirrel/simplesquirrel.hpp>
27void retireReplacedLayers(
const std::vector<TileLayer *> &
previous,
28 const std::vector<TileLayer *> &replacement) {
30 if (!
layer || std::find(replacement.begin(), replacement.end(),
layer) != replacement.end())
37void discardCandidateLayers(
const std::vector<TileLayer *> &layers) {
38 for (TileLayer *
layer : layers) {
56 if (!
layer)
return nullptr;
61 if (mapW <= 0 || mapH <= 0)
return nullptr;
66 if (!
layer)
return nullptr;
71 if (mapW <= 0 || mapH <= 0)
return nullptr;
72 return new Fov(mapW, mapH);
76 if (mapW <= 0 || mapH <= 0 ||
depth <= 0)
return nullptr;
81 std::vector<MapObject> objs;
83 if (layers.empty())
return nullptr;
84 retireReplacedLayers(loadedLayers_, layers);
86 loadedLayers_ = std::move(layers);
87 return loadedLayers_.front();
91 std::vector<MapObject> objs;
93 if (layers.empty())
return 0;
94 retireReplacedLayers(loadedLayers_, layers);
96 loadedLayers_ = std::move(layers);
97 return int(loadedLayers_.size());
107 std::vector<graphics::DrawItem2D> items;
122 collisionRects_.clear();
123 if (!
layer)
return 0;
124 const auto config =
layer->config();
126 const auto tileset =
layer->tileset();
129 std::vector<uint8_t> solid(
size_t(config->mapW * config->mapH), 0);
130 for (
int y = 0;
y < config->mapH; ++
y) {
131 for (
int x = 0;
x < config->mapW; ++
x) {
132 const int gid = int(
tileGid(
tiles->gids[
size_t(
y * config->mapW +
x)]));
133 const auto it = std::find_if(tileset->visuals.begin(), tileset->visuals.end(),
134 [gid](
const auto &
v) { return v.gid == gid; });
135 if (gid != 0 && it != tileset->visuals.end() && !it->collisionShapes.empty()) {
136 const float originX = config->originX +
x * (config->tileW + config->cellGapX);
137 const float originY = config->originY +
y * (config->tileH + config->cellGapY);
138 for (
const auto &
shape : it->collisionShapes)
141 solid[size_t(
y * config->mapW +
x)] = gid != 0 && it != tileset->visuals.end() && !it->walkable;
145 for (
int y = 0;
y < config->mapH; ++
y) {
146 for (
int x = 0;
x < config->mapW; ++
x) {
147 if (!solid[
size_t(
y * config->mapW +
x)])
continue;
149 while (
x + width < config->mapW && solid[
size_t(
y * config->mapW +
x +
width)])
153 while (
y + height < config->mapH && canGrow) {
155 if (!solid[
size_t((
y +
height) * config->mapW +
x +
dx)]) canGrow =
false;
160 solid[
size_t((
y +
dy) * config->mapW +
x +
dx)] = 0;
161 collisionRects_.push_back({config->originX +
x * (config->tileW + config->cellGapX),
162 config->originY +
y * (config->tileH + config->cellGapY),
163 width * (config->tileW + config->cellGapX),
164 height * (config->tileH + config->cellGapY)});
167 cap::forEach<ITileCollisionSink>([&](ITileCollisionSink *sink) {
168 sink->replaceTileCollision(
layer, collisionRects_.data(), collisionRects_.size());
170 return int(collisionRects_.size());
173int Map::getCollisionRectCount()
const {
return int(collisionRects_.size()); }
174float Map::getCollisionRectX(
int index)
const {
175 return index >= 0 &&
index < int(collisionRects_.size())
176 ? collisionRects_[size_t(
index)].x
179float Map::getCollisionRectY(
int index)
const {
180 return index >= 0 &&
index < int(collisionRects_.size())
181 ? collisionRects_[size_t(
index)].y
184float Map::getCollisionRectWidth(
int index)
const {
185 return index >= 0 &&
index < int(collisionRects_.size())
186 ? collisionRects_[size_t(
index)].width
189float Map::getCollisionRectHeight(
int index)
const {
190 return index >= 0 &&
index < int(collisionRects_.size())
191 ? collisionRects_[size_t(
index)].height
195int Map::getLayerCount()
const {
196 if (ecs::current()->getManager<TileLayer>() ==
nullptr)
return 0;
198 auto view = ecs::View<TileLayer, TileLayer::Config>();
199 for (
auto it =
view.begin(); it !=
view.end(); ++it) ++
n;
204 if (index < 0 || index >=
int(loadedLayers_.size()))
return nullptr;
205 return loadedLayers_[size_t(
index)];
208void Map::setObjects(std::vector<MapObject> objects) { objects_ = std::move(objects); }
210int Map::getObjectCount()
const {
return int(objects_.size()); }
212std::string Map::getObjectName(
int i)
const {
213 if (i < 0 || i >=
int(objects_.size()))
return {};
214 return objects_[size_t(i)].name;
217std::string Map::getObjectType(
int i)
const {
218 if (i < 0 || i >=
int(objects_.size()))
return {};
219 return objects_[size_t(i)].type;
222float Map::getObjectX(
int i)
const {
223 if (i < 0 || i >=
int(objects_.size()))
return 0.f;
224 return objects_[size_t(i)].x;
227float Map::getObjectY(
int i)
const {
228 if (i < 0 || i >=
int(objects_.size()))
return 0.f;
229 return objects_[size_t(i)].y;
232float Map::getObjectWidth(
int i)
const {
233 if (i < 0 || i >=
int(objects_.size()))
return 0.f;
234 return objects_[size_t(i)].width;
237float Map::getObjectHeight(
int i)
const {
238 if (i < 0 || i >=
int(objects_.size()))
return 0.f;
239 return objects_[size_t(i)].height;
242int Map::getObjectGid(
int i)
const {
243 if (i < 0 || i >=
int(objects_.size()))
return 0;
244 return int(objects_[
size_t(i)].gid);
248 std::string_view contractJson) {
249 std::vector<MapObject> objects;
252 if (layers.empty()) {
258 if (!admitted.ok()) {
259 discardCandidateLayers(layers);
262 retireReplacedLayers(loadedLayers_, layers);
263 setObjects(std::move(objects));
264 loadedLayers_ = std::move(layers);
270 std::string_view contractJson) {
271 std::vector<MapObject> objects;
274 if (layers.empty()) {
277 "$map", {},
"map.load"));
280 if (!admitted.ok()) {
281 discardCandidateLayers(layers);
284 retireReplacedLayers(loadedLayers_, layers);
285 setObjects(std::move(objects));
286 loadedLayers_ = std::move(layers);
291int Map::getObjectPropertyCount(
int objectIndex)
const {
292 if (objectIndex < 0 || objectIndex >=
int(objects_.size()))
return 0;
293 return int(objects_[
size_t(objectIndex)].
properties.size());
296std::string Map::getObjectPropertyName(
int objectIndex,
int propertyIndex)
const {
297 if (objectIndex < 0 || objectIndex >=
int(objects_.size()) || propertyIndex < 0)
return {};
298 const auto &
properties = objects_[size_t(objectIndex)].properties;
299 if (propertyIndex >=
int(
properties.size()))
return {};
301 std::advance(it, propertyIndex);
305bool Map::hasObjectProperty(
int objectIndex, std::string_view
name)
const {
306 if (objectIndex < 0 || objectIndex >=
int(objects_.size()))
return false;
307 return objects_[size_t(objectIndex)].properties.contains(std::string(
name));
310std::string Map::getObjectProperty(
int objectIndex, std::string_view
name, std::string
defaultValue)
const {
311 if (objectIndex < 0 || objectIndex >=
int(objects_.size()))
return defaultValue;
312 const auto &
properties = objects_[size_t(objectIndex)].properties;
317std::optional<std::size_t> Map::findObjectByName(std::string_view
name)
const {
323std::optional<std::size_t> Map::findObjectAt(
float x,
float y, std::string_view
type)
const {
324 if (!std::isfinite(
x) || !std::isfinite(
y))
return std::nullopt;
327 if (!
type.empty() &&
object.type !=
type)
continue;
328 const bool point =
object.
width <= 0.f &&
object.height <= 0.f;
329 if (
point ? (
object.
x ==
x &&
object.
y ==
y)
330 : (
x >=
object.x &&
y >=
object.y &&
x <=
object.x + std::max(0.f,
object.
width) &&
331 y <=
object.y + std::max(0.f,
object.
height)))
351 if (!logic)
return 0;
358 if (!logic)
return 0.f;
359 float ox = 0.f,
oy = 0.f;
365 if (!logic)
return 0.f;
366 float ox = 0.f,
oy = 0.f;
371std::string Map::lastDualGridError()
const {
return dualGridError_; }
373void Map::expose(ssq::Table &table) {
374 auto cls = table.addClass(
name, Map::create,
false);
378 "TileLayer", std::function<TileLayer *()>([]() ->
TileLayer * {
return nullptr; }),
true);
379 layer.addFunc(
"setOrigin", &TileLayer::setOrigin);
380 layer.addFunc(
"getX", &TileLayer::getX);
381 layer.addFunc(
"getY", &TileLayer::getY);
382 layer.addFunc(
"getMapWidth", &TileLayer::getMapWidth);
383 layer.addFunc(
"getMapHeight", &TileLayer::getMapHeight);
384 layer.addFunc(
"getTileWidth", &TileLayer::getTileWidth);
385 layer.addFunc(
"getTileHeight", &TileLayer::getTileHeight);
386 layer.addFunc(
"setTileSize", &TileLayer::setTileSize);
387 layer.addFunc(
"setCellGap", &TileLayer::setCellGap);
388 layer.addFunc(
"setRenderSpacing", &TileLayer::setRenderSpacing);
389 layer.addFunc(
"getCellGapX", &TileLayer::getCellGapX);
390 layer.addFunc(
"getCellGapY", &TileLayer::getCellGapY);
391 layer.addFunc(
"getRenderSpacingX", &TileLayer::getRenderSpacingX);
392 layer.addFunc(
"getRenderSpacingY", &TileLayer::getRenderSpacingY);
393 layer.addFunc(
"setVisualScale", &TileLayer::setVisualScale);
394 layer.addFunc(
"getVisualScaleX", &TileLayer::getVisualScaleX);
395 layer.addFunc(
"getVisualScaleY", &TileLayer::getVisualScaleY);
396 layer.addFunc(
"resize", &TileLayer::resize);
397 layer.addFunc(
"setTile", &TileLayer::setTile);
398 layer.addFunc(
"getTile", &TileLayer::getTile);
399 layer.addFunc(
"fillRect", &TileLayer::fillRect);
400 layer.addFunc(
"fill", &TileLayer::fill);
401 layer.addFunc(
"clear", &TileLayer::clear);
402 layer.addFunc(
"getRevision", &TileLayer::getRevision);
403 layer.addFunc(
"getChunkSize", &TileLayer::getChunkSize);
404 layer.addFunc(
"getChunkCount", &TileLayer::getChunkCount);
405 layer.addFunc(
"getNonEmptyChunkCount", &TileLayer::getNonEmptyChunkCount);
406 layer.addFunc(
"clearTileAnimation", &TileLayer::clearTileAnimation);
407 layer.addFunc(
"addTileAnimationFrame", &TileLayer::addTileAnimationFrame);
408 layer.addFunc(
"getTileAnimationFrameCount", &TileLayer::getTileAnimationFrameCount);
409 layer.addFunc(
"setTileDataString", &TileLayer::setTileDataString);
410 layer.addFunc(
"setTileDataNumber", &TileLayer::setTileDataNumber);
411 layer.addFunc(
"setTileDataBool", &TileLayer::setTileDataBool);
412 layer.addFunc(
"getTileDataType", &TileLayer::getTileDataType);
413 layer.addFunc(
"getTileDataString", &TileLayer::getTileDataString);
414 layer.addFunc(
"getTileDataNumber", &TileLayer::getTileDataNumber);
415 layer.addFunc(
"getTileDataBool", &TileLayer::getTileDataBool);
416 layer.addFunc(
"setTerrainRule", &TileLayer::setTerrainRule);
417 layer.addFunc(
"defineAutotileFamily", &TileLayer::defineAutotileFamily);
418 layer.addFunc(
"setAutotileRule", &TileLayer::setAutotileRule);
419 layer.addFunc(
"clearTerrainRules", &TileLayer::clearTerrainRules);
420 layer.addFunc(
"paintTerrain", &TileLayer::paintTerrain);
421 layer.addFunc(
"paintTerrainRect", &TileLayer::paintTerrainRect);
422 layer.addFunc(
"fillTerrain", &TileLayer::fillTerrain);
423 layer.addFunc(
"eraseTerrainRect", &TileLayer::eraseTerrainRect);
424 layer.addFunc(
"getTerrain", &TileLayer::getTerrain);
425 layer.addFunc(
"setTileset", &TileLayer::setTileset);
426 layer.addFunc(
"setTilesetTileSize", &TileLayer::setTilesetTileSize);
427 layer.addFunc(
"setTileVisual", &TileLayer::setTileVisual);
428 layer.addFunc(
"clearTileVisuals", &TileLayer::clearTileVisuals);
429 layer.addFunc(
"getTileVisualCount", &TileLayer::getTileVisualCount);
430 layer.addFunc(
"setTileMetadata", &TileLayer::setTileMetadata);
431 layer.addFunc(
"setTileNavigationProfile", &TileLayer::setTileNavigationProfile);
432 layer.addFunc(
"loadTilesetManifest", &TileLayer::loadTilesetManifest);
433 layer.addFunc(
"getTilesetTexture", &TileLayer::getTilesetTexture);
434 layer.addFunc(
"getTilesetFirstGid", &TileLayer::getTilesetFirstGid);
435 layer.addFunc(
"getTilesetColumns", &TileLayer::getTilesetColumns);
436 layer.addFunc(
"setCanvas", &TileLayer::setCanvas);
437 layer.addFunc(
"setCamera", &TileLayer::setCamera);
438 layer.addFunc(
"setLayer", &TileLayer::setLayer);
439 layer.addFunc(
"getLayer", &TileLayer::getLayer);
440 layer.addFunc(
"setVisible", &TileLayer::setVisible);
441 layer.addFunc(
"isVisible", &TileLayer::isVisible);
442 layer.addFunc(
"setReceiveLight", &TileLayer::setReceiveLight);
443 layer.addFunc(
"getReceiveLight", &TileLayer::getReceiveLight);
444 layer.addFunc(
"setTint", &TileLayer::setTint);
445 layer.addFunc(
"applyConfig", &TileLayer::applyConfig);
446 layer.addFunc(
"loadConfig", &TileLayer::loadConfig);
447 layer.addFunc(
"reloadConfig", &TileLayer::reloadConfig);
448 layer.addFunc(
"setAutoReload", &TileLayer::setAutoReload);
449 layer.addFunc(
"getAutoReload", &TileLayer::getAutoReload);
450 layer.addFunc(
"getConfigPath", &TileLayer::getConfigPath);
451 layer.addFunc(
"tileToWorldX", &TileLayer::tileToWorldX);
452 layer.addFunc(
"tileToWorldY", &TileLayer::tileToWorldY);
453 layer.addFunc(
"depthYAt", &TileLayer::depthYAt);
454 layer.addFunc(
"worldToTileX", &TileLayer::worldToTileX);
455 layer.addFunc(
"worldToTileY", &TileLayer::worldToTileY);
457 auto path = table.addClass<Path>(
458 "Path", std::function<Path *()>([]() -> Path * {
return nullptr; }),
true);
459 path.addFunc(
"getLength", &Path::getLength);
460 path.addFunc(
"getX", &Path::getX);
461 path.addFunc(
"getY", &Path::getY);
462 path.addFunc(
"getTotalCost", &Path::getTotalCost);
464 auto field = table.addClass<FlowField>(
465 "FlowField", std::function<FlowField *()>([]() -> FlowField * {
return nullptr; }),
true);
466 field.addFunc(
"getWidth", &FlowField::getWidth);
467 field.addFunc(
"getHeight", &FlowField::getHeight);
468 field.addFunc(
"getGoalX", &FlowField::getGoalX);
469 field.addFunc(
"getGoalY", &FlowField::getGoalY);
470 field.addFunc(
"costAt", &FlowField::costAt);
471 field.addFunc(
"nextX", &FlowField::nextX);
472 field.addFunc(
"nextY", &FlowField::nextY);
473 field.addFunc(
"isReachable", &FlowField::isReachable);
475 auto pf =
table.addClass<Pathfinder>(
476 "Pathfinder", std::function<Pathfinder *()>([]() -> Pathfinder * {
return nullptr; }),
true);
477 pf.addFunc(
"setTopology", &Pathfinder::setTopology);
478 pf.addFunc(
"getTopology", &Pathfinder::getTopology);
479 pf.addFunc(
"setDiagonal", &Pathfinder::setDiagonal);
480 pf.addFunc(
"getDiagonal", &Pathfinder::getDiagonal);
481 pf.addFunc(
"blockGid", &Pathfinder::blockGid);
482 pf.addFunc(
"unblockGid", &Pathfinder::unblockGid);
483 pf.addFunc(
"clearBlockedGids", &Pathfinder::clearBlockedGids);
484 pf.addFunc(
"setBlockEmpty", &Pathfinder::setBlockEmpty);
485 pf.addFunc(
"getBlockEmpty", &Pathfinder::getBlockEmpty);
486 pf.addFunc(
"setBlocked", &Pathfinder::setBlocked);
487 pf.addFunc(
"isWalkable", &Pathfinder::isWalkable);
488 pf.addFunc(
"setCellCost", &Pathfinder::setCellCost);
489 pf.addFunc(
"getCellCost", &Pathfinder::getCellCost);
490 pf.addFunc(
"syncFromLayer", &Pathfinder::syncFromLayer);
491 pf.addFunc(
"findPath",
static_cast<Path *(Pathfinder::*)(
int,
int,
int,
int)
>(&Pathfinder::findPath));
492 pf.addFunc(
"buildFlowField", &Pathfinder::buildFlowField);
493 pf.addFunc(
"followFlow", &Pathfinder::followFlow);
494 pf.addFunc(
"findGroupPath", &Pathfinder::findGroupPath);
495 pf.addFunc(
"invalidateCache", &Pathfinder::invalidateCache);
497 auto fov =
table.addClass<Fov>(
"Fov", std::function<Fov *()>([]() -> Fov * {
return nullptr; }),
499 fov.addFunc(
"getWidth", &Fov::getWidth);
500 fov.addFunc(
"getHeight", &Fov::getHeight);
501 fov.addFunc(
"getDepth", &Fov::getDepth);
502 fov.addFunc(
"setMode", &Fov::setMode);
503 fov.addFunc(
"getMode", &Fov::getMode);
504 fov.addFunc(
"setAlgorithm", &Fov::setAlgorithm);
505 fov.addFunc(
"getAlgorithm", &Fov::getAlgorithm);
506 fov.addFunc(
"setRadiusMetric", &Fov::setRadiusMetric);
507 fov.addFunc(
"getRadiusMetric", &Fov::getRadiusMetric);
508 fov.addFunc(
"setTopology", &Fov::setTopology);
509 fov.addFunc(
"getTopology", &Fov::getTopology);
510 fov.addFunc(
"setCornerPeek", &Fov::setCornerPeek);
511 fov.addFunc(
"getCornerPeek", &Fov::getCornerPeek);
512 fov.addFunc(
"blockOpaqueGid", &Fov::blockOpaqueGid);
513 fov.addFunc(
"unblockOpaqueGid", &Fov::unblockOpaqueGid);
514 fov.addFunc(
"clearOpaqueGids", &Fov::clearOpaqueGids);
515 fov.addFunc(
"setBlockEmpty", &Fov::setBlockEmpty);
516 fov.addFunc(
"getBlockEmpty", &Fov::getBlockEmpty);
517 fov.addFunc(
"setOpaque", &Fov::setOpaque);
518 fov.addFunc(
"isOpaque", &Fov::isOpaque);
519 fov.addFunc(
"setOpaque3", &Fov::setOpaque3);
520 fov.addFunc(
"isOpaque3", &Fov::isOpaque3);
521 fov.addFunc(
"syncFromLayer", &Fov::syncFromLayer);
522 fov.addFunc(
"setElevation", &Fov::setElevation);
523 fov.addFunc(
"getElevation", &Fov::getElevation);
524 fov.addFunc(
"setCliffBlock", &Fov::setCliffBlock);
525 fov.addFunc(
"getCliffBlock", &Fov::getCliffBlock);
526 fov.addFunc(
"setEyeOffset", &Fov::setEyeOffset);
527 fov.addFunc(
"getEyeOffset", &Fov::getEyeOffset);
528 fov.addFunc(
"setVerticalRange", &Fov::setVerticalRange);
529 fov.addFunc(
"getVerticalRange", &Fov::getVerticalRange);
530 fov.addFunc(
"addRevealer", &Fov::addRevealer);
531 fov.addFunc(
"addRevealer3", &Fov::addRevealer3);
532 fov.addFunc(
"removeRevealer", &Fov::removeRevealer);
533 fov.addFunc(
"clearRevealers", &Fov::clearRevealers);
534 fov.addFunc(
"setRevealerPosition", &Fov::setRevealerPosition);
535 fov.addFunc(
"setRevealerPosition3", &Fov::setRevealerPosition3);
536 fov.addFunc(
"setRevealerRadius", &Fov::setRevealerRadius);
537 fov.addFunc(
"setRevealerFacing", &Fov::setRevealerFacing);
538 fov.addFunc(
"clearRevealerFacing", &Fov::clearRevealerFacing);
539 fov.addFunc(
"setRevealerEnabled", &Fov::setRevealerEnabled);
540 fov.addFunc(
"getRevealerCount", &Fov::getRevealerCount);
541 fov.addFunc(
"setRevealerPerception", &Fov::setRevealerPerception);
542 fov.addFunc(
"getRevealerPerception", &Fov::getRevealerPerception);
543 fov.addFunc(
"setPerceptionRadiusScale", &Fov::setPerceptionRadiusScale);
544 fov.addFunc(
"getPerceptionRadiusScale", &Fov::getPerceptionRadiusScale);
545 fov.addFunc(
"setDetectionMargin", &Fov::setDetectionMargin);
546 fov.addFunc(
"getDetectionMargin", &Fov::getDetectionMargin);
547 fov.addFunc(
"getEffectiveRadius", &Fov::getEffectiveRadius);
548 fov.addFunc(
"canDetect", &Fov::canDetect);
549 fov.addFunc(
"canDetect3", &Fov::canDetect3);
550 fov.addFunc(
"markDirty", &Fov::markDirty);
551 fov.addFunc(
"isDirty", &Fov::isDirty);
552 fov.addFunc(
"compute", &Fov::compute);
553 fov.addFunc(
"isVisible", &Fov::isVisible);
554 fov.addFunc(
"isExplored", &Fov::isExplored);
555 fov.addFunc(
"isVisible3", &Fov::isVisible3);
556 fov.addFunc(
"isExplored3", &Fov::isExplored3);
557 fov.addFunc(
"getState", &Fov::getState);
558 fov.addFunc(
"getState3", &Fov::getState3);
559 fov.addFunc(
"clearMemory", &Fov::clearMemory);
560 fov.addFunc(
"resetVisibleOnly", &Fov::resetVisibleOnly);
561 fov.addFunc(
"getMaskValue", &Fov::getMaskValue);
562 fov.addFunc(
"getMaskByte", &Fov::getMaskByte);
563 fov.addFunc(
"getMaskValue3", &Fov::getMaskValue3);
564 fov.addFunc(
"getMaskByte3", &Fov::getMaskByte3);
565 fov.addFunc(
"buildMaskTexture", &Fov::buildMaskTexture);
566 fov.addFunc(
"buildMaskTextureSlice", &Fov::buildMaskTextureSlice);
569void Map::expose(ssq::Class &
cls) {
571 cls.addFunc(
"getName", &Map::getName);
572 cls.addFunc(
"newLayer", &Map::newLayer);
573 cls.addFunc(
"newLayerFromFile", &Map::newLayerFromFile);
574 cls.addFunc(
"loadFromFile", &Map::loadFromFile);
575 cls.addFunc(
"loadFromFileWithObjectContract",
576 [
vm](Map *
value,
const std::string &
path,
const std::string &contractJson) {
581 {},
"map.squirrel")),
584 value->loadFromFileWithObjectContract(
path, contractJson),
585 [](
int count) { return eve::Value(count); });
587 cls.addFunc(
"newPathfinder", &Map::newPathfinder);
588 cls.addFunc(
"newPathfinderSize", &Map::newPathfinderSize);
589 cls.addFunc(
"newFov", &Map::newFov);
590 cls.addFunc(
"newFovSize", &Map::newFovSize);
591 cls.addFunc(
"newFovVolume", &Map::newFovVolume);
592 cls.addFunc(
"update", &Map::update);
593 cls.addFunc(
"render", &Map::render);
594 cls.addFunc(
"pollConfigs", &Map::pollConfigs);
595 cls.addFunc(
"getLastVisibleTileCount", &Map::getLastVisibleTileCount);
596 cls.addFunc(
"getLastCustomVisualCount", &Map::getLastCustomVisualCount);
597 cls.addFunc(
"getLastAtlasCount", &Map::getLastAtlasCount);
598 cls.addFunc(
"getLastVisitedChunkCount", &Map::getLastVisitedChunkCount);
599 cls.addFunc(
"getLastVisitedCellCount", &Map::getLastVisitedCellCount);
600 cls.addFunc(
"publishCollision", &Map::publishCollision);
601 cls.addFunc(
"getCollisionRectCount", &Map::getCollisionRectCount);
602 cls.addFunc(
"getCollisionRectX", &Map::getCollisionRectX);
603 cls.addFunc(
"getCollisionRectY", &Map::getCollisionRectY);
604 cls.addFunc(
"getCollisionRectWidth", &Map::getCollisionRectWidth);
605 cls.addFunc(
"getCollisionRectHeight", &Map::getCollisionRectHeight);
606 cls.addFunc(
"getLayerCount", &Map::getLayerCount);
607 cls.addFunc(
"getLayer", &Map::getLayer);
608 cls.addFunc(
"getObjectCount", &Map::getObjectCount);
609 cls.addFunc(
"getObjectName", &Map::getObjectName);
610 cls.addFunc(
"getObjectType", &Map::getObjectType);
611 cls.addFunc(
"getObjectX", &Map::getObjectX);
612 cls.addFunc(
"getObjectY", &Map::getObjectY);
613 cls.addFunc(
"getObjectWidth", &Map::getObjectWidth);
614 cls.addFunc(
"getObjectHeight", &Map::getObjectHeight);
615 cls.addFunc(
"getObjectGid", &Map::getObjectGid);
616 cls.addFunc(
"getObjectPropertyCount", &Map::getObjectPropertyCount);
617 cls.addFunc(
"getObjectPropertyName", &Map::getObjectPropertyName);
618 cls.addFunc(
"hasObjectProperty", [](Map *self,
int objectIndex,
const std::string &
name) {
619 return self && self->hasObjectProperty(objectIndex,
name);
621 cls.addFunc(
"getObjectProperty",
622 [](Map *self,
int objectIndex,
const std::string &
name,
const std::string &
defaultValue) {
625 cls.addFunc(
"findObjectByName", [](Map *
value,
const std::string &
name) ->
int {
626 if (!
value)
return -1;
628 return found ?
static_cast<int>(*found) : -1;
630 cls.addFunc(
"findObjectAt", [](Map *
value,
float x,
float y,
const std::string &
type) ->
int {
631 if (!
value)
return -1;
633 return found ?
static_cast<int>(*found) : -1;
635 cls.addFunc(
"resolveDualGrid", &Map::resolveDualGrid);
636 cls.addFunc(
"resolveDualGridFilled", &Map::resolveDualGridFilled);
637 cls.addFunc(
"dualGridMaskAt", &Map::dualGridMaskAt);
638 cls.addFunc(
"dualGridFrame", &Map::dualGridFrame);
639 cls.addFunc(
"dualGridOffsetX", &Map::dualGridOffsetX);
640 cls.addFunc(
"dualGridOffsetY", &Map::dualGridOffsetY);
641 cls.addFunc(
"lastDualGridError", &Map::lastDualGridError);
struct SQVM * HSQUIRRELVM
std::map< std::string, PropertyRule > properties
#define Module_IMPL(ModuleName, newExpr)
graphics::Canvas * previous
The single Squirrel projection for common Result, Status and Value.
std::vector< WfcTile > tiles
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.
Move-only operation result carrying either a value or Status.
static Result success(T value)
Construct a successful result owning value.
static Result failure(Status status)
Construct a failed result from a structured status.
static Status success(StatusCode code=StatusCode::Ok)
Construct a successful status with an explicit non-error outcome.
The canonical owning dynamic value used by data-facing protocols.
int getWidth() const
Returns the width.
int getHeight() const
Returns the height.
static void collectSprites(std::vector< DrawItem2D > &out)
Append visible Renderable2D sprites into a shared queue.
static void drawItems(Graphics &gfx, std::vector< DrawItem2D > &items, bool present)
Sort and draw items. If present=true, calls gfx.present() at the end. Map::render uses present=false ...
Dynamic field-of-view / fog-of-war facade. Phase A: 2D shadowcast + multi-revealer + explored memory....
Map module — factory + script binding for 2D tilemaps. Per-frame: TileConfigSystem (hot reload) → uni...
TileLayer * newLayerFromFile(const std::string &path)
Load map JSON (Tiled-compatible subset or EVEngine simplified format). Creates one TileLayer per tile...
void setObjects(std::vector< MapObject > objects)
Replace object cache (used by load / hot reload).
void update(float dt)
Updates .
int loadFromFile(const std::string &path)
Same transactional replacement as newLayerFromFile, returning the published layer count.
Pathfinder * newPathfinderSize(int mapW, int mapH)
Custom grid pathfinder (no layer); fill with setBlocked / setCellCost.
int getLastCustomVisualCount() const
Returns the last custom visual count.
int getLastVisitedChunkCount() const
Returns the last visited chunk count.
int getLastAtlasCount() const
Returns the last atlas count.
Pathfinder * newPathfinder(TileLayer *layer)
Pathfinder bound to a TileLayer (syncs walkability from GIDs).
Fov * newFovVolume(int mapW, int mapH, int depth)
Volume FOV (W×H×D voxels); mode defaults to volume.
TileLayer * newLayer(int mapW, int mapH, float tileW=32.f, float tileH=32.f)
Creates a layer. @ownership Caller deletes unless documented otherwise.
Fov * newFovSize(int mapW, int mapH)
Custom grid FOV (no layer); fill with setOpaque.
void render(graphics::Graphics *gfx)
Renders .
int getLastVisitedCellCount() const
Returns the last visited cell count.
Fov * newFov(TileLayer *layer)
FOV bound to a TileLayer (syncs opacity from opaque GIDs).
int getLastVisibleTileCount() const
Last tile collection counters for project-owned diagnostics UIs.
int publishCollision(TileLayer *layer)
Generate merged collision from non-walkable tile metadata and notify adapters.
int pollConfigs()
Polls configs.
Pathfinding facade. Single-agent: A*. Group (same goal): Flow Field + follow. Grid/topology internals...
ECS tile layer entity. Script mutates tile GIDs / tileset / draw; TileRenderSystem batch-draws atlas ...
void clear()
Clears the layer to empty.
static TileLayer * createLayer(int mapW, int mapH, float tileW=32.f, float tileH=32.f)
void setVisible(bool visible)
static int lastVisibleTileCount()
Number of non-empty visible tiles collected by the last pass.
static void collect(std::vector< graphics::DrawItem2D > &out)
Append non-empty visible tiles into a shared 2D draw queue.
static int lastVisitedCellCount()
Last visited cell count.
static int lastAtlasCount()
Number of distinct atlas textures referenced by the last pass.
static int lastCustomVisualCount()
Number of collected tiles using irregular per-GID metadata.
static void update(float dt)
Advance TileSet animation clocks once per map update.
static int lastVisitedChunkCount()
Spatial-index work counters for deterministic performance regressions.
Map-owned CPU registry provider for generated grid artifacts.
const char * defaultValue
放置世界:格子占用(多通道)+ 地形语义 + 已放置建筑实例。 行为由 PlacementSystem 提供;本类暴露便于脚本绑定的薄封装方法。 坐标换算统一走 eve::grid(支持 rectang...
int dualGridMaskAt(TileLayer &logic, int dx, int dy, int filledGid)
4-bit corner mask for display cell (dx,dy) on a (logicW+1)×(logicH+1) grid. Samples logic (dx-1,...
std::vector< TileLayer * > loadMapText(const std::string &json, std::vector< MapObject > *objects, std::string *error)
Parse map JSON text (no filesystem). Same semantics as loadMapFile.
void dualGridHalfOffset(const TileLayer::Config &cfg, float &offX, float &offY)
Half-step origin delta for the display layer (added to logic origin). Orthogonal: (-tileW/2,...
uint32_t tileGid(uint32_t raw)
Strip Tiled flip / rotate flags; keep low 28 bits.
void registerMapArtifactProvider()
Register the map provider in the common capability registry.
std::vector< TileLayer * > loadMapFile(const std::string &path, std::vector< MapObject > *objects, std::string *error)
Loads map file.
bool resolveDualGrid(TileLayer *logic, TileLayer *display, const DualGridOptions &opts, std::string *error)
Resolve logic → display dual-grid tiles. Resizes display to (logicW+1)×(logicH+1),...
eve::Result< void > validateMapObjects(std::span< const MapObject > objects, std::string_view contractJson)
Validate map objects against an owning JSON content contract.
int dualGridDefaultFrame(int mask)
Default 4x4 atlas frame index for mask 0..15. -1 means draw nothing. Matches the SpriteCook / common ...
const EditorValue * field(const EditorValue &value, const char *name)
std::unordered_map< std::string, SkillDefinition > & table()
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
Dual-grid autotile (Oskar Stålberg style).
int filledGid
0 = any non-zero logic GID counts as filled; else only this GID.
A named, typed rectangle object from a Tiled objectgroup layer. Used by Map::setObjects / getObject* ...
float width
Extent in pixels.