Could be asleep, typing random messages instead.

[UScript] Need help realizing that I'M AN IDIOT

For questions and discussion about UnrealEd, UnrealScript, and other aspects of Unreal Engine design.

Moderators: Semfry, ividyon

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 09 Dec 2012, 22:30

No, I mean directfire shots miss me by just a little bit while I'm strafing. They hit me dead-center if I'm immobile.

Indirect shots hit me fairly reliably, but often fire straight into the floor for some reason or overshoot me a bit. Not sure what that's about.

[Edit] All my tests so far have been in a huge, open flat cube with zero inaccuracy on the pawns that are firing at me. I've managed to make directfire leading a lot more accurate at short and medium range, but it just barely fails to hit me at long range when I'm strafing.
Image

User avatar integration
Skaarj Berserker Skaarj Berserker
Posts: 445
Joined: 01 Sep 2010, 12:37

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 09 Dec 2012, 23:58

"Indirect shots hit me fairly reliably, but often fire straight into the floor for some reason"
That happens when the calculation fails. See my second post in this thread for improvisations in this case.

"or overshoot me a bit"
I assume you are not jumping. What happens, when you try:

Code: Select all

FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -qGrav, -qVel + p.Target.Velocity, p.Target.Location - ProjStart);
return FireRotation;
// where qVel = vect(0,0,-1)*qspeedz
// or qVel = vect(0,0,-1)*qspeedz - p.Velocity when pawns velocity is added to the projectile

"directfire shots miss me by just a little bit while I'm strafing"
You mean, when bleadtarget = true? Which code? This one:

FireSpot += (p.Target.Velocity * VSize(p.Target.Location - ProjStart))/projSpeed;

Or that:

class'EXUMath'.static.SmartAim(projSpeed, vect(0,0,0), p.Target.Velocity, p.Target.Location - ProjStart, qTime);
FireSpot += p.Target.Velocity * qTime;

respectively

FireRotation = class'EXUMath'.static.SmartAim(projSpeed, vect(0,0,0), p.Target.Velocity, p.Target.Location - ProjStart);
return FireRotation;

For the later one, have you verified the correctness of projSpeed? Or is the projectile's velocity affected by the pawn's velocity?

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 10 Dec 2012, 00:54

Most EXUGenericProjectiles subclasses have a fixed projectile speed (velocity = vector(rotation) * speed; and nothing more). Some of them have bUsePawnSpeed set to true, a variable I added to EXUGenericProjectiles, where it does this check before setting the velocity:

Code: Select all

   if(ScriptedPawn(Instigator)!=None && bUsePawnSpeed==True )
      Speed = ScriptedPawn(Instigator).ProjectileSpeed;


Then it sets the velocity of the projectile using the pawn's ProjectileSpeed value instead of using the projectile's default speed value.

EXUScriptedPawns mostly utilize EXUFireProjectile, a function which does this:

Code: Select all

function EXUFireProjectile(vector StartOffset, float Accuracy)
{
   local vector projStart;
   local int i;
   local float projSpeed;

   projSpeed = class<Projectile>(RangedProjectile).default.Speed;
   if( ProjectileSpeed != projSpeed )
      projSpeed = ProjectileSpeed;

   projStart = Location + (StartOffset * DrawScale>>Rotation);

   for(i=0; i<ProjectilesPerShot; i++)
      spawn(RangedProjectile, self,, projStart, class'exustaticfuncs'.static.AdjustShot(self, projSpeed, projStart, Accuracy, bLeadTarget, bWarnTarget, RangedProjectile));
}


Before today, parameter 2 in AdjustShot (now projSpeed) was hardcoded to 0 for some reason, I guess to just grab the projectile's default speed, but I make it take into account the ACTUAL speed being used by the pawn with the projSpeed check. So it passes the ACTUAL speed to the AdjustShot function now, which results in much closer but still incorrect aim while strafing and bLeadTarget=true.


That leads us back to AdjustShot. I have logged a bunch of things and found that the speed WAS definitely being passed correctly from EXUFireProjectile to AdjustShot, so it's not using the wrong speed value. I've tried all the possible solutions you've posted, but so far haven't had much luck with any of them and I can't figure out why.

Here's where I stand now, with some comments added for clarity. With the code just like this, indirect fire more or less works at medium range and below, but long range overshoots by a significant margin, bigger the further away I am. Directfire is also just barely missing me when I strafe at long range; the pawn isn't leading me quite enough.

[spoiler]

Code: Select all

