RogueLife/src/entities.h

196 lines
5.6 KiB
C

//---
// entities: Objects that move around the map
//---
#pragma once
#include "geometry.h"
#include "anim.h"
struct effect_area;
//---
// Agents
//---
typedef struct {
/* Maximum walking speed (m/s) */
fixed_t max_speed;
/* Rate a which target speed is approached (1/s) */
fixed_t propulsion;
/* Peak dash speed (m/s) */
fixed_t dash_speed;
/* Dash duration (s) */
fixed_t dash_duration;
/* Dash cooldown (s) */
fixed_t dash_cooldown;
} entity_movement_params_t;
typedef struct {
/* Current position */
fixed_t x, y;
/* Current speed */
fixed_t vx, vy;
/* Dash time remaining (if positive) or cooldown remaining (if negative) */
fixed_t dash;
/* Direction currently facing */
uint8_t facing;
/* Dash direction */
uint8_t dash_facing;
} entity_movement_t;
typedef struct {
/* Number of hits in the main combo (TODO: delegate to weapon?) */
uint8_t combo_length;
/* Next hit to be dealt */
uint8_t combo_next;
/* Delay until ideal time to start next hit */
fixed_t combo_delay;
} entity_player_t;
/* Alive agents with hitboxes and movement control */
typedef struct {
/* Map hitbox, centered around (movement.x, movement.y) */
frect_t hitbox;
/* Sprite hitbox, centered similarly */
frect_t sprite;
/* Current cinematic situation */
entity_movement_t movement;
/* Cinematic parameters */
entity_movement_params_t const *movement_params;
/* Player-only parameters */
entity_player_t const *player;
/* Animated image and state */
anim_state_t anim;
/* Current attack's effect area */
struct effect_area *current_attack;
/* Animation priority (to improve legibility) */
uint8_t anim_priority;
/* Whether attack follows movement */
uint8_t attack_follows_movement;
/* Enemy ID (0 for player) */
uint8_t identity;
/* Combat statistics */
uint16_t HP, ATK, DEF;
/* Time left until nexth pathfinding run (ms) */
// uint8_t pathfind_delay;
} entity_t;
/* Entity position */
fpoint_t entity_pos(entity_t const *e);
/* Entity hitbox, accounting for position */
frect_t entity_hitbox(entity_t const *e);
/* Entity sprite, accounting for position */
frect_t entity_sprite(entity_t const *e);
/* Update walk/sprint movement (stand still if direction == -1); this cinematic
state can be submitted for collisions and may or may not be accpeted */
entity_movement_t entity_move4(entity_t *e, int direction, fixed_t dt);
/* Update walk/sprint movement in any direction (for IAs) */
entity_movement_t entity_move(entity_t *e, fpoint_t direction, fixed_t dt);
/* Check if the entity is currently moving */
bool entity_moving(entity_t const *e);
/* Start dashing in the set direction */
void entity_dash(entity_t *e, int direction);
/* Check if the entity is currently dashing */
bool entity_dashing(entity_t const *e);
/* Set entity animation */
void entity_set_normal_anim(entity_t *e, anim_frame_t *frame, int priority);
void entity_set_directional_anim(entity_t *e, anim_frame_t *frame_dirs[],
int priority);
#define entity_set_anim(e, frame, priority) _Generic((frame), \
anim_frame_t *: entity_set_normal_anim(e, (void *)frame, priority), \
anim_frame_t **: entity_set_directional_anim(e, (void *)frame, priority))
/* Damage entity for that amount of raw strength. Returns actual damage after
DES is subtracted, and randomization. */
int entity_damage(entity_t *e, int base_damage);
//---
// Effect areas
//---
enum {
/* Bare-hand fist/close-contact attack */
EFFECT_ATTACK_HIT,
/* Normal attack by a slashing weapon */
EFFECT_ATTACK_SLASH,
/* Impaling attack using a slashing weapon */
EFFECT_ATTACK_IMPALE,
/* Shock attack */
EFFECT_ATTACK_SHOCK,
/* Monster spawning */
EFFECT_SPAWN,
};
/* Record of when an effect area hit an entity */
typedef struct {
/* Entity hit */
entity_t *entity;
/* Lifetime of the area at that time */
fixed_t lifetime;
} effect_area_record_t;
/* Effect area */
typedef struct effect_area {
/* Area sprite (used as a hitbox) */
frect_t sprite;
/* Position of center */
fpoint_t anchor;
/* Lifetime (s) */
fixed_t lifetime;
/* Animated image and state */
anim_state_t anim;
/* Effect repeat delay (s; 0 for no repeat) */
fixed_t repeat_delay;
/* List of entities that were hit */
effect_area_record_t *hits;
int hit_count;
/* Entity that caused the area */
entity_t *origin;
/* Type of effect */
uint16_t type;
/* Effect data (type-dependent) */
union {
/* EFFECT_ATTACK_HIT: source and ATK strength */
struct { int strength; int dir; } hit;
/* EFFECT_ATTACK_SLASH: source and ATK strength */
struct { int strength; int dir; } slash;
/* EFFECT_ATTACK_SHOCK: origin and ATK strength */
struct { int strength; fpoint_t origin; } shock;
} data;
} effect_area_t;
/* Create a new effect area of the specified type.
* sprite, anchor, lifetime, anim, repeat_delay, and data should be set. */
effect_area_t *effect_area_new(uint16_t type);
/* Create an effect area for a particular attack
All additional parameters are set by this function. */
effect_area_t *effect_area_new_attack(uint16_t type, entity_t *e, int facing);
/* Set area animation */
void effect_area_set_anim(effect_area_t *ea, anim_frame_t *frame);
/* Apply effect of area on entity */
struct game;
void effect_area_apply(struct game *g, effect_area_t *ea, entity_t *e);
/* Whether the area should be rendered in background (floor level) */
bool effect_area_is_background(effect_area_t const *ea);