Implement warehouse and granary

This commit is contained in:
2024-02-09 10:14:54 +01:00
parent ababd53846
commit 14f7e2b56c
6 changed files with 38 additions and 10 deletions

View File

@@ -117,21 +117,27 @@ BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt) {
return BZ_BT_FAIL; return BZ_BT_FAIL;
} }
BzBTStatus aiFindNearestStorage(AIBlackboard *data, f32 dt) { BzBTStatus aiFindNearestStorage(AIBlackboard *data, f32 dt) {
if (!ecs_has(ECS, data->entity, Worker))
return BZ_BT_FAIL;
ecs_filter_t *storageFilter = ecs_filter(ECS, { ecs_filter_t *storageFilter = ecs_filter(ECS, {
.terms = {{ecs_id(Position)}, {ecs_id(Storage)}}, .terms = {{ecs_id(Position)}, {ecs_id(Storage)}},
}); });
ecs_iter_t it = ecs_filter_iter(ECS, storageFilter); ecs_iter_t it = ecs_filter_iter(ECS, storageFilter);
const Vector2 pos = *ecs_get(ECS, data->entity, Position); const Vector2 pos = *ecs_get(ECS, data->entity, Position);
ResourceType resType = data->as.worker.harvestType;
ecs_entity_t closest = 0; ecs_entity_t closest = 0;
f32 closestDst = INFINITY; f32 closestDst = INFINITY;
Position closestPos = {INFINITY, INFINITY}; Position closestPos = {INFINITY, INFINITY};
while (ecs_filter_next(&it)) { while (ecs_filter_next(&it)) {
Position *storagePos = ecs_field(&it, Position, 1); Position *storagePos = ecs_field(&it, Position, 1);
Storage *storage = ecs_field(&it, Storage, 2);
for (i32 i = 0; i < it.count; i++) { for (i32 i = 0; i < it.count; i++) {
f32 dst = Vector2Distance(pos, closestPos); if (resType < 0 || resType >= RES_COUNT) continue;
if (!storage[i].stores[resType]) continue;
f32 dst = Vector2Distance(pos, storagePos[i]);
if (closestDst == INFINITY || dst < closestDst) { if (closestDst == INFINITY || dst < closestDst) {
closest = it.entities[i]; closest = it.entities[i];
closestDst = dst; closestDst = dst;

View File

@@ -95,11 +95,14 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
.hp = 100.0f, .hp = 100.0f,
.lastChanged = -1.0f, .lastChanged = -1.0f,
}; };
switch (type) { switch (type) {
case BUILDING_KEEP: case BUILDING_KEEP:
ecs_set(ECS, building, AddPopCapacity, {10}); ecs_set(ECS, building, AddPopCapacity, {10});
ecs_add_id(ECS, building, Storage); ecs_set(ECS, building, Storage, {
.stores[RES_WOOD] = true,
.stores[RES_GOLD] = true,
.stores[RES_FOOD] = true,
});
ecs_set(ECS, building, BuildingRecruitInfo, { ecs_set(ECS, building, BuildingRecruitInfo, {
.numSlots = 1, .numSlots = 1,
.slots[0] = { .slots[0] = {
@@ -112,6 +115,20 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
health.startHP = 1000.0f; health.startHP = 1000.0f;
health.hp = health.startHP; health.hp = health.startHP;
break; break;
case BUILDING_WAREHOUSE:
ecs_set(ECS, building, Storage, {
.stores[RES_WOOD] = true,
.stores[RES_GOLD] = true,
.stores[RES_FOOD] = false,
});
break;
case BUILDING_GRANARY:
ecs_set(ECS, building, Storage, {
.stores[RES_WOOD] = false,
.stores[RES_GOLD] = false,
.stores[RES_FOOD] = true,
});
break;
case BUILDING_BARRACKS: case BUILDING_BARRACKS:
ecs_set(ECS, building, BuildingRecruitInfo, { ecs_set(ECS, building, BuildingRecruitInfo, {
.numSlots = 2, .numSlots = 2,
@@ -136,7 +153,6 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
case BUILDING_HOUSE_05: case BUILDING_HOUSE_05:
case BUILDING_HOUSE_06: case BUILDING_HOUSE_06:
ecs_set(ECS, building, AddPopCapacity, {5}); ecs_set(ECS, building, AddPopCapacity, {5});
ecs_add_id(ECS, building, Storage);
break; break;
case BUILDING_WHEAT_0: case BUILDING_WHEAT_0:
case BUILDING_WHEAT_1: case BUILDING_WHEAT_1:
@@ -147,6 +163,7 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
ecs_set(ECS, building, Resource, {RES_FOOD, INT32_MAX}); ecs_set(ECS, building, Resource, {RES_FOOD, INT32_MAX});
health.startHP = 20.0f; health.startHP = 20.0f;
health.hp = health.startHP; health.hp = health.startHP;
hasCollision = false;
break; break;
default: default:
break; break;
@@ -154,8 +171,10 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
ecs_set_ptr(ECS, building, Health, &health); ecs_set_ptr(ECS, building, Health, &health);
if (hasCollision) if (hasCollision) {
bzTileMapSetCollisions(&game->map, true, COLL_LAYER_BUILDINGS, posX, posY, sizeX, sizeY); bzTileMapSetCollisions(&game->map, true, COLL_LAYER_BUILDINGS, posX, posY, sizeX, sizeY);
}
return building; return building;

View File

@@ -43,7 +43,7 @@ ECS_COMPONENT_DECLARE(Worker);
ECS_COMPONENT_DECLARE(Building); ECS_COMPONENT_DECLARE(Building);
ECS_COMPONENT_DECLARE(Unit); ECS_COMPONENT_DECLARE(Unit);
ECS_COMPONENT_DECLARE(BuildingRecruitInfo); ECS_COMPONENT_DECLARE(BuildingRecruitInfo);
ECS_TAG_DECLARE(Storage); ECS_COMPONENT_DECLARE(Storage);
ECS_COMPONENT_DECLARE(Harvestable); ECS_COMPONENT_DECLARE(Harvestable);
ECS_TAG_DECLARE(Buildable); ECS_TAG_DECLARE(Buildable);
ECS_TAG_DECLARE(Workable); ECS_TAG_DECLARE(Workable);
@@ -93,7 +93,7 @@ void initComponentIDs(ecs_world_t *ecs) {
ECS_COMPONENT_DEFINE(ecs, Building); ECS_COMPONENT_DEFINE(ecs, Building);
ECS_COMPONENT_DEFINE(ecs, Unit); ECS_COMPONENT_DEFINE(ecs, Unit);
ECS_COMPONENT_DEFINE(ecs, BuildingRecruitInfo); ECS_COMPONENT_DEFINE(ecs, BuildingRecruitInfo);
ECS_TAG_DEFINE(ecs, Storage); ECS_COMPONENT_DEFINE(ecs, Storage);
ECS_COMPONENT_DEFINE(ecs, Harvestable); ECS_COMPONENT_DEFINE(ecs, Harvestable);
ECS_TAG_DEFINE(ecs, Buildable); ECS_TAG_DEFINE(ecs, Buildable);
ECS_TAG_DEFINE(ecs, Workable); ECS_TAG_DEFINE(ecs, Workable);

View File

@@ -287,7 +287,10 @@ typedef struct Building {
Vec2i pos; Vec2i pos;
Vec2i size; Vec2i size;
} Building; } Building;
extern ECS_TAG_DECLARE(Storage); typedef struct Storage {
bool stores[RES_COUNT];
} Storage;
extern ECS_COMPONENT_DECLARE(Storage);
extern ECS_COMPONENT_DECLARE(Building); extern ECS_COMPONENT_DECLARE(Building);
typedef struct Harvestable { typedef struct Harvestable {
i32 harvestLimit; i32 harvestLimit;

View File

@@ -632,7 +632,6 @@ void igInspectWindow(ecs_entity_t entity, bool *open) {
//igTagCheckbox("GameEntity", ECS, entity, GameEntity); //igTagCheckbox("GameEntity", ECS, entity, GameEntity);
igTagCheckbox("Selectable", ECS, entity, Selectable); igTagCheckbox("Selectable", ECS, entity, Selectable);
igTagCheckbox("Selected", ECS, entity, Selected); igTagCheckbox("Selected", ECS, entity, Selected);
igTagCheckbox("Storage", ECS, entity, Storage);
igTagCheckbox("Attackable", ECS, entity, Attackable); igTagCheckbox("Attackable", ECS, entity, Attackable);
} }
if (ecs_has(ECS, entity, BzBTState) && if (ecs_has(ECS, entity, BzBTState) &&

View File

@@ -290,7 +290,8 @@ void drawMainMenuUI(Game *game, f32 dt) {
setScreen(game, SCREEN_GAME); setScreen(game, SCREEN_GAME);
unloadMap(game); unloadMap(game);
//loadMap(game, "assets/maps/tree_test.tmj"); //loadMap(game, "assets/maps/tree_test.tmj");
loadMap(game, "assets/maps/entity_test.tmj"); //loadMap(game, "assets/maps/entity_test.tmj");
loadMap(game, "assets/maps/worker_test.tmj");
//loadMap(game, "assets/maps/map_01.tmj"); //loadMap(game, "assets/maps/map_01.tmj");
} }
if (uiMainMenuButton("Settings", true)) { if (uiMainMenuButton("Settings", true)) {