static final function rotator AdjustShot(pawn p, float projSpeed, vector projStart, optional int spread, optional bool leadTarget, optional bool warnTarget, optional class<actor> projclass)
{
   local rotator FireRotation;
   local vector FireSpot;
   local actor HitActor;
   local vector HitLocation, HitNormal;
   local float qSpeedZ, qTime;

   //log("Check #1: ProjSpeed (inherited) is "$ProjSpeed);

   if(projclass!=none && projSpeed<=0 && ClassIsChildOf(projclass,class'projectile') && class<projectile>(projclass).default.speed>0)
      projspeed = class<projectile>(projclass).default.speed;

   //log("Check #2: ProjSpeed is "$ProjSpeed);   // Confirmed: speed is inherited properly. These were the logs I used to check, and they always matched.

   if(p==none)
      return rot(0,0,0);
   if ( p.Target == None )
      p.Target = p.Enemy;
   if ( p.Target == None )
      return p.Rotation;

   if ( !p.Target.bIsPawn )
      return rotator(p.Target.Location - p.Location);
   FireSpot = p.Target.Location;


   if (leadTarget && (projSpeed > 0))
   {
      //FireSpot += (p.Target.Velocity * VSize(p.Target.Location - ProjStart))/projSpeed;   // original FireSpot code

      class'EXUMath'.static.SmartAim(projSpeed, vect(0,0,0), p.Target.Velocity, p.Target.Location - ProjStart, qTime); // new FireSpot code
      FireSpot += p.Target.Velocity * qTime;
      // this new code seems to work fairly well, though the pawn overshoots its target often whether I use this code or the old one

      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);

      //this just adjusts the fire destination if the predicted location is behind geometry or something
      if (HitActor != None)
         FireSpot = 0.5 * (FireSpot + p.Target.Location);
   }

   HitActor = p; //so will fail first check unless shooting at feet 
   if ( p.bIsPlayer && (p.Location.Z + 19 >= p.Target.Location.Z) && p.Target.bIsPawn
      && (p.Weapon != None) && p.Weapon.bSplashDamage && (0.5 * (p.skill - 1) > FRand()) )
   {
      // Try to aim at feet
       HitActor = p.Trace(HitLocation, HitNormal, FireSpot - vect(0,0,80), FireSpot, false);
      if ( HitActor != None )
      {
         FireSpot = HitLocation + vect(0,0,3);
         HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
      }
      else
         HitActor = p;
   }
   if ( HitActor != None )
   {
      //try middle
      FireSpot.Z = p.Target.Location.Z;
       HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
   }
   if( HitActor != None )
   {
      ////try head
       FireSpot.Z = p.Target.Location.Z + 0.9 * p.Target.CollisionHeight;
       HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
   }
   if ( (HitActor != None) && (p.Target == p.Enemy) )
   {
      FireSpot = p.LastSeenPos;
      if ( p.Location.Z >= p.LastSeenPos.Z )
         FireSpot.Z -= 0.5 * p.Enemy.CollisionHeight;
      if ( p.Weapon != None )
      {
          HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
         if ( HitActor != None )
         {
            p.bFire = 0;
            p.bAltFire = 0;
            if(p.isa('scriptedpawn'))
            p.SetTimer(scriptedpawn(p).TimeBetweenAttacks, false);
         }
      }
   }
   
//=========================Inserted Code, written by integration - thanks man! =========================================

   if ( ScriptedPawn(p).RangedProjectile!=None && ScriptedPawn(p).RangedProjectile.default.Physics==Phys_Falling && p.Region.Zone.bWaterZone==false )
   {
      if ( ClassIsChildOf(projclass,Class'EXUGenericProjectiles') && class<EXUGenericProjectiles>(projclass).default.AddedZVelocity>0 )
         qSpeedZ = class<EXUGenericProjectiles>(projclass).default.AddedZVelocity;
      else
         qSpeedZ = 0;

      FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -1.0*p.Region.Zone.ZoneGravity, vect(0,0,-1)*qSpeedZ, FireSpot - ProjStart, qTime);

      log("Initial qTime is "$qTime);   // This always winds up >0, so the following logs never appear:

      // qTime = 0 -> can't hit target -> try smaller distance
      if ( qTime <= 0 )
      {
         log("Attempt #1, trying smaller distance");
         FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -1.0*p.Region.Zone.ZoneGravity, vect(0,0,-1)*qSpeedZ, 0.75*(FireSpot - ProjStart), qTime);
         log("qTime #1 is "$qTime);
      }
      if ( qTime <= 0 )
      {
         log("Attempt #2, trying even smaller distance");
         FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -1.0*p.Region.Zone.ZoneGravity, vect(0,0,-1)*qSpeedZ, 0.50*(FireSpot - ProjStart), qTime);
         log("qTime #2 is "$qTime);
      }
      // qTime = 0 -> can't hit target -> shoot in 45 degree angle
      if ( qTime <= 0 )
      {
         log("Attempt #3, trying 45 degree angle");
         FireRotation.pitch = 8192;
      }

      FireRotation.yaw += p.randrange(-spread,spread);
      FireRotation.pitch += (4.0 - p.skill)*p.randrange(-spread,spread);
   }
   else
   {
      FireRotation = Rotator(FireSpot - ProjStart);
      FireRotation.yaw += p.randrange(-spread,spread);
      FireRotation.pitch += p.randrange(-spread,spread);
   }

//====================================End insert ========================================================================

   if (warnTarget && Pawn(p.Target) != None)
      Pawn(p.Target).WarnTarget(p, projSpeed, vector(FireRotation));

   FireRotation.Yaw = FireRotation.Yaw & 65535;

   if ( (Abs(FireRotation.Yaw - (p.Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (p.Rotation.Yaw & 65535)) < 57343) )
   {
      if ( (FireRotation.Yaw > p.Rotation.Yaw + 32768) || ((FireRotation.Yaw < p.Rotation.Yaw) && (FireRotation.Yaw > p.Rotation.Yaw - 32768)) )
         FireRotation.Yaw = p.Rotation.Yaw - 8192;
      else
         FireRotation.Yaw = p.Rotation.Yaw + 8192;
   }

   p.viewRotation = FireRotation;
         
   return FireRotation;
}
[/spoiler]

Am I missing anything? Should I be inserting stuff in specific places that are out of order? More details on exact location of where things go if I've messed something up would be appreciated, but I already do appreciate your help thus far, it's been a big improvement already! :) We're really close to getting this nailed down, too.

[Edit] Oh, also! Projectiles with very low speed, right now, fire straight into the ground almost. The pawn doesn't attempt to arc them properly. Only faster projectiles work. I've been switching between two pawns, one that shoots slower-moving fireballs (1200 default speed, 2000 max) and one that shoots high-speed plasma projectiles (2900 speed, 3000 max). The higher speed ones work fine, but the low-speed ones are incapable of hitting beyond a very small radius around the pawn that shoots them. It's not the pawn or projectile, either, as I tried swapping the projectiles' speed values and even the two pawns' projectile types and confirmed it's the speed causing it.
Image

User avatar integration
Skaarj Berserker Skaarj Berserker
Posts: 445
Joined: 01 Sep 2010, 12:37

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 10 Dec 2012, 12:35

1200 speed is slower moving? LOL. I would always take a safety distance from default speed to max speed. Speed might be modified by the pawn's skill. Additionally, indirect projectiles can become faster (when they fall down or use some additional vertical speed). I suggest also logging the projectile's real velocity (see the MyBioGel code example somewhere in this thread).

