//--- // 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);