65 lines
1.8 KiB
C++
65 lines
1.8 KiB
C++
#include "vf/Hopper.h"
|
|
|
|
namespace vf {
|
|
|
|
namespace {
|
|
|
|
Vec3i above(const Vec3i& pos) { return pos + Vec3i{0, 1, 0}; }
|
|
|
|
bool pushOne(Container& source, ContainerStore& store, const Vec3i& target) {
|
|
Container* dest = store.at(target);
|
|
if (!dest) return false;
|
|
return source.transferTo(*dest, 1) > 0;
|
|
}
|
|
|
|
bool pullOne(ContainerStore& store, const Vec3i& source, Container& sink) {
|
|
Container* src = store.at(source);
|
|
if (!src) return false;
|
|
return src->transferTo(sink, 1) > 0;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool hopperCanTransfer(const Vec3i& pos, const HopperState& state, ContainerStore& store) {
|
|
Container* self = store.at(pos);
|
|
if (!self) return false;
|
|
|
|
Vec3i target = pos + faceDelta(state.facing);
|
|
if (!self->isEmpty()) {
|
|
Container* dest = store.at(target);
|
|
if (dest && !dest->isFull()) {
|
|
Container probe = *self;
|
|
Container destCopy = *dest;
|
|
if (probe.transferTo(destCopy, 1) > 0) return true;
|
|
}
|
|
}
|
|
|
|
Container* src = store.at(above(pos));
|
|
if (src && !src->isEmpty() && !self->isFull()) {
|
|
Container srcCopy = *src;
|
|
Container selfCopy = *self;
|
|
if (srcCopy.transferTo(selfCopy, 1) > 0) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool tickHopper(const World& world, const Vec3i& pos, HopperState& state, ContainerStore& store) {
|
|
if (world.blockAt(pos.x, pos.y, pos.z) != Block::Hopper) return false;
|
|
|
|
Container& self = store.ensure(pos, hopperSlots);
|
|
if (state.cooldown > 0) {
|
|
--state.cooldown;
|
|
return false;
|
|
}
|
|
|
|
bool moved = false;
|
|
Vec3i target = pos + faceDelta(state.facing);
|
|
moved |= pushOne(self, store, target);
|
|
moved |= pullOne(store, above(pos), self);
|
|
|
|
if (moved) state.cooldown = hopperCooldownTicks;
|
|
return moved;
|
|
}
|
|
|
|
} // namespace vf
|