]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Close to finalized, side scrolling view mode by Player 2
authorMario <zacjardine@y7mail.com>
Sun, 1 Mar 2015 03:48:53 +0000 (14:48 +1100)
committerMario <zacjardine@y7mail.com>
Sun, 1 Mar 2015 03:48:53 +0000 (14:48 +1100)
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/progs.src
qcsrc/common/csqcmodel_settings.qh
qcsrc/common/p2mathlib.qc [new file with mode: 0644]
qcsrc/common/p2mathlib.qh [new file with mode: 0644]
qcsrc/common/viewloc.qc [new file with mode: 0644]
qcsrc/common/viewloc.qh [new file with mode: 0644]
qcsrc/csqcmodellib/cl_player.qc
qcsrc/server/cl_physics.qc
qcsrc/server/progs.src
qcsrc/server/t_viewloc.qc

index cfadcd0ebc1d57441c14091ac81ecb1eedb6bfa8..5d169c9d7ceade86e64820ad02753459c2efe003 100644 (file)
@@ -404,11 +404,7 @@ void CSQCModel_AutoTagIndex_Apply(void)
        if(self.tag_entity && wasfreed(self.tag_entity))
                self.tag_entity = world;
 
-       if(self.viewloc && wasfreed(self.viewloc))
-               self.viewloc = world;
-
-       if(self.viewloc.entnum != self.tag_networkviewloc)
-               self.viewloc = findfloat(world, entnum, self.tag_networkviewloc);
+       viewloc_SetTags();
 
        if(self.tag_networkentity)
        {
index ece5da7b7c1131d3d5f8847bc4fdbfbbb7e6b35f..ca206355c56c14246585516bb7eafc42238c86d3 100644 (file)
@@ -48,6 +48,7 @@ weapons/projectile.qc // TODO
 ../common/net_notice.qc
 ../common/notifications.qc
 ../common/playerstats.qc
+../common/p2mathlib.qc
 ../common/test.qc
 ../common/urllib.qc
 ../common/util.qc
index 58ff0e3ba94b2df924384dcf67344cb37bbe043c..fdddc746304343f56b5ed880c994608b5e882ac2 100644 (file)
@@ -70,7 +70,8 @@
        CSQCModel_Hook_PostUpdate(isnew, isplayer, islocalplayer);
 #define CSQCMODEL_HOOK_PREDRAW \
        CSQCModel_Hook_PreDraw(isplayer);
-#define CSQCPLAYER_HOOK_POSTCAMERASETUP
+#define CSQCPLAYER_HOOK_POSTCAMERASETUP \
+       CSQCPlayer_SetViewLocation();
 
 // force updates of player entities that often even if unchanged
 #define CSQCPLAYER_FORCE_UPDATES 0.25
diff --git a/qcsrc/common/p2mathlib.qc b/qcsrc/common/p2mathlib.qc
new file mode 100644 (file)
index 0000000..ad569ff
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) 2015 Micah Talkiewicz.
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*/
+vector vec_bias(vector v, float f){
+       vector c;
+       c_x = v_x + f;
+       c_y = v_y + f;
+       c_z = v_z + f;
+       return c;
+}
+vector vec_to_min (vector a, vector b) {
+       vector c;
+       c_x = min (a_x, b_x);
+       c_y = min (a_y, b_y);
+       c_z = min (a_z, b_z);
+       return c;
+}
+vector vec_to_max (vector a, vector b) {
+       vector c;
+       c_x = max (a_x, b_x);
+       c_y = max (a_y, b_y);
+       c_z = max (a_z, b_z);
+       return c;
+}
+// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
+vector vec_bounds_in (vector point, vector a, vector b) {
+       vector c, d, e;
+        
+       d = vec_to_min(a,b);
+       e = vec_to_max(a,b);
+        
+       c = vec_to_max(point, d);
+       c = vec_to_min(c, e);
+        
+       return c;
+        
+}
+vector vec_bounds_out (vector point, vector a, vector b) {
+       vector c, d, e;
+        
+       d = vec_to_max(a,b);
+       e = vec_to_min(a,b);
+        
+       c = vec_to_max(point, d);
+       c = vec_to_min(c, e);
+        
+       return c;
+        
+}
+float angle_snap_f (float f, float increment){
+        
+       float i;
+       for (i = 0; i <= 360; ){
+               if (f <= i - increment)
+                       return  i - increment;
+               i = i + increment;
+       }
+        
+       return 0;
+}
+vector angle_snap_vec (vector v,  float increment) {
+       vector c;
+       c_x = angle_snap_f (v_x, increment);
+       c_y = angle_snap_f (v_y, increment);
+       c_z = angle_snap_f (v_z, increment);
+       return c;
+}
+
+vector aim_vec (vector origin, vector target) {
+       vector v;
+       //we float around x and y, but rotate around z
+       v_x = target_x - origin_x;
+       v_y = target_y - origin_y;
+       v_z = origin_z - target_z;
+       //get the angles actual
+       return vectoangles(normalize(v));
+}
diff --git a/qcsrc/common/p2mathlib.qh b/qcsrc/common/p2mathlib.qh
new file mode 100644 (file)
index 0000000..a8dc7ab
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2015 Micah Talkiewicz.
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*/
+
+vector vec_bias(vector v, float f);
+
+
+vector vec_to_min (vector a, vector b);
+vector vec_to_max (vector a, vector b);
+
+// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
+vector vec_bounds_in (vector point, vector a, vector b);
+vector vec_bounds_out (vector point, vector a, vector b);
+
+float angle_snap_f (float f, float increment);
+vector angle_snap_vec (vector v,  float increment);
+
+vector aim_vec (vector origin, vector target);
diff --git a/qcsrc/common/viewloc.qc b/qcsrc/common/viewloc.qc
new file mode 100644 (file)
index 0000000..960ad4c
--- /dev/null
@@ -0,0 +1,163 @@
+//#define COMPAT_VEX
+
+#ifndef COMPAT_VEX
+#include "util.qh"
+
+#if defined(CSQC)
+       #include "../dpdefs/csprogsdefs.qh"
+    #include "../client/defs.qh"
+    #include "constants.qh"
+#elif defined(MENUQC)
+#elif defined(SVQC)
+       #include "../server/defs.qh"
+#endif
+#endif
+
+#ifdef SVQC
+
+// client movement
+void viewloc_PlayerPhysics()
+{
+       if(self.viewloc)
+       {
+               self.disableclientprediction = 1;
+               vector oldmovement = self.movement;
+               self.movement_x = oldmovement_y;
+               self.movement_y = 0;
+
+               if(self.movement_x < 0)
+                       self.movement_x = -self.movement_x;
+
+               vector level_start, level_end;
+               level_start = self.viewloc.enemy.origin;
+               level_end = self.viewloc.goalentity.origin;
+               vector forward, backward;
+               forward = vectoangles(normalize(level_end - level_start));
+               backward = vectoangles(normalize(level_start - level_end));
+
+               if(self.movement_x < 0) // left
+                       self.angles = backward;
+               if(self.movement_x > 0) // right
+                       self.angles = forward;
+
+               if(oldmovement_x > 0)
+                       self.v_angle_x = self.angles_x = -50;
+               
+               if(!self.BUTTON_CROUCH)
+                       self.BUTTON_CROUCH = (oldmovement_x < 0);
+       }
+}
+
+#elif defined(CSQC)
+
+void viewloc_SetTags()
+{
+#ifdef COMPAT_VEX
+       entity self = CSQCModel_server2csqc(player_localentnum);
+#endif
+
+       if(self.viewloc && wasfreed(self.viewloc))
+               self.viewloc = world;
+
+       if(self.viewloc.entnum != self.tag_networkviewloc)
+       if(self.tag_networkviewloc == 0)
+               self.viewloc = world;
+       else
+               self.viewloc = findfloat(world, entnum, self.tag_networkviewloc);
+}
+
+#ifdef COMPAT_VEX
+entity view;
+#endif
+void viewloc_SetViewLocation()
+{
+#ifdef COMPAT_VEX
+       if(!view) { view = spawn(); }
+
+       view.viewloc = findfloat(world, entnum, getstati(STAT_VIEWLOC));
+       view.origin = pmove_org;
+#else
+       entity view = CSQCModel_server2csqc(player_localentnum);
+#endif
+       if(!view) { return; }
+       //NOTE: the "cam_" cvars sould probably be changed out with a spawnflag or an entity key. I have it like this for my testing -- Player_2
+       if(view.viewloc && !wasfreed(view.viewloc) && view.viewloc.enemy && view.viewloc.goalentity)
+       {
+               vector position_a, position_b, camera_position, camera_angle, forward, backward;
+               //vector scratch;
+
+               position_a = view.viewloc.enemy.origin;
+               position_b = view.viewloc.goalentity.origin;
+
+#if 0          
+               /*TODO: have the camera only move when a player moves too much from the center of the camera
+                * basically the player can move around in a "box" in the center of th screen with out changing the camera position or angles
+               */
+               if (cvar("cam_box")) {
+                       camera_position = vec_bounds_in(view.origin, position_a, position_b);
+               }
+               else
+#endif
+                       camera_position = vec_bounds_in(view.origin, position_a, position_b);
+
+
+               camera_angle = '0 0 0';
+
+               // a tracking camera follows the player when it leaves the world box 
+               if (cvar("cam_track")) {
+                       camera_angle = aim_vec (camera_position, view.origin);
+               }
+       
+               // hard snap changes the angle as soon as it crosses over the nearest 90 degree mark
+               if (cvar("cam_snap_hard")){
+                       camera_angle = angle_snap_vec(aim_vec(camera_position, view.origin), 90);
+               }
+               
+               // tries to avoid snapping unless it *really* needs to
+               if (cvar("cam_snap_close")){
+                       
+                       // like hard snap, but don't snap angles yet.
+                       camera_angle = aim_vec(camera_position, view.origin);
+                       
+                       /* if the difference between the old and new angle is 60 degrees or more, switch angles.
+                        * NOTE: bug/feature: this will use non-snaped angles for one frame.
+                        * doing this resualts in less code, faster code, and a smoother transisition between angles.
+                        */
+                       float camera_angle_diff = max(camera_angle_y, old_camera_angle_y) - min(camera_angle_y, old_camera_angle_y);
+
+                       if ( camera_angle_diff >= 60)
+                               old_camera_angle_y = angle_snap_f(camera_angle_y, 90);
+                       else
+                               camera_angle_y = old_camera_angle_y;
+               }
+               
+               //unlocking this allows the camera to look up and down. this also allows a top-down view.
+               if (!cvar("cam_snap_unlock")) {
+                       camera_angle_x = 0;
+                       camera_angle_z = 0;
+               }
+               
+#if 0
+               dprint(vtos(camera_position), "\n");
+               dprint(vtos(old_camera_angle), "\n");
+               dprint(vtos(camera_angle), "\n");
+#endif
+
+               freeze_org = getpropertyvec(VF_ORIGIN);
+               freeze_ang = getpropertyvec(VF_ANGLES);
+               setproperty(VF_ORIGIN, camera_position);
+               setproperty(VF_ANGLES, camera_angle);
+               
+               forward = vectoangles(normalize(vec_to_min(position_b, position_a) - vec_to_max(position_b, position_a)));
+               backward = vectoangles(normalize(vec_to_max(position_b, position_a) - vec_to_min(position_b, position_a)));
+               
+               if(input_movevalues_y < 0) // left
+                       view.angles = backward;
+               if(input_movevalues_y > 0) // favour right
+                       view.angles = forward;
+
+               setproperty(VF_CL_VIEWANGLES, view.angles);
+       }
+}
+
+#endif
diff --git a/qcsrc/common/viewloc.qh b/qcsrc/common/viewloc.qh
new file mode 100644 (file)
index 0000000..b3ae03c
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef VIEWLOC_H
+#define VIEWLOC_H
+
+.entity viewloc;
+
+#ifdef SVQC
+
+void viewloc_PlayerPhysics();
+
+#elif defined(CSQC)
+
+void viewloc_SetViewLocation();
+void viewloc_SetTags();
+
+#endif
+
+#endif
index 4ca438b221a2489d2b6e606574a748232bddd262..659a57c1c1b3664896aa9b8c5b1afefb9748e791 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011 Rudolf Polzer
+ * Copyright (c) 2015 Micah Talkiewicz
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -23,6 +24,7 @@
        #include "../dpdefs/csprogsdefs.qh"
        #include "../client/defs.qh"
        #include "../common/constants.qh"
