From dbc0ce5981ed495e9ea315b1053608dd3403c8d7 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Fri, 5 Jan 2024 08:36:05 +0100 Subject: [PATCH] Basic property editor --- game/components.c | 35 ++++++++++++++++++++++++ game/components.h | 6 +++++ game/main.c | 60 ++++++++++++++++++++++-------------------- game/map_init.c | 1 - game/systems/s_input.c | 2 +- 5 files changed, 73 insertions(+), 31 deletions(-) diff --git a/game/components.c b/game/components.c index 7136898..531ba71 100644 --- a/game/components.c +++ b/game/components.c @@ -77,3 +77,38 @@ void initComponentIDs(ecs_world_t *ecs) { ECS_TAG_DEFINE(ecs, Attackable); } + +#include +void igTagCheckbox(const char *label, ecs_world_t *ecs, + ecs_entity_t entity, ecs_entity_t tag) { + bool hasTag = ecs_has_id(ecs, entity, tag); + igCheckbox(label, &hasTag); + if (hasTag) + ecs_add_id(ecs, entity, tag); + else + ecs_remove_id(ecs, entity, tag); +} +void igResource(const char *label, ecs_world_t *ecs, + ecs_entity_t entity, ecs_entity_t comp) { + if (!ecs_has_id(ecs, entity, comp)) return; + igSeparatorText(label); + Resource *res = ecs_get_mut_id(ecs, entity, comp); + const char *resStrings[RES_COUNT]; + for (i32 i = 0; i < RES_COUNT; i++) { + resStrings[i] = getResourceTypePrettyName(i); + } + int curType = res->type; + igCombo_Str_arr("Type", &curType, resStrings, RES_COUNT, -1); + res->type = curType; + igInputInt("Amount", &res->amount, 1, 10, 0); +} +void igVec2(const char *label, ecs_world_t *ecs, + ecs_entity_t entity, ecs_entity_t comp) { + if (!ecs_has_id(ecs, entity, comp)) return; + igSeparatorText(label); + Vector2 *vec = ecs_get_mut_id(ecs, entity, comp); + igPushID_Str(label); + igInputFloat("X", &vec->x, 1.0f, 10.0f, "%.2f", 0); + igInputFloat("Y", &vec->y, 1.0f, 10.0f, "%.2f", 0); + igPopID(); +} diff --git a/game/components.h b/game/components.h index efed150..7d42d49 100644 --- a/game/components.h +++ b/game/components.h @@ -205,4 +205,10 @@ extern ECS_TAG_DECLARE(Attackable); void initComponentIDs(ecs_world_t *ecs); +void igTagCheckbox(const char *label, ecs_world_t *ecs, + ecs_entity_t entity, ecs_entity_t tag); +void igResource(const char *label, ecs_world_t *ecs, + ecs_entity_t entity, ecs_entity_t comp); +void igVec2(const char *label, ecs_world_t *ecs, + ecs_entity_t entity, ecs_entity_t comp); #endif //PIXELDEFENSE_COMPONENTS_H diff --git a/game/main.c b/game/main.c index a60ccb7..712eab7 100644 --- a/game/main.c +++ b/game/main.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -566,11 +565,38 @@ void render(float dt, void *userData) { } +static void igEntity(ecs_entity_t entity) { + char buf[64]; + snprintf(buf, sizeof(buf), "Entity: %ld", entity); + if (igTreeNode_Str(buf)) { + igSeparatorText("Tags"); + { + igTagCheckbox("GameEntity", ECS, entity, GameEntity); + igTagCheckbox("Selectable", ECS, entity, Selectable); + igTagCheckbox("Selected", ECS, entity, Selected); + igTagCheckbox("Storage", ECS, entity, Storage); + igTagCheckbox("Harvestable", ECS, entity, Harvestable); + igTagCheckbox("Workable", ECS, entity, Workable); + igTagCheckbox("Attackable", ECS, entity, Attackable); + } + igResource("Resource", ECS, entity, ecs_id(Resource)); + igVec2("Position", ECS, entity, ecs_id(Position)); + igVec2("Size", ECS, entity, ecs_id(Size)); + igVec2("Velocity", ECS, entity, ecs_id(Velocity)); + igVec2("Steering", ECS, entity, ecs_id(Steering)); + igVec2("TargetPosition", ECS, entity, ecs_id(TargetPosition)); + + igTreePop(); + } +} + void imguiRender(float dt, void *userData) { BZ_UNUSED(userData); Game *game = ecs_singleton_get_mut(ECS, Game); InputState *input = ecs_singleton_get_mut(ECS, InputState); + igShowDemoWindow(NULL); + igSetNextWindowSize((ImVec2){300, 400}, ImGuiCond_FirstUseEver); igBegin("Debug Menu", NULL, 0); igText("PathData pool available: %llu", bzObjectPoolGetNumFree(game->pools.pathData)); @@ -596,41 +622,17 @@ void imguiRender(float dt, void *userData) { igText("Input state: %s", inputState); if (igCollapsingHeader_TreeNodeFlags("Selection", 0)) { switch (input->state) { - case INPUT_SELECTED_UNITS: { - igText("Selected units:"); - ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected); - while (ecs_iter_next(&it)) { - for (i32 i = 0; i < it.count; i++) { - ecs_entity_t entity = it.entities[i]; - igText("Entity %llu", entity); - igText("Actions:"); - const Action *pAction = NULL; - if (ecs_has(ECS, entity, UnitAction)) { - pAction = ecs_get(ECS, entity, UnitAction)->first; - } - while (pAction) { - igText("\t%d: %s", pAction->type, actionTypeToPrettyStr(pAction->type)); - pAction = pAction->next; - } - } - } - break; - } + case INPUT_SELECTED_UNITS: case INPUT_SELECTED_OBJECT: { - igText("Selected objects:"); + ecs_defer_begin(ECS); ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected); while (ecs_iter_next(&it)) { for (i32 i = 0; i < it.count; i++) { ecs_entity_t entity = it.entities[i]; - if (ecs_has(ECS, entity, Harvestable) && - ecs_has(ECS, entity, Resource)) { - Resource *res = ecs_get_mut(ECS, entity, Resource); - const char *resName = getResourceTypePrettyName(res->type); - igText("\tEntity %llu:", entity); - igSliderInt("\t\twood", &res->amount, 0, 20, NULL, 0); - } + igEntity(entity); } } + ecs_defer_end(ECS); break; } default: diff --git a/game/map_init.c b/game/map_init.c index be551fe..3ab9948 100644 --- a/game/map_init.c +++ b/game/map_init.c @@ -42,7 +42,6 @@ bool initEntityObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) { .elapsed=i * 0.1f, }); */ - bzLogInfo("%d %.2f %.2f", object.gid, object.shape.sizeX, object.shape.sizeY); //EntityArms arms = { // .left=createEntity(ECS), // .right=createEntity(ECS), diff --git a/game/systems/s_input.c b/game/systems/s_input.c index 2a15dc2..e70fa03 100644 --- a/game/systems/s_input.c +++ b/game/systems/s_input.c @@ -340,7 +340,7 @@ void drawPlayerInputUIGround() { break; } case INPUT_SELECTED_UNITS: { - BZ_ASSERT(selectedUnitCount); + //BZ_ASSERT(selectedUnitCount); /* if (selectedUnitCount > 1 && isInputBtnDragged(input, primaryBtn)) { i32 numUnits = selectedUnitCount;