Game Development Community

Player Knock Down

by Jake Callery · in Torque Game Engine · 03/16/2008 (8:50 am) · 9 replies

Hey guys, I've been struggling with this for a couple of days now.

Basically all I want is to knock a player down, force them to sit there for a bit, and then get back up.

Currently I have:
function KorkBody::onKnockDown(%db, %thisPlayer)
{//onKnockDown
      
   //Stop the healing for a short time
   %thisPlayer.setRepairRate(0);
   
   //Force a pause
   %thisPlayer.setEnergyLevel(0);
   
   //Set knocked down state
   %thisPlayer.knockedDown = true;   
   
   //Schedule recovery
   %thisPlayer.knockSched = schedule(%db.knockDownDelay,0,"getUp",%db,%thisPlayer);
   %thisPlayer.setActionThread("death11",false,false);

}//onKnockDown

This works fine, where when the player is knocked down, he can no longer move for a time, then he can move again. Also, if he gets knocked down while the player isn't pressing any keys, the animation plays correctly as well. However if the player is pressing "w" for forward for instance when he is knocked down, then the animation doesn't play.

Any ideas on how to get this to work?

Thanks very much!

Jake

#1
03/16/2008 (2:29 pm)
Disable movement keys if knocked down is happening. Set up a variable in your knocked down state, then for each movement function throw a little "if knocked down, do nothing, else do the command" thing.
#2
03/16/2008 (3:07 pm)
Thanks for the ideas Chris!

So what I have done is set up a serverCmd:
function serverCmdCheckKnockdown(%client)
{
   return %client.player.knockedDown;
}

And in the default.bind.cs file:
function moveforward(%val)
{
   if(!commandToServer('CheckKnockDown'))
      $mvForwardAction = %val * $movementSpeed;
   else  
      echo("Can't move!");
}

However now I get:
Call to commandToServer in moveforward uses result of void function call.

I'm guessing that you cannot return a value from a commandToServer Call.
So how else can I get the .knockedDown var from the correct player?

Thanks again for the help!

Jake
#3
03/16/2008 (3:48 pm)
I've tried this as well:

function moveforward(%val)
{
   if($knockedDown)
      $mvForwardAction = 0;
   else
      $mvForwardAction = %val * $movementSpeed;
}


function KorkBody::onKnockDown(%db, %thisPlayer)
{//onKnockDown
//Stop the player from taking damage
   
   //Set local knockdown param
   $knockedDown = true;   
   $mvForwardAction = 0;
   
   //Stop the healing for a short time
   %thisPlayer.setRepairRate(0);
   
   //Force a pause
   %thisPlayer.setEnergyLevel(0);
   
   //Set knocked down state
   %thisPlayer.knockedDown = true;   
  
   //Schedule recovery
   %thisPlayer.knockSched = schedule(%db.knockDownDelay,0,"getUp",%db,%thisPlayer);
   %thisPlayer.setActionThread("death11",false,false);
}//onKnockDown

I have no idea how global vars work with multiplayer, but I tried it anyway.
If the animation starts, this allows it to finish without being interrupted.. however
if I'm still holding the forward key with the player is knocked down, the animation never starts.
But if I'm not holding it, and the animation starts, it doesn't get interrupted.

So I guess I need a way to either start the animation later, or kill the movement sooner..
maybe...

Any thoughts?
#4
03/16/2008 (3:53 pm)
Ok.. well it pretty much works now :)

I added this at the end of the onKnockDown callback.
This waits 10ms before it starts the animation. That seems to be long enough
for it to clear the movement keys out. I don't know how well this will work
under heavy loads... but its a start I guess..

schedule(10, 0, "playKnockDown", %db, %thisPlayer);
#5
03/16/2008 (4:03 pm)
Well, it seems that global vars (starting with a $) are not seen by the client.

So back to square one.

Any other thoughts perhaps?
#6
03/16/2008 (6:15 pm)
Try it the other way around. When the player is knocked down, call this function:

function clientCmdDisableMovement(%val)
{
if(%val)
{
$mvForwardAction = 0;
$mvBackwardAction = 0;
$mvLeftAction = 0;
$mvRightAction = 0;
$mvUpAction = 0;
$mvDownAction = 0;
$movementSpeed = 0;
$lastTurnSpeed=$Pref::Input::KeyboardTurnSpeed;
$Pref::Input::KeyboardTurnSpeed=0;
return;
}
$Pref::Input::KeyboardTurnSpeed = $lastTurnSpeed;
$movementSpeed=1;
}

To disable the players movement, just do this from the server:
CommandToClient(%thisPlayer.client,'DisableMovement',1);

To enable the players movement, just do this:
CommandToClient(%thisPlayer.client,'DisableMovement',0);


I haven't tested any of this, so I don't know if it will work perfectly. If it doesn't there's probably just a minor error in my code that is easy to fix.
#7
03/16/2008 (6:28 pm)
Ahh.. that makes more sense... I think that combined with the delayed start for the animation
is going to lick this one.

I'll get it in as soon as I get home from work tomorrow.

Thanks so much!

Jake
#8
03/17/2008 (3:21 pm)
@Maxwell: Thanks very much! Works like a champ. I still have to delay the animation 100ms or so.. so that could still be an issue depending on how much stress the client is under at the time, but hopefully it works enough of the time.

Thanks very much for all of the help!

Jake
#9
03/17/2008 (7:13 pm)
No problem!

If you ever need any other help like this, I'm your man. My email is braveskin@gmail.com