Game Development Community

REQ] Simple behaviour ... an "if dead load level

by David Janik-Jones · in Torque Game Builder · 07/25/2008 (7:44 pm) · 14 replies

A simple behaviour I can attach to an object that already has the "Takes Damage" behaviour on it. I'd like to set that to one life only and when he is "dead" instead of simply disappearing I'd like to immediately load a new level.

Or maybe a revised "Takes Damage" behaviour that adds that one thing in.

Any help appreciated. Thanks.

#1
07/29/2008 (2:16 pm)
Anyone?
#2
07/30/2008 (11:24 am)
Hi. I can't remember exactly how the original "Takes Damage" behavior worked, but assuming you'd store a health value somewhere, either in the behavior itself, or on the object to which it is attached you would probably do something like this.

function LoadLevelOnDeathBehavior::checkDead(%this)
{
   if (%this.owner.health > 0)
      return;
   
   // we schedule the level load to an external function to avoid a crash when this object is destroyed
   // (as its part of the current level) 
   schedule(5, 0, "loadLevel", sceneWindow2D, "game/data/levels/some_level.t2d");       
}

That's not tested and not guaranteed to work. Indeed, stuff like this is pretty game specific and normally part of your games overall structure. You might want a menu system or "game over" menu display in there. Of course, the new level could actually be your game over screen. Also, you don't need to use onUpdate to loop the "checkDead" function, and you're better off just checking for dead every second or so.

Hope that helps.
#3
07/30/2008 (12:23 pm)
Thanks Wes. I attempted myself to simply grab some code from the basic load level behaviour but I had no luck. I will plug this in later (when I get home) and have a look. Many thanks.
#4
07/30/2008 (2:31 pm)
It doesn't seem to work on it's when put in, although I'm not sure where's you'd put it, so i've also tried to add just the one line in the function TakesDamageBehavior::kill(%this) ... here's the code ...

//-----------------------------------------------------------------------------
// Torque Game Builder
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

if (!isObject(TakesDamageBehavior))
{
   %template = new BehaviorTemplate(TakesDamageBehavior);
   
   %template.friendlyName = "Takes Damage";
   %template.behaviorType = "Game";
   %template.description  = "Set the object to take damage from DealsDamage objects that collide with it";

   %template.addBehaviorField(health, "The amount of health the object has", int, 100);
   %template.addBehaviorField(lives, "The number of times the object can lose all its health", int, 3);
   %template.addBehaviorField(tintRedForDamage, "Tint the object red as it takes damage", bool, 0);
   %template.addBehaviorField(respawnTime, "The time between death and respawn (seconds)", float, 2.0);
   %template.addBehaviorField(invincibleTime, "The time after spawning before damage is applied (seconds)", float, 1.0);
   %template.addBehaviorField(respawnEffect, "The particle effect to play on spawn", object, "", t2dParticleEffect);
   %template.addBehaviorField(explodeEffect, "The particle effect to play on death", object, "", t2dParticleEffect);
}

function TakesDamageBehavior::onAddToScene(%this)
{
   %this.startHealth = %this.health;
   %this.startFrame = %this.owner.getFrame();
   %this.spawn();
}

function TakesDamageBehavior::takeDamage(%this, %amount, %assailant)
{
   if (%this.invincible)
      return;
   
   %this.health -= %amount;
   if (%this.health <= 0)
   {
      %this.explode();
      %this.kill();
      return;
   }
   
   if(%this.tintRedForDamage)
   {
      %tint = %this.health / %this.startHealth;
      %this.owner.setBlendColor(1, %tint, %tint, 1);
   }
}

function TakesDamageBehavior::kill(%this)
{
   %this.lives--;
   if (%this.lives <= 0)
   {
      %this.owner.safeDelete();
      // add this part here maybe?
      schedule(5, 0, "loadLevel", sceneWindow2D, "game/data/levels/some_level.t2d");
      return;
   }
   
   %this.invincible = true;
   %this.owner.visible = false;
   %this.owner.collisionActiveReceive = false;
   %this.schedule(%this.respawnTime * 1000, "spawn");
}

