From: Mario Date: Sun, 1 Mar 2015 03:48:53 +0000 (+1100) Subject: Close to finalized, side scrolling view mode by Player 2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=73490ff56f568b1aaa696ae12e5a8663330d7eac;p=xonotic%2Fxonotic-data.pk3dir.git Close to finalized, side scrolling view mode by Player 2 --- diff --git a/qcsrc/client/csqcmodel_hooks.qc b/qcsrc/client/csqcmodel_hooks.qc index cfadcd0eb..5d169c9d7 100644 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@ -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) { diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index ece5da7b7..ca206355c 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -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 diff --git a/qcsrc/common/csqcmodel_settings.qh b/qcsrc/common/csqcmodel_settings.qh index 58ff0e3ba..fdddc7463 100644 --- a/qcsrc/common/csqcmodel_settings.qh +++ b/qcsrc/common/csqcmodel_settings.qh @@ -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 index 000000000..ad569ffbc --- /dev/null +++ b/qcsrc/common/p2mathlib.qc @@ -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 index 000000000..a8dc7ab44 --- /dev/null +++ b/qcsrc/common/p2mathlib.qh @@ -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 index 000000000..960ad4c89 --- /dev/null +++ b/qcsrc/common/viewloc.qc @@ -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 index 000000000..b3ae03c18 --- /dev/null +++ b/qcsrc/common/viewloc.qh @@ -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 diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc index 4ca438b22..659a57c1c 100644 --- a/qcsrc/csqcmodellib/cl_player.qc +++ b/qcsrc/csqcmodellib/cl_player.qc @@ -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 { diff --git a/qcsrc/server/cl_physics.qc b/qcsrc/server/cl_physics.qc index db4eed221..697576972 100644 --- a/qcsrc/server/cl_physics.qc +++ b/qcsrc/server/cl_physics.qc @@ -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) { diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 848c49d44..b94ef71a6 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -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 diff --git a/qcsrc/server/t_viewloc.qc b/qcsrc/server/t_viewloc.qc index 38c841c8e..ac53daf23 100644 --- a/qcsrc/server/t_viewloc.qc +++ b/qcsrc/server/t_viewloc.qc @@ -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