Mercurial > molko
diff librpg/rpg/battle.h @ 192:4ad7420ab678
rpg: add minimalist battle system, continue #2477 @60h
- Implement battle as states,
- Add basic support for spells (no calculation yet),
- Add won/lost state,
- Add animations and messages,
- Add order.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 07 Nov 2020 16:00:39 +0100 |
parents | |
children | c0e0d4accae8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/librpg/rpg/battle.h Sat Nov 07 16:00:39 2020 +0100 @@ -0,0 +1,264 @@ +/* + * battle.h -- battles + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * 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_BATTLE_H +#define MOLKO_BATTLE_H + +#include <stdbool.h> + +#include <core/action.h> +#include <core/drawable.h> + +#include <ui/frame.h> +#include <ui/label.h> +#include <ui/gridmenu.h> + +#include "battle-bar.h" +#include "battle-state.h" +#include "selection.h" +#include "spell.h" + +union event; + +struct character; +struct sound; +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_FOREACH(bt, iter) \ + for (size_t i = 0; i < BATTLE_TEAM_MAX && ((iter) = &(bt)->team[i]); ++i) +#define BATTLE_ENEMY_FOREACH(bt, iter) \ + for (size_t i = 0; i < BATTLE_ENEMY_MAX && ((iter) = &(bt)->enemies[i]); ++i) + +#define BATTLE_THEME(bt) ((bt)->theme ? (bt)->theme : theme_default()) + +/** + * \brief In battle entity. + */ +struct battle_entity { + struct character *ch; /*!< (+&?) Character to use. */ + int x; /*!< (+) Position on screen. */ + int y; /*!< (+) Position on screen. */ + struct label name; /*!< (*) Where its name label is located. */ +}; + +/** + * \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. */ +}; + +/** + * \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. + */ + struct sound *music; + + /** + * (+&?) 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 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 team. + * + * \pre bt != NULL + * \param bt the battle object + */ +void +battle_next(struct battle *bt); + +/** + * 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); + +/** + * Default function to calculate damage calculation from the source to the + * given target and then add an amount indicator as a drawable. + * + * \pre bt != NULL + * \pre source != NULL + * \pre target != NULL + * \param bt the battle object + * \param source + */ +void +battle_attack(struct battle *bt, struct character *source, struct character *target); + +/** + * Default function to cast a spell. + */ +void +battle_cast(struct battle *bt, + struct character *source, + const struct spell *spell, + unsigned int selection); + +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); + +#endif /* MOLKO_BATTLE_H */