//--- // 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; /* Cooldown until next dash particle */ fixed_t dash_particle_cooldown; } entity_movement_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; /* Animated image and state */ anim_state_t anim; /* Current attack's effect area */ struct effect_area *current_attack; /* Whether attack follows movement */ uint8_t attack_follows_movement; /* Enemy ID (0 for player) */ uint8_t identity; /* Time left until nexth pathfinding run (ms) */ // uint8_t pathfind_delay; /* Combat statistics */ uint16_t HP, ATK, DEF; } 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); /* 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); void entity_set_directional_anim(entity_t *e, anim_frame_t *frame_dirs[]); #define entity_set_anim(e, frame) _Generic((frame), \ anim_frame_t *: entity_set_normal_anim(e, (void *)frame), \ anim_frame_t **: entity_set_directional_anim(e, (void *)frame)) /* 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_HIT, /* Normal attack by a slashing weapon */ EFFECT_SLASH, }; /* 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_HIT: source and ATK strength */ struct { int strength; int dir; } hit; /* EFFECT_SLASH: source and ATK strength */ struct { int strength; int dir; } slash; } 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); /* 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);