#pragma once // ----------------------------------------------------------------------------- // Мишени: статичные, не атакуют, респавнятся на том же месте. // 12 штук кучками (5 / 3 / 3 / 1) — расстановка захардкожена. // // Target — компонент ECS: сущности мишеней создаются в SpawnTargets, а вектор, // по которому ходят правила, — это плотный массив пула (см. ecs/ecs.h). // ----------------------------------------------------------------------------- #include #include "core/math.h" #include "ecs/ecs.h" #include "tuning.h" struct Target { ecs::Entity self = ecs::NO_ENTITY; Vec2 pos{}; // Своё место. Удар отбрасывает мишень, после чего она возвращается сюда: // без отдачи попадание в упор ничем не отличается от промаха. Vec2 home{}; Vec2 vel{}; float hp = 0.0f; float maxHp = 0.0f; float respawnTimer = 0.0f; float radius = 0.34f; bool alive = true; // Сопротивление отбросу, 0..1. 0 — мишень летит от удара как есть, // 1 — не сдвигается вообще. Тяжёлая цель гасит импульс клинка, и это // единственное, чем она отличается от лёгкой при равном HP. float knockResist = 0.0f; // Во сколько раз ослабляется импульс с учётом общего множителя из tuning. float KnockScale() const { const float r = Clampf(knockResist * g_tune.knockResistScale, 0.0f, 0.98f); return 1.0f - r; } }; // Импульс от удара (dir нормализован вызывающим). speed — импульс ДО того, // как мишень ему сопротивляется: сопротивление применяется здесь, в одном месте, // иначе половина источников урона про него забудет. void KnockTarget(Target& t, Vec2 dir, float speed); void SpawnTargets(ecs::World& world); void UpdateTargets(std::vector& targets, float dt); // Число живых мишеней (знаменатель в оценке покрытия, спек 6.5). int CountAliveTargets(const std::vector& targets);