+       #include "../common/p2mathlib.qh"
        #include "../common/stats.qh"
        #include "../common/util.qh"
        #include "interpolate.qh"
@@ -183,111 +185,9 @@ bool CSQCPlayer_IsLocalPlayer()
        return (self == csqcplayer);
 }
 
-vector addtovector(vector v, float f){
-       vector c;
-       c.x = v.x + f;
-       c.y = v.y + f;
-       c.z = v.z + f;
-       return c;
-}
-vector vectomin (vector a, vector b) {
-       vector c;
-       c.x = min (a.x, b.x);
-       c.y = min (a.y, b.y);
-       c.z = min (a.z, b.z);
-       return c;
-}
-
-vector vectomax (vector a, vector b) {
-       vector c;
-       c.x = max (a.x, b.x);
-       c.y = max (a.y, b.y);
-       c.z = max (a.z, b.z);
-       return c;
-}
-
-// there may already be a function for bounding a vector in this manner, however my very quick search did not reveal one -- Player_2
-vector vecinbounds (vector point, vector a, vector b) {
-       vector c, d, e;
-
-       d = vectomin(a,b);
-       e = vectomax(a,b);
-       
-       c = vectomax(point, d);
-       c = vectomin(c, e);
-       
-       return c;
-       
-}
-
-vector vecoutbounds (vector point, vector a, vector b) {
-       vector c, d, e;
-       
-       d = vectomax(a,b);
-       e = vectomin(a,b);
-       
-       c = vectomax(point, d);
-       c = vectomin(c, e);
-       
-       return c;
-       
-}
-
-//does QC have a static type? I'll just use a global I guess...
-vector old_camera_position = '0 0 0';
 void CSQCPlayer_SetViewLocation()
 {
-       if(self.viewloc && !wasfreed(self.viewloc) && self.viewloc.enemy && self.viewloc.goalentity)
-       {
-               entity view = CSQCModel_server2csqc(player_localentnum);
-               if(!view) { return; }
-
-               vector position_a, position_b, camera_position, camera_angle, forward, backward;
-
-               position_a = self.viewloc.enemy.origin;
-               position_b = self.viewloc.goalentity.origin;
-
-               if (cvar("cam_box")) {
-                       camera_position = vecinbounds(view.origin, position_a, position_b);
-               }
-               else
-                       camera_position = vecinbounds(view.origin, position_a, position_b);
-
-
-               //for a world box set camera_angle to no angle
-               camera_angle = '0 0 0';
-
-               // a tracking camera follows the player when it leaves the world box 
-               if (cvar("cam_track")) {
-                       //we float around x and y, but rotate around z
-                       camera_angle.x = view.origin.x - camera_position.x;
-                       camera_angle.y = view.origin.y - camera_position.y;
-                       camera_angle.z = camera_position.z - view.origin.z;
-                       //get the angles actual
-                       camera_angle = vectoangles(normalize(camera_angle));
-               }
-               
-               dprint(vtos(camera_position), "\n");
-               dprint(vtos(camera_angle), "\n");
-
-               freeze_org = getpropertyvec(VF_ORIGIN);
-               freeze_ang = getpropertyvec(VF_ANGLES);
-               setproperty(VF_ORIGIN, camera_position);
-               setproperty(VF_ANGLES, camera_angle);
-               
-               forward = vectoangles(normalize(vectomin(position_b, position_a) - vectomax(position_b, position_a)));
-               backward = vectoangles(normalize(vectomax(position_b, position_a) - vectomin(position_b, position_a)));
-               
-               if(input_movevalues_y < 0) // left
-                       view.angles = backward;
-               if(input_movevalues_y > 0) // favour right
-                       view.angles = forward;
-               
-               if(input_buttons & 256) // forward
-                       view.v_angle_x = view.angles_x = -50;
-               
-               setproperty(VF_CL_VIEWANGLES, view.angles);
-       }
+       viewloc_SetViewLocation();
 }
 
 void CSQCPlayer_SetCamera()
@@ -410,8 +310,6 @@ void CSQCPlayer_SetCamera()
                        refdefflags |= REFDEFFLAG_INTERMISSION;
 
                V_CalcRefdef(view, refdefflags);
-
-               CSQCPlayer_SetViewLocation();
        }
        else
        {
index db4eed221015dc39195c2bf1d9ea4e6f08e50e77..69757697275707992c027c43ea39f2b85c652108 100644 (file)
@@ -863,34 +863,7 @@ void SV_PlayerPhysics()
        if(time < self.ladder_time)
                self.disableclientprediction = 1;
 
-       if(self.viewloc)
-       {
-               self.disableclientprediction = 1;
-               vector oldmovement = self.movement;
-               self.movement_x = oldmovement_y;
-               self.movement_y = 0;
-
-               if(self.movement_x < 0)
-                       self.movement_x = -self.movement_x;
-
-               vector level_start, level_end;
-               level_start = self.viewloc.enemy.origin;
-               level_end = self.viewloc.goalentity.origin;
-               vector forward, backward;
-               forward = vectoangles(normalize(level_end - level_start));
-               backward = vectoangles(normalize(level_start - level_end));
-
-               if(self.movement_x < 0) // left
-                       self.angles = backward;
-               if(self.movement_x > 0) // right
-                       self.angles = forward;
-
-               if(oldmovement_x > 0)
-                       self.v_angle_x = self.angles_x = -50;
-               
-               if(!self.BUTTON_CROUCH)
-                       self.BUTTON_CROUCH = (oldmovement_x < 0);
-       }
+       viewloc_PlayerPhysics();
 
        if(self.frozen)
        {
index 848c49d44772a832eae5276b7019c31da6b504b8..b94ef71a619ac12791970c869758467beaf236c6 100644 (file)
@@ -106,6 +106,7 @@ weapons/weaponsystem.qc
 ../common/net_notice.qc
 ../common/notifications.qc
 ../common/playerstats.qc
+../common/p2mathlib.qc
 ../common/test.qc
 ../common/turrets/targettrigger.qc
 ../common/turrets/sv_turrets.qc
index 38c841c8eda626c35e4ca8b1de185ffb315828f0..ac53daf23808466bb0b02d6faeeb90658159bb1a 100644 (file)
@@ -1,3 +1,4 @@
+#ifndef COMPAT_VEX
 #if defined(CSQC)
 #elif defined(MENUQC)
 #elif defined(SVQC)
@@ -6,6 +7,7 @@
     #include "defs.qh"
        #include "t_viewloc.qh"
 #endif
+#endif
 
 #ifdef SVQC