Updated to version 3.
Usage:
- Code: Select all
seta freeaim 0 "enable free-aiming mode"
seta freeaim_sensitivity 6 "freeaim sensitivity"
seta freeaim_deadzone 0 "freeaim dead zone, as a factor of screen size (try 0.05)"
- Code: Select all
Index: data/qcsrc/client/View.qc
===================================================================
--- data/qcsrc/client/View.qc (revision 7452)
+++ data/qcsrc/client/View.qc (working copy)
@@ -306,6 +306,19 @@
return SHOTTYPE_HITWORLD;
}
+vector freeaim_angle, mouse_pos;
+float freeaim_active;
+void drawcrosshair(string name, float sizefloat, vector c, float a, float f)
+{
+ vector s;
+ s = drawgetimagesize(name);
+ s_x *= sizefloat;
+ s_y *= sizefloat;
+ drawpic(mouse_pos + '0.5 0 0' * (vid_conwidth - s_x) + '0 0.5 0' * (vid_conheight - s_y),
+ name, s, c, a, f);
+}
+
+
void CSQC_common_hud(void);
void CSQC_kh_hud(void);
@@ -334,11 +347,73 @@
ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+ vid_width = w;
+ vid_height = h;
+ fov = cvar("fov");
+
// Render the Scene
if(!intermission || !view_set)
{
view_origin = pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT);
- view_angles = input_angles;
+ view_angles = input_angles - freeaim_angle; // correct for last frame
+ if(cvar("freeaim") == 1)
+ {
+ if(!freeaim_active)
+ {
+ setwantsmousemove(1);
+ freeaim_active = 1;
+ }
+ mouse_pos = getmousepos();
+ if(mouse_pos != '0 0 0')
+ {
+ mouse_pos_x -= 0.5*vid_conwidth;
+ mouse_pos_y -= 0.5*vid_conheight;
+ }
+
+ v = GetCurrentFov(fov);
+ v_x = 1-(v_x/180);
+ v_y = mouse_pos_x/vid_conwidth;
+ v_z = -mouse_pos_y/vid_conwidth;
+ freeaim_angle = normalize(v);
+ f = cvar("freeaim_deadzone")*0.5;
+ if(fabs(v_y) > f || fabs(v_z) > f)
+ {
+ v_x = v_z*cvar("cl_pitchspeed")*-2;
+ v_y = v_y*cvar("cl_yawspeed")*-2;
+ v_z = 0;
+ view_angles += v*cvar_or("freeaim_sensitivity",6)*frametime;
+ }
+ view_angles_x = bound(cvar("in_pitch_min"),view_angles_x,cvar("in_pitch_max"));
+
+ v = freeaim_angle;
+ makevectors(view_angles);
+ input_angles = vectoangles(v_x*v_forward + v_y*v_right + v_z*v_up);
+ input_angles_x = 0-input_angles_x; // correct vectoangles
+ if(input_angles_x < -90)input_angles_x += 360;
+ if(input_angles_y >= 180)input_angles_y -= 360;
+ freeaim_angle = input_angles - view_angles;
+ if(freeaim_angle_y >= 180)freeaim_angle_y -= 360; // This WILL happen.
+ if(freeaim_angle_y <= -180)freeaim_angle_y += 360;
+
+ if(cvar("chase_active") == 0 && cvar("crosshair") != 0)
+ {
+ R_SetView(VF_ORIGIN, view_origin);
+ R_SetView(VF_ANGLES, view_angles);
+ }
+ else mouse_pos = '0 0 0';
+ R_SetView(VF_CL_VIEWANGLES, input_angles);
+ }
+ else
+ {
+ if(freeaim_active)
+ {
+ input_angles -= freeaim_angle;
+ R_SetView(VF_CL_VIEWANGLES, input_angles);
+ setwantsmousemove(0);
+ freeaim_active = 0;
+ }
+ mouse_pos = freeaim_angle = '0 0 0';
+ }
makevectors(view_angles);
view_forward = v_forward;
view_right = v_right;
@@ -346,9 +421,6 @@
view_set = 1;
}
- vid_width = w;
- vid_height = h;
-
#ifdef BLURTEST
if(time > blurtest_time0 && time < blurtest_time1)
{
@@ -382,7 +454,6 @@
CheckForGamestartChange();
maptimeAnnouncer();
- fov = cvar("fov");
if(button_zoom || fov <= 59.5)
{
if(!zoomscript_caught)
@@ -551,12 +622,8 @@
hud = getstati(STAT_HUD);
if(hud == HUD_SPIDERBOT)
{
- vector sz;
- CSQC_spider_HUD();
- sz = drawgetimagesize(SPIDER_CROSS);
- sz_x *= cvar_or("cl_vehicle_spiderbot_cross_size",1);
- sz_y *= cvar_or("cl_vehicle_spiderbot_cross_size",1);
- drawpic('0.5 0 0' * (vid_conwidth - sz_x) + '0 0.5 0' * (vid_conheight - sz_y), SPIDER_CROSS, sz, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
+ CSQC_spider_HUD();
+ drawcrosshair(SPIDER_CROSS, cvar_or("cl_vehicle_spiderbot_cross_size",1), '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
}
else
{
@@ -595,7 +662,7 @@
wcross_style = cvar_string("crosshair");
if (wcross_style != "0") {
- vector wcross_color, wcross_size;
+ vector wcross_color;
string wcross_wep, wcross_name;
float wcross_alpha, wcross_sizefloat;
@@ -631,10 +698,6 @@
wcross_sizefloat *= cvar("crosshair_hittest"); // is not queried if hittest is 0
if(shottype == SHOTTYPE_HITTEAM)
wcross_sizefloat /= cvar("crosshair_hittest"); // is not queried if hittest is 0
-
- wcross_size = drawgetimagesize(wcross_name);
- wcross_size_x *= wcross_sizefloat;
- wcross_size_y *= wcross_sizefloat;
// ring around crosshair representing bullets left in camping rifle clip
if (activeweapon == WEP_CAMPINGRIFLE)
@@ -652,15 +715,15 @@
for(j = -2; j <= 2; ++j)
{
if (bullets)
- drawpic(wcross_origin - '0.5 0 0' * (wcross_size_x * ring_scale + i) - '0 0.5 0' * (wcross_size_y * ring_scale + j), strcat("gfx/hud/rifle_ring_", ftos(bullets)), wcross_size * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
- drawpic(wcross_origin - '0.5 0 0' * (wcross_size_x + i) - '0 0.5 0' * (wcross_size_y + j), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+ drawcrosshair(strcat("gfx/hud/rifle_ring_", ftos(bullets)), wcross_sizefloat * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+ drawcrosshair( wcross_name, wcross_sizefloat, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
}
}
else
{
if (bullets)
- drawpic(wcross_origin - '0.5 0 0' * (wcross_size_x * ring_scale) - '0 0.5 0' * (wcross_size_y * ring_scale), strcat("gfx/hud/rifle_ring_", ftos(bullets)), wcross_size * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
- drawpic(wcross_origin - '0.5 0 0' * (wcross_size_x) - '0 0.5 0' * ( wcross_size_y), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+ drawcrosshair(strcat("gfx/hud/rifle_ring_", ftos(bullets)), wcross_sizefloat * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+ drawcrosshair(wcross_name, wcross_sizefloat, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
}
}
}