Improve harvest target assigment (asign closest first)
This commit is contained in:
@@ -96,6 +96,19 @@ static int entityPosPairCmpZero(const void *lhsData, const void *rhsData) {
|
|||||||
|
|
||||||
return vec2CmpZero(&lhs->pos, &rhs->pos);
|
return vec2CmpZero(&lhs->pos, &rhs->pos);
|
||||||
}
|
}
|
||||||
|
typedef struct EntityFloatPair {
|
||||||
|
ecs_entity_t entity;
|
||||||
|
f32 value;
|
||||||
|
} EntityFloatPair;
|
||||||
|
static int entityFloatPairCmp(const void *lhsData, const void *rhsData) {
|
||||||
|
const EntityFloatPair *lhs = lhsData;
|
||||||
|
const EntityFloatPair *rhs = rhsData;
|
||||||
|
|
||||||
|
if (lhs->value < rhs->value) return -1;
|
||||||
|
if (lhs->value > rhs->value) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void inputUnitAction(Game *game, InputState *input) {
|
void inputUnitAction(Game *game, InputState *input) {
|
||||||
ecs_query_t *query = input->queries.selected;
|
ecs_query_t *query = input->queries.selected;
|
||||||
BzTileMap *map = &game->map;
|
BzTileMap *map = &game->map;
|
||||||
@@ -127,35 +140,51 @@ void inputUnitAction(Game *game, InputState *input) {
|
|||||||
BzSpatialGridIter gridIt = bzSpatialGridIter(game->entityGrid,
|
BzSpatialGridIter gridIt = bzSpatialGridIter(game->entityGrid,
|
||||||
mPos.x - hRadius, mPos.y - hRadius,
|
mPos.x - hRadius, mPos.y - hRadius,
|
||||||
mPos.x + hRadius, mPos.y + hRadius);
|
mPos.x + hRadius, mPos.y + hRadius);
|
||||||
|
EntityFloatPair *harvestables = bzStackAlloc(&game->stackAlloc, 0);
|
||||||
|
i32 numHarvestables = 0;
|
||||||
|
while (bzSpatialGridQueryNext(&gridIt)) {
|
||||||
|
ecs_entity_t harvestEntity = *(ecs_entity_t *) gridIt.data;
|
||||||
|
if (!ecs_has(ECS, harvestEntity, Harvestable))
|
||||||
|
continue;
|
||||||
|
if (!ecs_has(ECS, harvestEntity, Resource))
|
||||||
|
continue;
|
||||||
|
if (!ecs_has(ECS, harvestEntity, Position))
|
||||||
|
continue;
|
||||||
|
if (!ecs_has(ECS, harvestEntity, HitBox))
|
||||||
|
continue;
|
||||||
|
Resource res = *ecs_get(ECS, harvestEntity, Resource);
|
||||||
|
if (res.type != resource.type)
|
||||||
|
continue;
|
||||||
|
Position harvestPos = *ecs_get(ECS, harvestEntity, Position);
|
||||||
|
HitBox harvestHB = *ecs_get(ECS, harvestEntity, HitBox);
|
||||||
|
harvestPos = entityGetCenter(harvestPos, harvestHB);
|
||||||
|
f32 dst = Vector2Distance(harvestPos, mPos);
|
||||||
|
harvestables[numHarvestables++] = (EntityFloatPair) {
|
||||||
|
harvestEntity, dst
|
||||||
|
};
|
||||||
|
}
|
||||||
|
qsort(harvestables, numHarvestables, sizeof(*harvestables), entityFloatPairCmp);
|
||||||
|
i32 idxHarvestable = 0;
|
||||||
|
|
||||||
ecs_defer_begin(ECS);
|
ecs_defer_begin(ECS);
|
||||||
ecs_iter_t it = ecs_query_iter(ECS, query);
|
ecs_iter_t it = ecs_query_iter(ECS, query);
|
||||||
while (ecs_query_next(&it)) {
|
while (ecs_query_next(&it)) {
|
||||||
for (i32 i = 0; i < it.count; i++) {
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
|
if (idxHarvestable >= numHarvestables)
|
||||||
|
break;
|
||||||
ecs_entity_t entity = it.entities[i];
|
ecs_entity_t entity = it.entities[i];
|
||||||
|
|
||||||
bool hasNext = false;
|
EntityFloatPair harvestEntity = {0, 0};
|
||||||
ecs_entity_t harvestEntity = 0;
|
while (idxHarvestable < numHarvestables) {
|
||||||
do {
|
harvestEntity = harvestables[idxHarvestable++];
|
||||||
hasNext = bzSpatialGridQueryNext(&gridIt);
|
Harvestable *harvestable = ecs_get_mut(ECS, harvestEntity.entity, Harvestable);
|
||||||
if (!hasNext) break;
|
|
||||||
harvestEntity = *(ecs_entity_t *) gridIt.data;
|
|
||||||
if (!ecs_has(ECS, harvestEntity, Resource))
|
|
||||||
continue;
|
|
||||||
const Resource *res = ecs_get(ECS, harvestEntity, Resource);
|
|
||||||
if (res->type != resource.type)
|
|
||||||
continue;
|
|
||||||
if (!ecs_has(ECS, harvestEntity, Harvestable))
|
|
||||||
continue;
|
|
||||||
Harvestable *harvestable = ecs_get_mut(ECS, harvestEntity, Harvestable);
|
|
||||||
if (harvestable->harvestCount >= harvestable->harvestLimit)
|
if (harvestable->harvestCount >= harvestable->harvestLimit)
|
||||||
continue;
|
continue;
|
||||||
harvestable->harvestCount++;
|
harvestable->harvestCount++;
|
||||||
break;
|
break;
|
||||||
} while (hasNext);
|
}
|
||||||
|
Position target = *ecs_get(ECS, harvestEntity.entity, Position);
|
||||||
if (!hasNext) break;
|
HitBox targetHB = *ecs_get(ECS, harvestEntity.entity, HitBox);
|
||||||
Position target = *ecs_get(ECS, harvestEntity, Position);
|
|
||||||
HitBox targetHB = *ecs_get(ECS, harvestEntity, HitBox);
|
|
||||||
target = entityGetCenter(target, targetHB);
|
target = entityGetCenter(target, targetHB);
|
||||||
|
|
||||||
f32 proximity = 4.0f;
|
f32 proximity = 4.0f;
|
||||||
@@ -166,7 +195,7 @@ void inputUnitAction(Game *game, InputState *input) {
|
|||||||
setAIBehaviour(entity, game->BTs.workerHarvest, &(AIBlackboard) {
|
setAIBehaviour(entity, game->BTs.workerHarvest, &(AIBlackboard) {
|
||||||
.as.worker = {
|
.as.worker = {
|
||||||
.harvestType = resource.type,
|
.harvestType = resource.type,
|
||||||
.harvestTarget = harvestEntity,
|
.harvestTarget = harvestEntity.entity,
|
||||||
.harvestPos = target,
|
.harvestPos = target,
|
||||||
},
|
},
|
||||||
.proximity = proximity,
|
.proximity = proximity,
|
||||||
|
|||||||
Reference in New Issue
Block a user