Your ExuFireProjectile() function looks a bit strange. Are you aware, that you always set projSpeed to ProjectileSpeed? This could be better:

Code: Select all

function EXUFireProjectile(vector StartOffset, float Accuracy)
{
   local vector projStart;
   local int i;
   local float projSpeed;
   local class<EXUGenericProjectiles> qClass;

   projSpeed = ProjectileSpeed;
   qClass = class<EXUGenericProjectiles>(RangedProjectile);
   if ( qClass != none )
   {
      if ( qClass.default.bUsePawnSpeed == false )
         projSpeed = qClass.default.speed;
      if ( projSpeed > qClass.default.maxSpeed && qClass.default.maxSpeed > 0 )
         projSpeed = qClass.default.maxSpeed;
   }

   projStart = Location + (StartOffset * DrawScale>>Rotation);

   for(i=0; i<ProjectilesPerShot; i++)
      spawn(RangedProjectile, self,, projStart, class'exustaticfuncs'.static.AdjustShot(self, projSpeed, projStart, Accuracy, bLeadTarget, bWarnTarget, RangedProjectile));
}

I tried to rewrite AdjustShot() a bit for indirect fire. However, it should still behave like before for direct fire. I also added some anti-bunnyjump code. The code is untested (like always).

[spoiler]

Code: Select all

static final function rotator AdjustShot(pawn p, float projSpeed, vector projStart, optional int spread, optional bool leadTarget, optional bool warnTarget, optional class<actor> projclass)
{
   local rotator FireRotation;
   local vector FireSpot;
   local actor HitActor;
   local vector HitLocation, HitNormal;

   local float qTime;  // after how many seconds does the projectile hit the target?
   local bool bGrav;   // projectile affected by gravity?
   local bool bJump;   // does the target jump?
   local class<EXUGenericProjectiles> qClass;
   local class<Projectile> qClass2;
   local vector qProj; // projectile's velocity which isn't influenced by the firerotation
   local vector qTarg; // target's velocity with qTarg.z set to 0 if target is jumping
   local vector qGrav; // gravimetrical infuence of the projectile
   local float qVert;  // target's expected vertical position change

   log("Check #1: ProjSpeed (inherited) is "$ProjSpeed);

   //if(projclass!=none && projSpeed<=0 && ClassIsChildOf(projclass,class'projectile') && class<projectile>(projclass).default.speed>0)
   //   projspeed = class<projectile>(projclass).default.speed;

   if(p==none)
      return rot(0,0,0);
   if ( p.Target == None )
      p.Target = p.Enemy;
   if ( p.Target == None )
      return p.Rotation;

   if ( !p.Target.bIsPawn )
      return rotator(p.Target.Location - p.Location);
   FireSpot = p.Target.Location;

   if ( projClass != none )
      qClass2 = class<Projectile>(projClass);
   else if ( p.Weapon != none )
      qClass2 = p.Weapon.projectileClass;
   else
      qClass2 = class<Projectile>(ScriptedPawn(p).RangedProjectile);
   qClass = class<EXUGenericProjectiles>(qClass2);
   
   bGrav = ( qClass2!=none && qClass2.default.Physics==Phys_Falling && p.Region.Zone.bWaterZone==false );
   if ( bGrav )
   {
      qGrav = p.Region.Zone.ZoneGravity;
      if ( qClass2.default.bBounce == true )
         qGrav *= 0.5;

      if ( qClass != none && qClass.default.AddedZVelocity>0 )
         qProj += vect(0,0,1) * qClass.default.AddedZVelocity;
   }
   //if ( qClass != none && qClass.default.bAddPawnSpeed )
   //   qProj += p.velocity;
   qTarg = p.Target.Velocity;
   bJump = ( p.Target.Physics==Phys_Falling );
   if ( bJump )
      qTarg.z = 0;

   if ( leadTarget && projSpeed > 0 )
   {
      //FireSpot += (p.Target.Velocity * VSize(p.Target.Location - ProjStart))/projSpeed;   // original FireSpot code

      class'EXUMath'.static.SmartAim(projSpeed, -qGrav, qTarg - qProj, FireSpot - ProjStart, qTime); // new FireSpot code
      FireSpot += qTarg * qTime;

      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);

      // this just adjusts the fire destination if the predicted location is behind geometry or something
      if (HitActor != None)
         FireSpot = 0.5 * (FireSpot + p.Target.Location);
   }

   if ( bJump && leadTarget )
   {
      // don't let you fool by jumping targets 
      qVert = p.Target.Region.Zone.ZoneGravity.z*0.5*qTime*qTime + p.Target.Velocity.z*qTime;
      if ( qVert > 0 )
         FireSpot.z += qVert;
      else
      {
         // target still in air when projectile hits?
         HitActor = p.Trace(HitLocation, HitNormal, FireSpot + vect(0,0,1)*(qVert-p.Target.collisionHeight), FireSpot, false);
         if ( HitActor != None && VSize(HitLocation-FireSpot) > p.Target.collisionHeight )
            FireSpot = HitLocation + vect(0,0,1)*p.Target.collisionHeight;  // hitlocation is the ground below target
         else if (HitActor == None )
            FireSpot.z += qVert;
      }
   }

   HitActor = p; //so will fail first check unless shooting at feet 
   if ( p.bIsPlayer && (p.Location.Z + 19 >= p.Target.Location.Z) && p.Target.bIsPawn
      && (p.Weapon != None) && p.Weapon.bSplashDamage && (0.5 * (p.skill - 1) > FRand()) )
   {
      // Try to aim at feet
      HitActor = p.Trace(HitLocation, HitNormal, FireSpot - vect(0,0,80), FireSpot, false);
      if ( HitActor != None )
      {
         FireSpot = HitLocation + vect(0,0,3);
         HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
      }
      else
         HitActor = p;
   }
   if ( HitActor != None )
   {
      // try middle
      //FireSpot.Z = p.Target.Location.Z;
      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
   }
   if( HitActor != None )
   {
      // try head
      //FireSpot.Z = p.Target.Location.Z + 0.9 * p.Target.CollisionHeight;
      FireSpot.Z += 0.9 * p.Target.CollisionHeight;
      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
   }
   if ( (HitActor != None) && (p.Target == p.Enemy) )
   {
      FireSpot = p.LastSeenPos;
      if ( p.Location.Z >= p.LastSeenPos.Z )
         FireSpot.Z -= 0.5 * p.Enemy.CollisionHeight;
      if ( p.Weapon != None )
      {
          HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
         if ( HitActor != None )
         {
            p.bFire = 0;
            p.bAltFire = 0;
            if(p.isa('scriptedpawn'))
            p.SetTimer(scriptedpawn(p).TimeBetweenAttacks, false);
         }
      }
   }
   
   if ( bGrav )
   {
      // this call might be redundant if bleadtarget=true and firespot hasn't chance since the first call
      // qTarg isn't in the formular because FireSpot has been changed according to it
      FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -qGrav, -qProj, FireSpot - ProjStart, qTime);
      //log( "Calc Error =" @ VSize(qGrav*0.5*qTime*qTime + (qProj+Vector(FireRotation)*projSpeed)*qTime + ProjStart - FireSpot) );

      log("Initial qTime is "$qTime);   // This always winds up >0, so the following logs never appear:
      // qTime = 0 -> can't hit target -> try smaller distance
      if ( qTime <= 0 )
      {
         log("Attempt #1, trying smaller distance");
         FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -qGrav, -qProj, 0.8*(FireSpot - ProjStart), qTime);
         log("qTime #1 is "$qTime);
      }
      if ( qTime <= 0 )
      {
         log("Attempt #2, trying even smaller distance");
         FireRotation = class'EXUMath'.static.SmartAim(projSpeed, -qGrav, -qProj, 0.6*(FireSpot - ProjStart), qTime);
         log("qTime #2 is "$qTime);
      }
      // qTime = 0 -> can't hit target -> shoot in 45 degree angle
      if ( qTime <= 0 )
      {
         log("Attempt #3, trying 45 degree angle");
         FireRotation.pitch = 8192;
      }

      //FireRotation.yaw += p.randrange(-spread,spread);
      //FireRotation.pitch += (4.0 - p.skill)*p.randrange(-spread,spread);
   }
   else
   {
      FireRotation = Rotator(FireSpot - ProjStart);
      //FireRotation.yaw += p.randrange(-spread,spread);
      //FireRotation.pitch += p.randrange(-spread,spread);
   }

   if (warnTarget && Pawn(p.Target) != None)
      Pawn(p.Target).WarnTarget(p, projSpeed, vector(FireRotation));

   FireRotation.Yaw = FireRotation.Yaw & 65535;

   if ( (Abs(FireRotation.Yaw - (p.Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (p.Rotation.Yaw & 65535)) < 57343) )
   {
      if ( (FireRotation.Yaw > p.Rotation.Yaw + 32768) || ((FireRotation.Yaw < p.Rotation.Yaw) && (FireRotation.Yaw > p.Rotation.Yaw - 32768)) )
         FireRotation.Yaw = p.Rotation.Yaw - 8192;
      else
         FireRotation.Yaw = p.Rotation.Yaw + 8192;
   }

   p.viewRotation = FireRotation;
         
   return FireRotation;
}
[/spoiler]

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 10 Dec 2012, 13:55

