feat(whip): aplicació de dany amb retall de hitbox, alreadyHit i friendly fire
This commit is contained in:
1 parent
d208ba02df
commit
df60709e6d
5 files changed
+217
-6
No files matched your search
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "external/fkyaml_node.hpp"
|
||||
@@ -10,6 +12,8 @@
|
||||
#include "game/entities/attack.hpp"
|
||||
|
||||
class Entity;
|
||||
class EntityManager;
|
||||
class Player;
|
||||
|
||||
// Atac de látigo: spawnejat pel jugador en entrar a `ATTACKING`. Viu la
|
||||
// durada de la seua animació (`swing`) i s'autoelimina al final.
|
||||
@@ -51,10 +55,20 @@ class WhipAttack : public Attack {
|
||||
// Configura l'estat runtime de la instància. Cal cridar-lo abans del
|
||||
// primer `update`. Selecciona la surface i la mida del pixel_rect_
|
||||
// segons direcció, i posa la cantonada superior-esquerra de la
|
||||
// hitbox a (spawn_x, spawn_y).
|
||||
// hitbox a (spawn_x, spawn_y). També calcula la `damage_rect_`
|
||||
// retallada contra murs i sarcs (mai sortiria del playfield ni
|
||||
// travessaria un sarc).
|
||||
void configure(Direction dir, float spawn_x, float spawn_y, float range_px);
|
||||
|
||||
// Avança animació; quan completa, marca dead.
|
||||
// Injecta el context que necessita la fase de dany: punter a
|
||||
// l'`EntityManager` (per iterar Hazards) i a la llista de jugadors
|
||||
// (per al friendly fire). Si no es crida, els frames actius no
|
||||
// apliquen dany — el whip queda merament visual. Cridar abans del
|
||||
// primer `update` (típicament just després de `configure`).
|
||||
void setWorldContext(EntityManager* manager, const std::vector<Player*>* players);
|
||||
|
||||
// Avança animació; durant frames actius, aplica dany; quan
|
||||
// l'animació es completa, marca dead.
|
||||
void update(float delta_time) override;
|
||||
|
||||
[[nodiscard]] auto getDirection() const -> Direction { return direction_; }
|
||||
@@ -71,6 +85,11 @@ class WhipAttack : public Attack {
|
||||
// Llargada de la hitbox abans de retallar contra murs/sarcs (en píxels).
|
||||
[[nodiscard]] auto getRangePx() const -> float { return range_px_; }
|
||||
|
||||
// Hitbox efectiva de dany (ja retallada pel primer bloquejador en la
|
||||
// línia d'atac). Exposada per als smoke tests; en producció només la
|
||||
// consumeix la pròpia `applyDamage`.
|
||||
[[nodiscard]] auto getDamageRect() const -> SDL_FRect { return damage_rect_; }
|
||||
|
||||
// Clau al `Resource::Cache` per a la surface de la direcció actual
|
||||
// (la que ha triat `configure()`). El caller (típicament `GameScene`)
|
||||
// resol la surface i la passa via `setSurface()`. Aquesta separació
|
||||
@@ -81,11 +100,31 @@ class WhipAttack : public Attack {
|
||||
private:
|
||||
[[nodiscard]] auto spriteFor(Direction dir) const -> const DirSprite&;
|
||||
|
||||
// Calcula la `damage_rect_` final: retalla la longitud de l'atac
|
||||
// contra el primer bloquejador (mur extern del playfield o sarc) en
|
||||
// la línia d'atac. Implementació iterativa píxel a píxel — el rang
|
||||
// típic és ~48 px, així que el cost és menyspreable.
|
||||
void computeDamageRect(Direction dir, float spawn_x, float spawn_y, float range_px);
|
||||
|
||||
// Aplica dany aquest frame: itera Hazards (Mummy whippable) i
|
||||
// jugadors (excepte `owner_`) que solapen amb `damage_rect_` i
|
||||
// estan en estat "atacable", crida `enterHurt` amb la direcció
|
||||
// adequada i els marca a `already_hit_` per garantir un sol
|
||||
// impacte per swing per objectiu.
|
||||
void applyDamage();
|
||||
|
||||
Direction direction_{Direction::EAST};
|
||||
AnimationComponent anim_swing_;
|
||||
std::vector<int> active_frames_;
|
||||
std::set<Entity*> already_hit_;
|
||||
// Set d'objectius ja colpejats aquest swing: usem `void*` perquè
|
||||
// hi guardem tant `Entity*` (Mummy) com `Player*` (que NO hereta
|
||||
// d'Entity) sense `reinterpret_cast` semànticament dubtós.
|
||||
std::unordered_set<void*> already_hit_;
|
||||
float range_px_{0.0F};
|
||||
SDL_FRect damage_rect_{0.0F, 0.0F, 0.0F, 0.0F};
|
||||
|
||||
EntityManager* entity_manager_{nullptr};
|
||||
const std::vector<Player*>* players_{nullptr};
|
||||
|
||||
DirSprite sprite_north_;
|
||||
DirSprite sprite_south_;
|
||||
|
||||
Reference in new issue
Block a user