diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarFallingBlocksAgent.cpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/game/StarFallingBlocksAgent.cpp')
-rw-r--r-- | source/game/StarFallingBlocksAgent.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/source/game/StarFallingBlocksAgent.cpp b/source/game/StarFallingBlocksAgent.cpp new file mode 100644 index 0000000..945daf5 --- /dev/null +++ b/source/game/StarFallingBlocksAgent.cpp @@ -0,0 +1,81 @@ +#include "StarFallingBlocksAgent.hpp" +#include "StarRoot.hpp" +#include "StarAssets.hpp" + +namespace Star { + +FallingBlocksAgent::FallingBlocksAgent(FallingBlocksFacadePtr worldFacade) + : m_facade(move(worldFacade)) { + m_immediateUpwardPropagateProbability = Root::singleton().assets()->json("/worldserver.config:fallingBlocksImmediateUpwardPropogateProbability").toFloat(); +} + +void FallingBlocksAgent::update() { + HashSet<Vec2I> processing = take(m_pending); + + while (!processing.empty()) { + List<Vec2I> positions; + for (auto const& pos : take(processing)) + positions.append(pos); + + m_random.shuffle(positions); + + positions.sort([](auto const& a, auto const& b) { + return a[1] < b[1]; + }); + + for (auto const& pos : positions) { + Vec2I belowPos = pos + Vec2I(0, -1); + Vec2I belowLeftPos = pos + Vec2I(-1, -1); + Vec2I belowRightPos = pos + Vec2I(1, -1); + + FallingBlockType thisBlock = m_facade->blockType(pos); + FallingBlockType belowBlock = m_facade->blockType(belowPos); + + Maybe<Vec2I> moveTo; + + if (thisBlock == FallingBlockType::Falling) { + if (belowBlock == FallingBlockType::Open) + moveTo = belowPos; + } else if (thisBlock == FallingBlockType::Cascading) { + if (belowBlock == FallingBlockType::Open) { + moveTo = belowPos; + } else { + FallingBlockType belowLeftBlock = m_facade->blockType(belowLeftPos); + FallingBlockType belowRightBlock = m_facade->blockType(belowRightPos); + + if (belowLeftBlock == FallingBlockType::Open && belowRightBlock == FallingBlockType::Open) + moveTo = m_random.randb() ? belowLeftPos : belowRightPos; + else if (belowLeftBlock == FallingBlockType::Open) + moveTo = belowLeftPos; + else if (belowRightBlock == FallingBlockType::Open) + moveTo = belowRightPos; + } + } + + if (moveTo) { + m_facade->moveBlock(pos, *moveTo); + if (m_random.randf() < m_immediateUpwardPropagateProbability) { + processing.add(pos + Vec2I(0, 1)); + processing.add(pos + Vec2I(-1, 1)); + processing.add(pos + Vec2I(1, 1)); + } + + visitLocation(pos); + visitLocation(*moveTo); + } + } + } +} + +void FallingBlocksAgent::visitLocation(Vec2I const& location) { + visitRegion(RectI::withSize(location, Vec2I(1, 1))); +} + +void FallingBlocksAgent::visitRegion(RectI const& region) { + for (int x = region.xMin() - 1; x <= region.xMax(); ++x) { + for (int y = region.yMin(); y <= region.yMax(); ++y) + m_pending.add({x, y}); + } +} + +} |