Yeah, I'm aware of that for now. The reason is that a lot of projectiles actually are supposed to be slower than their default speed, and some of them are supposed to be faster, so I let the pawn override the speed value for any projectile that supports it (most EXUGenericProjectiles do not, and have a fixed speed. Only certain subclasses are modifiable by the pawn for the sake of balance).

Really, this is sort of a huge mess in EXU and I will have to clean it up at some point. Not the first time I've had to do some major cleaning, either :P

I will give your new AdjustShot stuff a try today and see how it goes :tup:
Image

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 10 Dec 2012, 23:08

OK, after testing the new code, it wasn't working for indirect fire. All indirect projectiles fell to the ground immediately with no arc trajectory to speak of. Directfire was unchanged.

I switched back to the old, then the new again... and I tried out the code you suggested for the projectiles to see what their actual speed is. I noticed that with each shot, the speed was actually slightly higher than the default, 2000:

ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 0.776094
ScriptLog: Speed = 2097.705322
ScriptLog: Gravity = 442.683350
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 0.938366
ScriptLog: Speed = 2090.522461
ScriptLog: Gravity = 481.596771
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 0.990759
ScriptLog: Speed = 2088.017578
ScriptLog: Gravity = 472.707947
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 0.978381
ScriptLog: Speed = 2087.865723
ScriptLog: Gravity = 469.710663

Gravity changes a lot too, for some reason, but what I thought was happening was the pawn adding its OWN velocity to the shot. I've been testing this with Gasbags, and they are always firing when moving. However, I tested out a Krall with the same projectile set to bMovingRangedAttack=False, and got the same sort of speed discrepancy. So it seems that SOMETHING is influencing the speed a small amount, but it's not the pawn's own movement as far as I can tell. Even on a TENTACLE it changes:

ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 1.394187
ScriptLog: Speed = 2099.437500
ScriptLog: Gravity = 481.893616
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 1.578831
ScriptLog: Speed = 2091.280762
ScriptLog: Gravity = 463.800537
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 1.765386
ScriptLog: Speed = 2083.833740
ScriptLog: Gravity = 479.546417
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 1.948390
ScriptLog: Speed = 2077.042236
ScriptLog: Gravity = 467.322937
ScriptLog: Check #1: ProjSpeed (inherited) is 2000.000000
ScriptLog: Initial qTime is 1.949514
ScriptLog: Speed = 2077.042236
ScriptLog: Gravity = 488.790894

