From 14f7e2b56c9b9a67be5f260e882815b60be807eb Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Fri, 9 Feb 2024 10:14:54 +0100 Subject: [PATCH] Implement warehouse and granary --- game/ai_actions.c | 8 +++++++- game/building_factory.c | 27 +++++++++++++++++++++++---- game/components.c | 4 ++-- game/components.h | 5 ++++- game/main.c | 1 - game/systems/s_ui.c | 3 ++- 6 files changed, 38 insertions(+), 10 deletions(-) diff --git a/game/ai_actions.c b/game/ai_actions.c index bfebb1e..312beb0 100644 --- a/game/ai_actions.c +++ b/game/ai_actions.c @@ -117,21 +117,27 @@ BzBTStatus aiFindNextHarvestable(AIBlackboard *data, f32 dt) { return BZ_BT_FAIL; } BzBTStatus aiFindNearestStorage(AIBlackboard *data, f32 dt) { + if (!ecs_has(ECS, data->entity, Worker)) + return BZ_BT_FAIL; ecs_filter_t *storageFilter = ecs_filter(ECS, { .terms = {{ecs_id(Position)}, {ecs_id(Storage)}}, }); ecs_iter_t it = ecs_filter_iter(ECS, storageFilter); const Vector2 pos = *ecs_get(ECS, data->entity, Position); + ResourceType resType = data->as.worker.harvestType; ecs_entity_t closest = 0; f32 closestDst = INFINITY; Position closestPos = {INFINITY, INFINITY}; while (ecs_filter_next(&it)) { Position *storagePos = ecs_field(&it, Position, 1); + Storage *storage = ecs_field(&it, Storage, 2); 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) { closest = it.entities[i]; closestDst = dst; diff --git a/game/building_factory.c b/game/building_factory.c index c78bc38..69386f6 100644 --- a/game/building_factory.c +++ b/game/building_factory.c @@ -95,11 +95,14 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type, .hp = 100.0f, .lastChanged = -1.0f, }; - switch (type) { case BUILDING_KEEP: 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, { .numSlots = 1, .slots[0] = { @@ -112,6 +115,20 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type, health.startHP = 1000.0f; health.hp = health.startHP; 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: ecs_set(ECS, building, BuildingRecruitInfo, { .numSlots = 2, @@ -136,7 +153,6 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type, case BUILDING_HOUSE_05: case BUILDING_HOUSE_06: ecs_set(ECS, building, AddPopCapacity, {5}); - ecs_add_id(ECS, building, Storage); break; case BUILDING_WHEAT_0: 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}); health.startHP = 20.0f; health.hp = health.startHP; + hasCollision = false; break; default: break; @@ -154,8 +171,10 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type, ecs_set_ptr(ECS, building, Health, &health); - if (hasCollision) + if (hasCollision) { bzTileMapSetCollisions(&game->map, true, COLL_LAYER_BUILDINGS, posX, posY, sizeX, sizeY); + } + return building; diff --git a/game/components.c b/game/components.c index beea1d8..00f67fc 100644 --- a/game/components.c +++ b/game/components.c @@ -43,7 +43,7 @@ ECS_COMPONENT_DECLARE(Worker); ECS_COMPONENT_DECLARE(Building); ECS_COMPONENT_DECLARE(Unit); ECS_COMPONENT_DECLARE(BuildingRecruitInfo); -ECS_TAG_DECLARE(Storage); +ECS_COMPONENT_DECLARE(Storage); ECS_COMPONENT_DECLARE(Harvestable); ECS_TAG_DECLARE(Buildable); ECS_TAG_DECLARE(Workable); @@ -93,7 +93,7 @@ void initComponentIDs(ecs_world_t *ecs) { ECS_COMPONENT_DEFINE(ecs, Building); ECS_COMPONENT_DEFINE(ecs, Unit); ECS_COMPONENT_DEFINE(ecs, BuildingRecruitInfo); - ECS_TAG_DEFINE(ecs, Storage); + ECS_COMPONENT_DEFINE(ecs, Storage); ECS_COMPONENT_DEFINE(ecs, Harvestable); ECS_TAG_DEFINE(ecs, Buildable); ECS_TAG_DEFINE(ecs, Workable); diff --git a/game/components.h b/game/components.h index 8a4ed7a..4438b4a 100644 --- a/game/components.h +++ b/game/components.h @@ -287,7 +287,10 @@ typedef struct Building { Vec2i pos; Vec2i size; } Building; -extern ECS_TAG_DECLARE(Storage); +typedef struct Storage { + bool stores[RES_COUNT]; +} Storage; +extern ECS_COMPONENT_DECLARE(Storage); extern ECS_COMPONENT_DECLARE(Building); typedef struct Harvestable { i32 harvestLimit; diff --git a/game/main.c b/game/main.c index fab9db2..f061306 100644 --- a/game/main.c +++ b/game/main.c @@ -632,7 +632,6 @@ void igInspectWindow(ecs_entity_t entity, bool *open) { //igTagCheckbox("GameEntity", ECS, entity, GameEntity); igTagCheckbox("Selectable", ECS, entity, Selectable); igTagCheckbox("Selected", ECS, entity, Selected); - igTagCheckbox("Storage", ECS, entity, Storage); igTagCheckbox("Attackable", ECS, entity, Attackable); } if (ecs_has(ECS, entity, BzBTState) && diff --git a/game/systems/s_ui.c b/game/systems/s_ui.c index 2ab9067..711ebbb 100644 --- a/game/systems/s_ui.c +++ b/game/systems/s_ui.c @@ -290,7 +290,8 @@ void drawMainMenuUI(Game *game, f32 dt) { setScreen(game, SCREEN_GAME); unloadMap(game); //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"); } if (uiMainMenuButton("Settings", true)) {