Jump to content

Raycast Damage At Close Range Instead Of Projectile Spawning


Recommended Posts

As creation of projectiles takes program resources, I always thought that it was somewhat wasteful at close range. If you have a visible bullet projectile model (something stock Torque no longer bothers with) and if it is not ballistic with a delayed arming system (eg: not a grenade), players are not going to get the chance to see it spawn at close range anyway - so why not save a bit CPU effort and check for a 2 metre/unit raycast and just roll for damage if anything is that close. If nothing is found, then create the projectile normally. This also allows for longer projectiles which could clip into the gun when they spawn (eg: you're using an animated texture for a bullet trail on the projectile model).


First up in the weaponImage datablock, create a new flag to check for raycast, this could be an int on how much range to check for, but here I'm going to keep it simple and just use it as a bool.

 

datablock ShapeBaseImageData(YourWeaponImage)
{
//...
rayTest = 1;
//...
};

 

In scripts/server/weapon.cs onFIre() function:

function WeaponImage::onFire(%this, %obj, %slot)
{
   //echo("\c4WeaponImage::onFire( "@%this.getName()@", "@%obj.client.nameBase@", "@%slot@" )");
 
   // Make sure we have valid data
   if (!isObject(%this.projectile))
   {
      error("WeaponImage::onFire() - Invalid projectile datablock");
      return;
   }
 
   %doRay = %this.rayTest;//<---------yorks new
 
   //...
 
      // Add player's velocity
      %muzzleVelocity = VectorAdd(
         VectorScale(%muzzleVector, %this.projectile.muzzleVelocity),
         VectorScale(%objectVelocity, %this.projectile.velInheritFactor));
 
	//yorks new in here! start.
   if(%doRay == 1)
   {
      //use the 2m raycast to check for hits
      %masks = $TypeMasks::ShapeBaseObjectType;//standard projectile collison mask in projectile.cs
      %testDist = VectorAdd(%obj.getMuzzlePoint(%slot), VectorScale(%muzzleVector, 2));
      %hit = containerRayCast(%eyePoint, %testDist, %masks, %obj);
 
      if(%hit != 0)
      {
		  //hit something, find out what and resolve damage
         %target = firstWord(%hit);
 
         //echo("target hit = " @ %target);
 
         %pos = getWords(%hit, 1, 3);
         %rot = getWords(%hit, 4, 6);
 
         if (%target.getType() & ($TypeMasks::ShapeBaseObjectType))
            %target.damage(%obj, %pos, %projectile.directDamage, %projectile.damageType);
 
		//you might also want to spawn explosions or decals here or do another check for static/terrains or something
        %decal = %projectile.decal;
		%explode = %projectile.explosion;
        %blast = new explosion()
        {
            dataBlock = %explode;
            position = %pos;
            rotation = %rot;
        };
        MissionCleanup.add(%blast);
 
        decalManagerAddDecal(%pos, %rot, 0, 1, %decal, false);
 
		return;//no need to spawn a projectile now
	  }
   }
   //nothing found in the way, so spawn the projectile as standard //yorks end.
 
      // Create the projectile object
      %p = new (%this.projectileType)()
      {
         dataBlock = %this.projectile;
         initialVelocity = %muzzleVelocity;
         initialPosition = %obj.getMuzzlePoint(%slot);
         sourceObject = %obj;
         sourceSlot = %slot;
         client = %obj.client;
         sourceClass = %obj.getClassName();
      };
      MissionCleanup.add(%p);
   }
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...