So I am kind of at a loss here, but I think this IS what is causing the pawns to overshoot at long range. Something is adding more velocity to the projectile than they should have and the pawns are failing to take that into account. The projectile may also have acceleration of some sort, but I sure as hell haven't defined any, unless that's done natively. I can't find any code that would influence projectile speed.

Similarly, I even set MaxSpeed identical to Speed and still saw speed discrepancies, so it's not like it floats between Speed and MaxSpeed.

Any clues what to do next? The earlier version of AdjustShot (not the latest one) definitely works the best, save for the slight offset due to the projectile speeds.

Hell, I even summoned a bunch of plasma balls manually and those are going way over the MaxSpeed value! I was standing completely still while summoning these.

ScriptLog: Fabricate EXU.medplasmaballsp
ScriptLog: Speed = 2300.000000
ScriptLog: Gravity = 742.360535
ScriptLog: Fabricate EXU.medplasmaballsp
ScriptLog: Speed = 2300.000000
ScriptLog: Gravity = 810.047180
ScriptLog: Fabricate EXU.medplasmaballsp
ScriptLog: Speed = 2300.000000
ScriptLog: Gravity = 810.877014
ScriptLog: Fabricate EXU.medplasmaballsp
ScriptLog: Speed = 2300.000000
ScriptLog: Gravity = 814.243042



No idea what the deal is here!
Image

User avatar integration
Skaarj Berserker Skaarj Berserker
Posts: 445
Joined: 01 Sep 2010, 12:37

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 11 Dec 2012, 00:46

Hm... perhaps I have a wrong sign (+ instead of - or vice versa) somewhere in the new code.

For the first 2 projectiles gravity is obviously halved. Though the gravity for the last one looks strange. It's between 0.5g and 1g. About the speeds: Are you sure you have substracted the extra vertical speed correctly? If you haven't substracted it, you'd get uneven, different numbers (numbers are dependent of the projectile's initial pitch). It also would be nice if you log the values more than 1 time for each projectile.

Code: Select all

var vector qSpeed;
var vector qAccel;
var vector qTime;

event Tick( float DeltaTime )
{
   if ( qAccel == vect(0,0,0) )
   {
      if ( qSpeed == vect(0,0,0) )
         qSpeed = Velocity;
      else
      {
         qAccel = (Velocity - qSpeed)/DeltaTime;
         log( "Speed =" @ qSpeed.x @ qSpeed.y @ qSpeed.z );
         log( "Speed =" @ VSize( qSpeed - vect(0,0,1)*AddedZVelocity ) );
         log( "Gravity =" @ VSize(qAccel) );
      }
   }
   qTime += deltaTime
   if ( qTime > 0.2 )
  {
      qTime = 0;
      qSpeed = vect(0,0,0);
      qAccel = vect(0,0,0);
  }
}


Anyway, if you don't know any further, I could have a try on it. You'd have to give me the EXU system files and the map where you're testing it. I have no EXU installed.

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 11 Dec 2012, 18:28

I would appreciate that. However, the EXU2 source is massive and has like 2,500 files, so how about I make a test package with JUST the code we're actually dealing with?

I think this is probably enough to actually replicate the problem:
TScriptedPawn
TStaticFuncs
TMath
TGasbag
TSkaarj
TGenericProjectiles
TIndirectProj
TDirectProj

[Edit] Here we go: http://www.mediafire.com/?fwmr8fs3fq8s0lh

Add TEXU to your EditPackages and recompile. There's a few extra classes but not many, just for organization mainly. I have them more or less exactly the same as my classes are right now in EXU and I tested them to be sure the behavior was similar. The TEXU.TestSkaarj is useful for testing directfire aim while the TEXU.TestGasbag is using the indirect projectile right now.

Let me know if you need anything else and thanks so much for your time on this!
Image

User avatar integration
Skaarj Berserker Skaarj Berserker
Posts: 445
Joined: 01 Sep 2010, 12:37

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 11 Dec 2012, 21:58

Nice code compiler batch file you have there. The Skaarj's direct fire always hit me when walking in the same direction (I blocked him from moving towards me). Did you use another gametype? For the inderect projectile I changed gravity to 0.5g in the old code, because bBounce was true. Then the gasbag always hit me when I was standing still. Though it misaimed very much, when I was moving. I feared more bad things because of your comments. I am confident, that I can eliminate the flaws. I will call back tomorrow.

User avatar []KAOS[]Casey
Skaarj Berserker Skaarj Berserker
Posts: 426
Joined: 25 Sep 2008, 07:25

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 12 Dec 2012, 12:31

also keep in mind acceleration on the projectiles might be playing a factor {It doesn't always, and I don't know of any projectiles with a -Z accel ever}

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 12 Dec 2012, 13:56

[]KAOS[]Casey wrote:also keep in mind acceleration on the projectiles might be playing a factor {It doesn't always, and I don't know of any projectiles with a -Z accel ever}


Is accel handled natively? If not, what actually controls it? I can't find anything governing projectile acceleration, but I have seen it happen, especially deceleration in waterzones (another thing I suspect may be native and unmodifiable for my purposes without something super lame like a velocity override in tick).
Image

User avatar integration
Skaarj Berserker Skaarj Berserker
Posts: 445
Joined: 01 Sep 2010, 12:37

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 12 Dec 2012, 18:30

Pawns have accelrate which must be handled natively by the code. Projectiles don't have that variable, but they have the Acceleration variable too (lol why didn't I use that). When I look at the projectile movement properties, I don't know any variables which should affect it (before trying out GesbioAim I wouldn't have thought either that bBounce would affect gravity).

I used that code to log the projectile's speed.

Code: Select all

var vector qSpeed;
var vector qAccel;
var float qTime;
var float qInitTime;

