From dc403c099469a3ca5a7ba99f6086cf66bc58a792 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Wed, 22 Apr 2020 14:37:45 +0200
Subject: [PATCH] Adding input attacks & fixing a segfault
---
CMakeLists.txt | 9 +++-
Makefile | 3 +-
include/components/attack_component.h | 23 +++++++++
include/components/combat_holder.h | 4 +-
include/components/dialog_holder.h | 3 +-
include/systems/combat_manager.h | 8 +++
prefabs/combat.gcprefab | 2 +
prefabs/enemies/bee.gcprefab | 5 +-
src/components/attack_component.c | 49 ++++++++++++++++++
src/components/combat_holder.c | 2 +-
src/components/dialog_holder.c | 3 +-
src/components/dialog_methods.c | 2 +-
src/dialog_input.c | 4 ++
src/game_loader.c | 2 +
src/systems/combat_manager.c | 32 ++----------
src/systems/combat_methods.c | 72 +++++++++++++++++++++++++++
src/systems/dialog_methods.c | 12 ++---
17 files changed, 191 insertions(+), 44 deletions(-)
create mode 100644 include/components/attack_component.h
create mode 100644 src/components/attack_component.c
create mode 100644 src/systems/combat_methods.c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a868e8b..285bf81 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -289,7 +289,14 @@ add_executable(my_rpg
include/systems/combat_manager.h
src/components/player_component.c
include/components/player_component.h
- src/enemy_dataloader.c include/enemy.h src/components/combat_holder.c include/components/combat_holder.h src/components/dialog_methods.c)
+ src/enemy_dataloader.c
+ include/enemy.h
+ src/components/combat_holder.c
+ include/components/combat_holder.h
+ src/components/dialog_methods.c
+ src/components/attack_component.c
+ include/components/attack_component.h
+ src/systems/combat_methods.c)
add_compile_options(-W -Wall -Wextra -Wshadow)
diff --git a/Makefile b/Makefile
index 065ca9b..585974d 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,8 @@ SRC = src/main.c \
src/dialog_input.c \
src/systems/dialog_methods.c \
src/systems/combat_manager.c \
- src/components/player_component.c
+ src/components/player_component.c \
+ src/components/attack_component.c
OBJ = $(SRC:%.c=%.o)
diff --git a/include/components/attack_component.h b/include/components/attack_component.h
new file mode 100644
index 0000000..6e78aed
--- /dev/null
+++ b/include/components/attack_component.h
@@ -0,0 +1,23 @@
+/*
+** EPITECH PROJECT, 2020
+** my_rpg
+** File description:
+** attack_component.h
+*/
+
+
+#ifndef MY_RPG_ATTACK_COMPONENT_H
+#define MY_RPG_ATTACK_COMPONENT_H
+
+#include "component.h"
+
+typedef void (*attack)(gc_entity *from, gc_entity *enemy);
+
+struct attack_component {
+ gc_component base;
+ gc_data *attacks;
+};
+
+extern const struct attack_component attack_component;
+
+#endif //MY_RPG_ATTACK_COMPONENT_H
diff --git a/include/components/combat_holder.h b/include/components/combat_holder.h
index d3207d2..9ecbd00 100644
--- a/include/components/combat_holder.h
+++ b/include/components/combat_holder.h
@@ -13,7 +13,9 @@
enum combat_state
{
- STARTUP,
+ ATTACK,
+ ATTACKING,
+ DEFENDING,
IDLE
};
diff --git a/include/components/dialog_holder.h b/include/components/dialog_holder.h
index 17ed20f..e37bf8a 100644
--- a/include/components/dialog_holder.h
+++ b/include/components/dialog_holder.h
@@ -12,7 +12,7 @@
struct dialog_input {
char *text;
- callback_t callback;
+ void (*callback)(gc_engine *engine, int input_index);
};
struct dialog_line {
@@ -37,6 +37,7 @@ struct dialog_manager {
int dialog_id;
int input_id;
int current_line;
+ int input_index;
struct dialog_line *current_text;
struct dialog_holder *current_dialog;
struct dialog_input *current_input;
diff --git a/include/systems/combat_manager.h b/include/systems/combat_manager.h
index 852b8bc..84a1575 100644
--- a/include/systems/combat_manager.h
+++ b/include/systems/combat_manager.h
@@ -10,6 +10,8 @@
#define MY_RPG_COMBAT_MANAGER_H
#include "system.h"
+#include "components/combat_holder.h"
+#include "components/dialog_holder.h"
struct combat_manager {
gc_system base;
@@ -19,4 +21,10 @@ struct combat_manager {
extern const struct combat_manager combat_manager;
+#define ATTACK_TEXT "What attack will you do?"
+
+void combat_start(gc_engine *engine, char *enemy_name);
+void show_attacks(struct combat_holder *cmp, struct dialog_holder *dialog, \
+gc_scene *scene);
+
#endif //MY_RPG_COMBAT_MANAGER_H
diff --git a/prefabs/combat.gcprefab b/prefabs/combat.gcprefab
index c3baaeb..7be98e3 100644
--- a/prefabs/combat.gcprefab
+++ b/prefabs/combat.gcprefab
@@ -29,6 +29,8 @@
+
+
diff --git a/prefabs/enemies/bee.gcprefab b/prefabs/enemies/bee.gcprefab
index 7f514dd..9c464a0 100644
--- a/prefabs/enemies/bee.gcprefab
+++ b/prefabs/enemies/bee.gcprefab
@@ -8,7 +8,8 @@
-
-
+
+
+
\ No newline at end of file
diff --git a/src/components/attack_component.c b/src/components/attack_component.c
new file mode 100644
index 0000000..1346c25
--- /dev/null
+++ b/src/components/attack_component.c
@@ -0,0 +1,49 @@
+/*
+** EPITECH PROJECT, 2020
+** my_rpg
+** File description:
+** player.c
+*/
+
+#include "engine.h"
+#include "components/attack_component.h"
+
+static void ctr(void *component, va_list args)
+{
+ struct attack_component *cmp = (struct attack_component *)component;
+
+ cmp->attacks = va_arg(args, gc_data *);
+}
+
+static void fdctr(gc_entity *entity, gc_scene *scene, void *component, node *n)
+{
+ struct attack_component *cmp = (struct attack_component *)component;
+
+ // SET ATTACKS FROM the xml.
+}
+
+static void dtr(void *component)
+{
+ (void)component;
+}
+
+static char *serialize(void *component)
+{
+ (void)component;
+ return (NULL);
+}
+
+const struct attack_component attack_component = {
+ base: {
+ name: "attack_component",
+ size: sizeof(struct attack_component),
+ dependencies: (char *[]) {
+ NULL
+ },
+ ctr: &ctr,
+ fdctr: &fdctr,
+ dtr: &dtr,
+ serialize: &serialize,
+ destroy: &component_destroy
+ }
+};
diff --git a/src/components/combat_holder.c b/src/components/combat_holder.c
index 5de7778..0f3e85d 100644
--- a/src/components/combat_holder.c
+++ b/src/components/combat_holder.c
@@ -12,7 +12,7 @@ static void ctr(void *component, va_list args)
{
struct combat_holder *cmp = component;
- cmp->state = STARTUP;
+ cmp->state = ATTACK;
cmp->name = va_arg(args, char *);
}
diff --git a/src/components/dialog_holder.c b/src/components/dialog_holder.c
index c8742ec..29a799b 100644
--- a/src/components/dialog_holder.c
+++ b/src/components/dialog_holder.c
@@ -73,7 +73,8 @@ struct dialog_line *dialog_parse_text(gc_scene *scene, node *n)
for (n = n->child; n; n = n->next) {
txt->inputs[i].text = xml_getproperty(n, "text");
click = xml_gettempprop(n, "click");
- if (!(txt->inputs[i++].callback = scene->get_callback(scene, click)))
+ txt->inputs[i++].callback = scene->get_data(scene, "input", click);
+ if (!txt->inputs)
my_printf("Couldn't find a callback with the name: %s.\n", click);
}
return (txt);
diff --git a/src/components/dialog_methods.c b/src/components/dialog_methods.c
index afa842a..2587141 100644
--- a/src/components/dialog_methods.c
+++ b/src/components/dialog_methods.c
@@ -20,7 +20,7 @@ struct dialog_input *inputs)
line->name = name;
line->text = text;
if (inputs)
- for (count = 0; &inputs[count]; count++);
+ for (count = 0; inputs[count].text; count++);
line->input_count = count;
line->inputs = inputs;
for (count = 0; this->text[count]; count++);
diff --git a/src/dialog_input.c b/src/dialog_input.c
index c3a3d03..9ab7c49 100644
--- a/src/dialog_input.c
+++ b/src/dialog_input.c
@@ -14,6 +14,7 @@ enum gc_mousekeys key)
struct dialog_manager *man = GETSYS(engine, dialog_manager);
man->current_input = &man->current_text->inputs[0];
+ man->input_index = 0;
dialog_next(engine);
return (true);
}
@@ -24,6 +25,7 @@ enum gc_mousekeys key)
struct dialog_manager *man = GETSYS(engine, dialog_manager);
man->current_input = &man->current_text->inputs[1];
+ man->input_index = 1;
dialog_next(engine);
return (true);
}
@@ -34,6 +36,7 @@ enum gc_mousekeys key)
struct dialog_manager *man = GETSYS(engine, dialog_manager);
man->current_input = &man->current_text->inputs[2];
+ man->input_index = 2;
dialog_next(engine);
return (true);
}
@@ -44,6 +47,7 @@ enum gc_mousekeys key)
struct dialog_manager *man = GETSYS(engine, dialog_manager);
man->current_input = &man->current_text->inputs[3];
+ man->input_index = 3;
dialog_next(engine);
return (true);
}
\ No newline at end of file
diff --git a/src/game_loader.c b/src/game_loader.c
index b3c84fe..76fa684 100644
--- a/src/game_loader.c
+++ b/src/game_loader.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include "systems/map_movement_system.h"
#include "systems/game_manager_system.h"
#include "systems/controllers/keyboard_controller_system.h"
@@ -76,6 +77,7 @@ int register_customcmps(gc_engine *engine, bool map_editor)
engine->add_system(engine, &game_display_system);
engine->add_component(engine, &xp_component);
engine->add_component(engine, &player_component);
+ engine->add_component(engine, &attack_component);
engine->add_component(engine, &combat_holder);
engine->add_system(engine, new_system(&combat_manager, engine));
engine->finish_physics(engine);
diff --git a/src/systems/combat_manager.c b/src/systems/combat_manager.c
index 5a6ee6a..550b2d4 100644
--- a/src/systems/combat_manager.c
+++ b/src/systems/combat_manager.c
@@ -10,37 +10,13 @@
#include
#include
#include
+#include
#include "engine.h"
#include "my.h"
#include "components/dialog_holder.h"
#include "components/combat_holder.h"
#include "enemy.h"
-void combat_start(gc_engine *engine, char *enemy_name)
-{
- struct combat_manager *this = GETSYS(engine, combat_manager);
- gc_list *li = engine->scene->get_data(engine->scene, "enemies", NULL);
- gc_scene *scene = scene_create(engine, "prefabs/combat.gcprefab");
- struct enemy *enemy = NULL;
-
- if (!scene) {
- my_printf("The combat scene couldn't be found.\n");
- return;
- }
- this->game_scene = engine->scene;
- engine->scene = NULL;
- engine->change_scene(engine, scene);
- dialog_next(engine);
- for (; li; li = li->next) {
- enemy = li->data;
- if ((!enemy_name && random() % 100 < enemy->spawn_rate)
- || (enemy_name && !my_strcmp(enemy_name, enemy->name)))
- break;
- }
- if ((this->current_enemy = enemy))
- prefab_load(engine, enemy->prefab_src);
-}
-
void entity_moved(gc_engine *engine, va_list args)
{
gc_entity *entity = va_arg(args, gc_entity *);
@@ -79,10 +55,8 @@ float dtime)
return;
dialog = GETCMP(li->data, dialog_holder);
switch (cmp->state) {
- case STARTUP:
- dialog_add_line(dialog, NULL, "A bee has appeared.", NULL);
- cmp->state = IDLE;
- break;
+ case ATTACK:
+ return (show_attacks(cmp, dialog, scene));
case IDLE:
break;
}
diff --git a/src/systems/combat_methods.c b/src/systems/combat_methods.c
new file mode 100644
index 0000000..005506c
--- /dev/null
+++ b/src/systems/combat_methods.c
@@ -0,0 +1,72 @@
+/*
+** EPITECH PROJECT, 2020
+** my_rpg
+** File description:
+** combat_methods.c
+*/
+
+#include
+#include "systems/combat_manager.h"
+#include "tile.h"
+#include "components/player_component.h"
+#include "prefab.h"
+#include "components/attack_component.h"
+#include "engine.h"
+#include "my.h"
+#include "components/dialog_holder.h"
+#include "components/combat_holder.h"
+#include "enemy.h"
+
+void combat_start(gc_engine *engine, char *enemy_name)
+{
+ struct combat_manager *this = GETSYS(engine, combat_manager);
+ gc_list *li = engine->scene->get_data(engine->scene, "enemies", NULL);
+ gc_scene *scene = scene_create(engine, "prefabs/combat.gcprefab");
+ struct enemy *enemy = NULL;
+
+ if (!scene) {
+ my_printf("The combat scene couldn't be found.\n");
+ return;
+ }
+ this->game_scene = engine->scene;
+ engine->scene = NULL;
+ engine->change_scene(engine, scene);
+ dialog_next(engine);
+ for (; li; li = li->next) {
+ enemy = li->data;
+ if ((!enemy_name && random() % 100 < enemy->spawn_rate)
+ || (enemy_name && !my_strcmp(enemy_name, enemy->name)))
+ break;
+ }
+ if ((this->current_enemy = enemy))
+ prefab_load(engine, enemy->prefab_src);
+}
+
+void attack_callback(gc_engine *engine, int index)
+{
+ printf("Launching attack %d\n", index);
+}
+
+void show_attacks(struct combat_holder *cmp, struct dialog_holder *dialog, \
+gc_scene *scene)
+{
+ gc_entity *player_entity = scene->get_entity(scene, 50);
+ struct attack_component *player;
+ static struct dialog_input inputs[5];
+ int i = 0;
+
+ if (!player_entity)
+ return;
+ player = GETCMP(player_entity, attack_component);
+ if (!player)
+ return;
+ if (player->attacks) {
+ for (i = 0; player->attacks[i].name && i < 4; i++) {
+ inputs[i].text = player->attacks[i].name;
+ inputs[i].callback = &attack_callback;
+ }
+ }
+ inputs[i].text = NULL;
+ dialog_add_line(dialog, NULL, ATTACK_TEXT, inputs);
+ cmp->state = ATTACKING;
+}
\ No newline at end of file
diff --git a/src/systems/dialog_methods.c b/src/systems/dialog_methods.c
index 997e5aa..b40794c 100644
--- a/src/systems/dialog_methods.c
+++ b/src/systems/dialog_methods.c
@@ -44,14 +44,12 @@ my_strcmp(link->tile->type, "dialog"))
bool update_dialog(struct dialog_manager *this, gc_entity *text, \
gc_entity *name)
{
- struct renderer *rend;
+ struct renderer *rend = GETCMP(name, renderer);
- if (!text || !name)
- return (true);
this->current_text = this->current_dialog->text[this->current_line];
- rend = GETCMP(name, renderer);
if (!rend || rend->type != GC_TXTREND || !rend->data)
return (true);
+ rend->destroy = &text_safe_destroy;
if (this->current_text)
((gc_text *)rend->data)->text = this->current_text->name;
else
@@ -59,6 +57,7 @@ gc_entity *name)
rend = GETCMP(text, renderer);
if (!rend || rend->type != GC_TXTREND || !rend->data)
return (true);
+ rend->destroy = &text_safe_destroy;
if (this->current_text) {
((gc_text *) rend->data)->text = this->current_text->text;
this->current_input = &this->current_text->inputs[0];
@@ -95,7 +94,7 @@ static bool handle_input(gc_engine *engine, struct dialog_manager *this)
void run_input_func(struct dialog_manager *this, gc_engine *engine)
{
if (this->current_input->callback)
- this->current_input->callback(engine, NULL, (gc_vector2){0, 0}, 0);
+ this->current_input->callback(engine, this->input_index);
prefab_destroy(engine->scene, this->input_id);
this->input_id = -1;
}
@@ -116,7 +115,8 @@ void dialog_next(gc_engine *engine)
controllable_set_can_move(scene, false);
holder_name = scene->get_entity(scene, 1336);
entity = scene->get_entity(scene, 1337);
- if (!update_dialog(this, entity, holder_name) && handle_input(engine, this))
+ if (!entity || !holder_name
+ ||!update_dialog(this, entity, holder_name) && handle_input(engine, this))
return;
prefab_destroy(scene, this->dialog_id);
this->dialog_id = -1;