function TakesDamageBehavior::setVincible(%this)
{
   %this.invincible = false;
}

function TakesDamageBehavior::spawn(%this)
{
   %this.owner.collisionActiveReceive = true;
   %this.schedule(%this.invincibleTime * 1000, "setVincible");
   %this.health = %this.startHealth;
   %this.owner.setBlendColor(1, 1, 1, 1);
   %this.owner.visible = true;
   %this.owner.setFrame(%this.startFrame);
   
   if (isObject(%this.respawnEffect))
   {
      %explosion = %this.respawnEffect.cloneWithBehaviors();
      %explosion.position = %this.owner.position;
      %explosion.setEffectLifeMode("Kill", 1.0);
      %explosion.playEffect();
   }
}

function TakesDamageBehavior::explode(%this)
{
   if (isObject(%this.explodeEffect))
   {
      %explosion = %this.explodeEffect.cloneWithBehaviors();
      %explosion.position = %this.owner.position;
      %explosion.setEffectLifeMode("Kill", 1.0);
      %explosion.playEffect();
   }
}
#5
08/12/2008 (10:49 am)
Anyone figure out what I messed up in the above code sample by placing Wes' code into the standard behaviour?
#6
08/19/2008 (12:10 pm)
Bump. Anyone look at the above "TakesDamage" script and tell me how to incorporate Wes' idea to make it a "DieandLoadLevel" script?
#7
08/19/2008 (12:27 pm)
I think the problem is that this is the wrong way to schedule a call to a method of an object.
schedule(5, 0, "loadLevel", sceneWindow2D, "game/data/levels/some_level.t2d");

Try something like this.
sceneWindow2D.schedule( 5, "loadLevel", "game/data/levels/some_level.t2d");
#8
08/19/2008 (1:26 pm)
James, I will try this as soon as I get home!

EDIT ... I had the file at work and tested it ... it works flawlessly, thanks!!!!

I'm actually going to fiddle with the script so that the top of the behaviour panel has an additonal new field to enter the scene I want to load, based on the standard scene load scripts.

Again, many thanks.
#9
08/19/2008 (5:29 pm)
Not so much wrong as "not compatible". I have my own "loadLevel" function which is in the global namespace. Sorry David, I should have mentioned that. :S
#10
08/19/2008 (7:58 pm)
Edit:
Just downloaded 1.7.4 and it has the BehaviorShooter demo, with TakesDamageAdv, which has the ability to load levels upon unit death. It's used in the demo to reset the level. Are they there for you guys or was it simply never advertised that updated behaviors were in there? I built that demo completely out of behaviors so that lots of the little problems with levels and damage systems could be solved once there. Hope that helps you guys :)

Slight hijack here:
I haven't been working with TGB recently, but I wrote most of the current behaviors. I'm not sure what has been released, but I wrote "Advanced" versions of Shoots, TakesDamage, and DealsDamage for the BehaviorShooter Demo quite a while ago. I thought the BehaviorShooter Demo was included with more recent releases, but if it wasn't, please let me know and I can zip the project up.

The TakesDamageAdv in that project has a parameter for the level to load when the unit is killed (I use it to load reset the level when the player dies).

So, again, if someone still needs these, let me know and I'll paste/upload them asap.
#11
08/19/2008 (10:05 pm)
I need too the Advance versions of this behaviors....
where you will paste/upload??
#12
08/20/2008 (4:05 am)
Tom, I have 1.7.4 and have none of those. A link would be great, thanks, and while James' worked fine for me I still have the level hard coded which means I can not use it on different levels (scenes) to do the same effect.

Thanks!
#13
08/20/2008 (9:31 am)
@David: --TOM--> I thought the BehaviorShooter Demo was included with more recent releases....
the behaviors appear in GarageGames\TorqueGameBuilder-1.7.4\games\BehaviorShooter\game\behaviors\game\...
#14
08/20/2008 (11:20 am)
@Odiel ... That's perfect. Thanks to all who volunteered time on this question!