event Tick( float DeltaTime )
{
   if ( qInitTime == 0 )
      qInitTime = Level.TimeSeconds;
   if ( qAccel == vect(0,0,0) )
   {
      if ( qSpeed == vect(0,0,0) )
         qSpeed = Velocity;
      else
      {
         qAccel = (Velocity - qSpeed)/DeltaTime;
         if ( Level.TimeSeconds - DeltaTime - qInitTime < 0.01 )
         {
            log( "Init Speed =" @ VSize( Velocity - vect(0,0,1)*AddedZVelocity ) );
            //log( "Max Speed  =" @ maxspeed );
         }
         //log( "Time =" @ Level.TimeSeconds - DeltaTime - qInitTime );
         //log( "Velo =" @ qSpeed.z @ Sqrt(Square(qSpeed.x)+Square(qSpeed.y)) );
         log( "Norm =" @ VSize(qSpeed) );
         //log( "Grav =" @ qAccel.z @ Sqrt(Square(qAccel.x)+Square(qAccel.y)) );
      }
   }
   qTime += deltaTime;
   if ( qTime > 0.1 )
   {
      qTime = 0;
      qSpeed = vect(0,0,0);
      qAccel = vect(0,0,0);
   }
}

On later stages, I always got the expected values for initial speed and inflight speed. However, I got strange results when I tested it for the first time with a 2900 default speed projectile (3000 maxspeed).

ScriptLog: Init Speed = 2899.999756
ScriptLog: Time = 0.000000
ScriptLog: Velo = 380.050171 2894.405029
ScriptLog: Norm = 2919.249756
ScriptLog: Grav = -988.773987 6570.732910
ScriptLog: Time = 0.105721
ScriptLog: Velo = 225.832550 2479.742920
ScriptLog: Norm = 2490.005127
ScriptLog: Grav = -587.409424 0.100299
ScriptLog: Time = 0.208897
ScriptLog: Velo = 128.481842 2479.734863
ScriptLog: Norm = 2483.061035
ScriptLog: Grav = -689.820862 0.398293

As you can see on the first gravity value, the projectile's velocity was immeaditely downsized in the first frame, probably down to 2500. Back then I logged the values in 2 successive frames. As said before I couldn't reproduce it later. It seems, the logs caused lags, which resulted in wrong velocity. More logs also made the accelation values instable. When I tried only logging gravity I always got values between -450 and -500. Must be some kind of Heisenberg uncertainty principle. :)

Now, I come to Adjustshot. I had no problems with the newer code. The projectile always hit me, when it should - after I used the correct projectilespeed values. Your pawn gave back its projectilespeed when it should use the projectile's value (the bUseSpawnSpeed prompt is also missing in TInderectProjectile). I post again the code example from above.

Code: Select all

function EXUFireProjectile(vector StartOffset, float Accuracy)
{
   local vector projStart;
   local int i;
   local float projSpeed;
   local class<EXUGenericProjectiles> qClass;

   projSpeed = ProjectileSpeed;
   qClass = class<EXUGenericProjectiles>(RangedProjectile);
   if ( qClass != none )
   {
      if ( qClass.default.bUsePawnSpeed == false )
         projSpeed = qClass.default.speed;
      if ( projSpeed > qClass.default.maxSpeed && qClass.default.maxSpeed > 0 )
         projSpeed = qClass.default.maxSpeed;
   }

   projStart = Location + (StartOffset * DrawScale>>Rotation);

   for(i=0; i<ProjectilesPerShot; i++)
      spawn(RangedProjectile, self,, projStart, class'exustaticfuncs'.static.AdjustShot(self, projSpeed, projStart, Accuracy, bLeadTarget, bWarnTarget, RangedProjectile));
}


I tried to modify the AdjustShot code a little. The outcommented code tries to randomize the firerotation. I don't know if these changes are desirable. And I tried the execution pf a redundant smartaim call. As said before, a call of SmartAim(projSpeed,gravity,extraspeed,...) is expensive with gravity and extraspeed unequal 0 both, as a quartic equation is solved.

[spoiler]

Code: Select all

