X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fweapons%2Fcalculations.qc;h=a8587b1ab3167ea24242590a35b714b8ace98fe4;hb=b9c4f697a81bb47446239bdfa8ec1fc6083935b5;hp=16b507d14eee683e65c13e28a42399efdd48054f;hpb=737346fcfbe5912ff5de24c2f22c0dbd894429a6;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/weapons/calculations.qc b/qcsrc/common/weapons/calculations.qc index 16b507d14..a8587b1ab 100644 --- a/qcsrc/common/weapons/calculations.qc +++ b/qcsrc/common/weapons/calculations.qc @@ -1,3 +1,5 @@ +#include "calculations.qh" + // ============================= // Explosion Force Calculation // ============================= @@ -142,109 +144,170 @@ vector findperpendicular(vector v) return normalize(cliptoplane(p, v)); } +#ifdef SVQC + int W_GunAlign(entity this, int preferred_align) + { + entity own = this.owner; + // using wasfreed, as we don't actually clear .gunaligns yet + if(!own.gunaligns[preferred_align] || wasfreed(own.gunaligns[preferred_align]) || own.gunaligns[preferred_align] == this) + { + own.gunaligns[preferred_align] = this; + return preferred_align; // fall back if the good one is already choosable + } + + for(int j = 4; j > 0; --j) // start from left and try the others + { + if(!own.gunaligns[j] || wasfreed(own.gunaligns[j]) || own.gunaligns[j] == this) + { + own.gunaligns[j] = this; + return j; + } + } + + own.gunaligns[preferred_align] = this; + return preferred_align; // no other choice + } +#else + int W_GunAlign(entity this, int preferred_align) + { + // using wasfreed, as we don't actually clear gunaligns yet + if(!gunaligns[preferred_align] || wasfreed(gunaligns[preferred_align]) || gunaligns[preferred_align] == this) + { + gunaligns[preferred_align] = this; + return preferred_align; // fall back if the good one is already choosable + } + + for(int j = 4; j > 0; --j) + { + if(!gunaligns[j] || wasfreed(gunaligns[j]) || gunaligns[j] == this) + { + gunaligns[j] = this; + return j; + } + } + + gunaligns[preferred_align] = this; + return preferred_align; // no other choice + } +#endif + +#if 0 +int W_GetGunAlignment(entity player) +{ + int gunalign = STAT(GUNALIGN, player); + if(gunalign < 1 || gunalign > 4) + gunalign = 3; // default value + --gunalign; + + return gunalign; +} +#endif + vector W_CalculateSpread(vector forward, float spread, float spreadfactor, float spreadstyle) { float sigma; vector v1 = '0 0 0', v2; float dx, dy, r; - float sstyle; spread *= spreadfactor; //g_weaponspreadfactor; if(spread <= 0) return forward; - sstyle = spreadstyle; //autocvar_g_projectiles_spread_style; - if(sstyle == 0) + switch(spreadstyle) { - // this is the baseline for the spread value! - // standard deviation: sqrt(2/5) - // density function: sqrt(1-r^2) - return forward + randomvec() * spread; + case 0: + { + // this is the baseline for the spread value! + // standard deviation: sqrt(2/5) + // density function: sqrt(1-r^2) + return forward + randomvec() * spread; + } + case 1: + { + // same thing, basically + return normalize(forward + cliptoplane(randomvec() * spread, forward)); + } + case 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); + } + case 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; + } + case 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)); + } + case 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); + } + case 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); + } + case 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); + } + default: + 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)!"); } - 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: