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

summaryrefslogtreecommitdiff
path: root/source/game/StarFallingBlocksAgent.cpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarFallingBlocksAgent.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarFallingBlocksAgent.cpp')
-rw-r--r--source/game/StarFallingBlocksAgent.cpp81
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});
+ }
+}
+
+}