From fc2bcd9f4f97b171a64957b99b1a799eb1bf6377 Mon Sep 17 00:00:00 2001 From: div0 Date: Fri, 29 May 2009 20:19:56 +0000 Subject: [PATCH] As per lordhavoc's suggestion, all rockets are guided now as long as you hold down fire. Rocket becomes unguided if you release button (no laser toggling, but also no stealing). Guiding is NOT done via laser dot, but it always tries to get into the direction of your crosshair. Enjoy! NOTE: may need rebalacing of rocket launcher. git-svn-id: svn://svn.icculus.org/nexuiz/trunk@6787 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/qcsrc/client/View.qc | 10 +++--- data/qcsrc/client/projectile.qc | 4 +++ data/qcsrc/server/constants.qh | 2 +- data/qcsrc/server/w_rocketlauncher.qc | 52 ++++++++++++++++++++++++--- data/weapons.cfg | 4 ++- data/weaponsHavoc.cfg | 4 ++- 6 files changed, 64 insertions(+), 12 deletions(-) diff --git a/data/qcsrc/client/View.qc b/data/qcsrc/client/View.qc index 1f0f31a61..b0fdb81a4 100644 --- a/data/qcsrc/client/View.qc +++ b/data/qcsrc/client/View.qc @@ -232,6 +232,10 @@ float TrueAimCheck() mi = '-2 -2 -2'; ma = '2 2 2'; break; + case WEP_ELECTRO: // projectile has a size! + mi = '0 0 -3'; + ma = '0 0 -3'; + break; } vecs = decompressShotOrigin(getstati(STAT_SHOTORG)); @@ -247,12 +251,8 @@ float TrueAimCheck() dv = view_right * vecs_y + view_up * vecs_z; w_shotorg = view_origin + dv; - // move the vecs sideways as much as requested if possible - traceline(view_origin, w_shotorg + normalize(dv) * nudge, MOVE_NORMAL, trueaim); - w_shotorg = trace_endpos - normalize(dv) * nudge; - // now move the vecs forward as much as requested if possible - traceline(w_shotorg, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, trueaim); // FIXME this MOVE_NORMAL part will misbehave a little in csqc + tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, trueaim); // FIXME this MOVE_NORMAL part will misbehave a little in csqc w_shotorg = trace_endpos - view_forward * nudge; // now test whether we will actually hit the trueaimpoint... diff --git a/data/qcsrc/client/projectile.qc b/data/qcsrc/client/projectile.qc index 0910be1e5..bcf9f6665 100644 --- a/data/qcsrc/client/projectile.qc +++ b/data/qcsrc/client/projectile.qc @@ -303,6 +303,10 @@ void Ent_Projectile() self.mins = '-2 -2 -2'; self.maxs = '2 2 2'; break; + case PROJECTILE_GRENADE: + self.mins = '0 0 -3'; + self.maxs = '0 0 -3'; + break; case PROJECTILE_GRENADE_BOUNCING: self.mins = '0 0 -3'; self.maxs = '0 0 -3'; diff --git a/data/qcsrc/server/constants.qh b/data/qcsrc/server/constants.qh index ed9690d2b..c10e22ecd 100644 --- a/data/qcsrc/server/constants.qh +++ b/data/qcsrc/server/constants.qh @@ -1,5 +1,5 @@ string CVAR_CHECK_DEFAULT = "2374fb15eacd4470860923b3ccddc0ad"; -string CVAR_CHECK_WEAPONS = "c5b3e579a14c45d555550b08f203a607"; +string CVAR_CHECK_WEAPONS = "c902f188773bf165513eb5ac2642c028"; float FALSE = 0; float TRUE = 1; diff --git a/data/qcsrc/server/w_rocketlauncher.qc b/data/qcsrc/server/w_rocketlauncher.qc index 88cee8eb7..97bc3af56 100644 --- a/data/qcsrc/server/w_rocketlauncher.qc +++ b/data/qcsrc/server/w_rocketlauncher.qc @@ -91,10 +91,32 @@ void W_Rocket_RemoteExplode() } } +vector rocket_steerto(vector thisdir, vector goaldir, float maxturn_cos) +{ + if(thisdir * goaldir > maxturn_cos) + return goaldir; + float f, m2; + vector v; + // solve: + // g = normalize(thisdir + goaldir * X) + // thisdir * g = maxturn + // + // gg = thisdir + goaldir * X + // (thisdir * gg)^2 = maxturn^2 * (gg * gg) + // + // (1 + (thisdir * goaldir) * X)^2 = maxturn^2 * (1 + X*X + 2 * X * thisdir * goaldir) + f = thisdir * goaldir; + // (1 + f * X)^2 = maxturn^2 * (1 + X*X + 2 * X * f) + // 0 = (m^2 - f^2) * x^2 + (2 * f * (m^2 - 1)) * x + (m^2 - 1) + m2 = maxturn_cos * maxturn_cos; + v = solve_quadratic(m2 - f * f, 2 * f * (m2 - 1), m2 - 1); + return normalize(thisdir + goaldir * v_y); // the larger solution! +} + void W_Rocket_Think (void) { entity e; - vector desireddir, olddir, newdir; + vector desireddir, olddir, newdir, desiredorigin, goal; float turnrate, velspeed; self.nextthink = time; if (time > self.cnt) @@ -156,7 +178,7 @@ void W_Rocket_Think (void) turnrate = cvar("g_balance_rocketlauncher_laserguided_turnrate");//0.65; // how fast to turn desireddir = normalize(e.origin - self.origin); // get direction from my position to the laser target olddir = normalize(self.velocity); // get my current direction - newdir = normalize((olddir + desireddir * turnrate) * 0.5); // take the average of the 2 directions; not the best method but simple & easy + newdir = normalize(olddir + desireddir * turnrate); // take the average of the 2 directions; not the best method but simple & easy self.velocity = newdir * velspeed; // make me fly in the new direction at my flight speed self.angles = vectoangles(self.velocity); // turn model in the new flight direction @@ -165,6 +187,25 @@ void W_Rocket_Think (void) } else { + if(!self.rl_release && !self.owner.rl_release && cvar("g_balance_rocketlauncher_guiderate")) + { + velspeed = vlen(self.velocity); + + makevectors(self.owner.v_angle); + desireddir = v_forward; + desiredorigin = self.owner.origin + self.owner.view_ofs; + olddir = normalize(self.velocity); + + // now it gets tricky... we want to move like some curve to approximate the target direction + // but we are limiting the rate at which we can turn! + goal = desiredorigin + ((self.origin - desiredorigin) * desireddir + cvar("g_balance_rocketlauncher_guidegoal")) * desireddir; + newdir = rocket_steerto(olddir, normalize(goal - self.origin), cos(cvar("g_balance_rocketlauncher_guiderate") * frametime * PI / 180)); + + self.velocity = newdir * velspeed; + } + else + self.rl_release = 1; + if(self.rl_detonate_later) W_Rocket_RemoteExplode(); } @@ -236,7 +277,7 @@ void W_Rocket_Attack (void) missile.cnt = time + cvar("g_balance_rocketlauncher_lifetime"); missile.flags = FL_PROJECTILE; - CSQCProjectile(missile, cvar("g_balance_rocketlauncher_speedaccel") == 0 && !g_laserguided_missile, PROJECTILE_ROCKET, FALSE); // because of fly sound + CSQCProjectile(missile, cvar("g_balance_rocketlauncher_guiderate") == 0 && cvar("g_balance_rocketlauncher_speedaccel") == 0 && !g_laserguided_missile, PROJECTILE_ROCKET, FALSE); // because of fly sound // muzzle flash for 1st person view flash = spawn (); @@ -389,12 +430,15 @@ float w_rlauncher(float req) } else { - if (self.BUTTON_ATCK) + if (self.BUTTON_ATCK && self.rl_release) if (weapon_prepareattack(0, cvar("g_balance_rocketlauncher_refire"))) { W_Rocket_Attack(); weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_rocketlauncher_animtime"), w_ready); + self.rl_release = 0; } + if (!self.BUTTON_ATCK) + self.rl_release = 1; if (self.BUTTON_ATCK2) { rockfound = 0; diff --git a/data/weapons.cfg b/data/weapons.cfg index 0c21fd865..f60063139 100644 --- a/data/weapons.cfg +++ b/data/weapons.cfg @@ -3,7 +3,7 @@ // // And... don't forget to edit weaponsHavoc.cfg too. -set cvar_check_weapons c5b3e579a14c45d555550b08f203a607 +set cvar_check_weapons c902f188773bf165513eb5ac2642c028 // NOTE: this only replaces weapons on the map // use g_start_weapon_* to also replace the on-startup weapons! @@ -265,6 +265,8 @@ set g_balance_rocketlauncher_animtime 0.3 set g_balance_rocketlauncher_ammo 3 set g_balance_rocketlauncher_health 30 set g_balance_rocketlauncher_detonatedelay 0.2 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time +set g_balance_rocketlauncher_guiderate 120 // max degrees per second +set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic) set g_balance_rocketlauncher_laserguided_speed 1000 //650 set g_balance_rocketlauncher_laserguided_speedaccel 0 set g_balance_rocketlauncher_laserguided_speedstart 1000 diff --git a/data/weaponsHavoc.cfg b/data/weaponsHavoc.cfg index 69d91dba9..1935f677a 100644 --- a/data/weaponsHavoc.cfg +++ b/data/weaponsHavoc.cfg @@ -1,4 +1,4 @@ -set cvar_check_weapons c5b3e579a14c45d555550b08f203a607 +set cvar_check_weapons c902f188773bf165513eb5ac2642c028 // NOTE: this only replaces weapons on the map // use g_start_weapon_* to also replace the on-startup weapons! @@ -260,6 +260,8 @@ set g_balance_rocketlauncher_animtime 0.3 set g_balance_rocketlauncher_ammo 3 set g_balance_rocketlauncher_health 30 set g_balance_rocketlauncher_detonatedelay 0.2 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time +set g_balance_rocketlauncher_guiderate 0 // max degrees per second +set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic) set g_balance_rocketlauncher_laserguided_speed 1000 //650 set g_balance_rocketlauncher_laserguided_speedaccel 0 set g_balance_rocketlauncher_laserguided_speedstart 1000 -- 2.39.2