From 24d0565b3e298a395ded4d93480402ea0b11c9e6 Mon Sep 17 00:00:00 2001 From: terencehill Date: Fri, 4 Mar 2016 20:02:15 +0100 Subject: [PATCH] Shake the HUD when hurt --- _hud_common.cfg | 5 ++++ qcsrc/client/hud/hud.qc | 51 ++++++++++++++++++++++++++++++++++ qcsrc/client/hud/hud.qh | 5 ++++ qcsrc/client/hud/hud_config.qc | 1 + qcsrc/client/main.qc | 1 + 5 files changed, 63 insertions(+) diff --git a/_hud_common.cfg b/_hud_common.cfg index e58a449a2..90a363f7a 100644 --- a/_hud_common.cfg +++ b/_hud_common.cfg @@ -66,6 +66,11 @@ seta hud_panel_update_interval 2 "how often (in seconds) common panel cvars are seta hud_dynamic_follow 1 "HUD moves around following player's movement (effect shared with cl_followmodel, can be enabled independently from it though)" seta hud_dynamic_follow_scale 0.01 "HUD following scale" +seta hud_dynamic_shake 1 "shake the HUD when hurt" +seta hud_dynamic_shake_damage_max 90 "damage value at which the HUD shake effect is maximum" +seta hud_dynamic_shake_damage_min 10 "damage value at which the HUD shake effect is minimum" +seta hud_dynamic_shake_scale 0.4 "HUD shake scale" + seta hud_showbinds 1 "what to show in the HUD to indicate certain keys to press: 0 display commands, 1 bound keys, 2 both" seta hud_showbinds_limit 2 "maximum number of bound keys to show for a command. 0 for unlimited" set _hud_showbinds_reload 0 "set it to 1 to reload binds if you changed any. It is reset to 0 automatically" diff --git a/qcsrc/client/hud/hud.qc b/qcsrc/client/hud/hud.qc index 6523dfd33..7a526c7ab 100644 --- a/qcsrc/client/hud/hud.qc +++ b/qcsrc/client/hud/hud.qc @@ -451,6 +451,31 @@ void HUD_Reset() HUD_Mod_CTF_Reset(); } +float autocvar_hud_dynamic_shake; +float autocvar_hud_dynamic_shake_damage_max; +float autocvar_hud_dynamic_shake_damage_min; +float autocvar_hud_dynamic_shake_scale; +float hud_dynamic_shake_x[10] = {0, 1, -0.7, 0.5, -0.3, 0.2, -0.1, 0.1, 0.0, 0}; +float hud_dynamic_shake_y[10] = {0, 0.4, 0.8, -0.2, -0.6, 0.0, 0.3, 0.1, -0.1, 0}; +bool Hud_Shake_Update() +{ + if(time - hud_dynamic_shake_time < 0) + return false; + + float anim_speed = 17 + 9 * hud_dynamic_shake_factor; + float elapsed_time = (time - hud_dynamic_shake_time) * anim_speed; + int i = floor(elapsed_time); + if(i >= 9) + return false; + + float f = elapsed_time - i; + hud_dynamic_shake_ofs.x = ((1 - f) * hud_dynamic_shake_x[i] + f * hud_dynamic_shake_x[i+1]) * vid_conwidth * 0.27; + hud_dynamic_shake_ofs.y = ((1 - f) * hud_dynamic_shake_y[i] + f * hud_dynamic_shake_y[i+1]) * vid_conheight * 0.27; + hud_dynamic_shake_ofs.z = 0; + hud_dynamic_shake_ofs *= hud_dynamic_shake_factor * autocvar_hud_dynamic_shake_scale; + return true; +} + void calc_followmodel_ofs(entity view); void Hud_Dynamic_Frame() { @@ -465,6 +490,32 @@ void Hud_Dynamic_Frame() if (fabs(hud_dynamic_ofs.x) < 0.001) hud_dynamic_ofs.x = 0; if (fabs(hud_dynamic_ofs.y) < 0.001) hud_dynamic_ofs.y = 0; if (fabs(hud_dynamic_ofs.z) < 0.001) hud_dynamic_ofs.z = 0; + + float health = STAT(HEALTH); + if(autocvar_hud_dynamic_shake > 0 && !autocvar__hud_configure && health > 0) + { + if(hud_dynamic_shake_factor == -1) // don't allow the effect for this frame + hud_dynamic_shake_factor = 0; + else + { + float new_hud_dynamic_shake_factor = 0; + if(prev_health - health >= autocvar_hud_dynamic_shake_damage_min && autocvar_hud_dynamic_shake_damage_max > autocvar_hud_dynamic_shake_damage_min) + { + float m = max(autocvar_hud_dynamic_shake_damage_min, 1); + new_hud_dynamic_shake_factor = (prev_health - health - m) / (autocvar_hud_dynamic_shake_damage_max - m); + if(new_hud_dynamic_shake_factor >= 1) + new_hud_dynamic_shake_factor = 1; + if(new_hud_dynamic_shake_factor >= hud_dynamic_shake_factor) + { + hud_dynamic_shake_factor = new_hud_dynamic_shake_factor; + hud_dynamic_shake_time = time; + } + } + if(hud_dynamic_shake_factor) + if(!Hud_Shake_Update()) + hud_dynamic_shake_factor = 0; + } + } } void HUD_Main() diff --git a/qcsrc/client/hud/hud.qh b/qcsrc/client/hud/hud.qh index b80698ccf..4a3c1f4e3 100644 --- a/qcsrc/client/hud/hud.qh +++ b/qcsrc/client/hud/hud.qh @@ -149,6 +149,10 @@ float current_player; float autocvar_hud_dynamic_follow; float autocvar_hud_dynamic_follow_scale; +vector hud_dynamic_shake_ofs; +float hud_dynamic_shake_factor; +float hud_dynamic_shake_time; + // shared across viewmodel effects and dynamic hud code vector cl_followmodel_ofs; float cl_followmodel_time; @@ -393,6 +397,7 @@ REGISTER_HUD_PANEL(QUICKMENU, HUD_QuickMenu, quickmenu, PANEL_CO panel_bg_padding = panel.current_panel_bg_padding; \ panel_fg_alpha = panel.current_panel_fg_alpha * hud_fade_alpha; \ } \ + if(hud_dynamic_shake_factor > 0) panel_pos += hud_dynamic_shake_ofs; \ if(hud_dynamic_ofs.y) panel_pos.x += hud_dynamic_ofs.y * vid_conwidth; \ if(hud_dynamic_ofs.z) panel_pos.y += hud_dynamic_ofs.z * vid_conheight; \ if(hud_dynamic_ofs.x) { \ diff --git a/qcsrc/client/hud/hud_config.qc b/qcsrc/client/hud/hud_config.qc index 2ba78f798..fe1e19cb8 100644 --- a/qcsrc/client/hud/hud_config.qc +++ b/qcsrc/client/hud/hud_config.qc @@ -1263,6 +1263,7 @@ void HUD_Configure_Frame() menu_enabled = 0; if(autocvar_hud_cursormode) setcursormode(0); + hud_dynamic_shake_factor = -1; } } diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 14279816e..5f4953781 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -540,6 +540,7 @@ NET_HANDLE(ENT_CLIENT_CLIENTDATA, bool isnew) // clear race stuff race_laptime = 0; race_checkpointtime = 0; + hud_dynamic_shake_factor = -1; } if (autocvar_hud_panel_healtharmor_progressbar_gfx) { -- 2.39.2