RogueLife/src/game.h

207 lines
6.1 KiB
C

//---
// game: Static and dynamic information relating to an unfolding game
//---
#pragma once
#include "anim.h"
#include "level.h"
#include "map.h"
#include "pathfinding.h"
#include "player.h"
#include "render.h"
#include "comp/entity.h"
typedef struct score {
/* Number of kills */
int kill_number;
/* Longest combo chain so far */
int longest_combo_chain;
/* Total (accumulated) combo chain score */
int combo_chains;
/* Largest simultaneous kill streak */
int largest_simult_kill;
/* Total (accumulated) kill streak score */
int simult_kills;
/* Number of one shots kills */
int one_shot_kills;
/* Number of waves survived */
int waves_survived;
/* Current kill streak and its timer (basically a faster combo) */
int current_simult_kills;
fixed_t current_simult_kill_timer;
} score_t;
typedef struct game {
/* The map's coordinate system is the primary coordinate system in all of
this game's code */
map_t const *map;
/* Number of entities currently on each cell of the map */
uint8_t *occupation;
/* Position of each map cell in its animation cycle, in ms. Cells have
random offsets so animations are not all synchronized. We ignore the
wrapping effect entirely. */
uint16_t *map_anim;
/* User's camera */
camera_t camera;
/* Time played */
fixed_t time_total;
/* Screenshake duration left (effect disabled when 0), and amplitude */
fixed_t screenshake_duration;
int screenshake_amplitude;
/* List of entities */
entity_t **entities;
int entity_count;
/* Player; this must be one of the entities loaded in the game */
entity_t *player;
/* Field of movement to reach the player (used by most enemy AIs) */
pfg_all2one_t paths_to_player;
/* Level being played */
level_t const *level;
/* Current event, time spent in event */
int event;
fixed_t event_time;
/* Current freeze time left */
fixed_t freeze_time;
/* Number of waves encountered so far; if current event is a wave, number of
enemies spawned so far and enemies left to spawn */
int wave_number;
int wave_spawned;
uint8_t *wave_left;
/* Current combo score and its health (measured between 0 and 1, decreases
at a variable rate) */
int combo;
fixed_t combo_health;
/* Score information */
score_t score;
/* XP bar animation */
anim_state_t hud_xp_anim;
/* Backpack animation */
anim_state_t hud_backpack_anim;
/* Inventory/status menu opening time (0 is closed, 1 is open) */
fixed_t menu_time;
/* Whether the menu is open or closed. Dictates whether menu_time goes
towards 0 or 1 every frame */
bool menu_open;
/* Cursor within the inventory menu */
int menu_cursor;
/* Time when the game was finished (0 while playing) */
fixed_t finish_time;
/* Whether the game was won (valid when finish_time > 0) */
bool victory;
/* Final screen time (negative while playing, >= 0 when game finished) */
fixed_t final_screen_time;
/* Current UI message, and how long it stays on (if not overwritten) */
char const *message;
fixed_t message_time;
/* Flashing wave number timer */
fixed_t hud_wave_number_timer;
} game_t;
/* Allocate resources to load a level. */
bool game_load(game_t *g, level_t const *level);
/* Free resources allocated for the level. */
void game_unload(game_t *g);
/* Current level event. */
level_event_t const *game_current_event(game_t const *g);
/* Current wave. NULL if the current event is not a wave. */
level_wave_t const *game_current_wave(game_t const *g);
/* Whether the current event is finished */
bool game_current_event_finished(game_t const *g);
/* Move to next event */
void game_next_event(game_t *g);
/* Shake the screen for the specified amount of time */
void game_shake(game_t *g, int amplitude, fixed_t duration);
/* Freeze enemies and waves for the specified time */
void game_freeze(game_t *g, fixed_t duration);
/* Set the current game message */
void game_message(game_t *g, fixed_t duration, char const *fmt, ...);
/* Start backpack animations */
void game_hud_anim_backpack_item(game_t *g);
void game_hud_anim_backpack_open(game_t *g);
void game_hud_anim_backpack_close(game_t *g);
/* Compute total score */
int game_compute_score(game_t const *g);
/* Determine whethey victory was achieved */
bool game_victory_achieved(game_t const *g);
/* Determine whether players have lost */
bool game_defeated(game_t const *g);
//---
// Managing dynamic game elements
//---
/* Compute the number of entities on each cell. */
void game_compute_occupation(game_t *g);
/* Add an entity to the game (takes ownership; e will be freed). */
void game_add_entity(game_t *g, entity_t *e);
/* Like game_add_entity(), but with a visual effect */
void game_spawn_entity(game_t *g, entity_t *e);
/* Spawn a new enemy into the arena. Spawner is selected randomly if -1. */
void game_spawn_enemy(game_t *g, int identity, int spawner_id);
/* Remove dead entities. */
void game_remove_dead_entities(game_t *g);
//---
// Generic entity functions
//---
/* Count entities satisfying the provided predicate. */
int game_count_entities(game_t const *g, entity_predicate_t *predicate);
/* Filter and sort entities. The entities are sorted by increasing measure,
with negative measures filtering entities out. Returns an array of entity
indices (within [g->entities]) to be freed with free() in [*result], while
returning the number of matching entities. If 0, *result is NULL. */
int game_sort_entities(game_t const *g, entity_measure_t *measure,
uint16_t **result);
//---
// Per-frame update functions
//---
/* Spawn enemies from the current wave. */
void game_spawn_enemies(game_t *g);
/* Update all entities' and effect areas' animations. */
void game_update_animations(game_t *g, fixed_t dt, fixed_t dt_rt);
/* Update all entities' status ailments and temporary buffs/debuffs */
void game_update_effects(game_t *g, fixed_t dt);
/* Update all effect areas and apply their effects. */
void game_update_aoes(game_t *g, fixed_t dt);
/* Update all particles and remove the oldest ones. */
void game_update_particles(game_t *g, fixed_t dt);
/* Sort particles by increasing y position */
void game_sort_particles(game_t *g);
/* Decrease cooldowns for all fighters' skills */
void game_run_cooldowns(game_t *g, fixed_t dt);