Game Development Community

All my AI's use same Player classes

by Andy Hawkins · in Torque Game Engine · 04/07/2007 (4:04 am) · 3 replies

I've abstracted my AI's using code as below to become DemoPlayer and DemoPlayer2 - but trying code DemoPlayer::onDeath never gets called.

At runtime they both use the same Player::onDeath anim. Which ever AI's .cs file is loaded last takes precedence (or overrides all others) How can I make each AI use it's own onDeath function?

// I assume this overrides the default Player class
datablock PlayerData(DemoPlayer : PlayerSkeletonWithFireball)
{
   shootingDelay = 2000;
};

// then I create one with this...
%player = new AIPlayer() {
      dataBlock = DemoPlayer;
....
//  then I make a new one with this..
datablock PlayerData(DemoPlayer2 : PlayerSkeletonLicheKing)
{
   shootingDelay = 3000;
};

// then I create number 2 with this...
%player = new AIPlayer() {
      dataBlock = DemoPlayer2;

they both use this function in "Skeleton_LicheKing_Control.cs" because it was loaded last. I set a break point to verify this.

function Player::onDeath(%this,%player,%sourceObject, %sourceClient, %damageType, %damLoc)
{
   // Invoked when a object has died.
   echo("Dead");
   
   // explode?
   %obj = %this.getDataBlock();
   
   // fade now
   %this.startFade(0, 0, true);
   
   if ( %obj.Explosion !$= "" )
   {
      // spawn an explosion
      %pos = %this.getPosition();
      
      // generate a new ribcage
      %myExplosion = new Explosion()
      {
         
         dataBlock = SkeletonExplosion;
         position = %pos;
      };
   }
}

#1
04/07/2007 (11:46 am)
Function Player::onDeath ??

That's just not what you want.

DemoPlayer::onDeath

DemoPlayer2::onDeath

Try those instead. The demo players are just child datablocks of the player class right? Every time you make a function player::onDeath() you are overwriting the existing function player::onDeath() because there can be only one "player" class and it can have one "onDeath()" function (excluding overloading). So even if you added Player::onDeath to a completely unrelated *.cs it could still be used in place of the ones you want. It doesn't matter that you added them to Skeleton_LicheKing_Control.cs or not. Here's another neat trick Andy.

place code that's common to all players in function player
function Player::onDeath(%this,%player,%sourceObject, %sourceClient, %damageType, %damLoc)
{
   // Invoked when a object has died.
   echo("Dead");
   
   // fade now
   %this.startFade(0, 0, true);
}
and still be able to use it in the children by using Parent::onDeath()
function DemoPlayer2::onDeath(%this,%player,%sourceObject, %sourceClient, %damageType, %damLoc)
{
   //run universal code first
   Parent::onDeath(%player,%sourceObject, %sourceClient, %damageType, %damLoc)
   
   // make something cool and unique for demoplayer
   // spawn an explosion
      %pos = %this.getPosition();   
      %myExplosion = new Explosion()
      {
         dataBlock = DemoPlayer2Explosion;  //lets call a datablock specific to demoplayer2 because we can
         position = %pos;
      };
}

Hope this helps.
#2
01/02/2010 (12:59 pm)
Thanks!!!!
this solution works perfectly for me!!!
#3
01/02/2010 (5:50 pm)
For the record, Player::onDeath doesn't exist - it will never get called, because onDeath is always called on the datablock, not the object itself.