Objects can now be placed under tiles that have non-block collision
This commit is contained in:
parent
edbee201ee
commit
a7ae034278
@ -32,9 +32,9 @@ bool ObjectOrientation::placementValid(World const* world, Vec2I const& position
|
|||||||
if (!world)
|
if (!world)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto space : spaces) {
|
for (Vec2I space : spaces) {
|
||||||
space += position;
|
space += position;
|
||||||
if (world->tileIsOccupied(space, TileLayer::Foreground) || world->isTileProtected(space))
|
if (world->tileIsOccupied(space, TileLayer::Foreground, false, true) || world->isTileProtected(space))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -238,10 +238,16 @@ EntityPtr WorldClient::findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEnt
|
|||||||
return m_entityMap->findEntityAtTile(pos, entityFilter);
|
return m_entityMap->findEntityAtTile(pos, entityFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorldClient::tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral) const {
|
bool WorldClient::tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral, bool checkCollision) const {
|
||||||
if (!inWorld())
|
if (!inWorld())
|
||||||
return false;
|
return false;
|
||||||
return WorldImpl::tileIsOccupied(m_tileArray, m_entityMap, pos, layer, includeEphemeral);
|
return WorldImpl::tileIsOccupied(m_tileArray, m_entityMap, pos, layer, includeEphemeral, checkCollision);
|
||||||
|
}
|
||||||
|
|
||||||
|
CollisionKind WorldClient::tileCollisionKind(Vec2I const& pos) const {
|
||||||
|
if (!inWorld())
|
||||||
|
return CollisionKind::Null;
|
||||||
|
return WorldImpl::tileCollisionKind(m_tileArray, m_entityMap, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldClient::forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const {
|
void WorldClient::forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const {
|
||||||
|
@ -63,7 +63,8 @@ public:
|
|||||||
EntityPtr findEntity(RectF const& boundBox, EntityFilter entityFilter) const override;
|
EntityPtr findEntity(RectF const& boundBox, EntityFilter entityFilter) const override;
|
||||||
EntityPtr findEntityLine(Vec2F const& begin, Vec2F const& end, EntityFilter entityFilter) const override;
|
EntityPtr findEntityLine(Vec2F const& begin, Vec2F const& end, EntityFilter entityFilter) const override;
|
||||||
EntityPtr findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEntity> entityFilter) const override;
|
EntityPtr findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEntity> entityFilter) const override;
|
||||||
bool tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral = false) const override;
|
bool tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral = false, bool checkCollision = false) const override;
|
||||||
|
CollisionKind tileCollisionKind(Vec2I const& pos) const override;
|
||||||
void forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const override;
|
void forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const override;
|
||||||
bool isTileConnectable(Vec2I const& pos, TileLayer layer, bool tilesOnly = false) const override;
|
bool isTileConnectable(Vec2I const& pos, TileLayer layer, bool tilesOnly = false) const override;
|
||||||
bool pointTileCollision(Vec2F const& point, CollisionSet const& collisionSet = DefaultCollisionSet) const override;
|
bool pointTileCollision(Vec2F const& point, CollisionSet const& collisionSet = DefaultCollisionSet) const override;
|
||||||
|
@ -21,7 +21,11 @@ namespace Star {
|
|||||||
namespace WorldImpl {
|
namespace WorldImpl {
|
||||||
template <typename TileSectorArray>
|
template <typename TileSectorArray>
|
||||||
bool tileIsOccupied(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
|
bool tileIsOccupied(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
|
||||||
Vec2I const& pos, TileLayer layer, bool includeEphemeral);
|
Vec2I const& pos, TileLayer layer, bool includeEphemeral, bool checkCollision = false);
|
||||||
|
|
||||||
|
template <typename TileSectorArray>
|
||||||
|
CollisionKind tileCollisionKind(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
|
||||||
|
Vec2I const& pos);
|
||||||
|
|
||||||
template <typename TileSectorArray>
|
template <typename TileSectorArray>
|
||||||
bool rectTileCollision(shared_ptr<TileSectorArray> const& tileSectorArray, RectI const& region, bool solidCollision);
|
bool rectTileCollision(shared_ptr<TileSectorArray> const& tileSectorArray, RectI const& region, bool solidCollision);
|
||||||
@ -38,13 +42,13 @@ namespace WorldImpl {
|
|||||||
|
|
||||||
template <typename GetTileFunction>
|
template <typename GetTileFunction>
|
||||||
bool canPlaceMaterial(EntityMapPtr const& entityMap,
|
bool canPlaceMaterial(EntityMapPtr const& entityMap,
|
||||||
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile);
|
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, bool allowTileOverlap, GetTileFunction& getTile);
|
||||||
// returns true if this material could be placed if in the same batch other
|
// returns true if this material could be placed if in the same batch other
|
||||||
// tiles can be placed
|
// tiles can be placed
|
||||||
// that connect to it
|
// that connect to it
|
||||||
template <typename GetTileFunction>
|
template <typename GetTileFunction>
|
||||||
bool perhapsCanPlaceMaterial(EntityMapPtr const& entityMap,
|
bool perhapsCanPlaceMaterial(EntityMapPtr const& entityMap,
|
||||||
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile);
|
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, bool allowTileOverlap, GetTileFunction& getTile);
|
||||||
template <typename GetTileFunction>
|
template <typename GetTileFunction>
|
||||||
bool canPlaceMaterialColorVariant(Vec2I const& pos, TileLayer layer, MaterialColorVariant color, GetTileFunction& getTile);
|
bool canPlaceMaterialColorVariant(Vec2I const& pos, TileLayer layer, MaterialColorVariant color, GetTileFunction& getTile);
|
||||||
template <typename GetTileFunction>
|
template <typename GetTileFunction>
|
||||||
@ -80,11 +84,18 @@ namespace WorldImpl {
|
|||||||
|
|
||||||
template <typename TileSectorArray>
|
template <typename TileSectorArray>
|
||||||
bool tileIsOccupied(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
|
bool tileIsOccupied(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
|
||||||
Vec2I const& pos, TileLayer layer, bool includeEphemeral) {
|
Vec2I const& pos, TileLayer layer, bool includeEphemeral, bool checkCollision) {
|
||||||
|
auto& tile = tileSectorArray->tile(pos);
|
||||||
if (layer == TileLayer::Foreground)
|
if (layer == TileLayer::Foreground)
|
||||||
return tileSectorArray->tile(pos).foreground != EmptyMaterialId || entityMap->tileIsOccupied(pos, includeEphemeral);
|
return (checkCollision ? tile.collision >= CollisionKind::Dynamic : tile.foreground != EmptyMaterialId) || entityMap->tileIsOccupied(pos, includeEphemeral);
|
||||||
else
|
else
|
||||||
return tileSectorArray->tile(pos).background != EmptyMaterialId;
|
return tile.background != EmptyMaterialId;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TileSectorArray>
|
||||||
|
CollisionKind tileCollisionKind(shared_ptr<TileSectorArray> const& tileSectorArray, EntityMapPtr const& entityMap,
|
||||||
|
Vec2I const& pos) {
|
||||||
|
return tileSectorArray->tile(pos).collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TileSectorArray>
|
template <typename TileSectorArray>
|
||||||
@ -210,7 +221,7 @@ namespace WorldImpl {
|
|||||||
|
|
||||||
template <typename GetTileFunction>
|
template <typename GetTileFunction>
|
||||||
bool canPlaceMaterial(EntityMapPtr const& entityMap,
|
bool canPlaceMaterial(EntityMapPtr const& entityMap,
|
||||||
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile) {
|
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, bool allowTileOverlap, GetTileFunction& getTile) {
|
||||||
auto materialDatabase = Root::singleton().materialDatabase();
|
auto materialDatabase = Root::singleton().materialDatabase();
|
||||||
|
|
||||||
if (!isRealMaterial(material))
|
if (!isRealMaterial(material))
|
||||||
@ -239,26 +250,26 @@ namespace WorldImpl {
|
|||||||
if (!materialDatabase->canPlaceInLayer(material, layer))
|
if (!materialDatabase->canPlaceInLayer(material, layer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
auto& tile = getTile(pos);
|
||||||
if (layer == TileLayer::Background) {
|
if (layer == TileLayer::Background) {
|
||||||
if (getTile(pos).background != EmptyMaterialId)
|
if (tile.background != EmptyMaterialId && tile.background != ObjectPlatformMaterialId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can attach background blocks to other background blocks, *or* the
|
// Can attach background blocks to other background blocks, *or* the
|
||||||
// foreground block in front of it.
|
// foreground block in front of it.
|
||||||
if (!isAdjacentToConnectable(pos, 1, false)
|
if (!isAdjacentToConnectable(pos, 1, false) && !isConnectableMaterial(tile.foreground))
|
||||||
&& !isConnectableMaterial(getTile({pos[0], pos[1]}).foreground))
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (getTile(pos).foreground != EmptyMaterialId)
|
if (tile.foreground != EmptyMaterialId && tile.foreground != ObjectPlatformMaterialId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (entityMap->tileIsOccupied(pos))
|
if (!allowTileOverlap && entityMap->tileIsOccupied(pos))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!allowEntityOverlap && entityMap->spaceIsOccupied(RectF::withSize(Vec2F(pos), Vec2F(1, 1))))
|
if (!allowEntityOverlap && entityMap->spaceIsOccupied(RectF::withSize(Vec2F(pos), Vec2F(0.999f, 0.999f))))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!isAdjacentToConnectable(pos, 1, true) && !isConnectableMaterial(getTile({pos[0], pos[1]}).background))
|
if (!isAdjacentToConnectable(pos, 1, true) && !isConnectableMaterial(tile.background))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +278,7 @@ namespace WorldImpl {
|
|||||||
|
|
||||||
template <typename GetTileFunction>
|
template <typename GetTileFunction>
|
||||||
bool perhapsCanPlaceMaterial(EntityMapPtr const& entityMap,
|
bool perhapsCanPlaceMaterial(EntityMapPtr const& entityMap,
|
||||||
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, GetTileFunction& getTile) {
|
Vec2I const& pos, TileLayer layer, MaterialId material, bool allowEntityOverlap, bool allowTileOverlap, GetTileFunction& getTile) {
|
||||||
auto materialDatabase = Root::singleton().materialDatabase();
|
auto materialDatabase = Root::singleton().materialDatabase();
|
||||||
|
|
||||||
if (!isRealMaterial(material))
|
if (!isRealMaterial(material))
|
||||||
@ -276,17 +287,18 @@ namespace WorldImpl {
|
|||||||
if (!materialDatabase->canPlaceInLayer(material, layer))
|
if (!materialDatabase->canPlaceInLayer(material, layer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
auto& tile = getTile(pos);
|
||||||
if (layer == TileLayer::Background) {
|
if (layer == TileLayer::Background) {
|
||||||
if (getTile(pos).background != EmptyMaterialId)
|
if (tile.background != EmptyMaterialId && tile.background != ObjectPlatformMaterialId)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (getTile(pos).foreground != EmptyMaterialId)
|
if (tile.foreground != EmptyMaterialId && tile.foreground != ObjectPlatformMaterialId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (entityMap->tileIsOccupied(pos))
|
if (!allowTileOverlap && entityMap->tileIsOccupied(pos))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!allowEntityOverlap && entityMap->spaceIsOccupied(RectF::withSize(Vec2F(pos), Vec2F(1, 1))))
|
if (!allowEntityOverlap && entityMap->spaceIsOccupied(RectF::withSize(Vec2F(pos), Vec2F(0.999f, 0.999f))))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,9 +333,10 @@ namespace WorldImpl {
|
|||||||
bool perhaps = false;
|
bool perhaps = false;
|
||||||
|
|
||||||
if (auto placeMaterial = modification.ptr<PlaceMaterial>()) {
|
if (auto placeMaterial = modification.ptr<PlaceMaterial>()) {
|
||||||
perhaps = WorldImpl::perhapsCanPlaceMaterial(entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, getTile);
|
bool allowTileOverlap = placeMaterial->collisionOverride != TileCollisionOverride::None && collisionKindFromOverride(placeMaterial->collisionOverride) < CollisionKind::Dynamic;
|
||||||
|
perhaps = WorldImpl::perhapsCanPlaceMaterial(entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, allowTileOverlap, getTile);
|
||||||
if (perhaps)
|
if (perhaps)
|
||||||
good = WorldImpl::canPlaceMaterial(entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, getTile);
|
good = WorldImpl::canPlaceMaterial(entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, allowTileOverlap, getTile);
|
||||||
} else if (auto placeMod = modification.ptr<PlaceMod>()) {
|
} else if (auto placeMod = modification.ptr<PlaceMod>()) {
|
||||||
good = WorldImpl::canPlaceMod(pos, placeMod->layer, placeMod->mod, getTile);
|
good = WorldImpl::canPlaceMod(pos, placeMod->layer, placeMod->mod, getTile);
|
||||||
} else if (auto placeMaterialColor = modification.ptr<PlaceMaterialColor>()) {
|
} else if (auto placeMaterialColor = modification.ptr<PlaceMaterialColor>()) {
|
||||||
|
@ -756,10 +756,15 @@ EntityPtr WorldServer::findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEnt
|
|||||||
return m_entityMap->findEntityAtTile(pos, entityFilter);
|
return m_entityMap->findEntityAtTile(pos, entityFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorldServer::tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral) const {
|
bool WorldServer::tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral, bool checkCollision) const {
|
||||||
return WorldImpl::tileIsOccupied(m_tileArray, m_entityMap, pos, layer, includeEphemeral);
|
return WorldImpl::tileIsOccupied(m_tileArray, m_entityMap, pos, layer, includeEphemeral, checkCollision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CollisionKind WorldServer::tileCollisionKind(Vec2I const& pos) const {
|
||||||
|
return WorldImpl::tileCollisionKind(m_tileArray, m_entityMap, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WorldServer::forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const {
|
void WorldServer::forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const {
|
||||||
const_cast<WorldServer*>(this)->freshenCollision(region);
|
const_cast<WorldServer*>(this)->freshenCollision(region);
|
||||||
m_tileArray->tileEach(region, [iterator](Vec2I const& pos, ServerTile const& tile) {
|
m_tileArray->tileEach(region, [iterator](Vec2I const& pos, ServerTile const& tile) {
|
||||||
@ -1348,7 +1353,8 @@ TileModificationList WorldServer::doApplyTileModifications(TileModificationList
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (auto placeMaterial = modification.ptr<PlaceMaterial>()) {
|
if (auto placeMaterial = modification.ptr<PlaceMaterial>()) {
|
||||||
if (!WorldImpl::canPlaceMaterial(m_entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, m_tileGetterFunction))
|
bool allowTileOverlap = placeMaterial->collisionOverride != TileCollisionOverride::None && collisionKindFromOverride(placeMaterial->collisionOverride) < CollisionKind::Dynamic;
|
||||||
|
if (!WorldImpl::canPlaceMaterial(m_entityMap, pos, placeMaterial->layer, placeMaterial->material, allowEntityOverlap, allowTileOverlap, m_tileGetterFunction))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ServerTile* tile = m_tileArray->modifyTile(pos);
|
ServerTile* tile = m_tileArray->modifyTile(pos);
|
||||||
@ -1498,14 +1504,21 @@ void WorldServer::updateTileEntityTiles(TileEntityPtr const& entity, bool removi
|
|||||||
|
|
||||||
ServerTile* tile = m_tileArray->modifyTile(pos);
|
ServerTile* tile = m_tileArray->modifyTile(pos);
|
||||||
if (tile) {
|
if (tile) {
|
||||||
|
bool updated = false;
|
||||||
|
if (tile->foreground == materialSpace.material) {
|
||||||
tile->foreground = EmptyMaterialId;
|
tile->foreground = EmptyMaterialId;
|
||||||
tile->foregroundMod = NoModId;
|
tile->foregroundMod = NoModId;
|
||||||
tile->rootSource = {};
|
tile->rootSource = {};
|
||||||
if (tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground))) {
|
updated = true;
|
||||||
|
}
|
||||||
|
if (tile->collision == materialDatabase->materialCollisionKind(materialSpace.material)
|
||||||
|
&& tile->updateCollision(materialSpace.prevCollision.value(CollisionKind::None))) {
|
||||||
m_liquidEngine->visitLocation(pos);
|
m_liquidEngine->visitLocation(pos);
|
||||||
m_fallingBlocksAgent->visitLocation(pos);
|
m_fallingBlocksAgent->visitLocation(pos);
|
||||||
dirtyCollision(RectI::withSize(pos, {1, 1}));
|
dirtyCollision(RectI::withSize(pos, { 1, 1 }));
|
||||||
|
updated = true;
|
||||||
}
|
}
|
||||||
|
if (updated)
|
||||||
queueTileUpdates(pos);
|
queueTileUpdates(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1515,24 +1528,37 @@ void WorldServer::updateTileEntityTiles(TileEntityPtr const& entity, bool removi
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// add new material spaces and update the known material spaces entry
|
// add new material spaces and update the known material spaces entry
|
||||||
|
List<MaterialSpace> passedSpaces;
|
||||||
for (auto const& materialSpace : newMaterialSpaces) {
|
for (auto const& materialSpace : newMaterialSpaces) {
|
||||||
Vec2I pos = materialSpace.space + entity->tilePosition();
|
Vec2I pos = materialSpace.space + entity->tilePosition();
|
||||||
|
|
||||||
|
bool updated = false;
|
||||||
|
bool updatedCollision = false;
|
||||||
ServerTile* tile = m_tileArray->modifyTile(pos);
|
ServerTile* tile = m_tileArray->modifyTile(pos);
|
||||||
if (tile) {
|
if (tile && (tile->foreground == EmptyMaterialId || tile->foreground == materialSpace.material)) {
|
||||||
tile->foreground = materialSpace.material;
|
tile->foreground = materialSpace.material;
|
||||||
tile->foregroundMod = NoModId;
|
tile->foregroundMod = NoModId;
|
||||||
if (isRealMaterial(materialSpace.material))
|
if (isRealMaterial(materialSpace.material))
|
||||||
tile->rootSource = entity->tilePosition();
|
tile->rootSource = entity->tilePosition();
|
||||||
if (tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground))) {
|
passedSpaces.emplaceAppend(materialSpace).prevCollision.emplace(tile->collision);
|
||||||
|
updatedCollision = tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground));
|
||||||
|
updated = true;
|
||||||
|
passedSpaces.emplaceAppend(materialSpace);
|
||||||
|
}
|
||||||
|
else if (tile && tile->collision < CollisionKind::Dynamic) {
|
||||||
|
passedSpaces.emplaceAppend(materialSpace).prevCollision.emplace(tile->collision);
|
||||||
|
updatedCollision = tile->updateCollision(materialDatabase->materialCollisionKind(materialSpace.material));
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
if (updatedCollision) {
|
||||||
m_liquidEngine->visitLocation(pos);
|
m_liquidEngine->visitLocation(pos);
|
||||||
m_fallingBlocksAgent->visitLocation(pos);
|
m_fallingBlocksAgent->visitLocation(pos);
|
||||||
dirtyCollision(RectI::withSize(pos, {1, 1}));
|
dirtyCollision(RectI::withSize(pos, { 1, 1 }));
|
||||||
}
|
}
|
||||||
|
if (updated)
|
||||||
queueTileUpdates(pos);
|
queueTileUpdates(pos);
|
||||||
}
|
}
|
||||||
}
|
spaces.materials = move(passedSpaces);
|
||||||
spaces.materials = move(newMaterialSpaces);
|
|
||||||
|
|
||||||
// add new roots and update known roots entry
|
// add new roots and update known roots entry
|
||||||
for (auto const& rootPos : newRoots) {
|
for (auto const& rootPos : newRoots) {
|
||||||
|
@ -144,7 +144,8 @@ public:
|
|||||||
EntityPtr findEntity(RectF const& boundBox, EntityFilter entityFilter) const override;
|
EntityPtr findEntity(RectF const& boundBox, EntityFilter entityFilter) const override;
|
||||||
EntityPtr findEntityLine(Vec2F const& begin, Vec2F const& end, EntityFilter entityFilter) const override;
|
EntityPtr findEntityLine(Vec2F const& begin, Vec2F const& end, EntityFilter entityFilter) const override;
|
||||||
EntityPtr findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEntity> entityFilter) const override;
|
EntityPtr findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEntity> entityFilter) const override;
|
||||||
bool tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral = false) const override;
|
bool tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral = false, bool checkCollision = false) const override;
|
||||||
|
CollisionKind tileCollisionKind(Vec2I const& pos) const override;
|
||||||
void forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const override;
|
void forEachCollisionBlock(RectI const& region, function<void(CollisionBlock const&)> const& iterator) const override;
|
||||||
bool isTileConnectable(Vec2I const& pos, TileLayer layer, bool tilesOnly = false) const override;
|
bool isTileConnectable(Vec2I const& pos, TileLayer layer, bool tilesOnly = false) const override;
|
||||||
bool pointTileCollision(Vec2F const& point, CollisionSet const& collisionSet = DefaultCollisionSet) const override;
|
bool pointTileCollision(Vec2F const& point, CollisionSet const& collisionSet = DefaultCollisionSet) const override;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "StarEntity.hpp"
|
#include "StarEntity.hpp"
|
||||||
#include "StarTileDamage.hpp"
|
#include "StarTileDamage.hpp"
|
||||||
#include "StarInteractiveEntity.hpp"
|
#include "StarInteractiveEntity.hpp"
|
||||||
|
#include "StarCollisionBlock.hpp"
|
||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ struct MaterialSpace {
|
|||||||
|
|
||||||
Vec2I space;
|
Vec2I space;
|
||||||
MaterialId material;
|
MaterialId material;
|
||||||
|
Maybe<CollisionKind> prevCollision;
|
||||||
};
|
};
|
||||||
|
|
||||||
DataStream& operator<<(DataStream& ds, MaterialSpace const& materialSpace);
|
DataStream& operator<<(DataStream& ds, MaterialSpace const& materialSpace);
|
||||||
@ -89,7 +91,9 @@ inline MaterialSpace::MaterialSpace(Vec2I space, MaterialId material)
|
|||||||
: space(space), material(material) {}
|
: space(space), material(material) {}
|
||||||
|
|
||||||
inline bool MaterialSpace::operator==(MaterialSpace const& rhs) const {
|
inline bool MaterialSpace::operator==(MaterialSpace const& rhs) const {
|
||||||
return tie(space, material) == tie(rhs.space, rhs.material);
|
return space == rhs.space
|
||||||
|
&& material == rhs.material
|
||||||
|
&& prevCollision == rhs.prevCollision;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,10 @@ public:
|
|||||||
virtual EntityPtr findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEntity> entityFilter) const = 0;
|
virtual EntityPtr findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEntity> entityFilter) const = 0;
|
||||||
|
|
||||||
// Is the given tile layer and position occupied by an entity or block?
|
// Is the given tile layer and position occupied by an entity or block?
|
||||||
virtual bool tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral = false) const = 0;
|
virtual bool tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral = false, bool checkCollision = false) const = 0;
|
||||||
|
|
||||||
|
// Returns the collision kind of a tile.
|
||||||
|
virtual CollisionKind tileCollisionKind(Vec2I const& pos) const = 0;
|
||||||
|
|
||||||
// Iterate over the collision block for each tile in the region. Collision
|
// Iterate over the collision block for each tile in the region. Collision
|
||||||
// polys for tiles can extend to a maximum of 1 tile outside of the natural
|
// polys for tiles can extend to a maximum of 1 tile outside of the natural
|
||||||
|
Loading…
Reference in New Issue
Block a user