From 29a229d975cc30003334f66eed9454a7d95997c8 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Mon, 24 Aug 2026 21:48:43 +0200 Subject: [PATCH] feat(core): declare redstone-style circuit signal propagation interface --- core/include/vf/Circuit.h | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 core/include/vf/Circuit.h diff --git a/core/include/vf/Circuit.h b/core/include/vf/Circuit.h new file mode 100644 index 0000000..65e6983 --- /dev/null +++ b/core/include/vf/Circuit.h @@ -0,0 +1,84 @@ +#pragma once + +#include +#include +#include +#include "World.h" +#include "Block.h" + +namespace vf { + +constexpr int redstoneMaxPower = 15; + +enum class ComparatorMode : uint8_t { + Compare = 0, + Subtract = 1, +}; + +struct RepeaterState { + Face facing = Face::PosX; + int delayTicks = 1; + bool lastInput = false; + int countdown = -1; + bool pendingOutput = false; + bool outputOn = false; +}; + +struct ComparatorState { + Face facing = Face::PosX; + ComparatorMode mode = ComparatorMode::Compare; +}; + +class RedstoneCircuit { +public: + RedstoneCircuit(World& world, const Vec3i& origin, const Vec3i& dims); + + void setLever(const Vec3i& pos, bool on); + bool leverOn(const Vec3i& pos) const; + + void pressButton(const Vec3i& pos, int durationTicks = 10); + bool buttonActive(const Vec3i& pos) const; + + void setRepeater(const Vec3i& pos, Face facing, int delayTicks); + void setComparator(const Vec3i& pos, Face facing, ComparatorMode mode); + bool repeaterOutputOn(const Vec3i& pos) const; + + void tick(); + + int powerAt(int gx, int gy, int gz) const; + bool poweredAt(int gx, int gy, int gz) const { return powerAt(gx, gy, gz) > 0; } + + void applyLamps(); + + const Vec3i& regionOrigin() const { return origin; } + const Vec3i& regionDims() const { return dims; } + int currentTick() const { return tickCounter; } + +private: + int index(int lx, int ly, int lz) const { return (ly * dims.z + lz) * dims.x + lx; } + bool inBox(int lx, int ly, int lz) const; + bool toLocal(int gx, int gy, int gz, int& lx, int& ly, int& lz) const; + int fieldAt(const std::vector& field, int gx, int gy, int gz) const; + + void advanceComponents(); + void resolvePowerField(); + void injectOmni(const Vec3i& pos, int level, std::vector& wireQueue); + void injectOmniExcept(const Vec3i& pos, int level, const Vec3i& excludeOffset, + std::vector& wireQueue); + void injectDirectional(const Vec3i& pos, Face facing, int level, std::vector& wireQueue); + void propagateWire(std::vector& wireQueue); + int comparatorOutput(const Vec3i& pos, const ComparatorState& state) const; + + World& world; + Vec3i origin; + Vec3i dims; + int tickCounter = 0; + std::vector power; + std::vector previousPower; + std::unordered_map leverStates; + std::unordered_map buttonTimers; + std::unordered_map repeaters; + std::unordered_map comparators; +}; + +} // namespace vf