Files
2026-11-08 07:45:01 -05:00

62 lines
2.7 KiB
C++

#ifndef HITBOX_CLASS
#define HITBOX_CLASS
#include <functional>
#include <unordered_map>
#include <vector>
#include "t.h"
class Character;
class Animation;
struct Ability;
struct HitboxDebugLine;
// A box that hurts whatever character it touches, for the frame it's added in. Attacks put these out
// while they can connect, HitboxSystem works out what they hit.
struct Hitbox {
Character* owner = nullptr; // never hits whoever put it out
unsigned int swing = 0; // hitboxes sharing a nonzero swing hit each character once between them, over every frame
t box; // in the world, its scale is its size
float damage = 0.0f;
float knockback = 0.0f; // m/s away from the owner
float knockbackUp = 0.0f; // m/s upward
float stun = 0.0f; // real seconds whoever it hits can't do anything
float knockdown = 0.0f; // real seconds whoever it hits is knocked down for, 0 doesn't
bool hitsKnockedDown = false; // can hit characters that are knocked down, which nothing else can
Animation* killAnimation = nullptr; // played on whoever it kills, its Camera bone filming it, see Ability
const Ability* killAbility = nullptr; // the ability it's from, for the sounds that go with killAnimation
std::function<void(Character& target)> onHit; // called on top of the damage for each character it hits, if set
};
// Every hitbox in the game goes through here. Each frame they're added, checked against every character's
// body (its hurtbox), and cleared. It also draws them all for the hitbox debug view.
class HitboxSystem {
public:
using HitHandler = std::function<void(const Hitbox& hitbox, Character& target)>;
// For this frame only
void Add(const Hitbox& hitbox) { pending.push_back(hitbox); }
// Checks this frame's hitboxes against every living character, calling onHit for each new hit, then clears them.
// dt is real time, for how long the debug view keeps showing them.
void Resolve(const std::vector<Character*>& characters, const HitHandler& onHit, float dt);
// Hurtboxes in green, hitboxes in red, the ones that hit something in yellow. Hitboxes linger a moment
// after they're gone, dimming, so ones that only last a few frames can still be seen.
void AppendDebugLines(const std::vector<Character*>& characters, std::vector<HitboxDebugLine>& lines) const;
private:
struct Shown {
t box;
bool landed = false;
float timeLeft = 0.0f;
};
std::vector<Hitbox> pending;
std::unordered_map<unsigned int, std::vector<const Character*>> hitBySwing; // swings still going, and who they've hit
std::vector<Shown> shown;
};
#endif