Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarWorldImpl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/game/StarWorldImpl.hpp')
-rw-r--r--source/game/StarWorldImpl.hpp116
1 files changed, 60 insertions, 56 deletions
diff --git a/source/game/StarWorldImpl.hpp b/source/game/StarWorldImpl.hpp
index 0105deb..e8c0823 100644
--- a/source/game/StarWorldImpl.hpp
+++ b/source/game/StarWorldImpl.hpp
@@ -36,24 +36,23 @@ namespace WorldImpl {
List<Vec2I> collidingTilesAlongLine(WorldGeometry const& worldGeometry, shared_ptr<TileSectorArray> const& tileSectorArray,
Vec2F const& begin, Vec2F const& end, CollisionSet const& collisionSet, size_t maxSize, bool includeEdges);
- template <typename TileSectorArray>
- bool canPlaceMaterial(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
- Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap);
+ template <typename GetTileFunction>
+ bool canPlaceMaterial(EntityMapPtr const& entityMap,
+ Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile);
// returns true if this material could be placed if in the same batch other
// tiles can be placed
// that connect to it
- template <typename TileSectorArray>
- bool perhapsCanPlaceMaterial(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
- Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap);
- template <typename TileSectorArray>
- bool canPlaceMaterialColorVariant(shared_ptr<TileSectorArray> const& tileSectorArray, Vec2I const& pos,
- TileLayer layer, MaterialColorVariant color);
- template <typename TileSectorArray>
- bool canPlaceMod(shared_ptr<TileSectorArray> const& tileSectorArray, Vec2I const& pos, TileLayer layer, ModId mod);
+ template <typename GetTileFunction>
+ bool perhapsCanPlaceMaterial(EntityMapPtr const& entityMap,
+ Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile);
+ template <typename GetTileFunction>
+ bool canPlaceMaterialColorVariant(Vec2I const& pos, TileLayer layer, MaterialColorVariant color, GetTileFunction& getTile);
+ template <typename GetTileFunction>
+ bool canPlaceMod(Vec2I const& pos, TileLayer layer, ModId mod, GetTileFunction& getTile);
// Split modification list into good and bad
- template <typename TileSectorArray>
- pair<TileModificationList, TileModificationList> splitTileModifications(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
- TileModificationList const& modificationList, function<bool(Vec2I pos, TileModification modification)> extraCheck = {});
+ template <typename GetTileFunction>
+ pair<TileModificationList, TileModificationList> splitTileModifications(EntityMapPtr const& entityMap, TileModificationList const& modificationList,
+ bool allowEntityOverlap, function<bool(Vec2I pos, GetTileFunction& getTile, TileModification modification)> extraCheck = {});
template <typename TileSectorArray>
float windLevel(shared_ptr<TileSectorArray> const& tileSectorArray, Vec2F const& position, float weatherWindLevel);
@@ -207,43 +206,48 @@ namespace WorldImpl {
return res;
}
- template <typename TileSectorArray>
- bool canPlaceMaterial(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
- Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap) {
+ template <typename GetTileFunction>
+ bool canPlaceMaterial(EntityMapPtr const& entityMap,
+ Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile) {
auto materialDatabase = Root::singleton().materialDatabase();
if (!isRealMaterial(material))
return false;
auto isAdjacentToConnectable = [&](Vec2I const& pos, unsigned distance, bool foreground) {
- return tileSectorArray->tileSatisfies(pos, distance, [&](Vec2I const& tpos, typename TileSectorArray::Tile const& tile) {
- // Skip if we're looking at the block at pos, allow placement if
- // placing on world bottom
- if (tpos == pos)
- return false;
- else if (tpos[1] < 0)
- return true;
- else if (foreground)
- return isConnectableMaterial(tile.foreground);
- else
- return isConnectableMaterial(tile.background);
- });
+ if (pos.y() - distance < 0)
+ return true;
+
+ int maxY = pos.y() + distance + 1;
+ int maxX = pos.x() + distance + 1;
+ for (int y = pos.y() - distance; y != maxY; ++y) {
+ Vec2I tPos = { 0, y };
+ for (int x = pos.x() - distance; x != maxX; ++x) {
+ tPos[0] = x;
+ if (tPos != pos) {
+ auto& tile = getTile(tPos);
+ if (isConnectableMaterial(foreground ? tile.foreground : tile.background))
+ return true;
+ }
+ }
+ }
+ return false;
};
if (!materialDatabase->canPlaceInLayer(material, layer))
return false;
if (layer == TileLayer::Background) {
- if (tileSectorArray->tile(pos).background != EmptyMaterialId)
+ if (getTile(pos).background != EmptyMaterialId)
return false;
// Can attach background blocks to other background blocks, *or* the
// foreground block in front of it.
if (!isAdjacentToConnectable(pos, 1, false)
- && !isConnectableMaterial(tileSectorArray->tile({pos[0], pos[1]}).foreground))
+ && !isConnectableMaterial(getTile({pos[0], pos[1]}).foreground))
return false;
} else {
- if (tileSectorArray->tile(pos).foreground != EmptyMaterialId)
+ if (getTile(pos).foreground != EmptyMaterialId)
return false;
if (entityMap->tileIsOccupied(pos))
@@ -252,16 +256,16 @@ namespace WorldImpl {
if (!allowEntityOverlap && entityMap->spaceIsOccupied(RectF::withSize(Vec2F(pos), Vec2F(1, 1))))
return false;
- if (!isAdjacentToConnectable(pos, 1, true) && !isConnectableMaterial(tileSectorArray->tile({pos[0], pos[1]}).background))
+ if (!isAdjacentToConnectable(pos, 1, true) && !isConnectableMaterial(getTile({pos[0], pos[1]}).background))
return false;
}
return true;
}
- template <typename TileSectorArray>
- bool perhapsCanPlaceMaterial(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
- Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap) {
+ template <typename GetTileFunction>
+ bool perhapsCanPlaceMaterial(EntityMapPtr const& entityMap,
+ Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile) {
auto materialDatabase = Root::singleton().materialDatabase();
if (!isRealMaterial(material))
@@ -271,10 +275,10 @@ namespace WorldImpl {
return false;
if (layer == TileLayer::Background) {
- if (tileSectorArray->tile(pos).background != EmptyMaterialId)
+ if (getTile(pos).background != EmptyMaterialId)
return false;
} else {
- if (tileSectorArray->tile(pos).foreground != EmptyMaterialId)
+ if (getTile(pos).foreground != EmptyMaterialId)
return false;
if (entityMap->tileIsOccupied(pos))
@@ -287,31 +291,31 @@ namespace WorldImpl {
return true;
}
- template <typename TileSectorArray>
- bool canPlaceMaterialColorVariant(shared_ptr<TileSectorArray> const& tileSectorArray,
- Vec2I const& pos, TileLayer layer, MaterialColorVariant color) {
+ template <typename GetTileFunction>
+ bool canPlaceMaterialColorVariant(Vec2I const& pos, TileLayer layer, MaterialColorVariant color, GetTileFunction& getTile) {
auto materialDatabase = Root::singleton().materialDatabase();
- auto mat = tileSectorArray->tile(pos).material(layer);
- auto existingColor = tileSectorArray->tile(pos).materialColor(layer);
- auto existingHue = layer == TileLayer::Foreground ? tileSectorArray->tile(pos).foregroundHueShift : tileSectorArray->tile(pos).backgroundHueShift;
+ auto& tile = getTile(pos);
+ auto mat = tile.material(layer);
+ auto existingColor = tile.materialColor(layer);
+ auto existingHue = layer == TileLayer::Foreground ? tile.foregroundHueShift : tile.backgroundHueShift;
return existingHue != 0 || (existingColor != color && materialDatabase->isMultiColor(mat));
}
- template <typename TileSectorArray>
- bool canPlaceMod(shared_ptr<TileSectorArray> const& tileSectorArray, Vec2I const& pos, TileLayer layer, ModId mod) {
+ template <typename GetTileFunction>
+ bool canPlaceMod(Vec2I const& pos, TileLayer layer, ModId mod, GetTileFunction& getTile) {
if (!isRealMod(mod))
return false;
auto materialDatabase = Root::singleton().materialDatabase();
- auto mat = tileSectorArray->tile(pos).material(layer);
- auto existingMod = tileSectorArray->tile(pos).mod(layer);
+ auto mat = getTile(pos).material(layer);
+ auto existingMod = getTile(pos).mod(layer);
return existingMod != mod && materialDatabase->supportsMod(mat, mod);
}
- template <typename TileSectorArray>
- pair<TileModificationList, TileModificationList> splitTileModifications(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
- TileModificationList const& modificationList, bool allowEntityOverlap, function<bool(Vec2I pos, TileModification modification)> extraCheck) {
+ template <typename GetTileFunction>
+ pair<TileModificationList, TileModificationList> splitTileModifications(EntityMapPtr const& entityMap,
+ TileModificationList const& modificationList, bool allowEntityOverlap, GetTileFunction& getTile, function<bool(Vec2I pos, TileModification modification)> extraCheck) {
TileModificationList success;
TileModificationList unknown;
TileModificationList failures;
@@ -325,15 +329,15 @@ namespace WorldImpl {
if (extraCheck && !extraCheck(pos, modification)) {
good = false;
} else if (auto placeMaterial = modification.ptr<PlaceMaterial>()) {
- perhaps = WorldImpl::perhapsCanPlaceMaterial(tileSectorArray, entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap);
+ perhaps = WorldImpl::perhapsCanPlaceMaterial(entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, getTile);
if (perhaps)
- good = WorldImpl::canPlaceMaterial(tileSectorArray, entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap);
+ good = WorldImpl::canPlaceMaterial(entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, getTile);
} else if (auto placeMod = modification.ptr<PlaceMod>()) {
- good = WorldImpl::canPlaceMod(tileSectorArray, pos, placeMod->layer, placeMod->mod);
+ good = WorldImpl::canPlaceMod(pos, placeMod->layer, placeMod->mod, getTile);
} else if (auto placeMaterialColor = modification.ptr<PlaceMaterialColor>()) {
- good = WorldImpl::canPlaceMaterialColorVariant(tileSectorArray, pos, placeMaterialColor->layer, placeMaterialColor->color);
+ good = WorldImpl::canPlaceMaterialColorVariant(pos, placeMaterialColor->layer, placeMaterialColor->color, getTile);
} else if (modification.is<PlaceLiquid>()) {
- good = tileSectorArray->tile(pos).collision == CollisionKind::None;
+ good = getTile(pos).collision == CollisionKind::None;
} else {
good = false;
}