Game Development Community

dev|Pro Game Development Curriculum

Player Damage Explosion

by Thomas Tong · 06/13/2007 (10:26 am) · 7 comments

This article shows how to add a playerExplosion field to a projectile so you can spawn a different explosion depending if you've hit a player versus a basic object.

I've benefited from countless resources so i figured it's time to contribute my first resource even though it's small. :)

Alternatives to this include adding server explosions (which are unscoped)
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=12178

Or creating another projectile as you can do it with just script
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2884


Add Player Explosion Type to Header

Ln85
Projectile.h
   ExplosionData* waterExplosion;      // Water Explosion Datablock
   S32 waterExplosionId;               // Water Explosion ID
+   ExplosionData* playerExplosion;      // Player Explosion Datablock
+   S32 playerExplosionId;               // Player Explosion ID

Initialize to NULL

Projectile.cc 55
   waterExplosion = NULL;
   waterExplosionId = 0;
+   playerExplosion = NULL;
+   playerExplosionId = 0;


Add Script support

Projectile.cc 127
   addNamedField(explosion, TypeExplosionDataPtr, ProjectileData);
   addNamedField(waterExplosion, TypeExplosionDataPtr, ProjectileData);
+addNamedField(playerExplosion, TypeExplosionDataPtr, ProjectileData);

Projectile.cc 185
+   if (!playerExplosion && playerExplosionId != 0)
+      if (Sim::findObject(playerExplosionId, playerExplosion) == false)
+         Con::errorf(ConsoleLogEntry::General, "ProjectileData::onAdd: Invalid packet, bad datablockId(playerExplosion): %d", playerExplosionId);

Read / write from the network

Projectile.cc 278
+   if (stream->writeFlag(playerExplosion != NULL))
+      stream->writeRangedU32(playerExplosion->getId(), DataBlockObjectIdFirst,
+                                                       DataBlockObjectIdLast);

Projectile.cc 269
+   if (stream->readFlag())
+      playerExplosionId = stream->readRangedU32(DataBlockObjectIdFirst,  DataBlockObjectIdLast);


Spawn a player Explosion if you've hit a player type (feel free to change to different types)

Projectile.cc 738

+      if (mDataBlock->playerExplosion && (collideType & PlayerObjectType))
+         {
+         pExplosion = new Explosion;
+         pExplosion->onNewDataBlock(mDataBlock->playerExplosion);
+         }
+      else if (mDataBlock->waterExplosion && pointInWater(p))

As a quick test go to your crossbow.cs and change player explosion to the water explosion

explosion           = CrossbowExplosion;
   playerExplosion      = CrossbowWaterExplosion;


Other options are server side explosions (which are not scoped) or creating another projectile to hit the player. This was the cleanest way i could think of to easily get player damage graphics working. (Testing on a 1.5.1 build.

About the author

Recent Blogs

• Take my game! Please!
• Cratered v2

#1
06/14/2007 (7:52 pm)
Well done!
#2
06/25/2007 (6:21 pm)
Great stuff man! Much cleaner and opens up the engine for very specific explosion types. Thanks for this hopefully I'll be able to contribute some stuff soon. Also I'm using 1.5 works fine. Just remember you need explosionData for this to work and not just particleEmitter and particleData.
#3
06/26/2007 (7:27 am)
Thomas, sorry to bump but I'm curious if you could give an example of a particular decal for a particular class. Same as the explosion but using decals. Will the weapon decal system allow you place a decal on a player. I see the decal code right next to the explosion code and I would think it wouldn't be hard to do. I'm not an experienced coder thats why I'm asking you first, maybe you've already done this? But it would be tight to have a blood or bruised decal placed on the player when he is shot.

Thanks in Advance!
#4
06/28/2007 (1:31 pm)
Hi, I haven't looked at any thing regarding decals on a hit on the player so i don't know what may be involved for that. I would imagine it shouldn't be too difficult. The game I'm doing is pretty far away from the player so it's not exactly required. :)
#5
07/10/2007 (3:48 pm)
Decals on a player would (I imagine) be pretty ugly. Decals are pasted onto an object's bounding box. On a player, a decal wouldn't map around an arm or leg or anywhere else, it would just go right on the box, which means blood spatters part floating off the body. That's why Torque doesn't support that...Anyone who can find a fix is a genius.
#6
07/10/2007 (6:14 pm)
I'm thinking if you can create some skins for your player model then use some call to those different skins based on the getdamageLocation() function. I haven't looked into skins yet but I'm working with getting the damage location to do a variety of things right now. One is different levels of damage from a projectile base on the location then 2 I want to track it so I can give the player report at the end of every level to tell them what percentage of what shots went there. The first one is done. I'm working of the second. Then I will look into the limitations of swapping out the player class skin. But If anyone else can figure it out before that'be dope. I would go down the damageLocation swap skins route but thats just me. Also I'm thinking this is all done in script in the particular weapon's .cs under projectile onCollision.
#7
07/16/2007 (8:09 am)
sorry for double posting if this happened, i tried to post before but it didnt work.

first of all; great resource, works like a charm. two questions though.

first is very very nooby probably but i am not experienced with engine coding. what would be the collideType on engine when we explode agains a debrisPlayer? i obviously want blood to come from that too but i dont know how to pose the if statement.

second. obviously players will use this showing blood, or not, as a reference for hitting or not. i can imagine that if the clientside projectile collides with another player, but the server-side does not (which happens sometimes). the client will see blood, but his hit is not registered because on the server there was no hit.
is there anything we can do about that? for example move the bloody outburst explosion to some sort of an onDamage function in the engine or maybe we can check if the server did indeed register a hit too, and make that a condition for displaying the blood also.?