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 */