X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2FView.qc;h=3928ebd786e04427636bd2efd105ed3b45816441;hb=6835a9282dfc4e07327c7e20d9005268dc70945f;hp=e4deda0341b161f4cc9114748544a074d203680c;hpb=c637eb516648b51ef055d53244194805f53c3190;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc index e4deda0341..3928ebd786 100644 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@ -162,7 +162,7 @@ vector GetCurrentFov(float fov) else setsensitivityscale(1); - if(autocvar_cl_velocityzoom && autocvar_cl_velocityzoom_type) // _type = 0 disables velocity zoom too + if(autocvar_cl_velocityzoom_enabled && autocvar_cl_velocityzoom_type) // _type = 0 disables velocity zoom too { if(intermission) { curspeed = 0; } else @@ -183,7 +183,7 @@ vector GetCurrentFov(float fov) velocityzoom = bound(0, drawframetime / max(0.000000001, autocvar_cl_velocityzoom_time), 1); // speed at which the zoom adapts to player velocity avgspeed = avgspeed * (1 - velocityzoom) + (curspeed / autocvar_cl_velocityzoom_speed) * velocityzoom; - velocityzoom = exp(float2range11(avgspeed * -autocvar_cl_velocityzoom / 1) * 1); + velocityzoom = exp(float2range11(avgspeed * -autocvar_cl_velocityzoom_factor / 1) * 1); //print(ftos(avgspeed), " avgspeed, ", ftos(curspeed), " curspeed, ", ftos(velocityzoom), " return\n"); // for debugging } @@ -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; @@ -394,6 +390,30 @@ float contentavgalpha, liquidalpha_prev; vector liquidcolor_prev; float eventchase_current_distance; +float eventchase_running; +float WantEventchase() +{ + if(autocvar_cl_orthoview) + return FALSE; + if(intermission) + return TRUE; + if(spectatee_status >= 0) + { + if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_PORTO))) + return TRUE; + if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0)) + { + if(autocvar_cl_eventchase_death == 2) + { + // don't stop eventchase once it's started (even if velocity changes afterwards) + if(self.velocity == '0 0 0' || eventchase_running) + return TRUE; + } + else return TRUE; + } + } + return FALSE; +} vector damage_blurpostprocess, content_blurpostprocess; @@ -495,9 +515,10 @@ void CSQC_UpdateView(float w, float h) // event chase camera if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped { - WepSet weapons_stat = WepSet_GetFromStat(); - if(((spectatee_status >= 0 && (autocvar_cl_eventchase_death && is_dead)) || intermission) && !autocvar_cl_orthoview || (autocvar_cl_eventchase_nexball && spectatee_status >= 0 && gametype == MAPINFO_TYPE_NEXBALL && !(weapons_stat & WepSet_FromWeapon(WEP_PORTO)))) + if(WantEventchase()) { + eventchase_running = TRUE; + // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.) vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org); @@ -538,6 +559,7 @@ void CSQC_UpdateView(float w, float h) } else if(autocvar_chase_active < 0) // time to disable chase_active if it was set by this code { + eventchase_running = FALSE; cvar_set("chase_active", "0"); eventchase_current_distance = 0; // start from 0 next time } @@ -1151,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) - { - 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) + static float hitsound_time_prev = 0; + if (COMPARE_INCREASING(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) + if (autocvar_cl_hitsound && unaccounted_damage) { - 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); + // 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; @@ -1517,6 +1518,10 @@ void CSQC_UpdateView(float w, float h) weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD); weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE); + float ok_ammo_charge, ok_ammo_chargepool; + ok_ammo_charge = getstatf(STAT_OK_AMMO_CHARGE); + ok_ammo_chargepool = getstatf(STAT_OK_AMMO_CHARGEPOOl); + float vortex_charge, vortex_chargepool; vortex_charge = getstatf(STAT_VORTEX_CHARGE); vortex_chargepool = getstatf(STAT_VORTEX_CHARGEPOOL); @@ -1562,8 +1567,14 @@ void CSQC_UpdateView(float w, float h) ring_rgb = wcross_color; ring_image = "gfx/crosshair_ring.tga"; } - - if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring + else if (ok_ammo_charge) + { + ring_value = ok_ammo_chargepool; + ring_alpha = autocvar_crosshair_ring_reload_alpha; + ring_rgb = wcross_color; + ring_image = "gfx/crosshair_ring.tga"; + } + else if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring { ring_value = bound(0, weapon_clipload / weapon_clipsize, 1); ring_scale = autocvar_crosshair_ring_reload_size;