Commit 6835a928 authored by TimePath's avatar TimePath

Track hit time so that constant damage makes a noise

parent c5fbf16c
......@@ -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;
......
......@@ -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;
......
......@@ -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
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment