Advertisement
Guest User

UnrealScript GesBio subclass

a guest
Jun 5th, 2012
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //=============================================================================
  2. // qGESBioRifle.
  3. //=============================================================================
  4. class qGESBioRifle expands GESBioRifle;
  5.  
  6. // ############ Complex Numbers for solving a quartic equation #########
  7. struct Complex
  8. {
  9.     var float Re, Im;
  10. };
  11.  
  12. static final function Complex Compl( float Re, optional float Im )
  13. {
  14.     local Complex A;
  15.     A.Re = Re;
  16.     A.Im = Im;
  17.     return A;
  18. }
  19.  
  20. static final preoperator Complex - ( Complex A )
  21. {
  22.     A.Re = - A.Re;
  23.     A.Im = - A.Im;
  24.     return A;
  25. }
  26.  
  27. static final preoperator Complex / ( Complex A )
  28. {
  29.     local float f;
  30.     f = A.Re*A.Re + A.Im*A.Im;
  31.     A.Re /= f;
  32.     A.Im /= -f;
  33.     return A;
  34. }
  35.  
  36. static final operator(20) Complex + ( Complex A, Complex B )
  37. {
  38.     A.Re += B.Re;
  39.     A.Im += B.Im;
  40.     return A;
  41. }
  42.  
  43. static final operator(20) Complex - ( Complex A, Complex B )
  44. {  
  45.     A.Re -= B.Re;
  46.     A.Im -= B.Im;  
  47.     return A;
  48. }
  49.  
  50. static final operator(16) Complex * ( Complex A, Complex B )
  51. {
  52.     local Complex C;
  53.     C.Re = A.Re*B.Re - A.Im*B.Im;
  54.     C.Im = A.Re*B.Im + A.Im*B.Re;
  55.     return C;
  56. }
  57.  
  58. static final operator(16) Complex / ( Complex A, Complex B )
  59. {
  60.     return A * (/B);
  61. }
  62.  
  63. static final operator(12) Complex ** ( Complex A, float Power )
  64. {
  65.     local float Radius, Angle;
  66.     local Complex B;
  67.     // polar form: (Re,Im)= Radius*(cos(Angle),sin(Angle))
  68.     Radius = sqrt( A.Re*A.Re + A.Im*A.Im );
  69.     if ( A.Re > 0 )
  70.         Angle=Atan( A.Im/A.Re );
  71.     else if ( A.Re < 0 )
  72.     {
  73.         if ( A.Im >= 0 )
  74.             Angle=Atan( A.Im/A.Re ) + pi;  
  75.         else
  76.             Angle=Atan( A.Im/A.Re ) - pi;                      
  77.     }
  78.     else // A.Re == 0
  79.     {
  80.         if ( A.Im > 0 )
  81.             Angle = pi/2.;
  82.         else if ( A.Im < 0 )
  83.             Angle = -pi/2.;        
  84.     }
  85.     // calculate pow
  86.     Radius = Radius ** Power;
  87.     Angle *= Power;
  88.     // transform back to cartesian form
  89.     B.Re = Radius*cos(Angle);
  90.     B.Im = Radius*sin(Angle);
  91.     return B;
  92. }
  93.  
  94. static final operator(20) Complex + ( Complex A, float f ){ A.Re += f; return A; }
  95. static final operator(20) Complex + ( float f, Complex A ){ A.Re += f; return A; }
  96. static final operator(20) Complex - ( Complex A, float f ){ A.Re -= f; return A; }
  97. static final operator(20) Complex - ( float f, Complex A ){ return Compl(f)-A; }
  98. static final operator(16) Complex * ( Complex A, float f ){ A.Re *= f; A.Im *= f; return A; }
  99. static final operator(16) Complex * ( float f, Complex A ){ A.Re *= f; A.Im *= f; return A; }
  100. static final operator(16) Complex / ( Complex A, float f ){ A.Re /= f; A.Im /= f; return A; }
  101. static final operator(16) Complex / ( float f, Complex A ){ return Compl(f)/A; }
  102. static final function Complex SquareRoot(Complex A){ return A**0.5; }
  103. static final function Complex CubeRoot(Complex A){ return A**(1./3.); }
  104.  
  105. // returns the smallest positive solution x of e*x^4 + a*x^3 + b*x^2 + c*x + d = 0;
  106. static function float SolveQuartic(float e, float a, float b, float c, float d)
  107. {
  108.     local float p, q, r, s, t;
  109.     local Complex h, u, v, z, i, j;
  110.     local Complex x1, x2, x3, x4;
  111.     local Complex x,y;
  112.  
  113.     if ( e != 1 )
  114.     {
  115.         a /= e;
  116.         b /= e;
  117.         c /= e;
  118.         d /= e;
  119.     }
  120.     // Now we have x^4 + a*x^3 + b*x^2 + c*x + d = 0;
  121.     // substitute x = y - a/4, the scalar before y^3 disappears, we have
  122.     // y^4 + p*y^2 + q*y + r = 0 with
  123.     p = -3.*a*a/8. + b;
  124.     q = a*a*a/8. - a*b/2. + c;
  125.     r = -3.*a*a*a*a/256. + a*a*b/16. - a*c/4. + d;
  126.     if ( abs(q) < 0.00001 )
  127.     {   // (y^2 + p/2)^2 = - r + p^2/4
  128.         // y^2 = 0.5*( -p +/- sqrt(p^2-4r) )
  129.         i = SquareRoot( Compl(p*p-4*r) );
  130.         j = SquareRoot( 0.5*( -p + i ) );
  131.         x1 = -a/4. + j;
  132.         x2 = -a/4. - j;
  133.         j = SquareRoot( 0.5*( -p - i ) );
  134.         x3 = -a/4. + j;
  135.         x4 = -a/4. - j;
  136.     }
  137.     else
  138.     {
  139.     // This is equivalent to (y^2 + p/2)^2 = -q*y - r + p^2/4
  140.     // We want squares on both sides, add a variable z, such that
  141.     // (y^2 + p/2 + z/2)^2 = y^2*z -q*y - r + p^2/4 + p*z/2 + z*z/4 is
  142.     // (y^2 + p/2 + z/2)^2 = z*( y - 0.5*q/z )^2 . So z must fulfill
  143.     // 0.25*q^2/z^2 = 1/z*(-r+p^2/4) + p/2 + z/4, which is the cubic equation
  144.     // z^3 + 2*p*z^2 + (p^2-4*r)*z - q^2 = 0
  145.     // subsitute z = w - 2*p/3, the scalar before w^2 disappears, we have
  146.     // w^3 + 3*s*w + 2*t = 0 with
  147.         s = -p*p/9. - 4.*r/3.;
  148.         t = -p*p*p/27. + 4.*p*r/3. - q*q/2.;
  149.         if ( abs(s) < 0.00001 ) // w^3 = -2*t
  150.         {
  151.             // z = -2.*p/3. + CubeRoot( Compl(-2.*t) );
  152.             if ( -2*t >= 0 )
  153.                 z = - 2.*p/3. + Compl( (-2.*t)**(1./3.) );
  154.             else
  155.                 z = - 2.*p/3. - Compl( (+2.*t)**(1./3.) );
  156.         }
  157.         else
  158.         {
  159.     // let w = u + v, then w^3 = -2*t - 3*s*w has form
  160.     // u^3 + v^3 + 3*u*v*(u+v) = -2*t - 3*s*(u+v)
  161.     // assuming u^3 + v^3 = -2*t and 3*u*v = -3*s
  162.     // then we have for f = u^3 and g = v^3:
  163.     // f + g = -2*t   ,   f*g = -s^3
  164.     // and (f-g)^2 = (f+g)^2 - 4*f*g = 4*t^2 + 4*s^3
  165.     // the linear system f - g = 2*sqrt(t^2+s^3) , f + g = -2*t
  166.     // has the solutions f = -t + sqrt(t^2+s^3), g = -t - sqrt(t^2+s^3)
  167.     // Now we can solve u,v and finally z = u + v - 2*p/3
  168.             h = SquareRoot( Compl(t*t+s*s*s) );
  169.             u = CubeRoot( -t + h);
  170.             v = -s/u;            // u*v = -s
  171.             z = u + v - 2.*p/3.; // theoretically z should be real
  172.         }
  173.     // Back to (y^2 + p/2 + z/2)^2 = z*( y - 0.5*q/z )^2, take the root    
  174.     // y^2 + p/2 + z/2 = µ*sqrt(z)*( y - 0.5*q/z ) with µ=+1 or µ=-1
  175.     // y^2 - µ*i*y = -p/2 - z/2 - µ*0.5*q/i  with i =sqrt(z)
  176.     // ( y - µ*i/2 )^2 = z/4 - p/2 - z/2 - µ*0.5*q/i), take the root
  177.     // y - µ*i/2 = #*0.5*sqrt(-z-2*p-µ*2*q/i ) with #=+1 or #=-1
  178.     // x = -a/4 + 0.5*( µ*i +#*sqrt(-z-2*p-µ*2*q/i ) )
  179.         i = SquareRoot(z);
  180.         j = SquareRoot( -z-2*p-2*q/i );
  181.         x1 = -a/4. + 0.5*( i + j ); // µ=+1, #=+1
  182.         x2 = -a/4. + 0.5*( i - j ); // µ=+1, #=-1
  183.         j = SquareRoot( -z-2*p+2*q/i );
  184.         x3 = -a/4. + 0.5*( -i + j ); // µ=-1, #=+1
  185.         x4 = -a/4. + 0.5*( -i - j ); // µ=-1, #=-1
  186.     }  
  187. //  log(x1.Re@x1.Im); log(x2.Re@x2.Im); log(x3.Re@x3.Im); log(x4.Re@x4.Im);
  188. //  x = x1; y = x*x*x*x + a*x*x*x + b*x*x + c*x + d; log(y.Re@y.Im);
  189. //  x = x2; y = x*x*x*x + a*x*x*x + b*x*x + c*x + d; log(y.Re@y.Im);
  190. //  x = x3; y = x*x*x*x + a*x*x*x + b*x*x + c*x + d; log(y.Re@y.Im);
  191. //  x = x4; y = x*x*x*x + a*x*x*x + b*x*x + c*x + d; log(y.Re@y.Im);
  192.     // choose the smallest positive real root
  193.     e = 1000000;
  194.     if ( abs(x1.Im) < 0.00005 && x1.Re >= 0 &&  x1.Re < e )
  195.         e =  x1.Re;
  196.     if ( abs(x2.Im) < 0.00005 && x2.Re >= 0 &&  x2.Re < e )
  197.         e =  x2.Re;
  198.     if ( abs(x3.Im) < 0.00005 && x3.Re >= 0 &&  x3.Re < e )
  199.         e =  x3.Re;
  200.     if ( abs(x4.Im) < 0.00005 && x4.Re >= 0 &&  x4.Re < e )
  201.         e =  x4.Re;
  202.     if ( e == 1000000 )
  203.         return 0;
  204.     else
  205.         return e;
  206. }
  207.  
  208. // returns the smallest positive solution x of a*x² + b*x + c = 0
  209. static function float SolveQuadratic(float a, float b, float c)
  210. {
  211.     local float d;
  212.  
  213.     if ( a != 1 )
  214.     {
  215.         b /= a;
  216.         c /= a;
  217.     }
  218.     a = b*b - 4*c;
  219.     if ( a < 0 )
  220.         return 0;
  221.     if ( c < 0 )
  222.         return 0.5*( -b + sqrt(a) );
  223.     else if ( b < 0 )
  224.         return 0.5*( -b - sqrt(a) );
  225.     else
  226.         return 0;
  227. }
  228.  
  229. // #################### AIM FUNCTION ################################
  230.  
  231. function Projectile ProjectileFire(class<projectile> ProjClass, float ProjSpeed, bool bWarn)
  232. {
  233.     local Vector Start, X,Y,Z;
  234.     local float qTime;
  235.     local Pawn qOwner;
  236.     local Actor qTarget;
  237.  
  238.     qOwner = Pawn(Owner);
  239.     if ( Owner.Target == none && qOwner != none )
  240.     {
  241.         if ( qOwner.enemy != none && !qOwner.enemy.bDeleteme && qOwner.enemy != self )
  242.             Owner.Target = qOwner.enemy;
  243.     }
  244.     qTarget = Owner.Target;
  245.     if ( qTarget == none || qOwner == none )
  246.         return Super.ProjectileFire(ProjClass,ProjSpeed, bWarn);
  247.  
  248.     GetAxes(qOwner.ViewRotation,X,Y,Z);
  249.     Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
  250.     // call own function instead of owner.AdjustToss()
  251.     AdjustedAim = SmartAim(ProjSpeed, -0.5*Region.Zone.ZoneGravity,
  252.                 qTarget.Velocity + qTarget.Base.Velocity - vect(0,0,120),
  253.                 qTarget.Location - Start, qTime); // <----
  254.     // PlayerPawn(qTarget).ClientMessage(qTarget.Base);
  255.     if ( qTime <= 0 )
  256.         return none; // target too far away or too far above
  257.     Owner.MakeNoise(Pawn(Owner).SoundDampening);
  258.     if ( (bWarn || FRand() < 0.4) && Pawn(Target) != None )
  259.         Pawn(Target).WarnTarget(qOwner, ProjSpeed, Normal(qTarget.Location - Start) );
  260.     return Spawn(ProjClass,,, Start, AdjustedAim);
  261. }
  262.  
  263. // solves equation t*v*d = 0.5*a*t² + b*t + c, where
  264. // d: unknown, normed (d dot d = 1) shooting direction, which will be returned as a rotator
  265. // t: unknown scalar standing for the time
  266. // v: scalar standing for the projetile speed
  267. // a: vector standing for the gravity
  268. // b: vector standing for the initial speeds, which are independent of shooting direction
  269. // c: vector standing for the distance to your target
  270. function rotator SmartAim(float v, vector a, vector b, vector c, optional out float t)
  271. {
  272.     // solution can be obtained via comparing the lenghts of both sides
  273.     // t²*v² = 0.25*a²*t^4 + (a dot b)*t^3 + (a dot c + b²)*t² + 2*(b dot c)*t + c²
  274.     // which is a quartic equation in t
  275.     // if we know t, we can easily calculate d
  276.     if ( a != vect(0,0,0) && b != vect(0,0,0) )
  277.         t = SolveQuartic(a dot a*0.25, a dot b, a dot c + b dot b - v*v , b dot c*2., c dot c);
  278.     else if ( a != vect(0,0,0) )
  279.         t = sqrt( SolveQuadratic(a dot a*0.25, a dot c - v*v, c dot c) );
  280.     else if ( b != vect(0,0,0) )
  281.         t = SolveQuadratic(b dot b - v*v, b dot c*2., c dot c);
  282.     else
  283.         t = vsize(c)/v;
  284.     return rotator(0.5*t*t*a + t*b + c);
  285. }
  286.  
  287. // return delta to combat style
  288. function float SuggestAttackStyle()
  289. {
  290.     return +0.3;
  291. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement