X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_weaponsystem.qc;h=23dfaedceaf8cd1816f7340d0c10a8fabe50cd47;hb=8675941fb13c2d91b62332c58d9e9d8da6b47524;hp=7625e9b504ed36c80b7524852f722b7768aef1b6;hpb=789db90320bdb2045fb532ec9a03fb5869a13133;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index 7625e9b50..23dfaedce 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -541,15 +541,20 @@ void CL_Weaponentity_Think() } self.angles = '0 0 0'; - float f; + + float f = (self.owner.weapon_nextthink - time); if (self.state == WS_RAISE && !intermission_running) { - f = (self.owner.weapon_nextthink - time) * g_weaponratefactor / autocvar_g_balance_weaponswitchdelay; + entity newwep = get_weaponinfo(self.owner.switchweapon); + f = f * g_weaponratefactor / max(f, cvar(sprintf("g_balance_%s_switchdelay_raise", newwep.netname))); + //print(sprintf("CL_Weaponentity_Think(): cvar: %s, value: %f, nextthink: %f\n", sprintf("g_balance_%s_switchdelay_raise", newwep.netname), cvar(sprintf("g_balance_%s_switchdelay_raise", newwep.netname)), (self.owner.weapon_nextthink - time))); self.angles_x = -90 * f * f; } else if (self.state == WS_DROP && !intermission_running) { - f = 1 - (self.owner.weapon_nextthink - time) * g_weaponratefactor / autocvar_g_balance_weaponswitchdelay; + entity oldwep = get_weaponinfo(self.owner.weapon); + f = 1 - f * g_weaponratefactor / max(f, cvar(sprintf("g_balance_%s_switchdelay_drop", oldwep.netname))); + //print(sprintf("CL_Weaponentity_Think(): cvar: %s, value: %f, nextthink: %f\n", sprintf("g_balance_%s_switchdelay_drop", oldwep.netname), cvar(sprintf("g_balance_%s_switchdelay_drop", oldwep.netname)), (self.owner.weapon_nextthink - time))); self.angles_x = -90 * f * f; } else if (self.state == WS_CLEAR) @@ -1039,196 +1044,6 @@ void W_AttachToShotorg(entity flash, vector offset) } } -vector cliptoplane(vector v, vector p) -{ - return v - (v * p) * p; -} - -vector solve_cubic_pq(float p, float q) -{ - float D, u, v, a; - D = q*q/4.0 + p*p*p/27.0; - if(D < 0) - { - // irreducibilis - a = 1.0/3.0 * acos(-q/2.0 * sqrt(-27.0/(p*p*p))); - u = sqrt(-4.0/3.0 * p); - // a in range 0..pi/3 - // cos(a) - // cos(a + 2pi/3) - // cos(a + 4pi/3) - return - u * - ( - '1 0 0' * cos(a + 2.0/3.0*M_PI) - + - '0 1 0' * cos(a + 4.0/3.0*M_PI) - + - '0 0 1' * cos(a) - ); - } - else if(D == 0) - { - // simple - if(p == 0) - return '0 0 0'; - u = 3*q/p; - v = -u/2; - if(u >= v) - return '1 1 0' * v + '0 0 1' * u; - else - return '0 1 1' * v + '1 0 0' * u; - } - else - { - // cardano - u = cbrt(-q/2.0 + sqrt(D)); - v = cbrt(-q/2.0 - sqrt(D)); - return '1 1 1' * (u + v); - } -} -vector solve_cubic_abcd(float a, float b, float c, float d) -{ - // y = 3*a*x + b - // x = (y - b) / 3a - float p, q; - vector v; - p = (9*a*c - 3*b*b); - q = (27*a*a*d - 9*a*b*c + 2*b*b*b); - v = solve_cubic_pq(p, q); - v = (v - b * '1 1 1') * (1.0 / (3.0 * a)); - if(a < 0) - v += '1 0 -1' * (v_z - v_x); // swap x, z - return v; -} - -vector findperpendicular(vector v) -{ - vector p; - p_x = v_z; - p_y = -v_x; - p_z = v_y; - return normalize(cliptoplane(p, v)); -} - -vector W_CalculateProjectileSpread(vector forward, float spread) -{ - float sigma; - vector v1 = '0 0 0', v2; - float dx, dy, r; - float sstyle; - spread *= g_weaponspreadfactor; - if(spread <= 0) - return forward; - sstyle = autocvar_g_projectiles_spread_style; - - if(sstyle == 0) - { - // this is the baseline for the spread value! - // standard deviation: sqrt(2/5) - // density function: sqrt(1-r^2) - return forward + randomvec() * spread; - } - else if(sstyle == 1) - { - // same thing, basically - return normalize(forward + cliptoplane(randomvec() * spread, forward)); - } - else if(sstyle == 2) - { - // circle spread... has at sigma=1 a standard deviation of sqrt(1/2) - sigma = spread * 0.89442719099991587855; // match baseline stddev - v1 = findperpendicular(forward); - v2 = cross(forward, v1); - // random point on unit circle - dx = random() * 2 * M_PI; - dy = sin(dx); - dx = cos(dx); - // radius in our dist function - r = random(); - r = sqrt(r); - return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); - } - else if(sstyle == 3) // gauss 3d - { - sigma = spread * 0.44721359549996; // match baseline stddev - // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right - v1 = forward; - v1_x += gsl_ran_gaussian(sigma); - v1_y += gsl_ran_gaussian(sigma); - v1_z += gsl_ran_gaussian(sigma); - return v1; - } - else if(sstyle == 4) // gauss 2d - { - sigma = spread * 0.44721359549996; // match baseline stddev - // note: 2D gaussian has sqrt(2) times the stddev of 1D, so this factor is right - v1_x = gsl_ran_gaussian(sigma); - v1_y = gsl_ran_gaussian(sigma); - v1_z = gsl_ran_gaussian(sigma); - return normalize(forward + cliptoplane(v1, forward)); - } - else if(sstyle == 5) // 1-r - { - sigma = spread * 1.154700538379252; // match baseline stddev - v1 = findperpendicular(forward); - v2 = cross(forward, v1); - // random point on unit circle - dx = random() * 2 * M_PI; - dy = sin(dx); - dx = cos(dx); - // radius in our dist function - r = random(); - r = solve_cubic_abcd(-2, 3, 0, -r) * '0 1 0'; - return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); - } - else if(sstyle == 6) // 1-r^2 - { - sigma = spread * 1.095445115010332; // match baseline stddev - v1 = findperpendicular(forward); - v2 = cross(forward, v1); - // random point on unit circle - dx = random() * 2 * M_PI; - dy = sin(dx); - dx = cos(dx); - // radius in our dist function - r = random(); - r = sqrt(1 - r); - r = sqrt(1 - r); - return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); - } - else if(sstyle == 7) // (1-r) (2-r) - { - sigma = spread * 1.224744871391589; // match baseline stddev - v1 = findperpendicular(forward); - v2 = cross(forward, v1); - // random point on unit circle - dx = random() * 2 * M_PI; - dy = sin(dx); - dx = cos(dx); - // radius in our dist function - r = random(); - r = 1 - sqrt(r); - r = 1 - sqrt(r); - return normalize(forward + (v1 * dx + v2 * dy) * r * sigma); - } - else - error("g_projectiles_spread_style must be 0 (sphere), 1 (flattened sphere), 2 (circle), 3 (gauss 3D), 4 (gauss plane), 5 (linear falloff), 6 (quadratic falloff), 7 (stronger falloff)!"); - return '0 0 0'; - /* - * how to derive falloff functions: - * rho(r) := (2-r) * (1-r); - * a : 0; - * b : 1; - * rhor(r) := r * rho(r); - * cr(t) := integrate(rhor(r), r, a, t); - * scr(t) := integrate(rhor(r) * r^2, r, a, t); - * variance : scr(b) / cr(b); - * solve(cr(r) = rand * cr(b), r), programmmode:false; - * sqrt(0.4 / variance), numer; - */ -} - #if 0 float mspercallsum; float mspercallsstyle; @@ -1252,7 +1067,7 @@ void W_SetupProjectileVelocityEx(entity missile, vector dir, vector upDir, float } mspercallsum -= gettime(GETTIME_HIRES); #endif - dir = W_CalculateProjectileSpread(dir, spread); + dir = W_CalculateSpread(dir, spread, g_weaponspreadfactor, autocvar_g_projectiles_spread_style); #if 0 mspercallsum += gettime(GETTIME_HIRES); mspercallcount += 1;