static final function rotator AdjustShot(pawn p, float projSpeed, vector projStart, optional int spread, optional bool leadTarget, optional bool warnTarget, optional class<actor> projclass)
{
   local rotator FireRotation;
   local vector FireSpot;
   local actor HitActor;
   local vector HitLocation, HitNormal;

   local float qTime;  // after how many seconds does the projectile hit the target?
   local bool bGrav;   // projectile affected by gravity?
   local bool bJump;   // does the target jump?
   local class<TGenericProjectiles> qClass;
   local class<Projectile> qClass2;
   local vector qProj; // projectile's velocity which isn't influenced by the firerotation
   local vector qTarg; // target's velocity with qTarg.z set to 0 if target is jumping
   local vector qGrav; // gravimetrical infuence of the projectile
   local float qVert;  // target's expected vertical position change
   local bool bReuseAim; // do I have to call Smartaim again?

   //log("ProjSpeed (inherited) is "$ProjSpeed);

   if (p == none )
      return rot(0,0,0);
   if ( p.Target == None )
      p.Target = p.Enemy;
   if ( p.Target == None )
      return p.Rotation;

   if ( !p.Target.bIsPawn )
      return rotator(p.Target.Location - p.Location);
   FireSpot = p.Target.Location;

   if ( projClass != none )
      qClass2 = class<Projectile>(projClass);
   else if ( p.Weapon != none )
      qClass2 = p.Weapon.projectileClass;
   else
      qClass2 = class<Projectile>(ScriptedPawn(p).RangedProjectile);
   qClass = class<TGenericProjectiles>(qClass2);

   if ( projSpeed <= 0 ) // verify that projSpeed > 0
      if ( qClass2 != none && qClass2.default.speed > 0 )
         projSpeed = qClass2.default.speed;
      else
         projSpeed = 1500;
   
   bGrav = ( qClass2!=none && qClass2.default.Physics==Phys_Falling && p.Region.Zone.bWaterZone==false );
   if ( bGrav )
   {
      qGrav = p.Region.Zone.ZoneGravity;
      if ( qClass2.default.bBounce == true )
         qGrav *= 0.5;

      if ( qClass != none && qClass.default.AddedZVelocity>0 )
         qProj += vect(0,0,1) * qClass.default.AddedZVelocity;
   }
   //if ( qClass != none && qClass.default.bAddPawnSpeed )
   //   qProj += p.velocity;
   qTarg = p.Target.Velocity;
   bJump = ( p.Target.Physics==Phys_Falling );
   if ( bJump )
      qTarg.z = 0;

/*
   qTime = VSize(FireSpot - ProjStart)/projSpeed; // estimated time until impact
   if ( !bJump && leadTarget && qTime > 0.7 ) // randomize  target's predicted speed   
   {
      if ( VSize(qTarg) > 50 )
      {
         if ( FRand() < 0.5 ) // 50 % chance to aim somewhere else
            qTarg *= 0.2 + 0.7*FRand(); // multiply by a number between 0.2 and 0.9
      }
      else if ( Pawn(p.Target) != none && FRand() < 0.5 ) // 50 % chance to aim somewhere else
      {
         qTarg = Normal( (FireSpot - ProjStart) Cross vect(0,0,1) ); // horizontal, orthogonal to FireSpot - ProjStart

         if ( Pawn(p.Target). bIsPlayer && ( qTime < 1.5 || (qTime<2.0 && FRand()<0.5) ) )
          {
            FireSpot += (2*rand(2)-1)*280*qTarg; // assume player makes a dodgejump
            qTarg *= 0.4;
         }
         else
         {
            if ( FRand() < 0.3 )
               qTarg *= (2*rand(2)-1); // assume target strafes left or right
            else
            {
               //qVert = 2*pi*FRand(); // qVert is an angle between 0° and 360°
               qVert = rand(8)*0.25*pi; // qVert is 0,45,90,135,180,225,270 or 315 degree angle
               qTarg = cos(qVert)*qTarg + sin(qVert)*Normal(FireSpot - ProjStart); // horizontal and normed
            }
            if ( p.Target.Physics == Phys_Swimming )
               qTarg *= Pawn(p.Target).WaterSpeed;
            else if ( p.Target.Physics == Phys_Flying )
               qTarg *= Pawn(p.Target).AirSpeed;
            else
               qTarg *= Pawn(p.Target).GroundSpeed;
            qTarg *= 0.1 + 0.6*FRand(); // multiply by a number between 0.1 and 0.7
         }
      }
   }
*/

   //log( "jumping   =" @ bJump );
   //log( "projSpeed =" @ projSpeed );
    //log( "Gravity   =" @ qgrav.x @ qgrav.y @ qgrav.z );
    //log( "TargVelo  =" @ VSize(qTarg) );
   //log( "ProjConst =" @ qproj.x @ qproj.y @ qproj.z );

   if ( leadTarget )
   {
      //FireSpot += (p.Target.Velocity * VSize(p.Target.Location - ProjStart))/projSpeed;   // original FireSpot code

      FireRotation = class'TMath'.static.SmartAim(projSpeed, -qGrav, qTarg - qProj, FireSpot - ProjStart, qTime); // new FireSpot code
      FireSpot += qTarg * qTime;
      //log( "Calc Error =" @ VSize(qGrav*0.5*qTime*qTime + (qProj+Vector(FireRotation)*projSpeed)*qTime + ProjStart - FireSpot) );

      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
      // this just adjusts the fire destination if the predicted location is behind geometry or something
      if (HitActor != None)
         FireSpot = 0.5 * (FireSpot + p.Target.Location);
      else
         bReuseAim = true;
   }

   if ( bJump && leadTarget )
   {
      // don't be fooled by jumping targets
      bReuseAim = false;
      qVert = p.Target.Region.Zone.ZoneGravity.z*0.5*qTime*qTime + p.Target.Velocity.z*qTime;
      if ( qVert > 0 )
         FireSpot.z += qVert;
      else
      {
         // target still in air when projectile hits?
         HitActor = p.Trace(HitLocation, HitNormal, FireSpot + vect(0,0,1)*(qVert-p.Target.collisionHeight), FireSpot, false);
         if ( HitActor != None && VSize(HitLocation-FireSpot) > p.Target.collisionHeight )
            FireSpot = HitLocation + vect(0,0,1)*p.Target.collisionHeight;  // hitlocation is the ground below target
         else if (HitActor == None )
            FireSpot.z += qVert;
      }
   }

   HitActor = p; //so will fail first check unless shooting at feet
   if ( p.bIsPlayer && (p.Location.Z + 19 >= p.Target.Location.Z) && p.Target.bIsPawn
      && (p.Weapon != None) && p.Weapon.bSplashDamage && (0.5 * (p.skill - 1) > FRand()) )
   {
      // Try to aim at feet
      HitActor = p.Trace(HitLocation, HitNormal, FireSpot - vect(0,0,80), FireSpot, false);
      if ( HitActor != None )
      {
         bReuseAim = false;
         FireSpot = HitLocation + vect(0,0,3);
         HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
      }
      else
         HitActor = p;
   }
   if ( HitActor != None )
   {
      // try middle
      //FireSpot.Z = p.Target.Location.Z;
      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
   }
   if( HitActor != None )
   {
      // try head
      //FireSpot.Z = p.Target.Location.Z + 0.9 * p.Target.CollisionHeight;
      bReuseAim = false;
      FireSpot.Z += 0.9 * p.Target.CollisionHeight;
      HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
   }
   if ( (HitActor != None) && (p.Target == p.Enemy) )
   {
      // try last seen position
      bReuseAim = false;
      FireSpot = p.LastSeenPos;
      if ( p.Location.Z >= p.LastSeenPos.Z )
         FireSpot.Z -= 0.5 * p.Enemy.CollisionHeight;
      if ( p.Weapon != None )
      {
          HitActor = p.Trace(HitLocation, HitNormal, FireSpot, ProjStart, false);
         if ( HitActor != None )
         {
            p.bFire = 0;
            p.bAltFire = 0;
            if(p.isa('scriptedpawn'))
            p.SetTimer(scriptedpawn(p).TimeBetweenAttacks, false);
         }
      }
   }
   
   if ( bGrav )
   {
      // this call might be redundant if bleadtarget=true and firespot hasn't chance since the first call
      // qTarg isn't in the formular because FireSpot has been changed according to it
      if ( bReuseAim == false )
      {
         FireRotation = class'TMath'.static.SmartAim(projSpeed, -qGrav, -qProj, FireSpot - ProjStart, qTime);
         //log( "Calc Error =" @ VSize(qGrav*0.5*qTime*qTime + (qProj+Vector(FireRotation)*projSpeed)*qTime + ProjStart - FireSpot) );
      }
      //log("Initial qTime is "$qTime);   // This always winds up >0, so the following logs never appear:
      // qTime = 0 -> can't hit target -> try smaller distance
      if ( qTime <= 0 )
      {
         FireRotation = class'TMath'.static.SmartAim(projSpeed, -qGrav, -qProj, 0.8*(FireSpot - ProjStart), qTime);
         //log("Attempt #1, trying smaller distance, qTime #1 is "$qTime);
      }
      if ( qTime <= 0 )
      {
         FireRotation = class'TMath'.static.SmartAim(projSpeed, -qGrav, -qProj, 0.6*(FireSpot - ProjStart), qTime);
         //log("Attempt #2, trying even smaller distance, qTime #2 is "$qTime);
      }
      // qTime = 0 -> can't hit target -> shoot in 45 degree angle
      if ( qTime <= 0 )
      {
         //log("Attempt #3, trying 45 degree angle");
         FireRotation.pitch = 8192;
      }

      //FireRotation.yaw += p.randrange(-spread,spread);
      //FireRotation.pitch += (4.0 - p.skill)*p.randrange(-spread,spread);
   }
   else
   {
      FireRotation = Rotator(FireSpot - ProjStart);
      //FireRotation.yaw += p.randrange(-spread,spread);
      //FireRotation.pitch += p.randrange(-spread,spread);
   }

   if (warnTarget && Pawn(p.Target) != None)
      Pawn(p.Target).WarnTarget(p, projSpeed, vector(FireRotation));

   FireRotation.Yaw = FireRotation.Yaw & 65535;

   if ( (Abs(FireRotation.Yaw - (p.Rotation.Yaw & 65535)) > 8192) && (Abs(FireRotation.Yaw - (p.Rotation.Yaw & 65535)) < 57343) )
   {
      if ( (FireRotation.Yaw > p.Rotation.Yaw + 32768) || ((FireRotation.Yaw < p.Rotation.Yaw) && (FireRotation.Yaw > p.Rotation.Yaw - 32768)) )
         FireRotation.Yaw = p.Rotation.Yaw - 8192;
      else
         FireRotation.Yaw = p.Rotation.Yaw + 8192;
   }

   p.viewRotation = FireRotation;
         
   return FireRotation;
}
[/spoiler]
Last edited by integration on 12 Dec 2012, 18:51, edited 1 time in total.

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 12 Dec 2012, 18:36

