#include "Hitbox.h" #include #include #include "Character.h" #include "Ragdoll.h" #include "RenderSystem.h" #include "tFunctions.h" static constexpr float DEBUG_LINGER = 0.4f; // real seconds a hitbox stays drawn after it's gone static const glm::vec3 HURTBOX_COLOR(0.2f, 0.9f, 0.35f); static const glm::vec3 HITBOX_COLOR(1.0f, 0.2f, 0.2f); static const glm::vec3 LANDED_COLOR(1.0f, 0.85f, 0.2f); void HitboxSystem::Resolve(const std::vector& characters, const HitHandler& onHit, float dt) { // A swing nothing was added for this frame is over, so who it hit can go std::unordered_set going; for (const Hitbox& hitbox : pending) if (hitbox.swing != 0) going.insert(hitbox.swing); for (auto it = hitBySwing.begin(); it != hitBySwing.end(); ) it = going.count(it->first) ? std::next(it) : hitBySwing.erase(it); for (Shown& old : shown) old.timeLeft -= dt; shown.erase(std::remove_if(shown.begin(), shown.end(), [](const Shown& old) { return old.timeLeft <= 0.0f; }), shown.end()); // Taken first, a hit is free to add more for next frame const std::vector hitboxes = std::move(pending); pending.clear(); for (const Hitbox& hitbox : hitboxes) { bool landed = false; for (Character* target : characters) { if (target == hitbox.owner || target->IsDead() || target->ragdoll || !target->body) continue; if (target->DodgesHits() && !hitbox.hitsKnockedDown) continue; if (hitbox.swing != 0) { const std::vector& already = hitBySwing[hitbox.swing]; if (std::find(already.begin(), already.end(), target) != already.end()) continue; } if (!TInT(hitbox.box, target->body->t, false).has_value()) continue; if (hitbox.swing != 0) hitBySwing[hitbox.swing].push_back(target); landed = true; onHit(hitbox, *target); } shown.push_back({ hitbox.box, landed, DEBUG_LINGER }); } } void HitboxSystem::AppendDebugLines(const std::vector& characters, std::vector& lines) const { for (Character* character : characters) { if (!character->body) continue; if (character->ragdoll) { for (Ragdoll::Part* part : character->ragdoll->GetParts()) lines.push_back({ part->transform.t.GetMatrix(), HURTBOX_COLOR }); continue; } lines.push_back({ character->body->t.GetMatrix(), HURTBOX_COLOR }); } for (const Shown& old : shown) { const float fade = 0.3f + 0.7f * glm::clamp(old.timeLeft / DEBUG_LINGER, 0.0f, 1.0f); lines.push_back({ old.box.GetMatrix(), (old.landed ? LANDED_COLOR : HITBOX_COLOR) * fade }); } }