From 83106d5a49ef1852acb05960c8ca068e8e7b6aef Mon Sep 17 00:00:00 2001 From: terencehill Date: Wed, 14 Feb 2024 22:54:38 +0100 Subject: [PATCH] HUD hit indicator: allow displaying up to 10 indicators at the same time --- qcsrc/client/view.qc | 85 +++++++++++++++++++++++++++----------------- qcsrc/client/view.qh | 7 ++-- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 900114588..b2524b455 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -753,49 +753,70 @@ void View_EventChase(entity this) } } +#define HITINDICATOR_EXPIRED(i) (time >= HitIndicator_time[i] + autocvar_cl_hit_indicator_fade_time) + void HitIndicatorUpdate(float dmg, entity attacker) { - if (time < HitIndicator_time + 1 && HitIndicator_attacker == attacker) - HitIndicator_damage += dmg; + int i = 0; + int first_free_spot = -1; + for (i = 0; i < HITINDICATOR_MAX_COUNT; ++i) + { + if (first_free_spot == -1 && HITINDICATOR_EXPIRED(i)) + first_free_spot = i; + else if (attacker == HitIndicator_attacker[i] && !HITINDICATOR_EXPIRED(i)) + break; + } + + bool is_new = false; + if (i == HITINDICATOR_MAX_COUNT) // if no matching attacker found + { + if (first_free_spot == -1) // if no free spot found + return; // too many hits, ignore this new hit + i = first_free_spot; + is_new = true; + } + + HitIndicator_attacker[i] = attacker; + HitIndicator_time[i] = time; + if (is_new) + HitIndicator_damage[i] = dmg; else - HitIndicator_damage = dmg; - HitIndicator_attacker = attacker; - HitIndicator_time = time; + HitIndicator_damage[i] += dmg; } void HitIndicatorShow() { - if (!autocvar_cl_hit_indicator || autocvar_cl_hit_indicator_size <= 0 - || autocvar_chase_active || time > HitIndicator_time + autocvar_cl_hit_indicator_fade_time) - { + if (!autocvar_cl_hit_indicator || autocvar_cl_hit_indicator_size <= 0 || autocvar_chase_active) return; - } - entity attacker = HitIndicator_attacker; - if (!attacker) - return; + for (int i = 0; i < HITINDICATOR_MAX_COUNT; ++i) + { + entity attacker = HitIndicator_attacker[i]; + if (!attacker || HITINDICATOR_EXPIRED(i)) + continue; - // hide indicator if attacker is not visible (check ported from shownames.qc) - traceline(view_origin, attacker.origin, MOVE_NOMONSTERS, attacker); - if (trace_fraction < 1 && (trace_networkentity != attacker.sv_entnum && trace_ent.entnum != attacker.sv_entnum)) - return; + // hide indicator if attacker is not visible (check ported from shownames.qc) + traceline(view_origin, attacker.origin, MOVE_NOMONSTERS, attacker); + if (trace_fraction < 1 && (trace_networkentity != attacker.sv_entnum && trace_ent.entnum != attacker.sv_entnum)) + continue; - vector org = project_3d_to_2d(attacker.origin); - vector scr_center = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; - float radius = autocvar_cl_hit_indicator_radius * min(vid_conwidth, vid_conheight); - vector ofs = normalize(org - scr_center - org.z * eZ) * radius; - float ang = atan2(-ofs.x, -ofs.y); - if (org.z < 0) - { - ang += M_PI; - ofs = -ofs; - } - org = scr_center + ofs; - float alpha = autocvar_cl_hit_indicator_fade_alpha; - alpha *= 1 - (time - HitIndicator_time) / autocvar_cl_hit_indicator_fade_time; - float size = autocvar_cl_hit_indicator_size; - size = map_bound_ranges(HitIndicator_damage, 30, 90, size, size * 2); - drawspritearrow(org, ang, '1 0 0', alpha, size, true); + vector org = project_3d_to_2d(attacker.origin); + vector scr_center = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; + float radius = autocvar_cl_hit_indicator_radius * min(vid_conwidth, vid_conheight); + vector ofs = normalize(org - scr_center - org.z * eZ) * radius; + float ang = atan2(-ofs.x, -ofs.y); + if (org.z < 0) + { + ang += M_PI; + ofs = -ofs; + } + org = scr_center + ofs; + float alpha = autocvar_cl_hit_indicator_fade_alpha; + alpha *= 1 - (time - HitIndicator_time[i]) / autocvar_cl_hit_indicator_fade_time; + float size = autocvar_cl_hit_indicator_size; + size = map_bound_ranges(HitIndicator_damage[i], 30, 90, size, size * 2); + drawspritearrow(org, ang, '1 0 0', alpha, size, true); + } } vector damage_blurpostprocess, content_blurpostprocess; diff --git a/qcsrc/client/view.qh b/qcsrc/client/view.qh index 0a54db106..73412793e 100644 --- a/qcsrc/client/view.qh +++ b/qcsrc/client/view.qh @@ -99,9 +99,10 @@ float autocvar_cl_hit_indicator_fade_alpha = 0.8; float autocvar_cl_hit_indicator_fade_time = 1.5; float autocvar_cl_hit_indicator_radius = 0.15; float autocvar_cl_hit_indicator_size = 1.1; -entity HitIndicator_attacker; -float HitIndicator_damage; -int HitIndicator_time; +const int HITINDICATOR_MAX_COUNT = 10; +entity HitIndicator_attacker[HITINDICATOR_MAX_COUNT]; +float HitIndicator_damage[HITINDICATOR_MAX_COUNT]; +int HitIndicator_time[HITINDICATOR_MAX_COUNT]; void calc_followmodel_ofs(entity view); -- 2.39.2