]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/View.qc
A slightly better way of sticking the camera above the ground. Still bad though,...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / View.qc
index 40c3b957a12eb65bd33d9616c5c2f489b3cccf0e..c0bf17c6101dd5866b07e9e454614fb7529ad485 100644 (file)
@@ -366,6 +366,9 @@ vector myhealth_gentlergb;
 float contentavgalpha, liquidalpha_prev;
 vector liquidcolor_prev;
 
+float chase_current_distance;
+vector chase_old_origin;
+
 void CSQC_UpdateView(float w, float h)
 {
        entity e;
@@ -381,6 +384,7 @@ void CSQC_UpdateView(float w, float h)
        vid_height = vf_size_y;
 
        vector reticle_pos, reticle_size;
+       vector splash_pos, splash_size;
 
        WaypointSprite_Load();
 
@@ -400,6 +404,45 @@ void CSQC_UpdateView(float w, float h)
        input_angles = warpzone_fixview_cl_viewangles;
        view_angles = warpzone_fixview_angles;
 
+       // event chase cam
+       if(spectatee_status >= 0 && (autocvar_cl_chase_death || autocvar_cl_chase_intermission))
+       if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually
+       {
+               if((autocvar_cl_chase_death && getstati(STAT_HEALTH) <= 0 && !intermission) || (autocvar_cl_chase_intermission && intermission) && intermission <= 1) // not during the map voting screen
+               {
+                       // We must set chase_active in order to get a third person view (1st person weapon model hidden and own player model showing).
+                       // Ideally, there should be another way to enable third person mode, such as an R_SetView() function specifically for this purpose.
+
+                       if(!autocvar_chase_active)
+                               cvar_set("chase_active", "-1"); // -1 enables chase_active as well as marking it as set by this code, and not by the user (which would be 1)
+
+                       // make the camera smooth back
+                       if(autocvar_cl_chase_speed && chase_current_distance < autocvar_cl_chase_distance)
+                               chase_current_distance += autocvar_cl_chase_speed * (autocvar_cl_chase_distance - chase_current_distance) * frametime; // slow down smoothly
+                       else if(chase_current_distance != autocvar_cl_chase_distance)
+                               chase_current_distance = autocvar_cl_chase_distance;
+
+                       vector chase_target_origin;
+                       makevectors(view_angles);
+                       chase_target_origin = pmove_org - view_forward * chase_current_distance;
+
+                       // don't allow the camera to go through walls
+                       traceline(pmove_org, chase_target_origin, MOVE_NORMAL, self);
+                       if(trace_fraction == 1)
+                       {
+                               R_SetView(VF_ORIGIN, chase_target_origin);
+                               chase_old_origin = chase_target_origin;
+                       }
+                       else
+                               R_SetView(VF_ORIGIN, chase_old_origin);
+               }
+               else if(autocvar_chase_active < 0)
+               {
+                       cvar_set("chase_active", "0");
+                       chase_current_distance = 0; // start from 0
+               }
+       }
+
        if(autocvar_cl_lockview || (autocvar__hud_configure && spectatee_status <= 0))
        {
                pmove_org = freeze_pmove_org;
@@ -412,7 +455,7 @@ void CSQC_UpdateView(float w, float h)
        freeze_input_angles = input_angles;
 
        // Render the Scene
-       if(!intermission || !view_set)
+       if(!intermission || !view_set || (intermission && autocvar_cl_chase_intermission))
        {
                view_origin = pmove_org + vo;
                view_angles = input_angles;
@@ -644,35 +687,36 @@ void CSQC_UpdateView(float w, float h)
        else if(activeweapon == WEP_NEX && button_attack2 || activeweapon == WEP_SNIPERRIFLE && button_attack2)
                reticle_type = 2; // nex zoom
 
-       if(autocvar_cl_reticle_stretch)
+       if (reticle_type)
        {
-               reticle_size_x = vid_conwidth;
-               reticle_size_y = vid_conheight;
-               reticle_pos_x = 0;
-               reticle_pos_y = 0;
-       }
-       else
-       {
-               reticle_size_x = max(vid_conwidth, vid_conheight);
-               reticle_size_y = max(vid_conwidth, vid_conheight);
-               reticle_pos_x = (vid_conwidth - reticle_size_x) / 2;
-               reticle_pos_y = (vid_conheight - reticle_size_y) / 2;
-       }
+               if(autocvar_cl_reticle_stretch)
+               {
+                       reticle_size_x = vid_conwidth;
+                       reticle_size_y = vid_conheight;
+                       reticle_pos_x = 0;
+                       reticle_pos_y = 0;
+               }
+               else
+               {
+                       reticle_size_x = max(vid_conwidth, vid_conheight);
+                       reticle_size_y = max(vid_conwidth, vid_conheight);
+                       reticle_pos_x = (vid_conwidth - reticle_size_x) / 2;
+                       reticle_pos_y = (vid_conheight - reticle_size_y) / 2;
+               }
 
-       f = current_zoomfraction;
-       if(zoomscript_caught)
-               f = 1;
-       if(autocvar_cl_reticle_item_normal)
-       {
-               precache_pic("gfx/reticle_normal");
-               if(reticle_type == 1 && f)
-                       drawpic(reticle_pos, "gfx/reticle_normal", reticle_size, '1 1 1', f * autocvar_cl_reticle_item_normal, DRAWFLAG_NORMAL);
-       }
-       if(autocvar_cl_reticle_item_nex)
-       {
-               precache_pic("gfx/reticle_nex");
-               if(reticle_type == 2 && f)
-                       drawpic(reticle_pos, "gfx/reticle_nex", reticle_size, '1 1 1', f * autocvar_cl_reticle_item_nex, DRAWFLAG_NORMAL);
+               f = current_zoomfraction;
+               if(zoomscript_caught)
+                       f = 1;
+               if(autocvar_cl_reticle_item_normal)
+               {
+                       if(reticle_type == 1 && f)
+                               drawpic(reticle_pos, "gfx/reticle_normal", reticle_size, '1 1 1', f * autocvar_cl_reticle_item_normal, DRAWFLAG_NORMAL);
+               }
+               if(autocvar_cl_reticle_item_nex)
+               {
+                       if(reticle_type == 2 && f)
+                               drawpic(reticle_pos, "gfx/reticle_nex", reticle_size, '1 1 1', f * autocvar_cl_reticle_item_nex, DRAWFLAG_NORMAL);
+               }
        }
 
 
@@ -728,6 +772,11 @@ void CSQC_UpdateView(float w, float h)
        
        if(autocvar_hud_damage)
        {
+               splash_size_x = max(vid_conwidth, vid_conheight);
+               splash_size_y = max(vid_conwidth, vid_conheight);
+               splash_pos_x = (vid_conwidth - splash_size_x) / 2;
+               splash_pos_y = (vid_conheight - splash_size_y) / 2;
+
                float myhealth_flash_temp;
                myhealth = getstati(STAT_HEALTH);
 
@@ -784,7 +833,7 @@ void CSQC_UpdateView(float w, float h)
                        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);
                }
                else
-                       drawpic(reticle_pos, "gfx/blood", reticle_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
+                       drawpic(splash_pos, "gfx/blood", splash_size, stov(autocvar_hud_damage_color), bound(0, myhealth_flash_temp, 1) * autocvar_hud_damage, DRAWFLAG_NORMAL);
        }
 
        // Draw the mouse cursor
@@ -867,8 +916,6 @@ void CSQC_UpdateView(float w, float h)
                        // TrueAim check
                        float shottype;
 
-                       float weapon_clipload, weapon_clipsize, ring_scale;
-
                        // 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_z = 0;
@@ -1068,31 +1115,30 @@ void CSQC_UpdateView(float w, float h)
                        wcross_alpha *= 1 - autocvar__menu_alpha;
                        wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
 
-                       if (autocvar_crosshair_ring)
+                       // crosshair rings for weapon stats
+                       if (autocvar_crosshair_ring || autocvar_crosshair_ring_reload)
                        {
-                               float ring_value, ring_alpha, ring_inner_value, ring_inner_alpha;
+                               // declarations and stats
+                               float ring_value, ring_scale, ring_alpha, ring_inner_value, ring_inner_alpha;
                                string ring_image, ring_inner_image;
                                vector ring_rgb, ring_inner_rgb;
                                
-                               float ring_scale = autocvar_crosshair_ring_size;
-                               
+                               ring_scale = autocvar_crosshair_ring_size;
+
+                               float weapon_clipload, weapon_clipsize;
+                               weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD);
+                               weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE);
+
                                float nex_charge, nex_chargepool;
                                nex_charge = getstatf(STAT_NEX_CHARGE);
                                nex_chargepool = getstatf(STAT_NEX_CHARGEPOOL);
-                               
+
                                if(nex_charge_movingavg == 0) // this should only happen if we have just loaded up the game
                                        nex_charge_movingavg = nex_charge;
+                                       
 
-                               weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD);
-                               if (weapon_clipload) // ring around crosshair representing ammo left in weapon clip
-                               {
-                                       weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE);
-                                       ring_value = bound(0, weapon_clipload / weapon_clipsize, 1);
-                                       ring_alpha = autocvar_crosshair_ring_sniperrifle_alpha;
-                                       ring_image = "gfx/crosshair_ring.tga";
-                                       ring_rgb = wcross_color;
-                               }
-                               else if (activeweapon == WEP_NEX && nex_charge && autocvar_crosshair_ring_nex) // ring around crosshair representing velocity-dependent damage for the nex
+                               // handle the values
+                               if (activeweapon == WEP_NEX && nex_charge && autocvar_crosshair_ring_nex) // ring around crosshair representing velocity-dependent damage for the nex
                                {
                                        if (nex_chargepool || use_nex_chargepool) { 
                                                use_nex_chargepool = 1; 
@@ -1102,29 +1148,44 @@ void CSQC_UpdateView(float w, float h)
                                                ring_inner_value = bound(0, autocvar_crosshair_ring_nex_currentcharge_scale * (nex_charge - nex_charge_movingavg), 1); 
                                        }
                                                
-                                       ring_inner_alpha = wcross_alpha * autocvar_crosshair_ring_nex_inner_alpha;
-                                       ring_inner_image = "gfx/crosshair_ring_inner.tga";
+                                       ring_inner_alpha = autocvar_crosshair_ring_nex_inner_alpha;
                                        ring_inner_rgb = eX * autocvar_crosshair_ring_nex_inner_color_red + eY * autocvar_crosshair_ring_nex_inner_color_green + eZ * autocvar_crosshair_ring_nex_inner_color_blue;
-
+                                       ring_inner_image = "gfx/crosshair_ring_inner.tga";
+                                       
                                        // draw the outer ring to show the current charge of the weapon
                                        ring_value = nex_charge;
-                                       ring_alpha = wcross_alpha * autocvar_crosshair_ring_nex_alpha;
-                                       ring_image = "gfx/crosshair_ring_nexgun.tga";
+                                       ring_alpha = autocvar_crosshair_ring_nex_alpha;
                                        ring_rgb = wcross_color;
+                                       ring_image = "gfx/crosshair_ring_nexgun.tga";
                                }
                                else if (activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer) 
                                {
                                        ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
-                                       ring_alpha = wcross_alpha * autocvar_crosshair_ring_minelayer_alpha;
+                                       ring_alpha = autocvar_crosshair_ring_minelayer_alpha;
+                                       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 
+                               {
+                                       ring_value = bound(0, weapon_clipload / weapon_clipsize, 1);
+                                       ring_scale = autocvar_crosshair_ring_reload_size;
+                                       ring_alpha = autocvar_crosshair_ring_reload_alpha;
                                        ring_rgb = wcross_color;
+                                       
+                                       // Note: This is to stop Taoki from complaining that the image doesn't match all potential balances.
+                                       // if a new image for another weapon is added, add the code (and its respective file/value) here
+                                       if ((activeweapon == WEP_SNIPERRIFLE) && (weapon_clipsize == 80))
+                                               ring_image = "gfx/crosshair_ring_sniperrifle.tga";
+                                       else
+                                               ring_image = "gfx/crosshair_ring.tga";
                                }
-                               
+
                                if (autocvar_crosshair_ring_inner && ring_inner_value) // lets draw a ring inside a ring so you can ring while you ring
-                                       DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, ring_inner_alpha, DRAWFLAG_ADDITIVE);
-                               
+                                       DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_inner_image, ring_inner_value, ring_inner_rgb, wcross_alpha * ring_inner_alpha, DRAWFLAG_ADDITIVE);
+
                                if (ring_value)
-                                       DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_image, ring_value, ring_rgb, ring_alpha, DRAWFLAG_ADDITIVE);
+                                       DrawCircleClippedPic(wcross_origin, wcross_size_x * ring_scale, ring_image, ring_value, ring_rgb, wcross_alpha * ring_alpha, DRAWFLAG_ADDITIVE);
                        }
 
 #define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \