Advanced weapon behvaiour
by Daniel Buckmaster · in Torque Game Engine · 03/25/2008 (3:03 am) · 4 replies
I'm not that experienced with the ShapeBaseImage state system. What I want to know is how complicated certain effects would be to put into a state system.
-The Plasma Cannon
This was a cool idea thought up by one of the modelers I work with. To charge the weapon, you hold down the right mouse button. It gradually builds up heat (partile effects get bigger and bigger...). If you let go of the trigger, the heat decreases until you hit the button again. To fire, you hit the left mouse button. When you fire, the hat the weapon has built up is used to create the projectile. So if you're only got a tiny amount of heat, you get a wussy little plasma bolt. If you're right in the sweet spot, you get a huge shot. However, if you're too hot, then the gun explodes due to overload.
-The Bolter
This is a little simpler. The bolter fires four-round bursts whenever you pull the trigger.
-Halo's Plasma Rifle
I guess you know what thi means. It's an automatic weapon, but each time you fire, heat builds up. If the gun gets too hot, it overheats and you can't use it for a few seconds while it vents steam.
I'm sure there are a few other complicated examples, but basically - can these three feasibly be done with the state system?
-The Plasma Cannon
This was a cool idea thought up by one of the modelers I work with. To charge the weapon, you hold down the right mouse button. It gradually builds up heat (partile effects get bigger and bigger...). If you let go of the trigger, the heat decreases until you hit the button again. To fire, you hit the left mouse button. When you fire, the hat the weapon has built up is used to create the projectile. So if you're only got a tiny amount of heat, you get a wussy little plasma bolt. If you're right in the sweet spot, you get a huge shot. However, if you're too hot, then the gun explodes due to overload.
-The Bolter
This is a little simpler. The bolter fires four-round bursts whenever you pull the trigger.
-Halo's Plasma Rifle
I guess you know what thi means. It's an automatic weapon, but each time you fire, heat builds up. If the gun gets too hot, it overheats and you can't use it for a few seconds while it vents steam.
I'm sure there are a few other complicated examples, but basically - can these three feasibly be done with the state system?
About the author
Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!
#2
There's a point to this thread, believe me (sorry for being all wierd), but I'm gonna wait for more replies...
03/25/2008 (5:03 am)
For the bolter, I meant the weapon would actually fire (run through the whole state sequence) four times for each trigger press. Like the Battle rifle in Halo 2.There's a point to this thread, believe me (sorry for being all wierd), but I'm gonna wait for more replies...
#3
Basically call onFire 4x from your firing script for each trigger.
03/26/2008 (9:12 am)
An idea - what about some sort of wait state/ short timer between projectile onFire event?Basically call onFire 4x from your firing script for each trigger.
#4
03/26/2008 (9:24 am)
Here's my datablock for a 3-round burst weapon. My version of Torque is pretty tweaked, so not everything in this datablock will work for you, but the states should work fine.datablock ShapeBaseImageData(Type95Image)
{
shapeFile = "~/data/shapes/guns/type95.dts";
emap = true;
zoomx = 4;
zoombmp = "sniper2";
mountPoint = 0;
eyeOffset = "0.3 0.1 -0.3";//left-right,forward-back,up-down
correctMuzzleVector = true;//true;//false
className = "WeaponImage";
mass = 12;
// Projectile && Ammo.
item = Type95;
ammo = Type95Ammo;
clip = Type95Clip;
projectile = Type95Projectile;
projectileType = Projectile;
fireKick = 2.5;
KickRecoverTime = 1;
reloadTime = 4;
lightType = WeaponFireLight;
lightRadius = 10;
lightTime = 50;
lightColor = "0.5 0.5 0.25";
stateName[0] = "Preactivate";
stateTransitionOnLoaded[0] = "Activate";
stateTransitionOnNoAmmo[0] = "NoAmmo";
stateName[1] = "Activate";
stateTransitionOnTimeout[1] = "Ready";
stateTimeoutValue[1] = 0.6;
stateSequence[1] = "Activate";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "Fire";
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Fire2";
stateTimeoutValue[3] = 0.1;
stateEmitterTime[3] = 0.1;
stateEmitter[3] = GunSmokeEmitter;
stateFire[3] = true;
stateRecoil[3] = LightRecoil;
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateSound[3] = Type95FireSound;
stateName[4] = "Reload";
stateTransitionOnNoAmmo[4] = "NoAmmo";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 0.092;
stateAllowImageChange[4] = false;
stateEjectShell[4] = true;
stateName[5] = "NoAmmo";
stateTransitionOnAmmo[5] = "Reload";
stateSequence[5] = "NoAmmo";
stateTransitionOnTriggerDown[5] = "DryFire";
stateName[6] = "DryFire";
stateTimeoutValue[6] = 0.3;
stateScript[6] = "onFire";
stateTransitionOnTimeout[6] = "NoAmmo";
stateName[7] = "ReClip";
stateSequence[7] = "Reload";
stateName[8] = "Fire2";
stateTransitionOnTimeout[8] = "Fire3";
stateTimeoutValue[8] = 0.1;
stateEmitterTime[8] = 0.1;
stateEmitter[8] = GunSmokeEmitter;
stateFire[8] = false;
stateRecoil[8] = LightRecoil;
stateAllowImageChange[8] = false;
stateSequence[8] = "Fire";
stateScript[8] = "onFire";
stateSound[8] = Type95FireSound;
stateName[9] = "Fire3";
stateTransitionOnTimeout[9] = "WaitForRelease";
stateTimeoutValue[9] = 0.1;
stateEmitterTime[9] = 0.1;
stateEmitter[9] = GunSmokeEmitter;
stateFire[9] = false;
stateRecoil[9] = LightRecoil;
stateAllowImageChange[9] = false;
stateSequence[9] = "Fire";
stateScript[9] = "onFire";
stateSound[9] = Type95FireSound;
stateName[10]="WaitForRelease";
stateTransitionOnTriggerUp[10]="Reload";
};
Torque Owner James Laker (BurNinG)
The Bolter:
In the OnFire event of the Weapon you can just create 4 projectiles similar to this:
function AssaultCannonImage::onFire(%this, %obj, %slot) { %projectile = %this.projectile; // set the number of projectiles we are going to fire %shellcount = 1; // Decrement inventory ammo. The image's ammo state is update // automatically by the ammo inventory hooks. %obj.decInventory(%this.ammo, %shellcount); // Determin initial projectile velocity based on the // gun's muzzle point and the object's current velocity %muzzleVector = %obj.getMuzzleVector(%slot); %objectVelocity = %obj.getVelocity(); %muzzleVelocity = VectorAdd( VectorScale(%muzzleVector, %projectile.muzzleVelocity), VectorScale(%objectVelocity, %projectile.velInheritFactor)); %spread = 6/1000; // This defines the spread of the projectiles. If no value is set the gun will fire deadly accurate. %spread = %spread $= "" ? 0.001 : %spread; %spread = %spread <= 0 ? 0.001 : %spread; // 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 %muzzleVelocity = MatrixMulVector(%mat, %muzzleVelocity); // Returns axis angle attitude specification %shipAxisAngle = getWords(%obj.getTransform(),3,6); // Create the projectile object %o = new (%this.projectileType)() { dataBlock = %projectile; initialVelocity = %muzzleVelocity; initialPosition = %obj.getMuzzlePoint(%slot); initialRotation = %shipAxisAngle; sourceObject = %obj; sourceSlot = %slot; client = %obj.client; }; MissionCleanup.add(%o); // 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 %muzzleVelocity = MatrixMulVector(%mat, %muzzleVelocity); // Create the projectile object %p = new (%this.projectileType)() { dataBlock = %projectile; initialVelocity = %muzzleVelocity; initialPosition = %obj.getMuzzlePoint(%slot); initialRotation = %shipAxisAngle; sourceObject = %obj; sourceSlot = %slot; client = %obj.client; }; MissionCleanup.add(%p); // 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 %muzzleVelocity = MatrixMulVector(%mat, %muzzleVelocity); // Create the projectile object %q = new (%this.projectileType)() { dataBlock = %projectile; initialVelocity = %muzzleVelocity; initialPosition = %obj.getMuzzlePoint(%slot); initialRotation = %shipAxisAngle; sourceObject = %obj; sourceSlot = %slot; client = %obj.client; }; MissionCleanup.add(%q); // 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 %muzzleVelocity = MatrixMulVector(%mat, %muzzleVelocity); // Create the projectile object %r = new (%this.projectileType)() { dataBlock = %projectile; initialVelocity = %muzzleVelocity; initialPosition = %obj.getMuzzlePoint(%slot); initialRotation = %shipAxisAngle; sourceObject = %obj; sourceSlot = %slot; client = %obj.client; }; MissionCleanup.add(%r); return %r; }Note - above code might need some fixing, but its a start.Check out this Charging resource, it can very easily be modified to timeout when the to 'hot': www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2971