#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