62 lines
2.7 KiB
C++
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
|