Game Development Community

dev|Pro Game Development Curriculum

Projectile Spread and Shotguns

by Daniel Neilsen · 11/20/2001 (5:10 pm) · 7 comments

Download Code File

I believe a lot of developers will find this useful in at least some way so I have
written this small tutorial.

This tutorial does not require any engine modifications whatsoever and only
alters the game script files. In saying this, it should easily work with all versions
of the torque engine.

In this tutorial, any instructions that require editing will be prefixed with ****



PROJECTILE SPREAD AND SHOTGUNS

**** Open the file example/fps/server/scripts/rifle.cs

**** Find the RifleImage datablock. (approx line 271) and add the following lines into the datablock.


projectileSpread = 12/1000; // **** Added in Projectile Spread Tutorial
// This defines the spread of the projectiles. If no value is set the gun will fire
// deadly accurate.

isShotGun = false; // **** Added in Projectile Spread Tutorial
// This defines whether the weapon should act like a shotgun or not.
// Feel free to change as you see fit for fun ;)


The easiest way to imagine projectile spread is to create a circle that has a radius of our projectileSpread.
We then determine a random x y and z within that range and then we effect our normal projectile vector
to use this new random direction.


**** Replace the default RifleImage::onFire function with the following.


function RifleImage::onFire(%this, %obj, %slot)
{
// Decrease the weapons ammo on fire
%obj.decInventory(%this.ammo,1);

// Get the type of projectile we are gonna fire
%projectile = %this.projectile;

// Get the weapons projectile spread and ensure it is never 0
// (we need some spread direction even if it is extremely tiny)
%spread = %this.projectileSpread;
%spread = %spread $= "" ? 0.001 : %spread;
%spread = %spread <= 0 ? 0.001 : %spread;

// Determine if we are using a shotgun class weapon or not
// If we are using a shotgun, set the number of projectiles we are going to fire to 12
%shellcount = 1;
if(%projectile.isShotGun)
%shellcount = 12;

// Create each projectile and send it on its way
for(%shell=0; %shell<%shellcount; %shell++)
{
// Get the muzzle vector. This is the dead straight aiming point of the gun
%vector = %obj.getMuzzleVector(%slot);

// Get our players velocity. We must ensure that the players velocity is added
// onto the projectile
%objectVelocity = %obj.getVelocity();

// Determine scaled projectile vector. This is still in a straight line as
// per the default example
%vector1 = VectorScale(%vector, %projectile.muzzleVelocity);
%vector2 = VectorScale(%objectVelocity, %projectile.velInheritFactor);
%velocity = VectorAdd(%vector1,%vector2);

// Determine our random x, y and z points in our spread circle and create
// a spread matrix.
%x = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
%y = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
%z = (getRandom() - 0.5) * 2 * 3.1415926 * %spread;
%mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);

// Alter our projectile vector with our spread matrix
%velocity = MatrixMulVector(%mat, %velocity);


// Create our projectile
%p = new (%this.projectileType)()
{
dataBlock = %projectile;
initialVelocity = %velocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
};
MissionCleanup.add(%p);
}

return %p;
}


That should get projectile spread and shotguns working for you guys.
Try it out and if you have any questions just email me.

#1
11/20/2001 (6:33 pm)
looks like a nother cool tut, if this works for me , care if i turn this into html and link it tothe NoESCape Web Server
#2
11/20/2001 (7:13 pm)
Feel free Gary
#3
11/21/2001 (1:18 am)
Thx Daniel.

I have been looking to add this to my WWII project for a long time, and this one works very well.

// Clocks out
#4
07/12/2002 (12:18 am)
I think this:
// Create our projectile
%p = new (%this.projectileType)()
{
dataBlock = %projectile;
initialVelocity = %velocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
};

Should be this or it will never know to who the projectile belongs to:
// Create our projectile
%p = new (%this.projectileType)()
{
dataBlock = %projectile;
initialVelocity = %velocity;
initialPosition = %obj.getMuzzlePoint(%slot);
sourceObject = %obj;
sourceSlot = %slot;
client = %obj.client;
};
#5
12/15/2003 (7:06 am)
a little typ-oh
change:
if(%projectile.isShotGun)
into this:
if(%this.isShotGun)
works really well though great work
#6
01/19/2004 (2:50 pm)
Finding this just made my week. I spent the whole day playing with this and coming up with ideas for spells that cast different number of energy bolts etc.

Thanks for your help!!!
#7
08/09/2008 (5:42 am)
I was also thinking about it..