# HG changeset patch # User David Demelier # Date 1608734268 -3600 # Node ID 3991779aaba93528aad517f963cfe30f6517cf59 # Parent c43e39745cd8ff40fc0c32a3f58bf130dca67d4b adventure: initial test of spawn diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/CMakeLists.txt --- a/libmlk-adventure/CMakeLists.txt Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/CMakeLists.txt Wed Dec 23 15:37:48 2020 +0100 @@ -29,12 +29,22 @@ ${libadventure_SOURCE_DIR}/adventure/adventure_p.h ${libadventure_SOURCE_DIR}/adventure/assets.c ${libadventure_SOURCE_DIR}/adventure/assets.h + ${libadventure_SOURCE_DIR}/adventure/character/black-cat.c + ${libadventure_SOURCE_DIR}/adventure/character/black-cat.h + ${libadventure_SOURCE_DIR}/adventure/character/neth.c + ${libadventure_SOURCE_DIR}/adventure/character/neth.h ${libadventure_SOURCE_DIR}/adventure/dialog/save.c ${libadventure_SOURCE_DIR}/adventure/dialog/save.h + ${libadventure_SOURCE_DIR}/adventure/item/potion.c + ${libadventure_SOURCE_DIR}/adventure/item/potion.h ${libadventure_SOURCE_DIR}/adventure/mapscene/mapscene.c ${libadventure_SOURCE_DIR}/adventure/mapscene/mapscene.h ${libadventure_SOURCE_DIR}/adventure/molko.c ${libadventure_SOURCE_DIR}/adventure/molko.h + ${libadventure_SOURCE_DIR}/adventure/state/battle.c + ${libadventure_SOURCE_DIR}/adventure/state/battle.h + ${libadventure_SOURCE_DIR}/adventure/state/continue.c + ${libadventure_SOURCE_DIR}/adventure/state/continue.h ${libadventure_SOURCE_DIR}/adventure/state/mainmenu.c ${libadventure_SOURCE_DIR}/adventure/state/mainmenu.h ${libadventure_SOURCE_DIR}/adventure/state/map.c @@ -43,8 +53,6 @@ ${libadventure_SOURCE_DIR}/adventure/state/panic.h ${libadventure_SOURCE_DIR}/adventure/state/splashscreen.c ${libadventure_SOURCE_DIR}/adventure/state/splashscreen.h - ${libadventure_SOURCE_DIR}/adventure/state/continue.c - ${libadventure_SOURCE_DIR}/adventure/state/continue.h ${libadventure_SOURCE_DIR}/adventure/trace_hud.c ${libadventure_SOURCE_DIR}/adventure/trace_hud.h ) diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/action/spawner.c --- a/libmlk-adventure/adventure/action/spawner.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/action/spawner.c Wed Dec 23 15:37:48 2020 +0100 @@ -24,8 +24,13 @@ #include #include +#include #include +#include + +#include + #include "spawner.h" static inline unsigned int @@ -39,6 +44,24 @@ return fmin(s->steps, gap_x + gap_y); } +static void +fight(void) +{ + /* TODO: */ + struct battle *bt; + + bt = alloc_new0(sizeof (*bt)); + bt->enemies[0].ch = &character_black_cat; + bt->enemies[0].x = 400; + bt->enemies[0].y = 50; + bt->inventory = &molko.inventory; + + for (size_t i = 0; i < TEAM_MEMBER_MAX; ++i) + bt->team[i].ch = molko.team.members[i]; + + molko_fight(bt); +} + static bool update(struct action *act, unsigned int ticks) { @@ -53,9 +76,7 @@ if (s->steps == 0) { s->steps = util_nrand(s->low, s->high); - - /* TODO: start battle here. */ - return false; + fight(); } } @@ -80,5 +101,7 @@ s->action.data = s; s->action.update = update; + spawner_init(s); + return &s->action; } diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/adventure_p.h --- a/libmlk-adventure/adventure/adventure_p.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/adventure_p.h Wed Dec 23 15:37:48 2020 +0100 @@ -23,9 +23,11 @@ #if defined(MOLKO_WITH_NLS) # include -# define _(s) dgettext("libmlk-adventure", s) +# define _(s) dgettext("libmlk-adventure", s) +# define N_(s) s #else -# define _(s) s +# define _(s) s +# define N_(s) s #endif #endif /* !MOLKO_ADVENTURE_ADVENTURE_P_H */ diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/assets.c --- a/libmlk-adventure/adventure/assets.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/assets.c Wed Dec 23 15:37:48 2020 +0100 @@ -18,15 +18,19 @@ #include #include +#include #include #include #include +#include + #include #include "assets.h" -#define SPRITE(which, file, w, h) { which, file, w, h } +#define SPRITE(which, file, w, h) { which, file, w, h } +#define SOUND(which, file) { which, file } static struct { enum assets_sprite index; @@ -34,14 +38,24 @@ unsigned int cellw; unsigned int cellh; struct texture texture; - struct sprite sprite; } table_sprites[] = { SPRITE(ASSETS_SPRITE_UI_CURSOR, "sprites/ui-cursor.png", 24, 24), SPRITE(ASSETS_SPRITE_CHEST, "sprites/chest.png", 32, 32), + SPRITE(ASSETS_SPRITE_CHARACTER_BLACK_CAT, "images/black-cat.png", 123, 161), + SPRITE(ASSETS_SPRITE_CHARACTER_NETH, "sprites/john-walk.png", 256, 256), + SPRITE(ASSETS_SPRITE_CHARACTER_NETH_SWORD, "sprites/john-sword.png", 256, 256), SPRITE(ASSETS_SPRITE_FACES, "sprites/faces.png", 144, 144) }; -struct sprite *assets_sprites[ASSETS_SPRITE_NUM] = {0}; +static struct { + enum assets_sound index; + const char *path; +} table_sounds[] = { + SOUND(ASSETS_SOUND_ITEM_POTION, "sounds/potion.wav") +}; + +struct sprite assets_sprites[ASSETS_SPRITE_NUM]; +struct sound assets_sounds[ASSETS_SOUND_NUM]; static void init_sprites(void) @@ -50,10 +64,18 @@ if (!image_open(&table_sprites[i].texture, molko_path(table_sprites[i].path))) panic(); - sprite_init(&table_sprites[i].sprite, &table_sprites[i].texture, + sprite_init(&assets_sprites[table_sprites[i].index], + &table_sprites[i].texture, table_sprites[i].cellw, table_sprites[i].cellh); + } +} - assets_sprites[table_sprites[i].index] = &table_sprites[i].sprite; +static void +init_sounds(void) +{ + for (size_t i = 0; i < UTIL_SIZE(assets_sounds); ++i) { + if (!sound_open(&assets_sounds[table_sounds[i].index], molko_path(table_sounds[i].path))) + panic(); } } @@ -61,6 +83,10 @@ assets_init(void) { init_sprites(); + init_sounds(); + + /* Prepare the theme. */ + theme_default()->sprites[THEME_SPRITE_CURSOR] = &assets_sprites[ASSETS_SPRITE_UI_CURSOR]; } void @@ -68,4 +94,6 @@ { for (size_t i = 0; i < UTIL_SIZE(table_sprites); ++i) texture_finish(&table_sprites[i].texture); + for (size_t i = 0; i < UTIL_SIZE(table_sounds); ++i) + sound_finish(&assets_sounds[i]); } diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/assets.h --- a/libmlk-adventure/adventure/assets.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/assets.h Wed Dec 23 15:37:48 2020 +0100 @@ -19,7 +19,8 @@ #ifndef MOLKO_ADVENTURE_ASSETS_H #define MOLKO_ADVENTURE_ASSETS_H -struct sprite; +#include +#include enum assets_sprite { /* UI elements. */ @@ -28,13 +29,26 @@ /* Actions. */ ASSETS_SPRITE_CHEST, + /* Characters enemies. */ + ASSETS_SPRITE_CHARACTER_BLACK_CAT, + /* Team assets. */ + ASSETS_SPRITE_CHARACTER_NETH, + ASSETS_SPRITE_CHARACTER_NETH_SWORD, ASSETS_SPRITE_FACES, ASSETS_SPRITE_NUM }; -extern struct sprite *assets_sprites[ASSETS_SPRITE_NUM]; +enum assets_sound { + /* Items. */ + ASSETS_SOUND_ITEM_POTION, + + ASSETS_SOUND_NUM +}; + +extern struct sprite assets_sprites[ASSETS_SPRITE_NUM]; +extern struct sound assets_sounds[ASSETS_SOUND_NUM]; void assets_init(void); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/character/black-cat.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/character/black-cat.c Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,51 @@ +/* + * black-cat.c -- Black Cat enemy + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include + +#include "black-cat.h" + +static void +reset(struct character *ch) +{ + ch->hpmax = ch->hp = 126; + ch->mpmax = ch->mp = 12; + ch->atk = 10; + ch->def = 8; + ch->agt = 13; +} + +static void +exec(struct character *ch, struct battle *bt) +{ + battle_attack(bt, ch, NULL); +} + +struct character character_black_cat = { + .name = N_("Black Cat"), + .level = 4, + .sprites = { + [CHARACTER_SPRITE_NORMAL] = &assets_sprites[ASSETS_SPRITE_CHARACTER_BLACK_CAT] + }, + .reset = reset, + .exec = exec +}; diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/character/black-cat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/character/black-cat.h Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,24 @@ +/* + * black-cat.h -- Black Cat enemy + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_ADVENTURE_CHARACTER_BLACK_CAT_H +#define MOLKO_ADVENTURE_CHARACTER_BLACK_CAT_H + +extern struct character character_black_cat; + +#endif /* !MOLKO_ADVENTURE_CHARACTER_BLACK_CAT_H */ diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/character/neth.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/character/neth.c Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,46 @@ +/* + * neth.c -- Neth + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "neth.h" + +static void +reset(struct character *ch) +{ + /* TODO: compute hpmax given the level. */ + ch->hpmax = 570; + ch->mpmax = 50; + ch->atk = 22; + ch->def = 19; + ch->agt = 16; + ch->luck = 3; +} + +struct character character_neth = { + .name = N_("Neth"), + .level = 1, + .sprites = { + [CHARACTER_SPRITE_NORMAL] = &assets_sprites[ASSETS_SPRITE_CHARACTER_NETH], + [CHARACTER_SPRITE_SWORD] = &assets_sprites[ASSETS_SPRITE_CHARACTER_NETH_SWORD] + }, + .reset = reset +}; diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/character/neth.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/character/neth.h Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,24 @@ +/* + * neth.h -- Neth + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_ADVENTURE_CHARACTER_NETH_H +#define MOLKO_ADVENTURE_CHARACTER_NETH_H + +extern struct character character_neth; + +#endif /* !MOLKO_ADVENTURE_CHARACTER_NETH_H */ diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/dialog/save.c --- a/libmlk-adventure/adventure/dialog/save.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/dialog/save.c Wed Dec 23 15:37:48 2020 +0100 @@ -131,7 +131,7 @@ { /* TODO: determine face. */ for (size_t f = 0; f < TEAM_MAX; ++f) { - sprite_scale(assets_sprites[ASSETS_SPRITE_FACES], 0, f, + sprite_scale(&assets_sprites[ASSETS_SPRITE_FACES], 0, f, geo->saves[i].faces[f].x, geo->saves[i].faces[f].y, geo->saves[i].faces[f].w, @@ -194,7 +194,7 @@ static void draw_cursor(const struct dialog_save *dlg, const struct geo *geo) { - const struct sprite *sprite =assets_sprites[ASSETS_SPRITE_UI_CURSOR]; + const struct sprite *sprite = &assets_sprites[ASSETS_SPRITE_UI_CURSOR]; const int x = geo->saves[dlg->selected].x - sprite->cellw; const int y = geo->saves[dlg->selected].y; diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/item/potion.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/item/potion.c Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,42 @@ +/* + * potion.h -- give some heal points + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include + +#include +#include + +#include "potion.h" + +static void +exec(const struct item *i, struct character *ch) +{ + sound_play(&assets_sounds[ASSETS_SOUND_ITEM_POTION], -1, 0); + ch->hp = fmin(ch->hp + 50, ch->hpmax); +} + +const struct item item_potion = { + .name = N_("Potion"), + .description = N_("Recover 50 HP."), + .exec = exec +}; diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/item/potion.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/item/potion.h Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,24 @@ +/* + * potion.h -- give some heal points + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_ADVENTURE_ITEM_POTION_H +#define MOLKO_ADVENTURE_ITEM_POTION_H + +extern const struct item item_potion; + +#endif /* !MOLKO_ADVENTURE_ITEM_POTION_H */ diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/molko.c --- a/libmlk-adventure/adventure/molko.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/molko.c Wed Dec 23 15:37:48 2020 +0100 @@ -37,6 +37,7 @@ #include +#include #include #include #include @@ -113,10 +114,20 @@ void molko_teleport(const char *map, int origin_x, int origin_y) { + molko.state = MOLKO_STATE_MAP; + game_switch(state_map_new(map, origin_x, origin_y), false); game.inhibit = INHIBIT_NONE; } +void +molko_fight(struct battle *bt) +{ + molko.state = MOLKO_STATE_BATTLE; + + game_switch(state_battle_new(bt), false); +} + const char * molko_path(const char *file) { diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/molko.h --- a/libmlk-adventure/adventure/molko.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/molko.h Wed Dec 23 15:37:48 2020 +0100 @@ -23,9 +23,25 @@ #include #include +#include +#include + +struct battle; + +enum molko_state { + MOLKO_STATE_MAP, + MOLKO_STATE_BATTLE, +}; + struct molko { struct state *panic; + /* Make sure to set this accordingly when changing states. */ + enum molko_state state; + + struct team team; + struct inventory inventory; + /* For map state. */ struct texture map_player_texture; struct sprite map_player_sprite; @@ -42,6 +58,9 @@ void molko_teleport(const char *map, int origin_x, int origin_y); +void +molko_fight(struct battle *bt); + const char * molko_path(const char *file); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/state/battle.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/state/battle.c Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,101 @@ +/* + * battle.c -- manage a battle + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#include "battle.h" + +struct self { + struct battle *battle; + struct state state; +}; + +static void +start(struct state *state) +{ + struct self *self = state->data; + + battle_start(self->battle); +} + +static void +handle(struct state *state, const union event *ev) +{ + struct self *self = state->data; + + battle_handle(self->battle, ev); +} + +static void +update(struct state *state, unsigned int ticks) +{ + struct self *self = state->data; + + /* TODO: once we have stacked states, pop it. */ + if (battle_update(self->battle, ticks)) + game_quit(); +} + +static void +draw(struct state *state) +{ + struct self *self = state->data; + + painter_set_color(0xffffffff); + painter_clear(); + battle_draw(self->battle); + painter_present(); +} + +static void +finish(struct state *state) +{ + struct self *self = state->data; + + battle_finish(self->battle); + + free(self->battle); + free(self); +} + +struct state * +state_battle_new(struct battle *bt) +{ + assert(bt); + + struct self *self; + + self = alloc_new0(sizeof (*self)); + self->battle = bt; + self->state.data = self; + self->state.start = start; + self->state.handle = handle; + self->state.update = update; + self->state.draw = draw; + self->state.finish = finish; + + return &self->state; +} diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/state/battle.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/state/battle.h Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,28 @@ +/* + * battle.h -- manage a battle + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_ADVENTURE_STATE_BATTLE_H +#define MOLKO_ADVENTURE_STATE_BATTLE_H + +struct battle; +struct state; + +struct state * +state_battle_new(struct battle *); + +#endif /* !MOLKO_ADVENTURE_STATE_BATTLE_H */ diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/adventure/state/mainmenu.c --- a/libmlk-adventure/adventure/state/mainmenu.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/adventure/state/mainmenu.c Wed Dec 23 15:37:48 2020 +0100 @@ -36,10 +36,14 @@ #include #include +#include + #include #include #include +#include + #include "mainmenu.h" #include "continue.h" @@ -58,6 +62,11 @@ static void new(void) { + /* TODO: temporary. */ + molko.team.members[0] = &character_neth; + character_reset(molko.team.members[0]); + molko.team.members[0]->hp = molko.team.members[0]->hpmax; + molko.team.members[0]->mp = molko.team.members[0]->mpmax; molko_teleport("maps/map-world.map", -1, -1); } @@ -170,7 +179,7 @@ draw(struct state *state) { struct self *self = state->data; - struct sprite *cursor = assets_sprites[ASSETS_SPRITE_UI_CURSOR]; + struct sprite *cursor = &assets_sprites[ASSETS_SPRITE_UI_CURSOR]; int x, y; painter_set_color(0xffffffff); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/nls/fr.po --- a/libmlk-adventure/nls/fr.po Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/nls/fr.po Wed Dec 23 15:37:48 2020 +0100 @@ -15,13 +15,12 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # - #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-28 21:19+0100\n" +"POT-Creation-Date: 2020-12-22 10:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -30,14 +29,32 @@ "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:119 +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:107 msgid "Continue" msgstr "Continuer" -#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:118 +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/dialog/save.c:162 +#, c-format +msgid "Last played: %s" +msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:106 msgid "New" msgstr "Nouvelle partie" -#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:120 +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/item/potion.c:36 +msgid "Potion" +msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:108 msgid "Quit" msgstr "Quitter" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/item/potion.c:37 +msgid "Recover 50 HP." +msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/dialog/save.c:168 +#, c-format +msgid "Time played: %s" +msgstr "" diff -r c43e39745cd8 -r 3991779aaba9 libmlk-adventure/nls/libmlk-adventure.pot --- a/libmlk-adventure/nls/libmlk-adventure.pot Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-adventure/nls/libmlk-adventure.pot Wed Dec 23 15:37:48 2020 +0100 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-11-30 09:48+0100\n" +"POT-Creation-Date: 2020-12-22 10:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,14 +17,32 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:119 +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:107 msgid "Continue" msgstr "" -#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:118 +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/dialog/save.c:162 +#, c-format +msgid "Last played: %s" +msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:106 msgid "New" msgstr "" -#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:120 +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/item/potion.c:36 +msgid "Potion" +msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/state/mainmenu.c:108 msgid "Quit" msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/item/potion.c:37 +msgid "Recover 50 HP." +msgstr "" + +#: /Users/markand/Dev/molko/libmlk-adventure/adventure/dialog/save.c:168 +#, c-format +msgid "Time played: %s" +msgstr "" diff -r c43e39745cd8 -r 3991779aaba9 libmlk-data/maps/map-world.json --- a/libmlk-data/maps/map-world.json Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-data/maps/map-world.json Wed Dec 23 15:37:48 2020 +0100 @@ -63,7 +63,7 @@ { "name":"exec", "type":"string", - "value":"spawner" + "value":"spawner|800|1000" }], "rotation":0, "type":"", diff -r c43e39745cd8 -r 3991779aaba9 libmlk-data/sounds/potion.wav Binary file libmlk-data/sounds/potion.wav has changed diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/CMakeLists.txt --- a/libmlk-rpg/CMakeLists.txt Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/CMakeLists.txt Wed Dec 23 15:37:48 2020 +0100 @@ -60,6 +60,8 @@ ${libmlk-rpg_SOURCE_DIR}/rpg/character.h ${libmlk-rpg_SOURCE_DIR}/rpg/equipment.c ${libmlk-rpg_SOURCE_DIR}/rpg/equipment.h + ${libmlk-rpg_SOURCE_DIR}/rpg/inventory.c + ${libmlk-rpg_SOURCE_DIR}/rpg/inventory.h ${libmlk-rpg_SOURCE_DIR}/rpg/item.c ${libmlk-rpg_SOURCE_DIR}/rpg/item.h ${libmlk-rpg_SOURCE_DIR}/rpg/map-file.c diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/nls/libmlk-rpg.pot --- a/libmlk-rpg/nls/libmlk-rpg.pot Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/nls/libmlk-rpg.pot Wed Dec 23 15:37:48 2020 +0100 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-20 10:24+0100\n" +"POT-Creation-Date: 2020-12-22 10:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/battle-bar.c --- a/libmlk-rpg/rpg/battle-bar.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/battle-bar.c Wed Dec 23 15:37:48 2020 +0100 @@ -31,10 +31,26 @@ #include "battle.h" #include "battle-bar.h" #include "character.h" +#include "inventory.h" +#include "item.h" #include "spell.h" #include "rpg_p.h" static void +init_gridmenu(struct battle_bar *bar, const struct battle *bt) +{ + bar->sub_grid.x = bar->x; + bar->sub_grid.y = bar->menu_frame.y; + bar->sub_grid.w = bar->status_frame.w; + bar->sub_grid.h = bar->h; + bar->sub_grid.theme = bt->theme; + bar->sub_grid.nrows = 3; + bar->sub_grid.ncols = 4; + + memset(bar->sub_grid.menu, 0, sizeof (bar->sub_grid.menu)); +} + +static void draw_status_character_stats(const struct battle *bt, const struct character *ch, int x, @@ -314,16 +330,7 @@ void battle_bar_open_spells(struct battle_bar *bar, const struct battle *bt, struct character *ch) { - /* Sub menu bar on the left, take same space as status. */ - bar->sub_grid.x = bar->x; - bar->sub_grid.y = bar->menu_frame.y; - bar->sub_grid.w = bar->status_frame.w; - bar->sub_grid.h = bar->h; - bar->sub_grid.theme = bt->theme; - bar->sub_grid.nrows = 3; - bar->sub_grid.ncols = 4; - - memset(bar->sub_grid.menu, 0, sizeof (bar->sub_grid.menu)); + init_gridmenu(bar, bt); for (size_t i = 0; i < CHARACTER_SPELL_MAX; ++i) { if (ch->spells[i]) @@ -336,6 +343,21 @@ } void +battle_bar_open_items(struct battle_bar *bar, const struct battle *bt) +{ + init_gridmenu(bar, bt); + + for (size_t i = 0; i < INVENTORY_ITEM_MAX; ++i) { + if (bt->inventory->items[i].item) + bar->sub_grid.menu[i] = bt->inventory->items[i].item->name; + } + + gridmenu_repaint(&bar->sub_grid); + + bar->state = BATTLE_BAR_STATE_SUB; +} + +void battle_bar_draw(const struct battle_bar *bar, const struct battle *bt) { assert(bar); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/battle-bar.h --- a/libmlk-rpg/rpg/battle-bar.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/battle-bar.h Wed Dec 23 15:37:48 2020 +0100 @@ -19,12 +19,28 @@ #ifndef MOLKO_RPG_BATTLE_BAR_H #define MOLKO_RPG_BATTLE_BAR_H -/** - * \file battle-bar.h - * \brief Battle status bar and menu. +/* + * The bar is split into three individual pieces. + * + * +------------+--------+------------+ + * | Grid menu | Menu | Status | + * +------------+--------+------------+ + * * - * This module is a view and user input for the game battle. It is used by the - * \ref battle.h object. + * The left grid menu is only shown when member field state is set to \ref + * BATTLE_BAR_STATE_SUB, it is usually opened when user select a magic or an + * object. + * + * The menu in the middle is the main selection and contains the enumeration + * battle_bar_menu using top, right, bottom left edges for short selection. + * + * The last part on the right is the status pane where the team characters stats + * are listed. + * + * By itself, the bar never modify the battle object, it is the responsability + * of the battle object or the battle state to change the bar object and to + * track change on events. As such, the battle object is always passed as const + * parameter. */ #include @@ -37,155 +53,60 @@ union event; -/** - * \brief Main menu selection. - */ enum battle_bar_menu { - BATTLE_BAR_MENU_ATTACK = 0, /*!< Attack. */ - BATTLE_BAR_MENU_MAGIC = 1, /*!< Cast a spell. */ - BATTLE_BAR_MENU_OBJECTS = 2, /*!< Use an object*/ - BATTLE_BAR_MENU_SPECIAL = 3 /*!< Use a special character action. */ + BATTLE_BAR_MENU_ATTACK = 0, + BATTLE_BAR_MENU_MAGIC = 1, + BATTLE_BAR_MENU_OBJECTS = 2, + BATTLE_BAR_MENU_SPECIAL = 3 }; -/** - * \brief Bar state. - */ enum battle_bar_state { - BATTLE_BAR_STATE_NONE, /*!< No state yet. */ - BATTLE_BAR_STATE_MENU, /*!< Main menu selection. */ - BATTLE_BAR_STATE_SUB /*!< Sub grid menu opened. */ + BATTLE_BAR_STATE_NONE, + BATTLE_BAR_STATE_MENU, + BATTLE_BAR_STATE_SUB }; -/** - * \brief Battle bar. - * - * The bar is split into three individual pieces. - * - * ``` - * +------------+--------+------------+ - * | Grid menu | Menu | Status | - * +------------+--------+------------+ - * ``` - * - * The left grid menu is only shown when member field state is set to \ref - * BATTLE_BAR_STATE_SUB, it is usually opened when user select a magic or an - * object. - * - * The menu in the middle is the main selection and contains the enumeration - * \ref battle_bar_menu using top, right, bottom left edges for short selection. - * - * The last part on the right is the status pane where the team characters stats - * are listed. - * - * By itself, the bar never modify the battle object, it is the responsability - * of the battle object or the battle state to change the bar object and to - * track change on events. As such, the battle object is always passed as const - * parameter. - */ struct battle_bar { - int x; /*!< (+) Position in x. */ - int y; /*!< (+) Position in y. */ - unsigned int w; /*!< (+) Width. */ - unsigned int h; /*!< (+) Height. */ - enum battle_bar_state state; /*!< (-) Current state. */ + int x; + int y; + unsigned int w; + unsigned int h; + enum battle_bar_state state; /* Right status frame. */ - struct frame status_frame; /*!< (-) Right status frame. */ + struct frame status_frame; /* Main menu selection. */ - struct frame menu_frame; /*!< (-) Main menu frame. */ - enum battle_bar_menu menu; /*!< (-) Main menu selection. */ + struct frame menu_frame; + enum battle_bar_menu menu; /* Sub menu selection (spells/objects). */ - struct gridmenu sub_grid; /*!< (-) Sub menu object. */ + struct gridmenu sub_grid; }; -/** - * Repositionate every elements in the bar. - * - * Call this function at least once, when you have set the x, y, w and h fields - * of the bar. - * - * \pre bar != NULL - * \pre bt != NULL - * \param bar the bar to set - * \param bt the current battle - */ void battle_bar_positionate(struct battle_bar *bar, const struct battle *bt); -/** - * Handle an event. - * - * Depending on the current bar state, it will either update the main menu or - * the sub menu if opened. The function returns true if an element is considered - * activated (usually with the return key). - * - * You must not ignore the return value because the battle state should change. - * - * \pre bar != NULL - * \pre bt != NULL - * \pre ev != NULL - * \param bar this bar - * \param bt the current battle - * \param ev the current event - * \return True if an element has been activated. - */ bool battle_bar_handle(struct battle_bar *bar, const struct battle *bt, const union event *ev); -/** - * Reset the battle bar selection, state and grid. - * - * Call this function each time a new player is selected. - * - * \pre bar != NULL - * \param bar the bar to reset - */ void battle_bar_reset(struct battle_bar *bar); -/** - * Open global menu. - * - * \pre bar != NULL - * \param bar the bar - */ void battle_bar_open_menu(struct battle_bar *bar); -/** - * Open the view to select a spell by opening the grid menu. - * - * \pre bar != NULL - * \pre bt != NULL - * \pre character_ok(ch) - * \param bar this bar - * \param bt the current battle - * \param ch the owner of spells - */ void battle_bar_open_spells(struct battle_bar *bar, const struct battle *bt, struct character *ch); -/** - * Draw the bar. - * - * \pre bar != NULL - * \pre bt != NULL - * \param bar the bar to draw - * \param bt the current battle - */ +void +battle_bar_open_items(struct battle_bar *bar, const struct battle *bt); + void battle_bar_draw(const struct battle_bar *bar, const struct battle *bt); -/** - * Close internal resources if necessary. - * - * \pre bar != NULL - * \param bar the bar to clear - */ void battle_bar_finish(struct battle_bar *bar); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/battle-state-menu.c --- a/libmlk-rpg/rpg/battle-state-menu.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/battle-state-menu.c Wed Dec 23 15:37:48 2020 +0100 @@ -49,6 +49,13 @@ } static void +open_items(struct battle *bt) +{ + battle_bar_open_items(&bt->bar, bt); + battle_state_sub(bt); +} + +static void handle(struct battle_state *st, struct battle *bt, const union event *ev) { (void)st; @@ -62,6 +69,7 @@ open_spells(bt); break; case BATTLE_BAR_MENU_OBJECTS: + open_items(bt); break; case BATTLE_BAR_MENU_SPECIAL: break; diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/battle.c --- a/libmlk-rpg/rpg/battle.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/battle.c Wed Dec 23 15:37:48 2020 +0100 @@ -87,6 +87,21 @@ return NULL; } +static struct battle_entity * +random_select(struct battle_entity *group, size_t groupsz) +{ + struct battle_entity *ret = NULL, *et = NULL; + + do { + et = &group[util_nrand(0, groupsz - 1)]; + + if (et->ch) + ret = et; + } while (!ret); + + return ret; +} + static int cmp_order(const void *d1, const void *d2) { @@ -97,10 +112,10 @@ } static bool -is_team(const struct battle *bt, const struct battle_entity *et) +is_team(const struct battle *bt, const struct character *ch) { for (size_t i = 0; i < BATTLE_TEAM_MAX; ++i) - if (&bt->team[i] == et) + if (bt->team[i].ch == ch) return true; return false; @@ -257,11 +272,16 @@ struct character *source, struct character *target) { - (void)source; - assert(bt); assert(character_ok(source)); - assert(character_ok(target)); + + /* Target is empty? select randomly. */ + if (!target) { + if (is_team(bt, source)) + target = random_select(bt->enemies, BATTLE_ENEMY_MAX)->ch; + else + target = random_select(bt->team, BATTLE_TEAM_MAX)->ch; + } battle_state_attacking(bt, source, target); } @@ -303,7 +323,7 @@ } /* Change state depending on the kind of entity. */ - if (is_team(bt, bt->order_cur)) { + if (is_team(bt, bt->order_cur->ch)) { battle_bar_open_menu(&bt->bar); battle_state_menu(bt); } else diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/battle.h --- a/libmlk-rpg/rpg/battle.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/battle.h Wed Dec 23 15:37:48 2020 +0100 @@ -36,14 +36,14 @@ union event; struct character; +struct inventory; struct music; struct spell; struct theme; -#define BATTLE_TEAM_MAX (4) /*!< Maximum team members. */ -#define BATTLE_ENEMY_MAX (8) /*!< Maximum enemies. */ -#define BATTLE_ENTITY_MAX \ - (BATTLE_TEAM_MAX + BATTLE_ENEMY_MAX) +#define BATTLE_TEAM_MAX (4) +#define BATTLE_ENEMY_MAX (8) +#define BATTLE_ENTITY_MAX (BATTLE_TEAM_MAX + BATTLE_ENEMY_MAX) #define BATTLE_TEAM_FOREACH(bt, iter) \ for (size_t i = 0; i < BATTLE_TEAM_MAX && ((iter) = &(bt)->team[i]); ++i) @@ -52,248 +52,68 @@ #define BATTLE_THEME(bt) ((bt)->theme ? (bt)->theme : theme_default()) -/** - * \brief Generic battle status. - */ enum battle_status { - BATTLE_STATUS_NONE, /*!< Battle is not even started. */ - BATTLE_STATUS_RUNNING, /*!< Battle is running. */ - BATTLE_STATUS_WON, /*!< Battle has been won. */ - BATTLE_STATUS_LOST, /*!< Battle has been lost. */ + BATTLE_STATUS_NONE, + BATTLE_STATUS_RUNNING, + BATTLE_STATUS_WON, + BATTLE_STATUS_LOST, }; -/** - * \brief Battle structure. - */ struct battle { - /** - * (+&?) Battle state. - */ struct battle_state *state; - - /** - * (-) Battle status. - * - * This information is provided as final result once the battle has - * completed, modifying by the user won't change the battle routines. - */ enum battle_status status; - - /** - * (+) Member of team. - */ struct battle_entity team[BATTLE_TEAM_MAX]; - - /** - * (+) Ennemies to fight. - */ struct battle_entity enemies[BATTLE_ENEMY_MAX]; - - /** - * (+&?) Order of playing. - */ struct battle_entity *order[BATTLE_ENTITY_MAX]; - - /** - * (-&?) Current entity playing. - */ struct battle_entity *order_cur; - - /** - * (-) Current entity playing index. - */ size_t order_curindex; - - /** - * (+&?) An optional background. - */ struct texture *background; - - /** - * (+&?) A music to play. - * - * Music to play in the battle: - * - * - [0]: while the battle is running, - * - [1]: in case of victory, - * - [2]: in case of lost. - */ struct music *music[3]; - - /** - * (+&?) Theme to use. - */ struct theme *theme; - - /** - * (+) Stack of animations. - * - * The drawing animations are ran in parallel. - */ struct drawable_stack effects; - - /** - * (+) Stack of actions. - * - * The array [0] contains actions that must complete to continue the - * battle, it can be used to write some messages while blocking the - * battle. - * - * The array [1] is a set of actions that run in "parallel" and don't - * prevent the battle from continuing. - */ struct action_stack actions[2]; - - /** - * (-) Bottom bar. - */ + struct inventory *inventory; struct battle_bar bar; }; -/** - * Call this function before using the battle but after calling \a battle_init. - * - * If the team entities are positioned to 0, 0 they will be placed - * automatically. - * - * \pre bt != NULL - * \param bt the battle object - */ void battle_start(struct battle *bt); -/** - * Select next member in battle. - * - * \pre bt != NULL - * \param bt the battle object - */ void battle_next(struct battle *bt); struct battle_entity * battle_find(struct battle *bt, const struct character *ch); -/** - * Change battle state. - * - * \pre bt != NULL - * \pre st != NULL - * \param bt the battle object - * \param st the state (referenced) - * \warning This will immediately close the current state and call finish field - * function if defined. - */ void battle_switch(struct battle *bt, struct battle_state *st); -/** - * Compute battle ordering. - * - * \pre bt != NULL - * \param bt the battle object - */ void battle_order(struct battle *bt); -/** - * All in one function to animate and compute damage. - * - * Use this function from the character AI or when a character from the team - * should attack an enemy. - * - * This will do the following in order: - * - * 1. Change battle state to "attacking" - * 2. Change battle entity state to "moving" or "blinking" if source is member of - * team or enemies respectively. - * 3. Wait until animations complete. - * 4. Compute and produce damage. - * 5. Change battle state to "check" - * - * \pre bt != NULL - * \pre source != NULL - * \pre target != NULL - * \param bt the battle object - * \param source the entity attacking - * \param target the target entity - */ void battle_attack(struct battle *bt, struct character *source, struct character *target); -/** - * Default function to cast a spell. - * - * Prefer to use this function to cast a spell because it performs some checks - * and hooks before casting the spell. - * - * \pre bt != NULL - * \pre source != NULL - * \pre spell != NULL - * \param bt the current battle - * \param source the entity casting a spell - * \param spell the spell used - * \param selection the selection - */ void battle_cast(struct battle *bt, struct character *source, const struct spell *spell, unsigned int selection); -/** - * Spawn an indicator drawable to show damage. - * - * The drawable will draw the amount near the entity and fade away after - * several seconds. - * - * \pre bt != NULL - * \pre target != NULL - * \param bt the battle object - * \param target the target entity - * \param amount the amount of damage - */ void battle_indicator_hp(struct battle *bt, const struct character *target, unsigned int amount); -/** - * Handle an event. - * - * \pre bt != NULL - * \pre ev != NULL - * \param bt the battle object - * \param ev the event - */ void battle_handle(struct battle *bt, const union event *ev); -/** - * Update the battle. - * - * \pre bt != NULL - * \param bt the battle object - * \param ticks the number of milliseconds since last frame - */ bool battle_update(struct battle *bt, unsigned int ticks); -/** - * Draw the battle. - * - * \pre bt != NULL - * \param bt the battle object - */ void battle_draw(struct battle *bt); -/** - * Finish and dispose resources if necessary. - * - * \pre bt != NULL - * \param bt the battle object - */ void battle_finish(struct battle *bt); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/character.c --- a/libmlk-rpg/rpg/character.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/character.c Wed Dec 23 15:37:48 2020 +0100 @@ -30,7 +30,7 @@ bool character_ok(const struct character *ch) { - return ch && ch->name && ch->type && ch->reset && sprite_ok(ch->sprites[CHARACTER_SPRITE_NORMAL]); + return ch && ch->name && ch->reset && sprite_ok(ch->sprites[CHARACTER_SPRITE_NORMAL]); } const char * diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/character.h --- a/libmlk-rpg/rpg/character.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/character.h Wed Dec 23 15:37:48 2020 +0100 @@ -58,9 +58,8 @@ struct character { const char *name; - const char *type; + enum character_status status; unsigned int level; - enum character_status status; int hp; unsigned int hpmax; unsigned int hpbonus; diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/inventory.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-rpg/rpg/inventory.c Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,64 @@ +/* + * inventory.c -- item inventory + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "inventory.h" + +static struct inventory_slot * +find(struct inventory *iv, const struct item *item) +{ + for (size_t i = 0; i < INVENTORY_ITEM_MAX; ++i) + if (iv->items[i].item == item) + return &iv->items[i]; + + return NULL; +} + +bool +inventory_add(struct inventory *iv, const struct item *item, unsigned int amount) +{ + assert(iv); + assert(item); + + struct inventory_slot *slot; + + /* Find one existing, otherwise find one empty. */ + if (!(slot = find(iv, item))) + slot = find(iv, NULL); + + if (!slot) + return false; + + slot->amount += amount; + + return true; +} + +void +inventory_consume(struct inventory *iv, const struct item *item, unsigned int amount) +{ + assert(iv); + assert(item); + + struct inventory_slot *slot; + + if (!(slot = find(iv, item))) + slot->amount -= amount; +} diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/inventory.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-rpg/rpg/inventory.h Wed Dec 23 15:37:48 2020 +0100 @@ -0,0 +1,43 @@ +/* + * inventory.h -- item inventory + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_RPG_INVENTORY_H +#define MOLKO_RPG_INVENTORY_H + +#include + +#define INVENTORY_ITEM_MAX (512) + +struct item; + +struct inventory_slot { + unsigned int amount; + const struct item *item; +}; + +struct inventory { + struct inventory_slot items[INVENTORY_ITEM_MAX]; +}; + +bool +inventory_add(struct inventory *iv, const struct item *item, unsigned int amount); + +void +inventory_consume(struct inventory *iv, const struct item *item, unsigned int amount); + +#endif /* !MOLKO_RPG_INVENTORY_H */ diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/item.c --- a/libmlk-rpg/rpg/item.c Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/item.c Wed Dec 23 15:37:48 2020 +0100 @@ -21,7 +21,7 @@ #include "item.h" void -item_exec(struct item *item, struct character *ch) +item_exec(const struct item *item, struct character *ch) { assert(item); assert(ch); diff -r c43e39745cd8 -r 3991779aaba9 libmlk-rpg/rpg/item.h --- a/libmlk-rpg/rpg/item.h Mon Dec 21 09:50:16 2020 +0100 +++ b/libmlk-rpg/rpg/item.h Wed Dec 23 15:37:48 2020 +0100 @@ -19,61 +19,22 @@ #ifndef MOLKO_RPG_ITEM_H #define MOLKO_RPG_ITEM_H -/** - * \file item.h - * \brief Inventory items. - */ - #include struct character; struct texture; -/** - * \brief Inventory items. - */ struct item { - const char *name; /*!< (+) Name of item. */ - const char *summary; /*!< (+) Summary description. */ - struct texture *icon; /*!< (+&) Icon to show. */ - - /** - * (+) Execute the action for this character. - * - * \param item this item - * \param ch the character owner - */ - void (*exec)(struct item *item, struct character *ch); - - /** - * (+?) Tells if the item can be used in this context. - * - * \param item this item - * \param ch the character owner - */ + const char *name; + const char *description; + struct texture *icon; + void (*exec)(const struct item *item, struct character *ch); bool (*allowed)(const struct item *item, const struct character *ch); }; -/** - * Shortcut for item->exec (if not NULL). - * - * \pre item != NULL - * \pre ch != NULL - * \param item the item to use - * \param ch the character owner - */ void -item_exec(struct item *item, struct character *ch); +item_exec(const struct item *item, struct character *ch); -/** - * Shortcut for item->allowed (if not NULL). - * - * \pre item != NULL - * \pre ch != NULL - * \param item the item to use - * \param ch the character owner - * \return The return value of item->allowed or true if NULL. - */ bool item_allowed(const struct item *item, struct character *ch);