resource renewal tests

This commit is contained in:
Connor
2026-02-15 23:01:19 +09:00
parent 5534b169d6
commit 01eaebeb71
2 changed files with 121 additions and 9 deletions

View File

@@ -37,9 +37,7 @@ inline void Flecs_Resource(flecs::world& world)
world.component<ResourceHealth>() world.component<ResourceHealth>()
.member<uint16_t>("MaxHealth") .member<uint16_t>("MaxHealth")
.member<uint16_t>("Health") .member<uint16_t>("Health");
.member<uint16_t>("RenewalTicks")
.member<uint16_t>("Renewal");
world.component<ResourceTick>() world.component<ResourceTick>()
.is_a<TickAccumulator>(); .is_a<TickAccumulator>();
@@ -50,9 +48,6 @@ inline void Flecs_Resource(flecs::world& world)
world.component<Renewing>() world.component<Renewing>()
.add<Freezes, ResourceTick>(); .add<Freezes, ResourceTick>();
world.component<Renewing>()
.add<Freezes, ResourceTick>();
// harvesting resource to world inventory // harvesting resource to world inventory
world.system<const ResourceInfo, const ResourceTick, WorldInventory>() world.system<const ResourceInfo, const ResourceTick, WorldInventory>()
.kind(flecs::OnUpdate) .kind(flecs::OnUpdate)
@@ -70,11 +65,10 @@ inline void Flecs_Resource(flecs::world& world)
}); });
// decrease health if ResourceHealth component // decrease health if ResourceHealth component
world.system<const ResourceHealth, const ResourceTick>() world.system<ResourceHealth, const ResourceTick>()
.kind(flecs::OnUpdate) .kind(flecs::OnUpdate)
.without<Renewing>() .without<Renewing>()
.each([](ResourceHealth& health, ResourceTick tick){ .each([](ResourceHealth& health, ResourceTick tick){
if (tick.)
health.Health -= tick.Finished(); health.Health -= tick.Finished();
}); });
@@ -91,7 +85,17 @@ inline void Flecs_Resource(flecs::world& world)
}); });
// finish renewing // finish renewing
world.system<ResourceHealth, RenewingTick>("Finish Renewing")
.kind(flecs::OnUpdate)
.with<Renewing>()
.each([](flecs::entity entity, ResourceHealth& health, RenewingTick& tick) {
if (tick.Finished()) {
health.Health = health.MaxHealth;
entity.remove<Renewing>();
entity.add<FullyGrown>();
entity.ensure<ResourceTick>().AccumulatedTick = 0;
}
});
} }
inline void Resource_Ore_Helper(const flecs::entity& entity, uint16_t resourceID, uint16_t gatherTicks) inline void Resource_Ore_Helper(const flecs::entity& entity, uint16_t resourceID, uint16_t gatherTicks)
@@ -104,4 +108,21 @@ inline void Resource_Ore_Helper(const flecs::entity& entity, uint16_t resourceID
entity.set<ResourceInfo>(info); entity.set<ResourceInfo>(info);
entity.set<ResourceTick>(tick); entity.set<ResourceTick>(tick);
}
inline void Resource_Tree_Helper(const flecs::entity& entity, uint16_t resourceID,
uint16_t gatherTicks, uint16_t maxHealth, uint16_t renewalTicks)
{
Resource_Ore_Helper(entity, resourceID, gatherTicks);
ResourceHealth health{};
health.MaxHealth = maxHealth;
health.Health = maxHealth;
RenewingTick tick{};
tick.MaxTick = renewalTicks;
entity.set<ResourceHealth>(health);
entity.set<RenewingTick>(tick);
entity.add<FullyGrown>();
} }

View File

@@ -41,3 +41,94 @@ TEST_SUITE("Resource") {
CHECK(inv.GetItemsAmount(stoneID) >= 1); CHECK(inv.GetItemsAmount(stoneID) >= 1);
} }
} }
TEST_SUITE("Resource - Health & Renewing") {
TEST_CASE("tree resource loses health each gather cycle") {
WorldConfig config{};
uint16_t woodID = config.RegisterItem("Wood");
WorldInstance world{ config };
auto entity = world.GetEcsWorld().entity();
Resource_Tree_Helper(entity, woodID, 1, 3, 5);
world.ProcessFrame();
auto& inv = world.GetEcsWorld().ensure<WorldInventory>();
CHECK(inv.GetItemsAmount(woodID) == 1);
auto health = entity.get<ResourceHealth>();
CHECK(health.Health == 2);
}
TEST_CASE("tree enters renewing state when health reaches 0") {
WorldConfig config{};
uint16_t woodID = config.RegisterItem("Wood");
WorldInstance world{ config };
auto entity = world.GetEcsWorld().entity();
Resource_Tree_Helper(entity, woodID, 1, 2, 5);
// 2 gather cycles to deplete health
world.ProcessFrame();
world.ProcessFrame();
auto& inv = world.GetEcsWorld().ensure<WorldInventory>();
CHECK(inv.GetItemsAmount(woodID) == 2);
CHECK(entity.has<Renewing>());
// one more tick should not produce items while renewing
world.ProcessFrame();
CHECK(inv.GetItemsAmount(woodID) == 2);
}
TEST_CASE("tree restores health after renewal period") {
WorldConfig config{};
uint16_t woodID = config.RegisterItem("Wood");
WorldInstance world{ config };
auto entity = world.GetEcsWorld().entity();
Resource_Tree_Helper(entity, woodID, 1, 1, 5);
// 1 gather cycle depletes health
world.ProcessFrame();
CHECK(entity.has<Renewing>());
// 5 ticks for renewal
for (int i = 0; i < 5; ++i)
world.ProcessFrame();
CHECK_FALSE(entity.has<Renewing>());
CHECK(entity.has<FullyGrown>());
auto health = entity.get<ResourceHealth>();
CHECK(health.Health == health.MaxHealth);
}
TEST_CASE("tree resumes gathering after renewal") {
WorldConfig config{};
uint16_t woodID = config.RegisterItem("Wood");
WorldInstance world{ config };
auto entity = world.GetEcsWorld().entity();
Resource_Tree_Helper(entity, woodID, 1, 1, 5);
// deplete
world.ProcessFrame();
auto& inv = world.GetEcsWorld().ensure<WorldInventory>();
CHECK(inv.GetItemsAmount(woodID) == 1);
// renew (5 ticks)
for (int i = 0; i < 5; ++i)
world.ProcessFrame();
CHECK_FALSE(entity.has<Renewing>());
// should gather again
world.ProcessFrame();
CHECK(inv.GetItemsAmount(woodID) == 2);
}
}