From 02632b248c9fcf9c71d9099e2ac857d8b3d44393 Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:30:03 +1100 Subject: [PATCH] Fix more cases of tile collision not taking object material spaces into account Fixes #53 --- source/game/StarParticleManager.cpp | 2 +- source/game/StarWorldClient.cpp | 4 ++-- source/game/StarWorldGeneration.cpp | 2 +- source/game/StarWorldImpl.hpp | 10 +++++----- source/game/StarWorldServer.cpp | 2 +- source/game/StarWorldTiles.hpp | 5 +++++ 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/source/game/StarParticleManager.cpp b/source/game/StarParticleManager.cpp index 6ba0dbf..4629567 100644 --- a/source/game/StarParticleManager.cpp +++ b/source/game/StarParticleManager.cpp @@ -49,7 +49,7 @@ void ParticleManager::update(float dt, RectF const& cullRegion, float wind) { Vec2I pos(particle.position.floor()); TileType tiletype; auto const& tile = m_tileSectorArray->tile(pos); - if (isSolidColliding(tile.collision)) + if (isSolidColliding(tile.getCollision())) tiletype = TileType::Colliding; else if (tile.liquid.level > 0.5f) tiletype = TileType::Water; diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 535980b..b1ad698 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -256,7 +256,7 @@ void WorldClient::forEachCollisionBlock(RectI const& region, function(this)->freshenCollision(region); m_tileArray->tileEach(region, [iterator](Vec2I const& pos, ClientTile const& tile) { - if (tile.collision == CollisionKind::Null) { + if (tile.getCollision() == CollisionKind::Null) { iterator(CollisionBlock::nullBlock(pos)); } else { starAssert(!tile.collisionCacheDirty); @@ -1760,7 +1760,7 @@ void WorldClient::initWorld(WorldStartPacket const& startPacket) { m_weather.setup(m_geometry, [this](Vec2I const& pos) { auto const& tile = m_tileArray->tile(pos); - return !isRealMaterial(tile.background) && !isSolidColliding(tile.collision); + return !isRealMaterial(tile.background) && !isSolidColliding(tile.getCollision()); }); m_weather.readUpdate(startPacket.weatherData); diff --git a/source/game/StarWorldGeneration.cpp b/source/game/StarWorldGeneration.cpp index 55a3b46..b47b776 100644 --- a/source/game/StarWorldGeneration.cpp +++ b/source/game/StarWorldGeneration.cpp @@ -596,7 +596,7 @@ bool SpawnerWorld::spawningProhibited(RectF const& area) const { for (int x = region.xMin(); x < region.xMax(); ++x) { for (int y = region.yMin(); y < region.yMax(); ++y) { auto const& tile = m_worldServer->getServerTile({x, y}); - if (tile.collision == CollisionKind::Null || tile.dungeonId != NoDungeonId) + if (tile.getCollision() == CollisionKind::Null || tile.dungeonId != NoDungeonId) return true; } } diff --git a/source/game/StarWorldImpl.hpp b/source/game/StarWorldImpl.hpp index 3e3728b..a567ae6 100644 --- a/source/game/StarWorldImpl.hpp +++ b/source/game/StarWorldImpl.hpp @@ -86,7 +86,7 @@ namespace WorldImpl { Vec2I const& pos, TileLayer layer, bool includeEphemeral, bool checkCollision) { auto& tile = tileSectorArray->tile(pos); if (layer == TileLayer::Foreground) - return (checkCollision ? tile.collision >= CollisionKind::Dynamic : tile.foreground != EmptyMaterialId) || entityMap->tileIsOccupied(pos, includeEphemeral); + return (checkCollision ? tile.getCollision() >= CollisionKind::Dynamic : tile.foreground != EmptyMaterialId) || entityMap->tileIsOccupied(pos, includeEphemeral); else return tile.background != EmptyMaterialId; } @@ -94,13 +94,13 @@ namespace WorldImpl { template CollisionKind tileCollisionKind(shared_ptr const& tileSectorArray, EntityMapPtr const&, Vec2I const& pos) { - return tileSectorArray->tile(pos).collision; + return tileSectorArray->tile(pos).getCollision(); } template bool rectTileCollision(shared_ptr const& tileSectorArray, RectI const& region, CollisionSet const& collisionSet) { return tileSectorArray->tileSatisfies(region, [&collisionSet](Vec2I const&, typename TileSectorArray::Tile const& tile) { - return isColliding(tile.collision, collisionSet); + return isColliding(tile.getCollision(), collisionSet); }); } @@ -398,7 +398,7 @@ namespace WorldImpl { auto tile = tileSectorArray->tile(ipos); bool environmentBreathable = breathableMap.maybe(tile.dungeonId).value(worldTemplate->breathable(ipos[0], ipos[1])); bool liquidBreathable = remainder >= tile.liquid.level; - bool foregroundBreathable = tile.collision != CollisionKind::Block || !world->pointCollision(pos); + bool foregroundBreathable = tile.getCollision() != CollisionKind::Block || !world->pointCollision(pos); return environmentBreathable && foregroundBreathable && liquidBreathable; } @@ -429,7 +429,7 @@ namespace WorldImpl { bool backgroundTransparent = materialDatabase->backgroundLightTransparent(tile.background); bool foregroundTransparent = materialDatabase->foregroundLightTransparent(tile.foreground) - && tile.collision != CollisionKind::Dynamic; + && tile.getCollision() != CollisionKind::Dynamic; cell = {materialDatabase->radiantLight(tile.foreground, tile.foregroundMod).sum() / 3.0f, !foregroundTransparent}; cell.light += liquidsDatabase->radiantLight(tile.liquid).sum() / 3.0f; diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index d4f4a63..ad3b555 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -783,7 +783,7 @@ CollisionKind WorldServer::tileCollisionKind(Vec2I const& pos) const { void WorldServer::forEachCollisionBlock(RectI const& region, function const& iterator) const { const_cast(this)->freshenCollision(region); m_tileArray->tileEach(region, [iterator](Vec2I const& pos, ServerTile const& tile) { - if (tile.collision == CollisionKind::Null) { + if (tile.getCollision() == CollisionKind::Null) { iterator(CollisionBlock::nullBlock(pos)); } else { starAssert(!tile.collisionCacheDirty); diff --git a/source/game/StarWorldTiles.hpp b/source/game/StarWorldTiles.hpp index a4d0dae..2b73b7d 100644 --- a/source/game/StarWorldTiles.hpp +++ b/source/game/StarWorldTiles.hpp @@ -21,6 +21,7 @@ struct WorldTile { MaterialId material(TileLayer layer) const; ModId mod(TileLayer layer) const; MaterialColorVariant materialColor(TileLayer layer) const; + CollisionKind getCollision() const; tuple materialAndColor(TileLayer layer) const; bool isConnectable(TileLayer layer, bool materialOnly) const; bool isColliding(CollisionSet const& collisionSet) const; @@ -265,6 +266,10 @@ inline MaterialColorVariant WorldTile::materialColor(TileLayer layer) const { return backgroundColorVariant; } +inline CollisionKind WorldTile::getCollision() const { + return collision; +} + inline tuple WorldTile::materialAndColor(TileLayer layer) const { if (layer == TileLayer::Foreground) return std::tuple{