Adding a basic line by line dialog engine

This commit is contained in:
Anonymus Raccoon
2020-04-02 14:35:41 +02:00
parent 6e2097c3e1
commit 2f27e2e812
7 changed files with 125 additions and 27 deletions
+5 -4
View File
@@ -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;
+2 -2
View File
@@ -1,4 +1,4 @@
<gc_entities>
<panel src="panel" x="50%" y="87%" width="100%" height="26%" tag="dialog" />
<text text="glkgnzlkgnalnzfkzllf Hello World" x="7%" y="87%" centered="false" tag="dialog"/>
<panel src="panel" x="50%" y="87%" width="100%" height="26%" />
<text text="Fatal error: No dialog found." x="7%" y="87%" centered="false" text_id="1337" />
</gc_entities>
+17
View File
@@ -68,6 +68,23 @@
</renderer>
<map_linker x="5" y="2" />
</gc_entity>
<gc_entity>
<transform_component>
<Position x="0" y="0" />
<Size x="50" y="50" />
</transform_component>
<renderer src="cobblestone">
<Rect height="auto" width="auto" top="0" left="0" />
</renderer>
<map_linker x="2" y="6" />
<dialog_holder x="2" y="5" tile_texture="cobblestone">
<test_dialog line="Hello dirt block, I am the mighty cobble block." />
<test_dialog line="Can I do something for you?" />
</dialog_holder>
</gc_entity>
<panel src="main_ui_game" x="3%" y="2%" width="30%" height="15%" centered="false"/>
<text text="20/20" x="10%" y="6%" centered="false"/>
<text text="0/100" x="10%" y="14%" centered="false"/>
+1 -1
View File
@@ -186,7 +186,7 @@
<tile x="2" y="2" texture="grass_top" />
<tile x="2" y="3" texture="grass_top" />
<tile x="2" y="4" texture="grass_top" />
<tile x="2" y="5" texture="cobblestone" type="dialog" />
<tile x="2" y="5" texture="grass_top" />
<tile x="2" y="6" texture="grass_top" />
<tile x="2" y="7" texture="grass_top" />
<tile x="2" y="8" texture="grass_top" />
+42 -3
View File
@@ -8,22 +8,60 @@
#include "components/dialog_holder.h"
#include <stddef.h>
#include <malloc.h>
#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)
+57 -16
View File
@@ -5,43 +5,82 @@
** dialog_manager.c
*/
#include <components/map_linker.h>
#include <malloc.h>
#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,