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,