fix bug where items get already consumed right after being placed on a belt

This commit is contained in:
2026-04-20 22:14:55 +02:00
parent a924877e20
commit 35dd81748e
2 changed files with 32 additions and 23 deletions

View File

@@ -101,12 +101,13 @@ TEST_CASE("BeltSystem: third tryPutItem on full tile returns false", "[belt]")
// tryTakeItem
// ---------------------------------------------------------------------------
TEST_CASE("BeltSystem: tryTakeItem returns placed item", "[belt]")
TEST_CASE("BeltSystem: tryTakeItem returns placed item after reaching output edge", "[belt]")
{
BeltSystem bs(kFastBeltSpeed);
const QPoint tile(0, 0);
bs.placeBelt(tile, Rotation::East);
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
bs.tick(); // advance to output edge
const std::optional<Item> taken = bs.tryTakeItem(eastPort(tile));
@@ -114,7 +115,23 @@ TEST_CASE("BeltSystem: tryTakeItem returns placed item", "[belt]")
REQUIRE(taken->type.id == "iron_ore");
}
TEST_CASE("BeltSystem: tryTakeItem with two items returns both in sequence", "[belt]")
TEST_CASE("BeltSystem: tryTakeItem requires item to reach output edge before yielding", "[belt]")
{
BeltSystem bs(kFastBeltSpeed);
const QPoint tile(0, 0);
bs.placeBelt(tile, Rotation::East);
bs.tryPutItem(eastPort(tile), makeItem("iron_ore"));
// Item placed but not yet at output edge — must not be available.
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tile)).has_value());
REQUIRE_FALSE(bs.peekItem(eastPort(tile)).has_value());
// After one tick the item has reached progress 1.0 and is available.
bs.tick();
REQUIRE(bs.tryTakeItem(eastPort(tile)).has_value());
}
TEST_CASE("BeltSystem: tryTakeItem with two items returns both after each reaches output edge", "[belt]")
{
BeltSystem bs(kFastBeltSpeed);
const QPoint tile(0, 0);
@@ -122,15 +139,16 @@ TEST_CASE("BeltSystem: tryTakeItem with two items returns both in sequence", "[b
bs.tryPutItem(eastPort(tile), makeItem("first"));
bs.tryPutItem(eastPort(tile), makeItem("second"));
// First take returns front item (first placed, higher progress).
// Front item reaches output edge after one tick.
bs.tick();
const std::optional<Item> taken1 = bs.tryTakeItem(eastPort(tile));
REQUIRE(taken1.has_value());
// Second take returns the remaining item.
// Back item (now promoted to front) needs another tick to reach output edge.
bs.tick();
const std::optional<Item> taken2 = bs.tryTakeItem(eastPort(tile));
REQUIRE(taken2.has_value());
// Tile is now empty.
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tile)).has_value());
}
@@ -156,7 +174,7 @@ TEST_CASE("BeltSystem: tryTakeItem returns nullopt on direction mismatch", "[bel
// tick() — item advancement
// ---------------------------------------------------------------------------
TEST_CASE("BeltSystem: one tick moves item from tile A to tile B in a 2-tile chain", "[belt]")
TEST_CASE("BeltSystem: item transfers from tile A to tile B and becomes available after two ticks", "[belt]")
{
BeltSystem bs(kFastBeltSpeed);
const QPoint tileA(0, 0);
@@ -165,9 +183,9 @@ TEST_CASE("BeltSystem: one tick moves item from tile A to tile B in a 2-tile cha
bs.placeBelt(tileB, Rotation::East);
bs.tryPutItem(eastPort(tileA), makeItem("iron_ore"));
bs.tick();
bs.tick(); // item reaches output edge of A, moves to B at progress 0
bs.tick(); // item reaches output edge of B
// Item should have moved to tileB.
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tileA)).has_value());
const std::optional<Item> inB = bs.tryTakeItem(eastPort(tileB));
REQUIRE(inB.has_value());
@@ -187,7 +205,7 @@ TEST_CASE("BeltSystem: item stays at progress 1.0 when next tile is absent", "[b
REQUIRE(bs.tryTakeItem(eastPort(tileA)).has_value());
}
TEST_CASE("BeltSystem: item traverses 3-tile chain in 2 ticks", "[belt]")
TEST_CASE("BeltSystem: item traverses 3-tile chain in 3 ticks (one per tile)", "[belt]")
{
BeltSystem bs(kFastBeltSpeed);
const QPoint tileA(0, 0);
@@ -198,8 +216,9 @@ TEST_CASE("BeltSystem: item traverses 3-tile chain in 2 ticks", "[belt]")
bs.placeBelt(tileC, Rotation::East);
bs.tryPutItem(eastPort(tileA), makeItem("iron_ore"));
bs.tick(); // A -> B
bs.tick(); // B -> C
bs.tick(); // A output edge → moves to B at progress 0
bs.tick(); // B output edge → moves to C at progress 0
bs.tick(); // C output edge → available for pickup
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tileA)).has_value());
REQUIRE_FALSE(bs.tryTakeItem(eastPort(tileB)).has_value());