]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/view.qc
Merge branch 'master' into martin-t/globals
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / view.qc
index 27fa344b39cfa437321a303cfe3f732071e4caac..13c766f471640512e478205e4f123b7d8714e4a0 100644 (file)
@@ -48,6 +48,7 @@
 #define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOSHADOW | EF_SELECTABLE | EF_TELEPORT_BIT)
 
 float autocvar_cl_viewmodel_scale;
+float autocvar_cl_viewmodel_alpha;
 
 bool autocvar_cl_bobmodel;
 float autocvar_cl_bobmodel_speed;
@@ -75,54 +76,46 @@ float autocvar_cl_leanmodel_lowpass = 0.05;
        ret = ref_store = ref_store * (1 - frac) + (value) * frac;
 
 #define lowpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \
-{ \
        float __ignore; lowpass(value, frac, ref_store, __ignore); \
        ret = ref_store = bound((value) - (limit), ref_store, (value) + (limit)); \
-MACRO_END
+MACRO_END
 
 #define highpass(value, frac, ref_store, ret) MACRO_BEGIN \
-{ \
        float __f = 0; lowpass(value, frac, ref_store, __f); \
        ret = (value) - __f; \
-MACRO_END
+MACRO_END
 
 #define highpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \
-{ \
        float __f = 0; lowpass_limited(value, frac, limit, ref_store, __f); \
        ret = (value) - __f; \
-MACRO_END
+MACRO_END
 
 #define lowpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \
-{ \
        lowpass(value.x, frac, ref_store.x, ref_out.x); \
        lowpass(value.y, frac, ref_store.y, ref_out.y); \
-MACRO_END
+MACRO_END
 
 #define highpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \
-{ \
        highpass(value.x, frac, ref_store.x, ref_out.x); \
        highpass(value.y, frac, ref_store.y, ref_out.y); \
-MACRO_END
+MACRO_END
 
 #define highpass2_limited(value, frac, limit, ref_store, ref_out) MACRO_BEGIN \
-{ \
        highpass_limited(value.x, frac, limit, ref_store.x, ref_out.x); \
        highpass_limited(value.y, frac, limit, ref_store.y, ref_out.y); \
-MACRO_END
+MACRO_END
 
 #define lowpass3(value, frac, ref_store, ref_out) MACRO_BEGIN \
-{ \
        lowpass(value.x, frac, ref_store.x, ref_out.x); \
        lowpass(value.y, frac, ref_store.y, ref_out.y); \
        lowpass(value.z, frac, ref_store.z, ref_out.z); \
-MACRO_END
+MACRO_END
 
 #define highpass3(value, frac, ref_store, ref_out) MACRO_BEGIN \
-{ \
        highpass(value.x, frac, ref_store.x, ref_out.x); \
        highpass(value.y, frac, ref_store.y, ref_out.y); \
        highpass(value.z, frac, ref_store.z, ref_out.z); \
-MACRO_END
+MACRO_END
 
 void calc_followmodel_ofs(entity view)
 {
@@ -140,8 +133,7 @@ void calc_followmodel_ofs(entity view)
                vel = view.velocity;
        else
        {
-               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               MAKE_VECTORS_NEW(view_angles, forward, right, up);
                vel.x = view.velocity * forward;
                vel.y = view.velocity * right * -1;
                vel.z = view.velocity * up;
@@ -166,8 +158,7 @@ void calc_followmodel_ofs(entity view)
        if (autocvar_cl_followmodel_velocity_absolute)
        {
                vector fixed_gunorg;
-               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               MAKE_VECTORS_NEW(view_angles, forward, right, up);
                fixed_gunorg.x = gunorg * forward;
                fixed_gunorg.y = gunorg * right * -1;
                fixed_gunorg.z = gunorg * up;
@@ -297,12 +288,9 @@ 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 = this.alpha;
-       static bool wasinvehicle;
+       float a = ((autocvar_cl_viewmodel_alpha) ? bound(-1, autocvar_cl_viewmodel_alpha, this.m_alpha) : this.m_alpha);
        bool invehicle = player_localentnum > maxclients;
        if (invehicle) a = -1;
-       else if (wasinvehicle) a = 1;
-       wasinvehicle = invehicle;
        Weapon wep = this.activeweapon;
        int c = entcs_GetClientColors(current_player);
        vector g = weaponentity_glowmod(wep, NULL, c, this);
@@ -427,10 +415,14 @@ void Porto_Draw(entity this)
 
                vector pos = view_origin;
                vector dir = view_forward;
+               MAKE_VECTORS_NEW(autocvar_chase_active ? warpzone_save_view_angles : view_angles, forward, right, up);
+               pos += right * -wepent.movedir.y
+                       +  up * wepent.movedir.z;
+
                if (wepent.angles_held_status)
                {
-                       makevectors(wepent.angles_held);
-                       dir = v_forward;
+                       MAKE_VECTORS(wepent.angles_held, forward, right, up);
+                       dir = forward;
                }
 
                wepent.polyline[0] = pos;
@@ -457,8 +449,8 @@ void Porto_Draw(entity this)
                        {
                                vector ang = vectoangles2(trace_plane_normal, dir);
                                ang.x = -ang.x;
-                               makevectors(ang);
-                               if (!CheckWireframeBox(this, pos - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
+                               MAKE_VECTORS(ang, forward, right, up);
+                               if (!CheckWireframeBox(this, pos - 48 * right - 48 * up + 16 * forward, 96 * right, 96 * up, 96 * forward))
                                {
                                        n = max(2, idx);
                                        break;
@@ -577,15 +569,15 @@ vector GetCurrentFov(float fov)
                        curspeed = 0;
                else
                {
-                       makevectors(view_angles);
+                       MAKE_VECTORS_NEW(view_angles, forward, right, up);
                        v = pmove_vel;
                        if(csqcplayer)
                                v = csqcplayer.velocity;
 
                        switch(autocvar_cl_velocityzoom_type)
                        {
-                               case 3: curspeed = max(0, v_forward * v); break;
-                               case 2: curspeed = (v_forward * v); break;
+                               case 3: curspeed = max(0, forward * v); break;
+                               case 2: curspeed = (forward * v); break;
                                case 1: default: curspeed = vlen(v); break;
                        }
                }
@@ -631,6 +623,8 @@ vector GetOrthoviewFOV(vector ov_worldmin, vector ov_worldmax, vector ov_mid, ve
 // this function must match W_SetupShot!
 float zoomscript_caught;
 
+bool minigame_wasactive;
+
 vector wcross_origin;
 float wcross_scale_prev, wcross_alpha_prev;
 vector wcross_color_prev;
@@ -799,34 +793,41 @@ vector liquidcolor_prev;
 
 float eventchase_current_distance;
 float eventchase_running;
-bool WantEventchase(entity this)
+int WantEventchase(entity this)
 {
        if(autocvar_cl_orthoview)
-               return false;
+               return 0;
        if(STAT(GAME_STOPPED) || intermission)
-               return true;
+               return 1;
        if(this.viewloc)
-               return true;
+               return 1;
        if(spectatee_status >= 0)
        {
                if(hud != HUD_NORMAL && (autocvar_cl_eventchase_vehicle || spectatee_status > 0))
-                       return true;
+                       return 1;
                if(MUTATOR_CALLHOOK(WantEventchase, this))
-                       return true;
+                       return 1;
                if(autocvar_cl_eventchase_frozen && STAT(FROZEN))
-                       return true;
+                       return 1;
                if(autocvar_cl_eventchase_death && (STAT(HEALTH) <= 0))
                {
                        if(autocvar_cl_eventchase_death == 2)
                        {
                                // don't stop eventchase once it's started (even if velocity changes afterwards)
                                if(this.velocity == '0 0 0' || eventchase_running)
-                                       return true;
+                                       return 1;
                        }
-                       else return true;
+                       else return 1;
+               }
+               if (spectatee_status > 0 && autocvar_cl_eventchase_spectated_change)
+               {
+                       if (time <= spectatee_status_changed_time + min(3, autocvar_cl_eventchase_spectated_change_time))
+                               return 1;
+                       else if (eventchase_running)
+                               return -1; // disable chase_active while eventchase is still enabled so to avoid a glicth
                }
        }
-       return false;
+       return 0;
 }
 
 void HUD_Crosshair_Vehicle(entity this)
@@ -1345,21 +1346,22 @@ void HUD_Crosshair(entity this)
                        }
 
 #define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \
-                       MACRO_BEGIN { \
+                       MACRO_BEGIN \
+                               vector scaled_sz = sz * wcross_size; \
                                if(wcross_blur > 0) \
                                { \
                                        for(i = -2; i <= 2; ++i) \
                                        for(j = -2; j <= 2; ++j) \
-                                       M(i,j,sz,wcross_name,wcross_alpha*0.04); \
+                                       M(i,j,sz,scaled_sz,wcross_name,wcross_alpha*0.04); \
                                } \
                                else \
                                { \
-                                       M(0,0,sz,wcross_name,wcross_alpha); \
+                                       M(0,0,sz,scaled_sz,wcross_name,wcross_alpha); \
                                } \
-                       MACRO_END
+                       MACRO_END
 
-#define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \
-                       drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size.x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size.y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
+#define CROSSHAIR_DRAW_SINGLE(i,j,sz,scaled_sz,wcross_name,wcross_alpha) \
+                       drawpic(wcross_origin - ('0.5 0 0' * (scaled_sz.x + i * wcross_blur) + '0 0.5 0' * (scaled_sz.y + j * wcross_blur)), wcross_name, scaled_sz, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
 
 #define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \
                        CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha)
@@ -1528,7 +1530,7 @@ void HUD_Draw(entity this)
        if(autocvar_r_letterbox == 0)
                if(autocvar_viewsize < 120)
                {
-                       if(!(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS))
+                       if(!(ISGAMETYPE(RACE) || ISGAMETYPE(CTS)))
                                Accuracy_LoadLevels();
 
                        HUD_Main();
@@ -1555,17 +1557,16 @@ void ViewLocation_Mouse()
        //draw_cursor(viewloc_mousepos, '0.5 0.5 0', "/cursor_move", '1 1 1', cursor_alpha);
 }
 
-float mouse_over_panel;
-void HUD_Draw_Mouse()
+void HUD_Cursor_Show()
 {
        float cursor_alpha = 1 - autocvar__menu_alpha;
-       if(!mouse_over_panel)
+       if(cursor_type == CURSOR_NORMAL)
                draw_cursor_normal(mousepos, '1 1 1', cursor_alpha);
-       else if(mouse_over_panel == 1)
+       else if(cursor_type == CURSOR_MOVE)
                draw_cursor(mousepos, '0.5 0.5 0', "/cursor_move", '1 1 1', cursor_alpha);
-       else if(mouse_over_panel == 2)
+       else if(cursor_type == CURSOR_RESIZE)
                draw_cursor(mousepos, '0.5 0.5 0', "/cursor_resize", '1 1 1', cursor_alpha);
-       else
+       else if(cursor_type == CURSOR_RESIZE2)
                draw_cursor(mousepos, '0.5 0.5 0', "/cursor_resize2", '1 1 1', cursor_alpha);
 }
 
@@ -1574,13 +1575,22 @@ void HUD_Mouse(entity player)
        if(autocvar__menu_alpha == 1)
                return;
 
-       if(!HUD_WouldShowCursor())
+       if(!cursor_active)
        {
                if(player.viewloc && (player.viewloc.spawnflags & VIEWLOC_FREEAIM))
                        ViewLocation_Mouse(); // NOTE: doesn't use cursormode
                return;
        }
 
+       if (cursor_active == -1) // starting to display the cursor
+       {
+               // since HUD_Mouse is called by CSQC_UpdateView before CSQC_InputEvent,
+               // in the first frame mousepos is the mouse position of the last time
+               // the cursor was displayed, thus we ignore it to avoid a glictch
+               cursor_active = 1;
+               return;
+       }
+
        if(!autocvar_hud_cursormode)
                update_mousepos();
 
@@ -1588,7 +1598,7 @@ void HUD_Mouse(entity player)
                HUD_Panel_Mouse();
        else
        {
-               if (HUD_MinigameMenu_IsOpened() || active_minigame)
+               if (HUD_MinigameMenu_IsOpened())
                        HUD_Minigame_Mouse();
                if (QuickMenu_IsOpened())
                        QuickMenu_Mouse();
@@ -1598,7 +1608,7 @@ void HUD_Mouse(entity player)
 
        prevMouseClicked = mouseClicked;
 
-       HUD_Draw_Mouse();
+       HUD_Cursor_Show();
 }
 
 bool ov_enabled;
@@ -1737,7 +1747,8 @@ void CSQC_UpdateView(entity this, float w, float h)
                        }
                }
 
-               if(WantEventchase(this))
+               int eventchase = WantEventchase(this);
+               if (eventchase)
                {
                        vector current_view_origin_override = '0 0 0';
                        vector view_offset_override = '0 0 0';
@@ -1797,25 +1808,26 @@ void CSQC_UpdateView(entity this, float w, float h)
                        else if(eventchase_current_distance != chase_distance)
                                eventchase_current_distance = chase_distance;
 
-                       makevectors(view_angles);
+                       MAKE_VECTORS_NEW(view_angles, forward, right, up);
 
-                       vector eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance));
+                       vector eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
                        WarpZone_TraceBox(current_view_origin, autocvar_cl_eventchase_mins, autocvar_cl_eventchase_maxs, eventchase_target_origin, MOVE_WORLDONLY, this);
 
                        // If the boxtrace fails, revert back to line tracing.
                        if(!local_player.viewloc)
                        if(trace_startsolid)
                        {
-                               eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance));
+                               eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
                                WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, this);
-                               setproperty(VF_ORIGIN, (trace_endpos - (v_forward * autocvar_cl_eventchase_mins.z)));
+                               setproperty(VF_ORIGIN, (trace_endpos - (forward * autocvar_cl_eventchase_mins.z)));
                        }
                        else { setproperty(VF_ORIGIN, trace_endpos); }
 
                        if(!local_player.viewloc)
                                setproperty(VF_ANGLES, WarpZone_TransformVAngles(WarpZone_trace_transform, view_angles));
                }
-               else if(autocvar_chase_active < 0) // time to disable chase_active if it was set by this code
+
+               if (eventchase <= 0 && autocvar_chase_active < 0) // time to disable chase_active if it was set by this code
                {
                        eventchase_running = false;
                        cvar_set("chase_active", "0");
@@ -1934,10 +1946,7 @@ void CSQC_UpdateView(entity this, float w, float h)
        // Render the Scene
        view_origin = getpropertyvec(VF_ORIGIN);
        view_angles = getpropertyvec(VF_ANGLES);
-       makevectors(view_angles);
-       view_forward = v_forward;
-       view_right = v_right;
-       view_up = v_up;
+       MAKE_VECTORS(view_angles, view_forward, view_right, view_up);
 
 #ifdef BLURTEST
        if(time > blurtest_time0 && time < blurtest_time1)
@@ -2006,6 +2015,20 @@ void CSQC_UpdateView(entity this, float w, float h)
                }
        }
 
+       if(active_minigame && HUD_MinigameMenu_IsOpened())
+       {
+               if(!minigame_wasactive)
+               {
+                       localcmd("+button12\n");
+                       minigame_wasactive = true;
+               }
+       }
+       else if(minigame_wasactive)
+       {
+               localcmd("-button12\n");
+               minigame_wasactive = false;
+       }
+
        ColorTranslateMode = autocvar_cl_stripcolorcodes;
 
        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
@@ -2163,7 +2186,7 @@ void CSQC_UpdateView(entity this, float w, float h)
                R_EndPolygon();
        }
 
-       if(autocvar_cl_reticle)
+       if(autocvar_cl_reticle && !MUTATOR_CALLHOOK(DrawReticle))
        {
                string reticle_image = string_null;
                bool wep_zoomed = false;
@@ -2441,7 +2464,7 @@ void CSQC_UpdateView(entity this, float w, float h)
        else if(cvar("r_glsl_postprocess") == 2)
                cvar_set("r_glsl_postprocess", "0");
 
-       /*if(gametype == MAPINFO_TYPE_CTF)
+       /*if(ISGAMETYPE(CTF))
          {
          ctf_view();
          } else */
@@ -2474,14 +2497,14 @@ void CSQC_UpdateView(entity this, float w, float h)
                setproperty(VF_ORIGIN, '0 0 0');
                setproperty(VF_ANGLES, '0 0 0');
                setproperty(VF_PERSPECTIVE, 1);
-               makevectors('0 0 0');
+               MAKE_VECTORS_NEW('0 0 0', forward, right, up);
                vector v1, v2;
                cvar_set("vid_conwidth", "800");
                cvar_set("vid_conheight", "600");
-               v1 = cs_project(v_forward);
+               v1 = cs_project(forward);
                cvar_set("vid_conwidth", "640");
                cvar_set("vid_conheight", "480");
-               v2 = cs_project(v_forward);
+               v2 = cs_project(forward);
                if(v1 == v2)
                        cs_project_is_b0rked = 1;
                else