# HG changeset patch # User David Demelier # Date 1607771684 -3600 # Node ID eadd3dbfa0afb85e43ca392241ec15a195e15073 # Parent 2d8d1cacda3653dbb8195c5986daab4650ccdc09 adventure: add a basic chest diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-adventure/CMakeLists.txt --- a/libmlk-adventure/CMakeLists.txt Sat Dec 12 12:14:34 2020 +0100 +++ b/libmlk-adventure/CMakeLists.txt Sat Dec 12 12:14:44 2020 +0100 @@ -20,6 +20,8 @@ set( SOURCES + ${libadventure_SOURCE_DIR}/adventure/actions/chest.c + ${libadventure_SOURCE_DIR}/adventure/actions/chest.h ${libadventure_SOURCE_DIR}/adventure/actions/spawner.c ${libadventure_SOURCE_DIR}/adventure/actions/spawner.h ${libadventure_SOURCE_DIR}/adventure/actions/teleport.c diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-adventure/adventure/actions/chest.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/actions/chest.c Sat Dec 12 12:14:44 2020 +0100 @@ -0,0 +1,153 @@ +/* + * chest.c -- chest object + * + * 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 +#include +#include + +#include + +#include "chest.h" + +#define X(c) ((c)->x - ((c)->map)->view_x) +#define Y(c) ((c)->y - ((c)->map)->view_y) +#define W(c) ((c)->animation.sprite->cellw) +#define H(c) ((c)->animation.sprite->cellh) +#define TOLERANCE (10) + +static bool +is_near(const struct chest *c) +{ + const int x = c->x - c->map->player_sprite->cellw - TOLERANCE; + const int y = c->y - c->map->player_sprite->cellh - TOLERANCE; + const unsigned int w = W(c) + c->map->player_sprite->cellw + (TOLERANCE * 2); + const unsigned int h = H(c) + c->map->player_sprite->cellh + (TOLERANCE * 2); + + return maths_is_boxed(x, y, w, h, c->map->player_x, c->map->player_y); +} + +static void +invoke(struct chest *c) +{ + c->state = CHEST_STATE_ANIMATE; + + animation_start(&c->animation); + + if (c->sound) + sound_play(c->sound, -1, 0); +} + +static void +handle(struct action *act, const union event *ev) +{ + struct chest *c = act->data; + + if (!is_near(c) || c->state != CHEST_STATE_CLOSED) + return; + + switch (ev->type) { + case EVENT_KEYDOWN: + if (ev->key.key == KEY_ENTER) + invoke(c); + break; + case EVENT_CLICKDOWN: + if (maths_is_boxed(X(c), Y(c), W(c), H(c), ev->click.x, ev->click.y)) + invoke(c); + break; + default: + break; + } +} + +static bool +update(struct action *act, unsigned int ticks) +{ + struct chest *c = act->data; + + if (c->state != CHEST_STATE_ANIMATE) + return false; + + if (animation_update(&c->animation, ticks)) { + c->state = CHEST_STATE_OPEN; + + if (c->exec) + c->exec(c); + } + + return false; +} + +static void +draw(struct action *act) +{ + struct chest *c = act->data; + + switch (c->state) { + case CHEST_STATE_OPEN: + sprite_draw( + c->animation.sprite, + c->animation.sprite->nrows - 1, + c->animation.sprite->ncols - 1, + X(c), + Y(c) + ); + break; + case CHEST_STATE_ANIMATE: + animation_draw(&c->animation, X(c), Y(c)); + break; + default: + sprite_draw(c->animation.sprite, 0, 0, X(c), Y(c)); + break; + } +} + +void +chest_init(struct chest *c) +{ + assert(c); + + if (c->save && c->property) { + if (!save_get_property(c->save, c->property)) + panic(); + + /* TODO: add an utility. */ + if (strcmp(c->property->value, "true") == 0) + c->state = CHEST_STATE_OPEN; + } +} + +struct action * +chest_action(struct chest *c) +{ + assert(c); + + c->action.data = c; + c->action.handle = handle; + c->action.update = update; + c->action.draw = draw; + + return &c->action; +} diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-adventure/adventure/actions/chest.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/actions/chest.h Sat Dec 12 12:14:44 2020 +0100 @@ -0,0 +1,59 @@ +/* + * chest.h -- chest object + * + * 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_ACTIONS_CHEST_H +#define MOLKO_ADVENTURE_ACTIONS_CHEST_H + +#include +#include + +struct map; +struct sound; + +enum chest_state { + CHEST_STATE_CLOSED, + CHEST_STATE_ANIMATE, + CHEST_STATE_OPEN +}; + +struct chest { + /* Mandatory. */ + int x; + int y; + struct map *map; + struct animation animation; + + /* Defaulted. */ + enum chest_state state; + struct action action; + + /* Optional. */ + struct save *save; + struct save_property *property; + struct sound *sound; + void *data; + void (*exec)(struct chest *); +}; + +void +chest_init(struct chest *c); + +struct action * +chest_action(struct chest *c); + +#endif /* !MOLKO_ADVENTURE_ACTIONS_CHEST_H */ diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-adventure/adventure/assets.c --- a/libmlk-adventure/adventure/assets.c Sat Dec 12 12:14:34 2020 +0100 +++ b/libmlk-adventure/adventure/assets.c Sat Dec 12 12:14:44 2020 +0100 @@ -36,7 +36,8 @@ struct texture texture; struct sprite sprite; } table_sprites[] = { - SPRITE(ASSETS_SPRITE_UI_CURSOR, "sprites/ui-cursor.png", 24, 24) + SPRITE(ASSETS_SPRITE_UI_CURSOR, "sprites/ui-cursor.png", 24, 24), + SPRITE(ASSETS_SPRITE_CHEST, "sprites/chest.png", 32, 32) }; struct sprite *assets_sprites[ASSETS_SPRITE_NUM] = {0}; diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-adventure/adventure/assets.h --- a/libmlk-adventure/adventure/assets.h Sat Dec 12 12:14:34 2020 +0100 +++ b/libmlk-adventure/adventure/assets.h Sat Dec 12 12:14:44 2020 +0100 @@ -19,11 +19,15 @@ #ifndef MOLKO_ADVENTURE_ASSETS_H #define MOLKO_ADVENTURE_ASSETS_H -#include +struct sprite; enum assets_sprite { /* UI elements. */ ASSETS_SPRITE_UI_CURSOR, + + /* Actions. */ + ASSETS_SPRITE_CHEST, + ASSETS_SPRITE_NUM }; diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-data/sprites/chest.png Binary file libmlk-data/sprites/chest.png has changed diff -r 2d8d1cacda36 -r eadd3dbfa0af libmlk-data/sprites/chest.xcf Binary file libmlk-data/sprites/chest.xcf has changed