cargo component refactoring
This commit is contained in:
@@ -6,13 +6,14 @@
|
||||
|
||||
#include "Building.h"
|
||||
#include "BuildingSystem.h"
|
||||
#include "CargoComponent.h"
|
||||
#include "DeliverScrapBehavior.h"
|
||||
#include "EntityAdmin.h"
|
||||
#include <map>
|
||||
|
||||
#include "ModuleOwnerComponent.h"
|
||||
#include "PositionComponent.h"
|
||||
#include "SalvageCargoComponent.h"
|
||||
#include "SalvagerComponent.h"
|
||||
#include "ScrapDataComponent.h"
|
||||
#include "ScrapSystem.h"
|
||||
#include "tracing.h"
|
||||
@@ -32,44 +33,53 @@ void SalvagerSystem::tick(Tick currentTick, ScrapSystem& scraps, BuildingSystem&
|
||||
const std::vector<ScrapInfo> allScrap = scraps.allScrapInfo();
|
||||
|
||||
// Tick down per-module collection cooldowns.
|
||||
m_admin.forEach<SalvageCargoComponent>(
|
||||
[](entt::entity /*e*/, SalvageCargoComponent& c)
|
||||
m_admin.forEach<SalvagerComponent>(
|
||||
[](entt::entity /*e*/, SalvagerComponent& s)
|
||||
{
|
||||
if (c.cooldownTicksRemaining > 0) { --c.cooldownTicksRemaining; }
|
||||
if (s.cooldownTicksRemaining > 0) { --s.cooldownTicksRemaining; }
|
||||
});
|
||||
|
||||
// Scrap units already claimed by not-yet-applied collection cycles, so two
|
||||
// modules don't both target the last unit of the same pile (the claim would be
|
||||
// dropped at apply time). A pile is available while its amount exceeds its claims.
|
||||
std::map<entt::entity, int> claimedUnits;
|
||||
// Collection cycles already in flight toward each ship's shared cargo pool, so
|
||||
// concurrent modules on the same ship never start more cycles than the remaining
|
||||
// capacity can hold (REQ-SHP-SALVAGE).
|
||||
std::map<entt::entity, int> pendingByShip;
|
||||
for (const PendingCollection& pc : m_pendingCollections)
|
||||
{
|
||||
++claimedUnits[pc.scrap];
|
||||
++pendingByShip[pc.ship];
|
||||
}
|
||||
|
||||
// Cycle start: each ready, in-range module with free cargo begins a collection
|
||||
// cycle — emit the beam now, collect one scrap mid-beam, start the cooldown now.
|
||||
m_admin.forEach<SalvageCargoComponent, ModuleOwnerComponent>(
|
||||
[&](entt::entity moduleEntity, SalvageCargoComponent& c, const ModuleOwnerComponent& o)
|
||||
// Cycle start: each ready, in-range module whose ship's pool has free space begins
|
||||
// a collection cycle — emit the beam now, collect one scrap mid-beam, start the
|
||||
// cooldown now.
|
||||
m_admin.forEach<SalvagerComponent, ModuleOwnerComponent>(
|
||||
[&](entt::entity /*moduleEntity*/, SalvagerComponent& s, const ModuleOwnerComponent& o)
|
||||
{
|
||||
if (c.current >= c.capacity || c.cooldownTicksRemaining > 0) { return; }
|
||||
if (c.collectionIntervalTicks <= 0) { return; }
|
||||
if (!m_admin.hasAll<PositionComponent>(o.owner)) { return; }
|
||||
if (s.cooldownTicksRemaining > 0 || s.collectionIntervalTicks <= 0) { return; }
|
||||
if (!m_admin.hasAll<PositionComponent, CargoComponent>(o.owner)) { return; }
|
||||
|
||||
const CargoComponent& cargo = m_admin.get<CargoComponent>(o.owner);
|
||||
if (cargo.current + pendingByShip[o.owner] >= cargo.maxCapacity) { return; }
|
||||
|
||||
const QVector2D ownerPos = m_admin.get<PositionComponent>(o.owner).value;
|
||||
for (const ScrapInfo& si : allScrap)
|
||||
{
|
||||
if ((si.position - ownerPos).length() > c.collectionRange_tiles) { continue; }
|
||||
if ((si.position - ownerPos).length() > s.collectionRange_tiles) { continue; }
|
||||
if (claimedUnits[si.entity] >= m_admin.get<ScrapDataComponent>(si.entity).amount)
|
||||
{
|
||||
continue; // every remaining unit of this pile is already spoken for
|
||||
}
|
||||
outBeamFiredEvents.push_back(
|
||||
BeamFiredEvent{BeamKind::Salvage, o.owner, si.entity, currentTick});
|
||||
m_pendingCollections.push_back({moduleEntity, si.entity,
|
||||
m_pendingCollections.push_back({o.owner, si.entity,
|
||||
currentTick + kBeamImpactDelayTicks});
|
||||
++claimedUnits[si.entity];
|
||||
c.cooldownTicksRemaining = c.collectionIntervalTicks;
|
||||
++pendingByShip[o.owner];
|
||||
s.cooldownTicksRemaining = s.collectionIntervalTicks;
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -86,18 +96,14 @@ void SalvagerSystem::tick(Tick currentTick, ScrapSystem& scraps, BuildingSystem&
|
||||
bay->anchor.y() + bay->footprint.height() / 2.0f);
|
||||
if ((pos.value - bayCenter).length() > 1.0f) { return; }
|
||||
|
||||
// Decrement the first non-empty salvage child belonging to this ship.
|
||||
bool delivered = false;
|
||||
m_admin.forEach<SalvageCargoComponent, ModuleOwnerComponent>(
|
||||
[&](entt::entity /*ce*/, SalvageCargoComponent& c, const ModuleOwnerComponent& o)
|
||||
{
|
||||
if (delivered || o.owner != ship || c.current <= 0) { return; }
|
||||
if (buildings.deliverScrapToSalvageBay(deliver.deliveryBay))
|
||||
{
|
||||
--c.current;
|
||||
delivered = true;
|
||||
}
|
||||
});
|
||||
// Hand over one unit from the ship's shared cargo pool.
|
||||
if (!m_admin.hasAll<CargoComponent>(ship)) { return; }
|
||||
CargoComponent& cargo = m_admin.get<CargoComponent>(ship);
|
||||
if (cargo.current <= 0) { return; }
|
||||
if (buildings.deliverScrapToSalvageBay(deliver.deliveryBay))
|
||||
{
|
||||
--cargo.current;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -108,12 +114,12 @@ void SalvagerSystem::applyPendingCollections(Tick currentTick, ScrapSystem& scra
|
||||
{
|
||||
if (it->appliesAt <= currentTick)
|
||||
{
|
||||
if (m_admin.isValid(it->module) && m_admin.hasAll<SalvageCargoComponent>(it->module))
|
||||
if (m_admin.isValid(it->ship) && m_admin.hasAll<CargoComponent>(it->ship))
|
||||
{
|
||||
SalvageCargoComponent& c = m_admin.get<SalvageCargoComponent>(it->module);
|
||||
if (c.current < c.capacity && scraps.collectOne(it->scrap))
|
||||
CargoComponent& cargo = m_admin.get<CargoComponent>(it->ship);
|
||||
if (cargo.current < cargo.maxCapacity && scraps.collectOne(it->scrap))
|
||||
{
|
||||
++c.current;
|
||||
++cargo.current;
|
||||
}
|
||||
}
|
||||
it = m_pendingCollections.erase(it);
|
||||
|
||||
Reference in New Issue
Block a user