Game Development Community

dev|Pro Game Development Curriculum

Drop-in Grenades.

by FruitBatInShades · 01/30/2005 (1:08 am) · 43 comments

This little resource started life out as this thread but did not work for me. With the help of Craig Ball, Anthony Rosenbaum(who also wrote the original code) and David Barr I got the basic stuff working. This is my first attempt at torquescript so bear with me but it works well apart from the two issues mentioned at the end.

Save this as Grenades.cs in your server scripts directory:-
//-----------------------------------------------------------
//  Grenades.cs - Class to add grenades to torque via script
//-----------------------------------------------------------
// This script file is an easy way to add grenades to your
// FPS.  Just exec this script from game.cs and bind a key 
// to call the throwGrenadeDB function
//-----------------------------------------------------------

datablock ItemData(Grenade)
{
   category = "Grenades";
   shapeFile = "starter.fps/data/shapes/items/healthkit.dts";
   mass = 0.7;
   friction = 1;
   elasticity = 0.3; //how much bounce 0.1 = none, 1 = funny
   repairAmount = 50;
   maxDamage = 0.2;
   directDamage = 1;
   damageRadius = 20;
   radiusDamage = 1;
   areaImpulse = 1000;
   dynamicType = $TypeMasks::DamagableItemObjectType;
   explosion = CrossbowExplosion;
   fadeIn = 0;
};

function Grenade::Explode(%dataBlock, %obj)
{
   echo("Grenade::Explode called");
   %pos = %obj.getPosition();
   echo("Grenade::Explode Doing Damaged");
   radiusDamage(%obj,%pos,%dataBlock.damageRadius,%dataBlock.radiusDamage,"Grenade",%dataBlock.areaImpulse);
   %obj.setDamageState(Destroyed);
   %obj.schedule(99, "delete");
}

function Grenade::Damage(%this,%obj,%sourceObject, %position, %damage, %damageType)
{
   echo("Grenade::Damage called");
   //Grenade has recieved damage so detonate it
   cancel(%obj.ExplodeEventID);//Cancel previous explode timer
   %obj.setDamageState(Destroyed);
   %obj.schedule(99,"delete");
}

function Grenade::onDestroyed(%data,%obj)
{
   echo("Grenade::onDestroyed called");
}

function ShapeBase::throwGrenadeDB(%this,%GrenadeTypeDB,%client,%DelayToExplode)
{
	//%GrenadeTypeDB 	= the datablock type for this grenade
	//%client			= client object
	//%time				= time in milliseconds before explode
	
	//Check time is not silly or negative
	if (%DelayToExplode < 1)
		%DelayToExplode = 500;
	
	echo("ShapeBase::throwGrenade grenade, creating item");
	%item = new Item()
	{
		dataBlock 	= %GrenadeTypeDB;
		rotation 	= "1 0 0 " @ (getRandom() * 360);
		sourceObject= %client.player;
		client		= %client;
		ExplodeEventID=0;
	};
	//call the more general throwObject
	%this.throwObject(%item);
	//set detonantion delay
	%item.ExplodeEventID = %GrenadeTypeDB.schedule(%DelayToExplode, "Explode",%item);
	//make sure we tidy up :)
	MissionCleanup.add(%item);
}

function ShapeBase::throwObject(%this,%obj){
   // Throw the given object in the direction the shape is
   // looking.  The force values are hardcoded...
   echo("ShapeBase::throwObject grenade, getting direction");
   %eye = %this.getEyeVector();
   %vec = vectorScale(%eye, 20);
   // Add a vertical component to give the item a better arc
   %dot = vectorDot("0 0 1",%eye);
      if (%dot < 0)
            %dot = -%dot;
      %vec = vectorAdd(%vec,vectorScale("0 0 7",1 - %dot));
      // Add the shape's velocity
      %vec = vectorAdd(%vec,%this.getVelocity());
      // Set the object's position and initial velocity
      %pos = getBoxCenter(%this.getWorldBox());
      %obj.setTransform(%pos);
      echo("ShapeBase::throwObject grenade, Applying impulse");
      // Since the object is thrown from the center of the
      // shape, the object needs to avoid colliding with it's
      // thrower.
      %obj.setCollisionTimeout(%this);    
      %obj.applyImpulse(%pos,%vec);
}
If you know what your doing, put the binding stuff anywhere you like :)
Known issues
There are a few issues, if you can solve them please let me know so I can update this resource.

