Author Topic: Homing Projectile  (Read 2760 times)

Ok guys, need some serious help here. I need a script that makes a projectile home onto the nearest target (player).
I don't care if it is some schedule loop, I just need it to home onto a player. The weapon in question is a slow firing weapon that has a long recharge, so a schedule loop would be fine. Just please help me out here.

Ironic, I replied to your PM literally 5 seconds before you made this topic.




Yeah, sure. No problem. What you have to do is create a new projectile that's turned towards the player.

Code: [Select]
function ProjectileData::HomeToObject(%this, %projectile, %object) {
if(!isObject(%object) || !isObject(%projectile))
return;
if(%projectile.age > %projectile.getDatablock().lifetime*2)
return;
%speedScale = vectorLen(%projectile.getVelocity());
%projectilePosition = %projectile.getPosition();
%forwardVector = %projectile.getVelocity();
%normalDist = vectorSub(%object.getPosition(), %projectilePosition);
for(%i = 0; %i < 3; %i++)
%deltaVector = %deltaVector SPC mClampF(getWord(%normalDist,%i), getWord(%forwardVector,%i) - (0.5*%speedScale), getWord(%forwardVector, %i) + (0.5*%speedScale));
%deltaVector = vectorScale(vectorNormalize(getSubStr(%deltaVector, 1, strLen(%deltaVector) - 1)), %speedScale);
%projectile.setName("homingProjectile");
%newProjectile = new Projectile(:homingProjectile) {
initialPosition = %projectilePosition;
initialVelocity = %deltaVector;
age = %projectile.age + 1;
};
MissionCleanup.add(%newProjectile);
%projectile.delete();
%newProjectile.getDatablock().schedule(50, HomeToObject, %newProjectile, %object);
}
« Last Edit: November 06, 2013, 11:02:07 PM by $trinick »

This came from the homing rocket launcher.

package HomingRocket
{
   function Projectile::onAdd(%obj,%a,%b)
   {
      Parent::onAdd(%obj,%a,%b);
      if(%obj.dataBlock.getID() == homingRocketLauncherProjectil e.getID())
      {
         if(!%obj.doneHomingDelay)
            %obj.schedule(300,spawnHomingRocket);
         else
            %obj.schedule(75,spawnHomingRocket);
      }
   }
};activatePackage(HomingRocket);

function Projectile::spawnHomingRocket(%this)
{
   if(!isObject(%this.client))
      return;
   
   if(!isObject(%this) || vectorLen(%this.getVelocity()) == 0)
      return;
      
   %client = %this.client;
   %muzzle = vectorLen(%this.getVelocity());
   
   if(!isObject(%this.target) || %this.target.getState() $= "Dead" || %this.target.getMountedImage(0) == adminWandImage.getID() || vectorDist(%this.getPosition(),%this.target.getHackPosition()) > 30)
   {
      %pos = %this.getPosition();
      %radius = 100;
      %searchMasks = $TypeMasks::PlayerObjectType;
      InitContainerRadiusSearch(%pos, %radius, %searchMasks);
      %minDist = 1000;
      while ((%searchObj = containerSearchNext()) != 0 )
      {
         if((miniGameCanDamage(%client,%searchObj)) == 1)
         {
            if(%searchObj.getState() $= "Dead")
               continue;
            
            //if(%client == %searchObj.client)
            if(%this.sourceObject == %searchObj)
               continue;
            
            if(isTeamFriendly(%this,%searchObj) != 0)
               continue;
            
            if(%searchObj.getMountedImage(0) == adminWandImage.getID())
               continue;
            
            if(%searchObj.isCloaked)
               continue;
            
            %d = vectorDist(%pos,%searchObj.getPosition());
            if(%d < %minDist)
            {
               %minDist = %d;
               %found = %searchObj;
            }
         }
      }
      
      if(isObject(%found))
         %this.target = %found;
      else
      {
         %this.schedule(300,spawnHomingRocket);
         return;
      }
   }
   
   %found = %this.target;
   
   %pos = %this.getPosition();
   %start = %pos;
   %end = %found.getHackPosition();
   %enemypos = %end;
   %vec = vectorNormalize(vectorSub(%end,%start));
   for(%i=0;%i<5;%i++)
   {
      %t = vectorDist(%start,%end) / vectorLen(vectorScale(getWord(%vec,0) SPC getWord(%vec,1),%muzzle));
      %velaccl = vectorScale(%accl,%t);
      
      %x = getword(%velaccl,0);
      %y = getword(%velaccl,1);
      %z = getWord(%velaccl,2);
      
      %x = (%x < 0 ? 0 : %x);
      %y = (%y < 0 ? 0 : %y);
      %z = (%z < 0 ? 0 : %z);
      
      %vel = vectorAdd(vectorScale(%found.getVelocity(),%t),%x SPC %y SPC %z);
      %end = vectorAdd(%enemypos,%vel);
      %vec = vectorNormalize(vectorSub(%end,%start));
   }
   
   %addVec = vectorAdd(%this.getVelocity(),vectorScale(%vec,180/vectorDist(%pos,%end)*(%muzzle/40)));
   %vec = vectorNormalize(%addVec);
   
   %p = new Projectile()
   {
      dataBlock = %this.dataBlock;
      initialPosition = %pos;
      initialVelocity = vectorScale(%vec,%muzzle);
      sourceObject = %this.sourceObject;
      client = %this.client;
      sourceSlot = 0;
      originPoint = %this.originPoint;
      doneHomingDelay = 1;
      target = %this.target;
      reflectTime = %this.reflectTime;
   };
   
   if(isObject(%p))
   {
      MissionCleanup.add(%p);
      %p.setScale(%this.getScale());
      %this.delete();
   }
}

