X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fclient%2Fview.qc;h=ece38598ecc96dd42dc7792f70d974fdac5851c3;hp=9c19493dced8d4a72e34053237c816449e44335e;hb=0071121b663dc3d841a2c28d27c1015899f0f402;hpb=64f2b309aa5be8aafb9ad2137174bb6d99aeb876 diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 9c19493dce..ece38598ec 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -62,10 +62,9 @@ float autocvar_cl_leanmodel_highpass = 0.2; float autocvar_cl_leanmodel_lowpass = 0.05; #define avg_factor(avg_time) (1 - exp(-frametime / max(0.001, avg_time))) -#define lowpass(value, frac, ref_store, ret) MACRO_BEGIN \ -{ \ - ret = ref_store = ref_store * (1 - frac) + (value) * frac; \ -} MACRO_END + +#define lowpass(value, frac, ref_store, ret) \ + ret = ref_store = ref_store * (1 - frac) + (value) * frac; #define lowpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \ { \ @@ -125,7 +124,6 @@ void calc_followmodel_ofs(entity view) float frac; vector gunorg = '0 0 0'; static vector vel_average; - static vector gunorg_prev = '0 0 0'; static vector gunorg_adjustment_highpass; static vector gunorg_adjustment_lowpass; @@ -313,14 +311,12 @@ void viewmodel_draw(entity this) e.csqcmodel_effects = fx; CSQCModel_Effects_Apply(e); } + if(a >= 0) { string name = wep.mdl; - if(wep == WEP_TUBA) - { - name = (this.tuba_instrument == 0) ? "tuba" : - (this.tuba_instrument == 1) ? "akordeon" : - "kleinbottle"; - } + string newname = wep.wr_viewmodel(wep, this); + if(newname) + name = newname; bool swap = name != this.name_last; // if (swap) { @@ -330,7 +326,7 @@ void viewmodel_draw(entity this) this.viewmodel_angles = this.angles; } anim_update(this); - if (!this.animstate_override && !this.animstate_looping) + if ((!this.animstate_override && !this.animstate_looping) || time > this.animstate_endtime) anim_set(this, this.anim_idle, true, false, false); } float f = 0; // 0..1; 0: fully active @@ -360,6 +356,7 @@ void viewmodel_draw(entity this) this.angles = this.viewmodel_angles; this.angles_x = (-90 * f * f); viewmodel_animate(this); + MUTATOR_CALLHOOK(DrawViewModel, this); setorigin(this, this.origin); } @@ -526,7 +523,7 @@ vector GetCurrentFov(float fov) current_zoomfraction = (current_viewzoom - 1) / (1/zoomfactor - 1); if(zoomsensitivity < 1) - setsensitivityscale(pow(current_viewzoom, 1 - zoomsensitivity)); + setsensitivityscale(current_viewzoom ** (1 - zoomsensitivity)); else setsensitivityscale(1); @@ -670,7 +667,7 @@ float TrueAimCheck(entity wepent) mv = MOVE_NORMAL; if(zoomscript_caught) { - tracebox(view_origin, '0 0 0', '0 0 0', view_origin + view_forward * MAX_SHOT_DISTANCE, mv, ta); + tracebox(view_origin, '0 0 0', '0 0 0', view_origin + view_forward * max_shot_distance, mv, ta); return EnemyHitCheck(); } break; @@ -696,7 +693,7 @@ float TrueAimCheck(entity wepent) vecs = decompressShotOrigin(STAT(SHOTORG)); - traceline(traceorigin, traceorigin + view_forward * MAX_SHOT_DISTANCE, mv, ta); + traceline(traceorigin, traceorigin + view_forward * max_shot_distance, mv, ta); trueaimpoint = trace_endpos; if(vdist((trueaimpoint - traceorigin), <, g_trueaim_minrange)) @@ -763,7 +760,7 @@ bool WantEventchase(entity this) { if(autocvar_cl_orthoview) return false; - if(intermission) + if(STAT(GAME_STOPPED) || intermission) return true; if(this.viewloc) return true; @@ -773,6 +770,8 @@ bool WantEventchase(entity this) return true; if(MUTATOR_CALLHOOK(WantEventchase, this)) return true; + if(autocvar_cl_eventchase_frozen && STAT(FROZEN)) + return true; if(autocvar_cl_eventchase_death && (STAT(HEALTH) <= 0)) { if(autocvar_cl_eventchase_death == 2) @@ -847,8 +846,8 @@ void HitSound() 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)); + float d = unaccounted_damage; + float pitch_shift = (b*d*(a-1) + a*c*(1-b)) / (d*(a-1) + c*(1-b)); // if sound variation is disabled, set pitch_shift to 1 if (autocvar_cl_hitsound == 1) @@ -879,6 +878,14 @@ void HitSound() sound(NULL, CH_INFO, SND_TYPEHIT, VOL_BASE, ATTN_NONE); typehit_time_prev = typehit_time; } + + static float kill_time_prev = 0; + float kill_time = STAT(KILL_TIME); + if (COMPARE_INCREASING(kill_time, kill_time_prev) > autocvar_cl_hitsound_antispam_time) + { + sound(NULL, CH_INFO, SND_KILL, VOL_BASE, ATTN_NONE); + kill_time_prev = kill_time; + } } vector crosshair_getcolor(entity this, float health_stat) @@ -900,7 +907,7 @@ vector crosshair_getcolor(entity this, float health_stat) case 2: // crosshair_color_by_health { - float x = health_stat; + float hp = health_stat; //x = red //y = green @@ -908,33 +915,33 @@ vector crosshair_getcolor(entity this, float health_stat) wcross_color.z = 0; - if(x > 200) + if(hp > 200) { wcross_color.x = 0; wcross_color.y = 1; } - else if(x > 150) + else if(hp > 150) { - wcross_color.x = 0.4 - (x-150)*0.02 * 0.4; - wcross_color.y = 0.9 + (x-150)*0.02 * 0.1; + wcross_color.x = 0.4 - (hp-150)*0.02 * 0.4; + wcross_color.y = 0.9 + (hp-150)*0.02 * 0.1; } - else if(x > 100) + else if(hp > 100) { - wcross_color.x = 1 - (x-100)*0.02 * 0.6; - wcross_color.y = 1 - (x-100)*0.02 * 0.1; - wcross_color.z = 1 - (x-100)*0.02; + wcross_color.x = 1 - (hp-100)*0.02 * 0.6; + wcross_color.y = 1 - (hp-100)*0.02 * 0.1; + wcross_color.z = 1 - (hp-100)*0.02; } - else if(x > 50) + else if(hp > 50) { wcross_color.x = 1; wcross_color.y = 1; - wcross_color.z = 0.2 + (x-50)*0.02 * 0.8; + wcross_color.z = 0.2 + (hp-50)*0.02 * 0.8; } - else if(x > 20) + else if(hp > 20) { wcross_color.x = 1; - wcross_color.y = (x-20)*90/27/100; - wcross_color.z = (x-20)*90/27/100 * 0.2; + wcross_color.y = (hp-20)*90/27/100; + wcross_color.z = (hp-20)*90/27/100 * 0.2; } else { @@ -965,7 +972,7 @@ void HUD_Crosshair(entity this) { float f, i, j; vector v; - if(!scoreboard_active && !camera_active && intermission != 2 && + if(!scoreboard_active && !camera_active && intermission != 2 && !STAT(GAME_STOPPED) && spectatee_status != -1 && !csqcplayer.viewloc && !MUTATOR_CALLHOOK(DrawCrosshair) && !HUD_MinigameMenu_IsOpened() ) { @@ -997,7 +1004,7 @@ void HUD_Crosshair(entity this) float shottype; // wcross_origin = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; - wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward); + wcross_origin = project_3d_to_2d(view_origin + max_shot_distance * view_forward); wcross_origin.z = 0; if(autocvar_crosshair_hittest) { @@ -1195,7 +1202,7 @@ void HUD_Crosshair(entity this) } ring_inner_alpha = autocvar_crosshair_ring_vortex_inner_alpha; - ring_inner_rgb = eX * autocvar_crosshair_ring_vortex_inner_color_red + eY * autocvar_crosshair_ring_vortex_inner_color_green + eZ * autocvar_crosshair_ring_vortex_inner_color_blue; + ring_inner_rgb = vec3(autocvar_crosshair_ring_vortex_inner_color_red, autocvar_crosshair_ring_vortex_inner_color_green, autocvar_crosshair_ring_vortex_inner_color_blue); ring_inner_image = "gfx/crosshair_ring_inner.tga"; // draw the outer ring to show the current charge of the weapon @@ -1341,6 +1348,71 @@ void HUD_Crosshair(entity this) } } +const int MAX_SPECIALCOMMAND = 15; +vector specialcommand_slots[MAX_SPECIALCOMMAND]; +vector specialcommand_colors[MAX_SPECIALCOMMAND]; +const float SPECIALCOMMAND_SPEED = 150; +const float SPECIALCOMMAND_TURNSPEED = 2; +const float SPECIALCOMMAND_SIZE = 0.025; +const float SPECIALCOMMAND_CHANCE = 0.35; +float sc_spawntime, sc_changetime; +vector sc_color = '1 1 1'; +void SpecialCommand() +{ + if(!STAT(MOVEVARS_SPECIALCOMMAND)) + return; + + if(time >= sc_changetime) + { + sc_changetime = time + 1; + sc_color = randomvec() * 1.5; + sc_color.x = bound(0.2, sc_color.x, 0.75); + sc_color.y = bound(0.2, sc_color.y, 0.75); + sc_color.z = bound(0.2, sc_color.z, 0.75); + } + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), sc_color, autocvar_hud_colorflash_alpha * bound(0.1, sc_changetime - time, 0.3), DRAWFLAG_ADDITIVE); + + if(!precache_pic("gfx/smile")) + return; // damn party poopers + + for(int j = MAX_SPECIALCOMMAND - 1; j >= 0; --j) + { + vector slot = specialcommand_slots[j]; + if(slot.y) + slot.y += SPECIALCOMMAND_SPEED * frametime; + if(slot.z) + slot.z = sin(SPECIALCOMMAND_TURNSPEED * M_PI * time); + if(slot.y >= vid_conheight) + slot = '0 0 0'; + + if(slot == '0 0 0') + { + if(random() <= SPECIALCOMMAND_CHANCE && time > sc_spawntime) // low chance to spawn! + { + slot.x = bound(0, (random() * vid_conwidth + 1), vid_conwidth); + slot.y = 1; // start it off 0 so we can use it + slot.z = random(); + sc_spawntime = time + bound(0.4, random(), 0.75); // prevent spawning another one for this amount of time! + vector newcolor = randomvec() * 2; + newcolor.x = bound(0.4, newcolor.x, 1); + newcolor.y = bound(0.4, newcolor.y, 1); + newcolor.z = bound(0.4, newcolor.z, 1); + specialcommand_colors[j] = newcolor; + } + } + else + { + vector splash_size = '0 0 0'; + splash_size.x = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE; + splash_size.y = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE; + drawpic(vec2(slot), "gfx/smile", vec2(splash_size), specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL); + //drawrotpic(vec2(slot), slot.z, "gfx/smile", vec2(splash_size), vec2(splash_size) / 2, specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL); + } + + specialcommand_slots[j] = slot; + } +} + void HUD_Draw(entity this) { // if we don't know gametype and scores yet avoid drawing the scoreboard @@ -1350,31 +1422,40 @@ void HUD_Draw(entity this) if(!gametype) return; + Hud_Dynamic_Frame(); + if(!intermission) if (MUTATOR_CALLHOOK(HUD_Draw_overlay)) { - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, M_ARGV(0, vector), autocvar_hud_colorflash_alpha * M_ARGV(1, float), DRAWFLAG_ADDITIVE); + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), M_ARGV(0, vector), autocvar_hud_colorflash_alpha * M_ARGV(1, float), DRAWFLAG_ADDITIVE); } else if(STAT(FROZEN)) { - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + vector col = '0.25 0.90 1'; + if(STAT(REVIVE_PROGRESS)) + col += vec3(STAT(REVIVE_PROGRESS), -STAT(REVIVE_PROGRESS), -STAT(REVIVE_PROGRESS)); + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); } + + HUD_Scale_Enable(); if(!intermission) if(STAT(NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death { - DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * STAT(NADE_TIMER)) - ('0 1 1' * STAT(NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); - drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL); + vector col = '0.25 0.90 1' + vec3(STAT(NADE_TIMER), -STAT(NADE_TIMER), -STAT(NADE_TIMER)); + DrawCircleClippedPic(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(NADE_TIMER), col, autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), vec2(vid_conwidth, 0.025 * vid_conheight), '1 1 1', 1, DRAWFLAG_NORMAL); } else if(STAT(CAPTURE_PROGRESS)) { - DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(CAPTURE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); - drawstring_aspect(eY * 0.64 * vid_conheight, _("Capture progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL); + DrawCircleClippedPic(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(CAPTURE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + drawstring_aspect(eY * 0.64 * vid_conheight, _("Capture progress"), vec2(vid_conwidth, 0.025 * vid_conheight), '1 1 1', 1, DRAWFLAG_NORMAL); } else if(STAT(REVIVE_PROGRESS)) { - DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); - drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL); + DrawCircleClippedPic(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); + drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), vec2(vid_conwidth, 0.025 * vid_conheight), '1 1 1', 1, DRAWFLAG_NORMAL); } + HUD_Scale_Disable(); if(autocvar_r_letterbox == 0) if(autocvar_viewsize < 120) @@ -1387,6 +1468,7 @@ void HUD_Draw(entity this) } // crosshair goes VERY LAST + SpecialCommand(); UpdateDamage(); HUD_Crosshair(this); HitSound(); @@ -1739,7 +1821,7 @@ void CSQC_UpdateView(entity this, float w, float h) t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0); r = t * blurtest_radius; - f = 1 / pow(t, blurtest_power) - 1; + f = 1 / (t ** blurtest_power) - 1; cvar_set("r_glsl_postprocess", "1"); cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0")); @@ -1766,8 +1848,8 @@ void CSQC_UpdateView(entity this, float w, float h) if(!postinit) PostInit(); - if(intermission && !gameover_time) - gameover_time = time; + if(intermission && !intermission_time) + intermission_time = time; if(intermission && !isdemo() && !(calledhooks & HOOK_END)) { @@ -1957,7 +2039,7 @@ void CSQC_UpdateView(entity this, float w, float h) if(autocvar_cl_reticle) { - string reticle_image = ""; + string reticle_image = string_null; bool wep_zoomed = false; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { @@ -1966,7 +2048,7 @@ void CSQC_UpdateView(entity this, float w, float h) if(wep != WEP_Null && wep.wr_zoom) { bool do_zoom = wep.wr_zoom(wep, NULL); - if(wep.w_reticle && wep.w_reticle != "") + if(!reticle_image && wep.w_reticle && wep.w_reticle != "") reticle_image = wep.w_reticle; wep_zoomed += do_zoom; } @@ -1982,7 +2064,7 @@ void CSQC_UpdateView(entity this, float w, float h) } else if(wep_zoomed && autocvar_cl_reticle_weapon) { - if(reticle_image && reticle_image != "") { reticle_type = 2; } + if(reticle_image) { reticle_type = 2; } else { reticle_type = 0; } } else if(button_zoom || zoomscript_caught) @@ -2018,7 +2100,7 @@ void CSQC_UpdateView(entity this, float w, float h) switch(reticle_type) { case 1: drawpic(reticle_pos, "gfx/reticle_normal", reticle_size, '1 1 1', f * autocvar_cl_reticle_normal_alpha, DRAWFLAG_NORMAL); break; - case 2: drawpic(reticle_pos, reticle_image, reticle_size, '1 1 1', f * autocvar_cl_reticle_weapon_alpha, DRAWFLAG_NORMAL); break; + case 2: if(reticle_image) drawpic(reticle_pos, reticle_image, reticle_size, '1 1 1', f * autocvar_cl_reticle_weapon_alpha, DRAWFLAG_NORMAL); break; } } } @@ -2030,7 +2112,7 @@ void CSQC_UpdateView(entity this, float w, float h) // improved polyblend - if(autocvar_hud_contents) + if(autocvar_hud_contents && !MUTATOR_CALLHOOK(HUD_Contents)) { float contentalpha_temp, incontent, liquidalpha, contentfadetime; vector liquidcolor; @@ -2075,7 +2157,7 @@ void CSQC_UpdateView(entity this, float w, float h) contentavgalpha = contentavgalpha * (1 - contentalpha_temp) + incontent * contentalpha_temp; if(contentavgalpha) - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL); + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL); if(autocvar_hud_postprocessing) { @@ -2151,13 +2233,13 @@ void CSQC_UpdateView(entity this, float w, float h) if(autocvar_cl_gentle_damage == 2) { if(myhealth_flash < pain_threshold) // only randomize when the flash is gone - myhealth_gentlergb = eX * random() + eY * random() + eZ * random(); + myhealth_gentlergb = randomvec(); } else myhealth_gentlergb = stov(autocvar_hud_damage_gentle_color); if(myhealth_flash_temp > 0) - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL); + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), myhealth_gentlergb, autocvar_hud_damage_gentle_alpha_multiplier * bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL); } else if(myhealth_flash_temp > 0) drawpic(splash_pos, "gfx/blood", splash_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL); @@ -2241,7 +2323,9 @@ void CSQC_UpdateView(entity this, float w, float h) // draw 2D entities IL_EACH(g_drawables_2d, it.draw2d, it.draw2d(it)); Draw_ShowNames_All(); +#if ENABLE_DEBUGDRAW Debug_Draw(); +#endif scoreboard_active = Scoreboard_WouldDraw();