From 6835a9282dfc4e07327c7e20d9005268dc70945f Mon Sep 17 00:00:00 2001 From: TimePath Date: Sat, 20 Dec 2014 19:05:24 +1100 Subject: [PATCH] Track hit time so that constant damage makes a noise --- qcsrc/client/View.qc | 113 ++++++++++++++++------------------------ qcsrc/common/stats.qh | 30 +++++------ qcsrc/common/util.qh | 3 ++ qcsrc/server/g_world.qc | 7 +++ 4 files changed, 69 insertions(+), 84 deletions(-) diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc index 0a5f73b55f..3928ebd786 100644 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@ -375,10 +375,6 @@ entity nightvision_noise, nightvision_noise2; #define MAX_TIME_DIFF 5 float pickup_crosshair_time, pickup_crosshair_size; -float hitsound_time_prev; -float spectatee_status_prev; // for preventing hitsound when switching spectatee -float damage_dealt_total, damage_dealt_total_prev; -float typehit_time, typehit_time_prev; float hitindication_crosshair_size; float use_vortex_chargepool; @@ -1177,83 +1173,62 @@ void CSQC_UpdateView(float w, float h) scoreboard_active = HUD_WouldDrawScoreboard(); // varying sound pitch - damage_dealt_total = getstati(STAT_DAMAGE_DEALT_TOTAL); - - // detect overflow on server side - if (damage_dealt_total < damage_dealt_total_prev) + + // accumulate damage with each stat update + static float unaccounted_damage = 0; + float unaccounted_damage_new = getstati(STAT_DAMAGE_DEALT_TOTAL); + static float damage_dealt_time_prev = 0; + float damage_dealt_time = getstatf(STAT_HIT_TIME); + if (damage_dealt_time != damage_dealt_time_prev) { - dprint("resetting dmg total: ", ftos(damage_dealt_total), " prev: ", ftos(damage_dealt_total_prev), "\n"); - damage_dealt_total_prev = 0; + unaccounted_damage += unaccounted_damage_new; + dprint("dmg total: ", ftos(unaccounted_damage), " (+", ftos(unaccounted_damage_new), ")", "\n"); } + damage_dealt_time_prev = damage_dealt_time; // prevent hitsound when switching spectatee + static float spectatee_status_prev = 0; if (spectatee_status != spectatee_status_prev) - { - damage_dealt_total_prev = damage_dealt_total; - } + unaccounted_damage = 0; spectatee_status_prev = spectatee_status; - // amount of damage since last hit sound - float unaccounted_damage = damage_dealt_total - damage_dealt_total_prev; - - - if (autocvar_cl_hitsound == 1) + static float hitsound_time_prev = 0; + if (COMPARE_INCREASING(time, hitsound_time_prev) > autocvar_cl_hitsound_antispam_time) { - if ( time - hitsound_time_prev > autocvar_cl_hitsound_antispam_time ) - if ( damage_dealt_total > 0 ) - { - sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE); - hitsound_time_prev = time; - } - } - else if (unaccounted_damage > 0 && autocvar_cl_hitsound > 0 && time - hitsound_time_prev > autocvar_cl_hitsound_antispam_time) - { - // customizable gradient function that crosses (0,a), (c,1) and asymptotically approaches b - float a, b, c, x; - a = autocvar_cl_hitsound_max_pitch; - b = autocvar_cl_hitsound_min_pitch; - c = autocvar_cl_hitsound_nom_damage; - x = unaccounted_damage; - float pitch_shift = (b*x*(a-1) + a*c*(1-b)) / (x*(a-1) + c*(1-b)); - - // if sound variation is disabled, set pitch_shift to 1 - if (autocvar_cl_hitsound == 1) - { - pitch_shift = 1; - } - - // if pitch shift is reversed, mirror in (max-min)/2 + min - if (autocvar_cl_hitsound == 3) + if (autocvar_cl_hitsound && unaccounted_damage) { - float mirror_value = (a-b)/2 + b; - pitch_shift = mirror_value + (mirror_value - pitch_shift); + // customizable gradient function that crosses (0,a), (c,1) and asymptotically approaches b + float a = autocvar_cl_hitsound_max_pitch; + float b = autocvar_cl_hitsound_min_pitch; + float c = autocvar_cl_hitsound_nom_damage; + float x = unaccounted_damage; + float pitch_shift = (b*x*(a-1) + a*c*(1-b)) / (x*(a-1) + c*(1-b)); + + // if sound variation is disabled, set pitch_shift to 1 + if (autocvar_cl_hitsound == 1) + pitch_shift = 1; + + // if pitch shift is reversed, mirror in (max-min)/2 + min + if (autocvar_cl_hitsound == 3) + { + float mirror_value = (a-b)/2 + b; + pitch_shift = mirror_value + (mirror_value - pitch_shift); + } + + dprint("dmg total (dmg): ", ftos(unaccounted_damage), " (+", ftos(unaccounted_damage_new), "), pitch shift: ", ftos(pitch_shift), "\n"); + + // todo: avoid very long and very short sounds from wave stretching using different sound files? seems unnecessary + // todo: normalize sound pressure levels? seems unnecessary + + sound7(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTN_NONE, pitch_shift * 100, 0); } - - dprint("dmg total (dmg): ", ftos(damage_dealt_total), " (+", ftos(unaccounted_damage), "), pitch shift: ", ftos(pitch_shift), "\n"); - - // todo: avoid very long and very short sounds from wave stretching using different sound files? seems unnecessary - // todo: normalize sound pressure levels? seems unnecessary - - // scale to fit function interface - float param_pitch_shift = pitch_shift * 100; - - // play sound - sound7(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTN_NONE, param_pitch_shift, 0); - - // track damage accounted for - damage_dealt_total_prev = damage_dealt_total; - - // remember when this sound was played to prevent sound spam + unaccounted_damage = 0; hitsound_time_prev = time; } - else if (autocvar_cl_hitsound == 0) - { - // forget the damage to prevent hitsound when enabling it - damage_dealt_total_prev = damage_dealt_total; - } - - typehit_time = getstatf(STAT_TYPEHIT_TIME); - if(typehit_time - typehit_time_prev > autocvar_cl_hitsound_antispam_time) + + static float typehit_time_prev = 0; + float typehit_time = getstatf(STAT_TYPEHIT_TIME); + if (COMPARE_INCREASING(typehit_time, typehit_time_prev) > autocvar_cl_hitsound_antispam_time) { sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTN_NONE); typehit_time_prev = typehit_time; diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index ce6e005d87..f057029979 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -56,21 +56,21 @@ const float STAT_VORTEX_CHARGE = 50; const float STAT_LAST_PICKUP = 51; const float STAT_HUD = 52; const float STAT_VORTEX_CHARGEPOOL = 53; -const float STAT_DAMAGE_DEALT_TOTAL = 54; -const float STAT_TYPEHIT_TIME = 55; -const float STAT_LAYED_MINES = 56; -const float STAT_HAGAR_LOAD = 57; -const float STAT_SWITCHINGWEAPON = 58; -const float STAT_SUPERWEAPONS_FINISHED = 59; -const float STAT_VEHICLESTAT_HEALTH = 60; -const float STAT_VEHICLESTAT_SHIELD = 61; -const float STAT_VEHICLESTAT_ENERGY = 62; -const float STAT_VEHICLESTAT_AMMO1 = 63; -const float STAT_VEHICLESTAT_RELOAD1 = 64; -const float STAT_VEHICLESTAT_AMMO2 = 65; -const float STAT_VEHICLESTAT_RELOAD2 = 66; -const float STAT_VEHICLESTAT_W2MODE = 67; -// 68 empty? +const float STAT_HIT_TIME = 54; +const float STAT_DAMAGE_DEALT_TOTAL = 55; +const float STAT_TYPEHIT_TIME = 56; +const float STAT_LAYED_MINES = 57; +const float STAT_HAGAR_LOAD = 58; +const float STAT_SWITCHINGWEAPON = 59; +const float STAT_SUPERWEAPONS_FINISHED = 60; +const float STAT_VEHICLESTAT_HEALTH = 61; +const float STAT_VEHICLESTAT_SHIELD = 62; +const float STAT_VEHICLESTAT_ENERGY = 63; +const float STAT_VEHICLESTAT_AMMO1 = 64; +const float STAT_VEHICLESTAT_RELOAD1 = 65; +const float STAT_VEHICLESTAT_AMMO2 = 66; +const float STAT_VEHICLESTAT_RELOAD2 = 67; +const float STAT_VEHICLESTAT_W2MODE = 68; const float STAT_NADE_TIMER = 69; const float STAT_SECRETS_TOTAL = 70; const float STAT_SECRETS_FOUND = 71; diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index 14dd59d048..49ec62ad3d 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -451,3 +451,6 @@ vector bezier_quadratic_getpoint(vector a, vector p, vector b, float t); vector bezier_quadratic_getderivative(vector a, vector p, vector b, float t); #define APPEND_TO_STRING(list,sep,add) ((list) = (((list) != "") ? strcat(list, sep, add) : (add))) + +// Returns the correct difference between two always increasing numbers +#define COMPARE_INCREASING(to,from) (to < from ? from + to + 2 : to - from) \ No newline at end of file diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index f97a4254df..4b14ef3a16 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -755,6 +755,7 @@ void spawnfunc_worldspawn (void) addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load); addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size); addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup); + addstat(STAT_HIT_TIME, AS_FLOAT, hit_time); addstat(STAT_DAMAGE_DEALT_TOTAL, AS_INT, damage_dealt_total); addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time); addstat(STAT_LAYED_MINES, AS_INT, minelayer_mines); @@ -2210,14 +2211,20 @@ void EndFrame() if(self.enemy.typehitsound) self.typehit_time = time; else if(self.enemy.damage_dealt) + { + self.hit_time = time; self.damage_dealt_total = ceil(self.enemy.damage_dealt); + } } else { if(self.typehitsound) self.typehit_time = time; else if(self.damage_dealt) + { + self.hit_time = time; self.damage_dealt_total = ceil(self.damage_dealt); + } } } altime = time + frametime * (1 + autocvar_g_antilag_nudge); -- 2.39.2