Ironic, I replied to your PM literally 5 seconds before you made this topic.
-snip-
This isnt working.
I have %p.schedule(300,HomeToObject, %this, %projectile, %object);

I tried it without the %p and with %projectile, I tried changing ProjectileData to starshotProjectile, and I alsol tried it without %this, %projectile, %object. Any idea why this is happening? No console errors either...

The schedule is in the starshotImage::onFire code.

This isnt working.
I have %p.schedule(300,HomeToObject, %this, %projectile, %object);

I tried it without the %p and with %projectile, I tried changing ProjectileData to starshotProjectile, and I alsol tried it without %this, %projectile, %object. Any idea why this is happening? No console errors either...

The schedule is in the starshotImage::onFire code.
Give us the code so we can actually see what's going on.

Give us the code so we can actually see what's going on.
Here it is
Code: [Select]
function starshotImage::onFire(%this,%obj,%slot)
{
if((%obj.lastFireTime+%this.minShotTime) > getSimTime())
return;
%obj.lastFireTime = getSimTime();

%projectile = %this.projectile;
%spread = 0.002;
%shellcount = 2;
%scaleFactor = getWord(%obj.getScale(),2)/2;

%client = %obj.client;
%pos = %obj.getHackPosition();

for(%shell=0; %shell<%shellcount; %shell++)
{
%vector = %obj.getMuzzleVector(%slot);
%objectVelocity = %obj.getVelocity();
%vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
%vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
%velocity = VectorAdd(%vector1,%vector2);
%x = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
%y = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
%z = (getRandom() - 0.5) * 10 * 3.1415926 * %spread;
%mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
%velocity = MatrixMulVector(%mat, %velocity);

%p = new (%this.projectileType)()
{
dataBlock = %projectile;
initialVelocity = %velocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
MissionCleanup.add(%p);
starshotprojectile.schedule(300, HomeToObject, %this, %projectile, %object);
%p.setScale(%scaleFactor SPC %scaleFactor SPC %scaleFactor);
}
return %p;
}

function ProjectileData::HomeToObject(%this, %projectile, %object) {
if(!isObject(%object) || !isObject(%projectile))
return;
if(%projectile.age > %projectile.getDatablock().lifetime*2)
return;
echo("Homing!");
%speedScale = vectorLen(%projectile.getVelocity());
%projectilePosition = %projectile.getPosition();
%forwardVector = %projectile.getVelocity();
%normalDist = vectorSub(%object.getPosition(), %projectilePosition);
for(%i = 0; %i < 3; %i++)
%deltaVector = %deltaVector SPC mClampF(getWord(%normalDist,%i), getWord(%forwardVector,%i) - (0.5*%speedScale), getWord(%forwardVector,

%i) + (0.5*%speedScale));
%deltaVector = vectorScale(vectorNormalize(getSubStr(%deltaVector, 1, strLen(%deltaVector) - 1)), %speedScale);
%projectile.setName("homingProjectile");
%newProjectile = new Projectile(:homingProjectile) {
initialPosition = %projectilePosition;
initialVelocity = %deltaVector;
age = %projectile.age + 1;
};
MissionCleanup.add(%newProjectile);
%projectile.delete();
%newProjectile.getDatablock().schedule(50, HomeToObject, %newProjectile, %object);
}



The rest of the script is basic weapons scripts like particles

ALSO:

Console error located
Code: [Select]
ERROR: delete - you cannot delete datablocks directly
BackTrace: ->ProjectileData::HomeToObject


Add-Ons/Weapon_Starshot/server.cs (0): Unable to find object: '0' attempting to call function 'getDataBlock'
BackTrace: ->ProjectileData::HomeToObject

I already fixed your code in the pad you linked me to.

I already fixed your code in the pad you linked me to.
It dosn't seem to lock onto bots. My friend is lasy so he wont test it.

You have no code that decides what object to lock onto, you're actually referencing the variable %object when no value has been assigned to it.

I would love to see the code fixed, as I have been looking for this myself

I would love to see the code fixed, as I have been looking for this myself
The code I posted works pretty well.

He only got console errors because his misuse of it caused it to blow up.

So would something like this work?
Code: [Select]
     %pos = %this.getPosition();
      %radius = 100; 
      %searchMasks = $TypeMasks::PlayerObjectType;
      InitContainerRadiusSearch(%pos, %radius, %searchMasks);
      %minDist = 1000;
      while ((%object = containerSearchNext()) != 0 )

Uh, you may as well just do initContainerRadiusSearch(%this.getPosition(), 100, $TypeMasks::PlayerObjectType); %target = containerSearchNext();

Uh, you may as well just do initContainerRadiusSearch(%this.getPosition(), 100, $TypeMasks::PlayerObjectType); %target = containerSearchNext();
New console error
Code: [Select]
Add-Ons/Weapon_Starshot/server.cs (451): Unable to find object: 'starshotProjectile' attempting to call function 'delete'
BackTrace: ->ProjectileData::HomeToObject


Add-Ons/Weapon_Starshot/server.cs (0): Unable to find object: '0' attempting to call function 'getDataBlock'
BackTrace: ->ProjectileData::HomeToObject


Add-Ons/Weapon_Starshot/server.cs (0): Unable to find object: '' attempting to call function 'schedule'
BackTrace: ->ProjectileData::HomeToObject

Add-Ons/Weapon_Starshot/server.cs (430): Unknown command getPosition.

Code: [Select]
%p = new (%this.projectileType)()
{
dataBlock = %projectile;
initialVelocity = %velocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
MissionCleanup.add(%p);

                // your code to find %object

%p.getDatablock().schedule(300, HomeToObject, %p, %object);
%p.setScale(%scaleFactor SPC %scaleFactor SPC %scaleFactor);

Try changing it to that.