I'll give this a shot tonight. Thanks so much for pursuing this.
Image

User avatar Buff Skeleton
>:E >:E
Posts: 4173
Joined: 15 Dec 2007, 00:46

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 14 Dec 2012, 04:42

OK, sorry I didn't get to this last night. I applied the new AdjustShot code you just posted to TEXU and applied the EXUFireProjectile code you used above (made sure the references were correct) and I'm still having the same problems with direct and indirect, although indirect is falling short somewhat differently. Were you able to get pawns to hit you when you were moving in a straight line perpendicular to the enemies? Or were you just standing still?

Directfire looks like this (forgive my shitty MSPaint skills):

Image

When I move perpendicular to the Skaarj, it is only able to hit me at very short range when leading the target. Otherwise, its shots lag behind me but NOT by very much. It's failing to account for something, some small amount of lead distance. It's not aiming for exactly where I am, because even far away it only misses by a short amount. It almost misses by the same amount no matter the distance. This happens if I strafe in a single direction without changing direction; in theory, the Skaarj should hit me with every shot by leading its shots when I don't change my movement speed or direction, but it ALWAYS falls short. This is the problem I've been having all along.


Indirect is falling short regardless of whether I'm moving or stationary:

Image

It's not like it's hitting a maximum distance, either. It falls short no matter how far I am once I'm beyond very short range, so it CAN shoot out far, but it just isn't. Though the degree with which it falls short increases the farther away I am.

As far as bUsePawnSpeed being missing in the indirect projectile, not all projectiles use that, so I was simulating the situation I had before. It's meant to be an example of a projectile with a fixed speed that the pawn cannot (or should not be able to) change, so there is no code for it nor is it set to true in the defaults. Only the directfire projectile should use that for the sake of testing.

Here's an updated source of the test files so you can see what I've done if you want to be sure we're on the same page:
http://www.mediafire.com/?sd7am9c7v176r5r


This is somewhat unrelated, too, but I think it's really interesting and important to note that logging seems to mess with the actual speed. I know that logging can influence the game in some ways, but never knew it could alter projectile speed so significantly! It's like how you can't measure a photon without destroying it, in a sense :)
Image

User avatar ividyon
Administrator Administrator
Posts: 2354
Joined: 12 Nov 2007, 14:43
Location: Germany
Contact:

Subject: Re: [UScript] Need help putting integration's indirectfire code into pawn aiming AI

Post Posted: 14 Dec 2012, 09:51

So basically, EXU wasn't even the hardest it could be yet because monsters would not fire projectiles precisely? :P
UnrealSP.org webmaster & administrator

Previous Next

Who is online

Users browsing this forum: No registered users and 34 guests

Copyright © 2001-2024 UnrealSP.org

Powered by phpBB® Forum Software © phpBB Limited