feat(core): add hopper item transfer between containers

This commit is contained in:
dualfroz committed 2026-08-25 10:37:13 +02:00
1 parent a6bae52f26
commit 9f0cbc3410
2 files changed
+93

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
#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