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

summaryrefslogtreecommitdiff
path: root/source/game/StarWorldServer.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-08-21 00:59:02 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-08-21 00:59:02 +1000
commita7ae03427805cdf0886ca9eb40add54cf970fc4f (patch)
treed8b4c7d81b485e7a1bbe7ed3584bb34b5eb9fda4 /source/game/StarWorldServer.cpp
parentedbee201ee2debbe56e27636760a9d650b8ff685 (diff)
Objects can now be placed under tiles that have non-block collision
Diffstat (limited to 'source/game/StarWorldServer.cpp')
-rw-r--r--source/game/StarWorldServer.cpp60
1 files changed, 43 insertions, 17 deletions
diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp
index 6579c91..26ce363 100644
--- a/source/game/StarWorldServer.cpp
+++ b/source/game/StarWorldServer.cpp
@@ -756,10 +756,15 @@ EntityPtr WorldServer::findEntityAtTile(Vec2I const& pos, EntityFilterOf<TileEnt
return m_entityMap->findEntityAtTile(pos, entityFilter);
}
-bool WorldServer::tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral) const {
- return WorldImpl::tileIsOccupied(m_tileArray, m_entityMap, pos, layer, includeEphemeral);
+bool WorldServer::tileIsOccupied(Vec2I const& pos, TileLayer layer, bool includeEphemeral, bool checkCollision) const {
+ 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 {
const_cast<WorldServer*>(this)->freshenCollision(region);
m_tileArray->tileEach(region, [iterator](Vec2I const& pos, ServerTile const& tile) {
@@ -1348,7 +1353,8 @@ TileModificationList WorldServer::doApplyTileModifications(TileModificationList
continue;
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;
ServerTile* tile = m_tileArray->modifyTile(pos);
@@ -1498,15 +1504,22 @@ void WorldServer::updateTileEntityTiles(TileEntityPtr const& entity, bool removi
ServerTile* tile = m_tileArray->modifyTile(pos);
if (tile) {
- tile->foreground = EmptyMaterialId;
- tile->foregroundMod = NoModId;
- tile->rootSource = {};
- if (tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground))) {
+ bool updated = false;
+ if (tile->foreground == materialSpace.material) {
+ tile->foreground = EmptyMaterialId;
+ tile->foregroundMod = NoModId;
+ tile->rootSource = {};
+ updated = true;
+ }
+ if (tile->collision == materialDatabase->materialCollisionKind(materialSpace.material)
+ && tile->updateCollision(materialSpace.prevCollision.value(CollisionKind::None))) {
m_liquidEngine->visitLocation(pos);
m_fallingBlocksAgent->visitLocation(pos);
- dirtyCollision(RectI::withSize(pos, {1, 1}));
+ dirtyCollision(RectI::withSize(pos, { 1, 1 }));
+ updated = true;
}
- queueTileUpdates(pos);
+ if (updated)
+ queueTileUpdates(pos);
}
}
@@ -1515,24 +1528,37 @@ void WorldServer::updateTileEntityTiles(TileEntityPtr const& entity, bool removi
} else {
// add new material spaces and update the known material spaces entry
+ List<MaterialSpace> passedSpaces;
for (auto const& materialSpace : newMaterialSpaces) {
Vec2I pos = materialSpace.space + entity->tilePosition();
+ bool updated = false;
+ bool updatedCollision = false;
ServerTile* tile = m_tileArray->modifyTile(pos);
- if (tile) {
+ if (tile && (tile->foreground == EmptyMaterialId || tile->foreground == materialSpace.material)) {
tile->foreground = materialSpace.material;
tile->foregroundMod = NoModId;
if (isRealMaterial(materialSpace.material))
tile->rootSource = entity->tilePosition();
- if (tile->updateCollision(materialDatabase->materialCollisionKind(tile->foreground))) {
- m_liquidEngine->visitLocation(pos);
- m_fallingBlocksAgent->visitLocation(pos);
- dirtyCollision(RectI::withSize(pos, {1, 1}));
- }
- queueTileUpdates(pos);
+ 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_fallingBlocksAgent->visitLocation(pos);
+ dirtyCollision(RectI::withSize(pos, { 1, 1 }));
+ }
+ if (updated)
+ queueTileUpdates(pos);
}
- spaces.materials = move(newMaterialSpaces);
+ spaces.materials = move(passedSpaces);
// add new roots and update known roots entry
for (auto const& rootPos : newRoots) {