}
}
+void HitIndicatorUpdate(float dmg, int attacker)
+{
+ if (time < HitIndicator_time + 1 && HitIndicator_attacker == attacker)
+ HitIndicator_damage += dmg;
+ else
+ HitIndicator_damage = dmg;
+ HitIndicator_attacker = attacker;
+ HitIndicator_time = time;
+}
+
void HitIndicatorShow()
{
if (!autocvar_cl_hit_indicator || autocvar_cl_hit_indicator_size <= 0
- || time > HitIndicator_time + 1
- || !HitIndicator_attacker || !CSQCModel_server2csqc(HitIndicator_attacker - 1))
+ || autocvar_chase_active || time > HitIndicator_time + autocvar_cl_hit_indicator_fade_time)
{
return;
}
entity attacker = CSQCModel_server2csqc(HitIndicator_attacker - 1);
+ if (!HitIndicator_attacker || !CSQCModel_server2csqc(HitIndicator_attacker - 1))
+ 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))
+ return;
+
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);
ang += M_PI;
ofs = -ofs;
}
- org = scr_centersss + ofs;
- drawspritearrow(org, ang, '1 0 0', 0.8, autocvar_cl_hit_indicator_size);
+ 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 damage_blurpostprocess, content_blurpostprocess;
vector autocvar_cl_gunoffset;
bool autocvar_cl_hit_indicator = 1;
+float autocvar_cl_hit_indicator_fade_alpha = 0.8;
+float autocvar_cl_hit_indicator_fade_time = 1;
float autocvar_cl_hit_indicator_radius = 0.15;
float autocvar_cl_hit_indicator_size = 1.1;
int HitIndicator_attacker;
+int HitIndicator_damage;
int HitIndicator_time;
void calc_followmodel_ofs(entity view);
NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew)
{
float thedamage, rad, edge, thisdmg;
- bool hitplayer = false, hitme = false;
+ bool hitplayer = false;
int species, forcemul;
vector force, thisforce;
+ float hitme_damage = 0;
w_deathtype = ReadShort();
w_issilent = (w_deathtype & 0x8000);
DamageEffect(it, w_org, thisdmg, w_deathtype, species);
- if(it == csqcplayer)
- hitme = true; // this impact damaged me
+ if(it == csqcplayer && attacker - 1 != player_localnum)
+ hitme_damage = thisdmg; // this impact damaged me
else if(it != csqcplayer && (it.isplayermodel & ISPLAYER_MODEL))
hitplayer = true; // this impact damaged another player
});
if(!DEATH_ISSPECIAL(w_deathtype))
{
- if(hitme)
- {
- HitIndicator_attacker = attacker;
- HitIndicator_time = time;
- }
+ if(hitme_damage > 0)
+ HitIndicatorUpdate(hitme_damage, attacker);
// TODO spawn particle effects and sounds based on w_deathtype
if(!hitplayer || rad) // don't show ground impacts for hitscan weapons if a player was hit
}
// returns location of sprite text
-vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
+vector drawspritearrow(vector o, float ang, vector rgb, float a, float t, bool no_border)
{
float size = 9.0 * t;
- float border = 1.5 * t;
+ float border = no_border ? 0 : 1.5 * t;
float margin = 4.0 * t;
float borderDiag = border * M_SQRT2;
SetResourceExplicit(this, RES_HEALTH, -1);
}
- o = drawspritearrow(o, ang, rgb, a, SPRITE_ARROW_SCALE * t);
+ o = drawspritearrow(o, ang, rgb, a, SPRITE_ARROW_SCALE * t, false);
string pic = "";
bool is_text = true;
void drawhealthbar(vector org, float rot, float h, vector sz, vector hotspot, float width, float height, float margin, float border, float align, vector rgb, float a, vector hrgb, float ha, float f);
// returns location of sprite text
-vector drawspritearrow(vector o, float ang, vector rgb, float a, float t);
+vector drawspritearrow(vector o, float ang, vector rgb, float a, float t, bool no_border);
// returns location of sprite healthbar
vector drawsprite_TextOrIcon(bool is_text, vector o, float ang, float minwidth, vector rgb, float a, vector sz, string str);
if(draw_healthbar || draw_text) // make sure it's actually being drawn
{
- o = drawspritearrow(o, M_PI, rgb, a, SPRITE_ARROW_SCALE * t);
+ o = drawspritearrow(o, M_PI, rgb, a, SPRITE_ARROW_SCALE * t, false);
}
if(draw_text)
{
seta cl_voice_directional_taunt_attenuation 0.5 "this defines the distance from which taunts can be heard"
seta cl_hit_indicator 1 "show a 2d directional indicator around the screen center when a player hits you"
+seta cl_hit_indicator_fade_time 1 "how long hit indicator takes to fade away"
+seta cl_hit_indicator_fade_alpha 1 "initial hit indicator alpha"
seta cl_hit_indicator_radius 0.15 "show the directional indicator at this percentage of the screen from the center"
seta cl_hit_indicator_size 1.1 "directional indicator size"