mirror of
https://github.com/zoriya/ForecastingVillage.git
synced 2026-05-25 23:58:47 +00:00
Adding a basic line by line dialog engine
This commit is contained in:
@@ -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;
|
||||
|
||||
+1
-1
Submodule lib/gamacon updated: 5483805a16...59415972ed
@@ -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>
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user