163 lines
4.7 KiB
C++
163 lines
4.7 KiB
C++
#include <doctest/doctest.h>
|
|
#include "Components/Configs/WorldConfig.hpp"
|
|
#include "Core/WorldInstance.h"
|
|
#include "Components/Chute.hpp"
|
|
|
|
TEST_SUITE("Chute") {
|
|
TEST_CASE("chute transports item from source to destination") {
|
|
WorldConfig config{};
|
|
uint16_t stoneID = config.RegisterItem("Stone");
|
|
|
|
WorldInstance world{ config };
|
|
|
|
// source inventory with items, destination empty
|
|
auto source = world.GetEcsWorld().entity();
|
|
Inventory_Helper(source, config, 100);
|
|
source.ensure<Inventory>().AddItems(stoneID, 3);
|
|
|
|
auto dest = world.GetEcsWorld().entity();
|
|
Inventory_Helper(dest, config, 100);
|
|
|
|
// vertical drop: (0,10) -> (0,0), should be fast
|
|
std::vector<Vector2> path = { {0, 10}, {0, 0} };
|
|
auto chuteEntity = world.GetEcsWorld().entity();
|
|
Chute_Helper(chuteEntity, path,
|
|
source.get<Inventory>(),
|
|
dest.get<Inventory>());
|
|
|
|
// get the transit time
|
|
auto chute = chuteEntity.get<Chute>();
|
|
uint16_t transitTicks = chute.Data.GetMetaData()->TicksToReachEnd;
|
|
CHECK(transitTicks > 0);
|
|
|
|
// tick once to pull items from source into chute
|
|
world.ProcessFrame();
|
|
|
|
auto srcInv = source.get<Inventory>();
|
|
CHECK(srcInv.GetItemsAmount(stoneID) == 0);
|
|
|
|
// tick until items arrive
|
|
for (uint16_t i = 1; i < transitTicks; ++i)
|
|
world.ProcessFrame();
|
|
|
|
auto destInv = dest.get<Inventory>();
|
|
CHECK(destInv.GetItemsAmount(stoneID) == 0);
|
|
|
|
world.ProcessFrame();
|
|
|
|
destInv = dest.get<Inventory>();
|
|
CHECK(destInv.GetItemsAmount(stoneID) == 3);
|
|
}
|
|
|
|
TEST_CASE("chute respects transit time for longer paths") {
|
|
WorldConfig config{};
|
|
uint16_t ironID = config.RegisterItem("Iron");
|
|
|
|
WorldInstance world{ config };
|
|
|
|
auto source = world.GetEcsWorld().entity();
|
|
Inventory_Helper(source, config, 100);
|
|
source.ensure<Inventory>().AddItems(ironID, 1);
|
|
|
|
auto dest = world.GetEcsWorld().entity();
|
|
Inventory_Helper(dest, config, 100);
|
|
|
|
// multi-link path with gradual descent
|
|
std::vector<Vector2> path = { {0, 10}, {1, 9}, {2, 8}, {3, 7}, {4, 6}, {5, 5} };
|
|
auto chuteEntity = world.GetEcsWorld().entity();
|
|
Chute_Helper(chuteEntity, path,
|
|
source.get<Inventory>(),
|
|
dest.get<Inventory>());
|
|
|
|
auto chute = chuteEntity.get<Chute>();
|
|
uint16_t transitTicks = chute.Data.GetMetaData()->TicksToReachEnd;
|
|
CHECK(transitTicks > 1);
|
|
|
|
// pull items into chute
|
|
world.ProcessFrame();
|
|
|
|
// tick one less than transit time — item should not have arrived
|
|
for (uint16_t i = 1; i < transitTicks; ++i)
|
|
world.ProcessFrame();
|
|
|
|
auto destInv = dest.get<Inventory>();
|
|
CHECK(destInv.GetItemsAmount(ironID) == 0);
|
|
|
|
// one more tick — item arrives
|
|
world.ProcessFrame();
|
|
|
|
destInv = dest.get<Inventory>();
|
|
CHECK(destInv.GetItemsAmount(ironID) == 1);
|
|
}
|
|
|
|
TEST_CASE("chute overflows to world inventory when destination is full") {
|
|
WorldConfig config{};
|
|
uint16_t stoneID = config.RegisterItem("Stone");
|
|
|
|
WorldInstance world{ config };
|
|
|
|
auto source = world.GetEcsWorld().entity();
|
|
Inventory_Helper(source, config, 100);
|
|
source.ensure<Inventory>().AddItems(stoneID, 3);
|
|
|
|
// destination can only hold 1
|
|
auto dest = world.GetEcsWorld().entity();
|
|
Inventory_Helper(dest, config, 1);
|
|
|
|
std::vector<Vector2> path = { {0, 10}, {0, 0} };
|
|
auto chuteEntity = world.GetEcsWorld().entity();
|
|
Chute_Helper(chuteEntity, path,
|
|
source.get<Inventory>(),
|
|
dest.get<Inventory>());
|
|
|
|
auto chute = chuteEntity.get<Chute>();
|
|
uint16_t transitTicks = chute.Data.GetMetaData()->TicksToReachEnd;
|
|
|
|
// tick enough for all items to arrive
|
|
for (uint16_t i = 0; i <= transitTicks; ++i)
|
|
world.ProcessFrame();
|
|
|
|
auto destInv = dest.get<Inventory>();
|
|
CHECK(destInv.GetItemsAmount(stoneID) == 1);
|
|
|
|
auto& worldInv = world.GetEcsWorld().ensure<WorldInventory>();
|
|
CHECK(worldInv.GetItemsAmount(stoneID) == 2);
|
|
}
|
|
|
|
TEST_CASE("horizontal chute uses minimum speed") {
|
|
WorldConfig config{};
|
|
uint16_t woodID = config.RegisterItem("Wood");
|
|
|
|
WorldInstance world{ config };
|
|
|
|
auto source = world.GetEcsWorld().entity();
|
|
Inventory_Helper(source, config, 100);
|
|
source.ensure<Inventory>().AddItems(woodID, 1);
|
|
|
|
auto dest = world.GetEcsWorld().entity();
|
|
Inventory_Helper(dest, config, 100);
|
|
|
|
// flat path: dy=0 throughout, should use MinSpeed
|
|
ChuteConfig chuteConfig{ .Gravity = 1.0f, .MinSpeed = 0.5f };
|
|
std::vector<Vector2> path = { {0, 0}, {5, 0} };
|
|
auto chuteEntity = world.GetEcsWorld().entity();
|
|
Chute_Helper(chuteEntity, path,
|
|
source.get<Inventory>(),
|
|
dest.get<Inventory>(),
|
|
chuteConfig);
|
|
|
|
auto chute = chuteEntity.get<Chute>();
|
|
uint16_t transitTicks = chute.Data.GetMetaData()->TicksToReachEnd;
|
|
|
|
// distance=5, speed=0.5 -> 10 ticks
|
|
CHECK(transitTicks == 10);
|
|
|
|
// tick enough for item to arrive
|
|
for (uint16_t i = 0; i <= transitTicks; ++i)
|
|
world.ProcessFrame();
|
|
|
|
auto destInv = dest.get<Inventory>();
|
|
CHECK(destInv.GetItemsAmount(woodID) == 1);
|
|
}
|
|
}
|