Stomping was guarded by the invincibility check, so during a downward dash the player could never deal stomp damage. Move the invincibility guard to only protect against taking damage, not dealing it. Extend dash invincibility by PLAYER_DASH_INV_GRACE (0.15s) past the dash duration so the player is briefly protected after landing. Closes #15
113 lines
4.6 KiB
C
113 lines
4.6 KiB
C
#ifndef JNR_PLAYER_H
|
|
#define JNR_PLAYER_H
|
|
|
|
#include "engine/entity.h"
|
|
#include "engine/camera.h"
|
|
#include "engine/tilemap.h"
|
|
|
|
/* Player physics tuning */
|
|
#define PLAYER_SPEED 150.0f /* horizontal speed (px/s) */
|
|
#define PLAYER_ACCEL 1200.0f /* ground acceleration */
|
|
#define PLAYER_DECEL 1600.0f /* ground deceleration (friction)*/
|
|
#define PLAYER_AIR_ACCEL 600.0f /* air acceleration */
|
|
#define PLAYER_JUMP_FORCE 320.0f /* initial jump velocity */
|
|
#define PLAYER_JUMP_CUT 0.4f /* multiplier when releasing jump*/
|
|
#define PLAYER_COYOTE_TIME 0.08f /* seconds after leaving edge */
|
|
#define PLAYER_JUMP_BUFFER 0.1f /* seconds before landing */
|
|
|
|
#define PLAYER_WIDTH 12
|
|
#define PLAYER_HEIGHT 16
|
|
|
|
/* Sprite dimensions (art is larger than hitbox) */
|
|
#define PLAYER_SPRITE_W 24
|
|
#define PLAYER_SPRITE_H 24
|
|
#define PLAYER_DEATH_SPRITE_W 32
|
|
#define PLAYER_DEATH_SPRITE_H 32
|
|
|
|
/* Shooting */
|
|
#define PLAYER_SHOOT_COOLDOWN 0.12f /* seconds between shots */
|
|
|
|
/* Dash / Jetpack */
|
|
#define PLAYER_DASH_SPEED 350.0f /* dash velocity (px/s) */
|
|
#define PLAYER_DASH_DURATION 0.15f /* seconds the dash lasts */
|
|
#define PLAYER_DASH_MAX_CHARGES 3 /* max jetpack charges */
|
|
#define PLAYER_DASH_RECHARGE 30.0f /* seconds to recharge one charge*/
|
|
|
|
/* Jetpack boost (from powerup) */
|
|
#define PLAYER_JETPACK_BOOST_DURATION 15.0f /* seconds the boost lasts */
|
|
#define PLAYER_JETPACK_BOOST_RECHARGE 0.5f /* boosted recharge rate (s) */
|
|
|
|
/* Invincibility after taking damage */
|
|
#define PLAYER_INV_TIME 1.5f /* seconds of invincibility */
|
|
#define PLAYER_DASH_INV_GRACE 0.15f /* extra invincibility after dash */
|
|
|
|
/* Aim direction (for shooting) */
|
|
typedef enum AimDir {
|
|
AIM_FORWARD, /* horizontal, based on facing */
|
|
AIM_UP, /* straight up */
|
|
AIM_DIAG_UP, /* 45 degrees up + forward */
|
|
} AimDir;
|
|
|
|
typedef struct PlayerData {
|
|
float coyote_timer;
|
|
float jump_buffer_timer;
|
|
bool jumping;
|
|
bool was_on_ground; /* on_ground last frame (landing detect) */
|
|
float shoot_cooldown;
|
|
float inv_timer; /* invincibility timer */
|
|
/* Dash / Jetpack */
|
|
float dash_timer; /* remaining dash time (0=not dashing) */
|
|
int dash_charges; /* available jetpack charges */
|
|
int dash_max_charges; /* max charges (for HUD) */
|
|
float dash_recharge_timer; /* time until next charge restored*/
|
|
Vec2 dash_dir; /* direction of current dash */
|
|
float jetpack_boost_timer; /* remaining boost time (0=off) */
|
|
/* Weapon */
|
|
bool has_gun; /* false until gun powerup picked up */
|
|
/* Aiming */
|
|
AimDir aim_dir; /* current aim direction */
|
|
bool looking_up; /* holding up without moving */
|
|
float look_up_timer; /* how long up has been held */
|
|
/* Down-arrow double-tap (free downward jetpack) */
|
|
float down_tap_timer; /* time since last mid-air down press */
|
|
/* Death / Respawn */
|
|
float respawn_timer; /* countdown after death anim finishes */
|
|
Vec2 spawn_point; /* where to respawn */
|
|
} PlayerData;
|
|
|
|
/* Register player entity type with the entity manager */
|
|
void player_register(EntityManager *em);
|
|
|
|
/* Entity callbacks */
|
|
void player_update(Entity *self, float dt, const Tilemap *map);
|
|
void player_render(Entity *self, const Camera *cam);
|
|
void player_destroy(Entity *self);
|
|
|
|
/* Spawn a fully configured player entity */
|
|
Entity *player_spawn(EntityManager *em, Vec2 pos);
|
|
|
|
/* Set the entity manager the player lives in (for spawning projectiles) */
|
|
void player_set_entity_manager(EntityManager *em);
|
|
|
|
/* Get the player's current look-up offset for the camera */
|
|
float player_get_look_up_offset(const Entity *self);
|
|
|
|
/* Get jetpack dash charge info for HUD (returns false if entity is not player) */
|
|
bool player_get_dash_charges(const Entity *self, int *charges, int *max_charges,
|
|
float *recharge_pct, bool *boosted);
|
|
|
|
/* Arm the player (give them the gun). Safe to call multiple times. */
|
|
void player_give_gun(Entity *self);
|
|
|
|
/* Check if the player has a gun */
|
|
bool player_has_gun(const Entity *self);
|
|
|
|
/* Check if the player is requesting a respawn (death anim finished + timer expired).
|
|
* Returns true when respawn should occur. */
|
|
bool player_wants_respawn(const Entity *self);
|
|
|
|
/* Reset the player to alive state at the given position */
|
|
void player_respawn(Entity *self, Vec2 pos);
|
|
|
|
#endif /* JNR_PLAYER_H */
|