X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fclient%2Fview.qc;h=1a01662d1b910661da2b7654b7e695309ca28988;hb=HEAD;hp=0399ef87b1d9d7cf9531168c4ac9bf632c5c061d;hpb=ccf1757e6a71d864249ebe4f3cd13331529bcb41;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 0399ef87b..5c67a2115 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -269,7 +270,6 @@ void viewmodel_animate(entity this) this.origin += bobmodel_ofs(view); } -.vector viewmodel_origin, viewmodel_angles; .float weapon_nextthink; .float weapon_eta_last; .float weapon_switchdelay; @@ -278,8 +278,6 @@ void viewmodel_animate(entity this) void viewmodel_draw(entity this) { - if(!this.activeweapon || !autocvar_r_drawviewmodel) - return; int mask = (intermission || (STAT(HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL; float a = ((autocvar_cl_viewmodel_alpha) ? bound(-1, autocvar_cl_viewmodel_alpha, this.m_alpha) : this.m_alpha); int wepskin = this.m_skin; @@ -287,7 +285,7 @@ void viewmodel_draw(entity this) if (invehicle) a = -1; Weapon wep = this.activeweapon; int c = entcs_GetClientColors(current_player); - vector g = weaponentity_glowmod(wep, NULL, c, this); + vector g = weaponentity_glowmod(wep, c, this); entity me = CSQCModel_server2csqc(player_localentnum - 1); int fx = ((me.csqcmodel_effects & EFMASK_CHEAP) | EF_NODEPTHTEST) @@ -313,8 +311,7 @@ void viewmodel_draw(entity this) { this.name_last = name; CL_WeaponEntity_SetModel(this, name, swap); - this.viewmodel_origin = this.origin; - this.viewmodel_angles = this.angles; + this.origin += autocvar_cl_gunoffset; } anim_update(this); if ((!this.animstate_override && !this.animstate_looping) || time > this.animstate_endtime) @@ -343,8 +340,6 @@ void viewmodel_draw(entity this) } } this.weapon_eta_last = f; - this.origin = this.viewmodel_origin; - this.angles = this.viewmodel_angles; this.angles_x = (-90 * f * f); viewmodel_animate(this); MUTATOR_CALLHOOK(DrawViewModel, this); @@ -359,11 +354,6 @@ STATIC_INIT(viewmodel) { vector project_3d_to_2d(vector vec) { vec = cs_project(vec); - if(cs_project_is_b0rked > 0) - { - vec.x *= vid_conwidth / vid_width; - vec.y *= vid_conheight / vid_height; - } return vec; } @@ -492,7 +482,7 @@ vector GetCurrentFov(float fov) } } - if(almost_equals(current_viewzoom, 1)) + if(zoomfactor == 1 || current_viewzoom > 0.999) // zoomfactor check prevents a division by 0 current_zoomfraction = 0; else if(almost_equals(current_viewzoom, 1/zoomfactor)) current_zoomfraction = 1; @@ -534,20 +524,20 @@ vector GetCurrentFov(float fov) velocityzoom = 1; float frustumx, frustumy, fovx, fovy; - frustumy = tan(fov * M_PI / 360.0) * 0.75 * current_viewzoom * velocityzoom; + frustumy = tan(fov * (M_PI / 360)) * 0.75 * current_viewzoom * velocityzoom; frustumx = frustumy * vid_width / vid_height / vid_pixelheight; - fovx = atan2(frustumx, 1) / M_PI * 360.0; - fovy = atan2(frustumy, 1) / M_PI * 360.0; + fovx = atan2(frustumx, 1) * (360 / M_PI); + fovy = atan2(frustumy, 1) * (360 / M_PI); return '1 0 0' * fovx + '0 1 0' * fovy; } vector GetViewLocationFOV(float fov) { - float frustumy = tan(fov * M_PI / 360.0) * 0.75; + float frustumy = tan(fov * (M_PI / 360)) * 0.75; float frustumx = frustumy * vid_width / vid_height / vid_pixelheight; - float fovx = atan2(frustumx, 1) / M_PI * 360.0; - float fovy = atan2(frustumy, 1) / M_PI * 360.0; + float fovx = atan2(frustumx, 1) * (360 / M_PI); + float fovy = atan2(frustumy, 1) * (360 / M_PI); return '1 0 0' * fovx + '0 1 0' * fovy; } @@ -624,8 +614,24 @@ int WantEventchase(entity this, bool want_vehiclechase) return 0; } +bool waiting_CAMERA_SPECTATOR_update; void View_EventChase(entity this) { + if(spectatee_status > 0 && autocvar_chase_active > 0) + { + // if chase_active is enabled by the user, spectator camera never switches to 1st person + // that means CAMERA_SPECTATOR 1 behaves as 0 and is redundant, so we forcedly skip it + if (STAT(CAMERA_SPECTATOR) == 1) + { + if (!waiting_CAMERA_SPECTATOR_update) + { + Impulse_Send(IMP_weapon_drop); // switch to CAMERA_SPECTATOR 2 + waiting_CAMERA_SPECTATOR_update = true; + } + } + else waiting_CAMERA_SPECTATOR_update = false; + } + // event chase camera if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped { @@ -868,41 +874,49 @@ void HUD_Draw(entity this) Hud_Dynamic_Frame(); if(!intermission) - if (MUTATOR_CALLHOOK(HUD_Draw_overlay)) { - 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)) - { - vector col = '0.25 0.90 1'; - float col_fade = max(0, STAT(REVIVE_PROGRESS) * 2 - 1); - float alpha_fade = 0.3 + 0.7 * (1 - max(0, STAT(REVIVE_PROGRESS) * 4 - 3)); - if(col_fade) - col += vec3(col_fade, -col_fade, -col_fade); - drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha * alpha_fade, DRAWFLAG_ADDITIVE); + if (MUTATOR_CALLHOOK(HUD_Draw_overlay)) + { + vector col = M_ARGV(0, vector); + float alpha_multipl = M_ARGV(1, float); + if (alpha_multipl > 0) + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha * alpha_multipl, DRAWFLAG_ADDITIVE); + } + else if(STAT(FROZEN)) + { + vector col = '0.25 0.90 1'; + float col_fade = max(0, STAT(REVIVE_PROGRESS) * 2 - 1); + float alpha_fade = 0.3 + 0.7 * (1 - max(0, STAT(REVIVE_PROGRESS) * 4 - 3)); + if(col_fade) + col += vec3(col_fade, -col_fade, -col_fade); + drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), col, autocvar_hud_colorflash_alpha * alpha_fade, 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 - { - 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", 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(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring", 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(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring", 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); + if(STAT(NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death + { + 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", 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(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring", 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(vec2(0.5 * vid_conwidth, 0.6 * vid_conheight), 0.1 * vid_conheight, "gfx/crosshair_ring", 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) { if(!MUTATOR_CALLHOOK(DrawScoreboardAccuracy)) @@ -911,11 +925,13 @@ void HUD_Draw(entity this) HUD_Main(); HUD_Scale_Disable(); } + } // crosshair goes VERY LAST UpdateDamage(); HUD_Crosshair(this); HitSound(); + Local_Notification_Queue_Process(); } void ViewLocation_Mouse() @@ -1204,6 +1220,7 @@ void View_PostProcessing() { float e1 = (autocvar_hud_postprocessing_maxbluralpha != 0); float e2 = (autocvar_hud_powerup != 0); + bool want_postprocessing = false; if(autocvar_hud_postprocessing && (e1 || e2)) // TODO: Remove this code and re-do the postprocess handling in the engine, where it properly belongs. { // enable or disable rendering types if they are used or not @@ -1221,6 +1238,7 @@ void View_PostProcessing() old_blurradius = blurradius; old_bluralpha = bluralpha; } + want_postprocessing = true; } else if(cvar_string("r_glsl_postprocess_uservec1") != "0 0 0 0") // reduce cvar_set spam as much as possible { @@ -1247,18 +1265,24 @@ void View_PostProcessing() cvar_set("r_glsl_postprocess_uservec2", strcat(ftos((sharpen_intensity / 5) * autocvar_hud_powerup), " ", ftos(-sharpen_intensity * autocvar_hud_powerup), " 0 0")); old_sharpen_intensity = sharpen_intensity; } + want_postprocessing = true; } else if(cvar_string("r_glsl_postprocess_uservec2") != "0 0 0 0") // reduce cvar_set spam as much as possible { cvar_set("r_glsl_postprocess_uservec2", "0 0 0 0"); old_sharpen_intensity = 0; } - + } + if (want_postprocessing) + { if(cvar("r_glsl_postprocess") == 0) cvar_set("r_glsl_postprocess", "2"); } - else if(cvar("r_glsl_postprocess") == 2) - cvar_set("r_glsl_postprocess", "0"); + else + { + if(cvar("r_glsl_postprocess") == 2) + cvar_set("r_glsl_postprocess", "0"); + } } void View_Lock() @@ -1529,7 +1553,7 @@ void View_UpdateFov() setproperty(VF_FOV, fov); } -void CSQC_UpdateView(entity this, float w, float h) +void CSQC_UpdateView(entity this, float w, float h, bool notmenu) { TC(int, w); TC(int, h); @@ -1591,7 +1615,6 @@ void CSQC_UpdateView(entity this, float w, float h) current_player = player_localnum; myteam = entcs_GetTeam(current_player); - // abused multiple places below entity local_player = ((csqcplayer) ? csqcplayer : CSQCModel_server2csqc(player_localentnum - 1)); if(!local_player) local_player = this; // fall back! @@ -1608,8 +1631,10 @@ void CSQC_UpdateView(entity this, float w, float h) // run viewmodel_draw before updating view_angles to the angles calculated by WarpZone_FixView // viewmodel_draw needs to use the view_angles set by the engine on every CSQC_UpdateView call - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) - viewmodel_draw(viewmodels[slot]); + if(autocvar_r_drawviewmodel) + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + if(viewmodels[slot].activeweapon) + viewmodel_draw(viewmodels[slot]); // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); @@ -1648,11 +1673,18 @@ void CSQC_UpdateView(entity this, float w, float h) { if(calledhooks & HOOK_START) { + int gamecount = cvar("cl_matchcount"); localcmd("\ncl_hook_gameend\n"); + // NOTE: using localcmd here to ensure it's executed AFTER cl_hook_gameend + // earlier versions of the game abuse the hook to set this cvar + localcmd(strcat("cl_matchcount ", itos(gamecount + 1), "\n")); + //cvar_set("cl_matchcount", itos(gamecount + 1)); calledhooks |= HOOK_END; } } + Welcome_Message_Show_Try(); + Announcer(); View_CheckButtonStatus(); @@ -1673,7 +1705,6 @@ void CSQC_UpdateView(entity this, float w, float h) // Draw the World (and sky) setproperty(VF_DRAWWORLD, 1); - // Set the console size vars vid_conwidth = autocvar_vid_conwidth; vid_conheight = autocvar_vid_conheight; vid_pixelheight = autocvar_vid_pixelheight; @@ -1682,18 +1713,8 @@ void CSQC_UpdateView(entity this, float w, float h) View_DemoCamera(); - // Draw the Crosshair - setproperty(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden - - // Draw the Engine Status Bar (the default Quake HUD) - setproperty(VF_DRAWENGINESBAR, 0); - - // Update the mouse position - /* - mousepos_x = vid_conwidth; - mousepos_y = vid_conheight; - mousepos = mousepos*0.5 + getmousepos(); - */ + setproperty(VF_DRAWCROSSHAIR, 0); // hide engine crosshair + setproperty(VF_DRAWENGINESBAR, 0); // hide engine status bar IL_EACH(g_drawables, it.draw, it.draw(it)); @@ -1710,11 +1731,17 @@ void CSQC_UpdateView(entity this, float w, float h) // draw 2D entities IL_EACH(g_drawables_2d, it.draw2d, it.draw2d(it)); + IL_EACH(g_damagetext, it.draw2d, it.draw2d(it)); Draw_ShowNames_All(); #if ENABLE_DEBUGDRAW Debug_Draw(); #endif + if (autocvar__scoreboard_team_selection) + { + Scoreboard_UI_Enable(1); + cvar_set("_scoreboard_team_selection", "0"); + } scoreboard_active = Scoreboard_WouldDraw(); HUD_Draw(this); // this parameter for deep vehicle function @@ -1725,34 +1752,6 @@ void CSQC_UpdateView(entity this, float w, float h) NextFrameCommand = string_null; } - // we must do this check AFTER a frame was rendered, or it won't work - if(cs_project_is_b0rked == 0) - { - string w0, h0; - w0 = ftos(autocvar_vid_conwidth); - h0 = ftos(autocvar_vid_conheight); - //setproperty(VF_VIEWPORT, '0 0 0', '640 480 0'); - //setproperty(VF_FOV, '90 90 0'); - setproperty(VF_ORIGIN, '0 0 0'); - setproperty(VF_ANGLES, '0 0 0'); - setproperty(VF_PERSPECTIVE, 1); - vector forward, right, up; - MAKE_VECTORS('0 0 0', forward, right, up); - vector v1, v2; - cvar_set("vid_conwidth", "800"); - cvar_set("vid_conheight", "600"); - v1 = cs_project(forward); - cvar_set("vid_conwidth", "640"); - cvar_set("vid_conheight", "480"); - v2 = cs_project(forward); - if(v1 == v2) - cs_project_is_b0rked = 1; - else - cs_project_is_b0rked = -1; - cvar_set("vid_conwidth", w0); - cvar_set("vid_conheight", h0); - } - HUD_Mouse(local_player); cl_notice_run(); @@ -1772,7 +1771,7 @@ vector camera_offset, current_camera_offset, mouse_angles, current_angles, curre void CSQC_Demo_Camera() { float speed, attenuation, dimensions; - vector tmp, delta; + vector tmp; if( autocvar_camera_reset || !camera_mode ) { @@ -1813,30 +1812,22 @@ void CSQC_Demo_Camera() } } - while (mouse_angles.x < -180) mouse_angles.x = mouse_angles.x + 360; - while (mouse_angles.x > 180) mouse_angles.x = mouse_angles.x - 360; - while (mouse_angles.y < -180) mouse_angles.y = mouse_angles.y + 360; - while (mouse_angles.y > 180) mouse_angles.y = mouse_angles.y - 360; - - // Fix difference when angles don't have the same sign - delta = '0 0 0'; - if(mouse_angles.y < -60 && current_angles.y > 60) - delta = '0 360 0'; - if(mouse_angles.y > 60 && current_angles.y < -60) - delta = '0 -360 0'; - if(autocvar_camera_look_player) attenuation = autocvar_camera_look_attenuation; else attenuation = autocvar_camera_speed_attenuation; attenuation = 1 / max(1, attenuation); - current_angles += (mouse_angles - current_angles + delta) * attenuation; + current_angles += (mouse_angles - current_angles) * attenuation; + + // limit current pitch angle to sane values + if (current_angles.x < -90) current_angles.x = -90; + if (current_angles.x > 90 ) current_angles.x = 90; - while (current_angles.x < -180) current_angles.x = current_angles.x + 360; - while (current_angles.x > 180) current_angles.x = current_angles.x - 360; - while (current_angles.y < -180) current_angles.y = current_angles.y + 360; - while (current_angles.y > 180) current_angles.y = current_angles.y - 360; + // limit mouse and current yaw angles to standard values simultaneously so that the difference + // between these angles is not altered + while (current_angles.y < -180 && mouse_angles.y < -180) {current_angles.y += 360; mouse_angles.y += 360;} + while (current_angles.y > 180 && mouse_angles.y > 180 ) {current_angles.y -= 360; mouse_angles.y -= 360;} // Camera position tmp = '0 0 0';