1. Grenades just sometimes disappear. Usually the first one thrown and then randomly after that. Still trying to figuire out why.
2.
Page «Previous 1 2 3 Last »
#1
01/30/2005 (9:33 pm)
@FruitBatInShades - I'm intrigued by your issue w/ portals. Is this occuring with one of the stock DIFs, or one of your own. If it is happening with a stock DIF, could you please list which one? I'd like to examine this. Meanwhile, when I have time, I'll put together an interior w/ Portals and try this out.

Thanks,

[HOW]EdM|EGTGE
#2
01/31/2005 (7:02 am)
@Edward: It seems to be periodic problem which worries me. When I track down the particulars I'll post more info.
#3
01/31/2005 (8:01 am)
I havent tried it with portals but i have found that by default, items collide with triggers. I had to modify the code to fix it.
#4
01/31/2005 (8:34 am)
@Eric: fancy sharing that modification?
#5
01/31/2005 (11:35 am)
Perhaps I am doing this wrong. No clue..

Bottom of server/scripts/grenades.cs


function serverCmdthrowGrenadeNow(%client)
{

%client.player.throwGrenadeDB(Grenade,%client,5);
}

moveMap.bindCmd(keyboard, "g", "commandToServer(\'throwGrenadeNow\');", "");



What happens is game froze up for several seconds and thats it. I do not see anything thrown or explode.. however in the console I do see all the echos from the grenade script.

What am i doing wrong?

Thanks!
#6
01/31/2005 (12:00 pm)
there is bug in the 1.3 engine that may lead to this. Check out this thread
Is the shape file correct? post the error messages
#7
01/31/2005 (12:18 pm)
Hi!

Yes, the shape file is correct. I do not get any error messages in the console/log, the only thing i get is a freeze up and then game goes on. Here is what I see in the log. I will checkout the link you given me.

Thanks

Mapping string: throwGrenadeNow to index: 3
ShapeBase::throwGrenade grenade, creating item
ShapeBase::throwObject grenade, getting direction
ShapeBase::throwObject grenade, Applying impulse
Grenade::Explode called
Grenade::Explode Doing Damaged
Grenade::Damage called
Grenade::onDestroyed called
#8
01/31/2005 (1:21 pm)
@FruitBatInShades: Sure. At the top of engine/game/item.cc you will see a line that looks like this
const U32 sServerCollisionMask = (sClientCollisionMask |
                                  TriggerObjectType);

Simply remove the "| TriggerObjectType" part and items wont collide with triggers. The problem is, this means that they wont set off triggers either.
#9
01/31/2005 (1:28 pm)
Thanks for the help FruitBatInShades! I am using 1.3 (not head) and that fix from the link worked out good...

Works great in except for one thing. I use the castle pack and when i try to use a grenade all works fine till it explodes, this is where the game freezes for a second or two.. Then all is good. I narrowed it down to the call to radiusDamange inside the explode function. If I change the datablocks damageRadius variable from 20 to 1 and run the level with the castle in it all is good, cept for no radius damage unless you are on top of the thing. Raising the damageRadius higher causes a longer freeze.

I had a similar problem with the cvs HEAD version while using the castle pack (which is why i reverted back to the original sdk) any type of weapon fire would choke torque (the crossbow, etc), while in/on or in proximity of the castle. Makes no sense to me, no clue why.

Anyway, seems to be an engine problem... Thanks for the great resource!
#10
01/31/2005 (2:00 pm)
@Donald: I'm afraid thats the problem with the speed of the particle routines. They are VERY heavy when up close. Make a simpler explosion.
#11
01/31/2005 (3:23 pm)
Ha! Ok.. So i created a custom explosion datablock with no particles at all. All i get is a slight flash of light under the object. Still, no-go.. freeze during explosion while in or around the castle. No worries, I will toy with this some other time.

Thanks
#12
01/31/2005 (5:46 pm)
@Donald: I'd guess its something to do with the occlusion or collision but I'm really new to torque. If you do figuire it out could you post your findings please?
#13
01/31/2005 (11:09 pm)
Hi! I was able to resolve my issues and grenades work perfect. I will just paste in my datablock and the entire functions that i modified.

datablock ItemData(Grenade)
{   

	category = "Grenades";   
	shapeFile = "starter.fps/data/shapes/items/healthkit.dts";   
	mass = 0.7;   
	friction = 1;   
	elasticity = 0.3; 	//how much bounce 0.1 = none, 1 = funny   
	
	repairAmount = 50;   
	maxDamage = 0.2;   
	directDamage = 30;   
	damageRadius = 20;   
	radiusDamage = 20;   
	areaImpulse = 200;   
	dynamicType = $TypeMasks::DamagableItemObjectType;   
	explosion = CrossbowExplosion;
	fadeIn = 0;

};
	
function Grenade::Explode(%dataBlock, %obj)
{   

	echo("Grenade::Explode called"); 

	%obj.ExplodeEventID = 0;

	%obj.setDamageState(Destroyed);   
	%obj.schedule(99, "delete"); 

}

function Grenade::Damage(%this,%obj,%sourceObject, %position, %damage, %damageType)
{  
	echo("Grenade::Damage called");

	if (%obj.ExplodeEventID)
	{
	   cancel(%obj.ExplodeEventID);
	   %obj.ExplodeEventID=0;
	   
	   %obj.setDamageState(Destroyed);   
	   %obj.schedule(99, "delete"); 
	}
	
}

function Grenade::onDestroyed(%data,%obj)
{   
	
	echo("Grenade::onDestroyed called");

	%pos = %obj.getPosition();
    radiusDamage(%obj,%pos,%data.damageRadius,%data.radiusDamage,"Grenade",%data.areaimpulse);

}

First in the datablock, i changed

areaImpulse = 1000;

to

areaImpulse = 200;

Anything starting around 4-500 seemed to freeze up torque when near such a large interior (in/around/on) as the castle. The same effect I got with the castle I can also achieve by dropping 5-10 grenades close to each other on the default stronghold mission (no, i do not think it has to do with particles). Lowering the areaimpulse change is what fixed my problem.

I did make a few other changes.

If a grenade goes off on its own radiusdamage is applied. If you shoot the grenade it goes off but no damage is applied.. So, my changes

I moved radiusDamage function down to the onDestroyed member function so radius damage is applied both when the grenade explodes and when it is shot. I also clear the ExplodeEventID in the explode function. This is checked in damage to see if we already exploaded, if so, we do not need to schedule deletion of the object (as it has already been scheduled in explode)

Hope this helps. It works great for me. I can throw countless grenades without issue now.

EDIT: I edited the original code with a few changes, less code.... works same..
#14
02/01/2005 (2:15 am)
Thats great donald :) Performance is a lot better now. Looks like the impulse function is a hungry beast. thanks
#15
02/01/2005 (7:49 pm)
Also increasing the mass of the things that get hit with the impulse would help keep Torque from locking up. That was something realized a long time ago by Sabercyd I think it was.
#16
02/01/2005 (9:44 pm)
Sorry guys but I am still having trouble with this. I have followed the link about changing item.cc, recompiled and I still, sometimes, lock up the game when I try to throw a grenade. When it doesn't lock up I don't see a Grenade I just blow up after a second. I copied and pasted the above code so I know it matches. What do you think I should look for?

Edit:
It still sometimes locks up but when it doesn't I only see the Grenade once it has hit the ground. I never see it travel through the air... any thoughts?
#17
02/02/2005 (11:52 am)
Hi Brandon,

I did not see a grenade thrown either untill I updated item.cc and recompiled torquedemo.exe. Make sure you made the right change. Also when you call throwGrenadeDB make sure you use long enough delay. Stupid me was using 5 (for 5 seconds) but forgot that delays are expressed in milliseconds. So it would throw it, but it would not even move into view before it exploded. I set my delay to 5000 for 5 seconds.

Also, here is a link to a zip containing my grenades.cs, it already has keybindings at the bottom, just drop in starter.fps/server/scripts/, exec it from game.cs and use the G key to throw one. See if this helps.

Note: My grenade.cs includes oncollision so if someone walks over or into a grenade i throw it blows up. If you do not want that to happen just remove the entire oncollision method from grenades.cs

www.donstoys.com/torque/grenades.zip
#18
02/02/2005 (1:39 pm)
you need a grenade object for this right, because i just tried to put it in the RW demo and it had errors like couldnt find object 0 and such. I did also ran the strarted the script in game.cs
#19
02/02/2005 (1:46 pm)
I do not know about the RW demo. I am using torque 1.3 starter fps (starter.fps) that comes with the engine.

Top of the grenade.cs in the grenade datablock (datablock ItemData(Grenade)) the shape is defined as

shapeFile = "starter.fps/data/shapes/items/healthkit.dts";

We are just using the healtkit. You will have to provide your own shape and/or update the path to the shape file (you can use just about any shape to test it out, try something small).

Im going to create a grenade shape sometime soon, will post for all when i get time to do it (I know there are others out there but i like to create my own).

hope this helps
#20
02/03/2005 (10:38 am)
Thanks for the help Donald. I was able to get it working after I recompiled again. Maybe I just dreamed that I did it before. Anyway, the grenades are great, thanks for the great resource FruitBat.
Page «Previous 1 2 3 Last »