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;