From 2f27e2e81289db8e7a9e43cbaba244544d282039 Mon Sep 17 00:00:00 2001 From: Anonymus Raccoon Date: Thu, 2 Apr 2020 14:35:41 +0200 Subject: [PATCH] Adding a basic line by line dialog engine --- include/components/dialog_holder.h | 9 ++-- lib/gamacon | 2 +- prefabs/dialog.gcprefab | 4 +- prefabs/game.gcprefab | 17 +++++++ prefabs/tilemap.gcmap | 2 +- src/components/dialog_holder.c | 45 ++++++++++++++++-- src/systems/dialog_manager.c | 73 +++++++++++++++++++++++------- 7 files changed, 125 insertions(+), 27 deletions(-) diff --git a/include/components/dialog_holder.h b/include/components/dialog_holder.h index e23077a..cfac244 100644 --- a/include/components/dialog_holder.h +++ b/include/components/dialog_holder.h @@ -15,16 +15,17 @@ struct dialog_holder { char **text; bool single_usage; bool has_seen; - - int current_line; - char *current_text; + struct tile *tile; }; const struct dialog_holder dialog_holder; struct dialog_manager { gc_system base; - bool is_dialog_open; + int dialog_id; + int current_line; + char *current_text; + struct dialog_holder *current_dialog; }; const struct dialog_manager dialog_manager; diff --git a/lib/gamacon b/lib/gamacon index 5483805..5941597 160000 --- a/lib/gamacon +++ b/lib/gamacon @@ -1 +1 @@ -Subproject commit 5483805a16b604e74ecbeb681264638ab5579b1f +Subproject commit 59415972ed68b09f1274c8d9b7975de056514348 diff --git a/prefabs/dialog.gcprefab b/prefabs/dialog.gcprefab index aaa260d..390d64b 100644 --- a/prefabs/dialog.gcprefab +++ b/prefabs/dialog.gcprefab @@ -1,4 +1,4 @@ - - + + \ No newline at end of file diff --git a/prefabs/game.gcprefab b/prefabs/game.gcprefab index 0a024a2..443025a 100644 --- a/prefabs/game.gcprefab +++ b/prefabs/game.gcprefab @@ -68,6 +68,23 @@ + + + + + + + + + + + + + + + + + diff --git a/prefabs/tilemap.gcmap b/prefabs/tilemap.gcmap index 355e226..b923815 100644 --- a/prefabs/tilemap.gcmap +++ b/prefabs/tilemap.gcmap @@ -186,7 +186,7 @@ - + diff --git a/src/components/dialog_holder.c b/src/components/dialog_holder.c index fc60e16..410a2a4 100644 --- a/src/components/dialog_holder.c +++ b/src/components/dialog_holder.c @@ -8,22 +8,60 @@ #include "components/dialog_holder.h" #include #include +#include "components/vertex_component.h" +#include "map_utils.h" +#include "my.h" + +void setup_tile_interactions(struct dialog_holder *this, gc_scene *scene, \ +gc_vector2i pos, char *tile_texture) +{ + gc_list *maps = scene->get_entity_by_cmp(scene, "vertex_component"); + struct vertex_component *map; + struct tile *tile; + + if (!maps) + return; + map = GETCMP(maps[0].data, vertex_component); + if (!map || !map->map) + return; + tile = get_tile_at(map, pos); + if (!tile) + return; + if (tile->type) + my_printf("Warning, a dialog is overriding a custom tile type: %s\n", \ +tile->type); + tile->type = "dialog"; + if (tile->texture) + tile->texture = scene->get_data(scene, "sprite", tile_texture); + this->tile = tile; +} static void ctr(void *component, va_list args) { struct dialog_holder *cmp = (struct dialog_holder *)component; + gc_scene *scene = va_arg(args, gc_scene *); + int x; + int y; + char *texture; + if (!scene) + return; cmp->text = va_arg(args, char **); cmp->single_usage = va_arg(args, int); cmp->has_seen = false; - cmp->current_line = 0; - cmp->current_text = NULL; + x = va_arg(args, int); + y = va_arg(args, int); + texture = va_arg(args, char *); + setup_tile_interactions(cmp, scene, (gc_vector2i){x, y}, texture); } static void fdctr(gc_entity *entity, gc_scene *scene, void *component, node *n) { struct dialog_holder *cmp = (struct dialog_holder *)component; int count = xml_getchildcount(n); + int x = xml_getintprop(n, "x"); + int y = xml_getintprop(n, "y"); + char *texture = xml_gettmpstring(n, "tile_texture", NULL); cmp->single_usage = xml_getbool(n, "single_usage", false); cmp->text = malloc(sizeof(char *) * (count + 1)); @@ -31,8 +69,9 @@ static void fdctr(gc_entity *entity, gc_scene *scene, void *component, node *n) return; n = n->child; for (int i = 0; n; n = n->next, i++) - cmp->text[i] = xml_getproperty(n, "data"); + cmp->text[i] = xml_getproperty(n, "line"); cmp->text[count] = NULL; + setup_tile_interactions(cmp, scene, (gc_vector2i){x, y}, texture); } static void dtr(void *component) diff --git a/src/systems/dialog_manager.c b/src/systems/dialog_manager.c index 9df8ff2..4ee0f20 100644 --- a/src/systems/dialog_manager.c +++ b/src/systems/dialog_manager.c @@ -5,43 +5,82 @@ ** dialog_manager.c */ -#include +#include +#include "components/map_linker.h" +#include "text.h" #include "my.h" #include "components/dialog_holder.h" -#include "components/tag_component.h" +#include "components/renderer.h" #include "prefab.h" #include "engine.h" #include "tile.h" -void load_dialog(gc_engine *engine, gc_entity *player) +void load_dialog(struct dialog_manager *this, gc_engine *engine, \ +gc_entity *player) { struct map_linker *link = GETCMP(player, map_linker); + gc_scene *scene = engine->scene; + gc_list *holders = scene->get_entity_by_cmp(scene, "dialog_holder"); + struct dialog_holder *dialog; if (!link || !link->tile->type || my_strcmp(link->tile->type, "dialog")) return; - prefab_load(engine, "prefabs/dialog.gcprefab"); + this->dialog_id = prefab_load(engine, "prefabs/dialog.gcprefab"); + if (this->dialog_id < 0) + my_printf("Couldn't load the dialog prefab.\n"); + if (!holders) + return; + for (; holders; holders = holders->next) { + dialog = GETCMP(holders->data, dialog_holder); + if (dialog->tile == link->tile) + this->current_dialog = dialog; + } + if (!this->current_dialog) + return; + this->current_text = this->current_dialog->text[0]; + this->current_line = 0; +} + +bool update_dialog(struct dialog_manager *this, gc_entity *text, \ +gc_scene *scene) +{ + struct renderer *rend; + + if (!text) + return (true); + rend = GETCMP(text, renderer); + if (!rend || rend->type != GC_TXTREND || !rend->data) + return (true); + if (((gc_text *)rend->data)->text) + free(((gc_text *)rend->data)->text); + this->current_text = this->current_dialog->text[this->current_line]; + if (this->current_text) + ((gc_text *)rend->data)->text = my_strdup(this->current_text); + else + ((gc_text *)rend->data)->text = NULL; + this->current_line++; + return (!this->current_text); } static void check_for_dialog(gc_engine *engine, va_list args) { - struct dialog_manager *dima = GETSYS(engine, dialog_manager); + struct dialog_manager *this = GETSYS(engine, dialog_manager); gc_keybindings key = va_arg(args, gc_keybindings); gc_scene *scene = engine->scene; - gc_list *list; gc_entity *entity = scene->get_entity(scene, 50); if (key != SPACE || !entity) return; - dima->is_dialog_open = !dima->is_dialog_open; - if (dima->is_dialog_open) { - load_dialog(engine, entity); + if (this->dialog_id == -1) + load_dialog(this, engine, entity); + entity = scene->get_entity(scene, 1337); + if (!update_dialog(this, entity, scene)) return; + for (gc_list *li = scene->entities; li; li = li->next) { + if (((gc_entity *) li->data)->prefab_id == this->dialog_id) + ((gc_entity *) li->data)->destroy(li->data, scene); } - list = scene->get_entity_by_cmp(scene, "tag_component"); - for (gc_list *li = list; li; li = li->next) { - if (!my_strcmp(GETCMP(li->data, tag_component)->tag, "dialog")) - ((gc_entity *)li->data)->destroy(li->data, scene); - } + this->dialog_id = -1; } static void update_entity(gc_engine *engine, void *system, gc_entity *entity, \ @@ -55,7 +94,9 @@ static void ctr(void *system, va_list list) struct dialog_manager *dima = (struct dialog_manager *)system; engine->add_event_listener(engine, "key_pressed", &check_for_dialog); - dima->is_dialog_open = false; + dima->dialog_id = -1; + dima->current_line = 0; + dima->current_text = NULL; } static void dtr(void *system, gc_engine *engine) @@ -67,7 +108,7 @@ const struct dialog_manager dialog_manager = { base: { name: "dialog_manager", component_name: "dialog_holder", - size: sizeof(gc_system), + size: sizeof(struct dialog_manager), ctr: &ctr, dtr: &dtr, check_dependencies: &system_check_dependencies,