Game Development Community

Wounded movement animation

by Quest Johnny · in Torque Game Engine · 08/19/2004 (7:04 pm) · 13 replies

I want to have my chrs display a "wounded" animation state when their health drops to a certain level, e.g., limping along, nursing wounds such as one sees in Resident Evil.

Now, I have some idea how to do this in the engine code, but I'm wondering if there a way to do it only in script. I ask because I notice for a lot of the things one wants to do in-game, there is a script solution, if you can find it. I have a feeling that if I set the thread to "wounded" it will just get overridden by the engine to "run."

#1
08/20/2004 (4:30 am)
I dont know if this helps but look at this resource maybe
it can give you a clue.
Here
#2
08/20/2004 (5:36 am)
Well, you can try setting it to wounded in script.. Myself, i always thought that engine was over-ridden by script? So it may go with wounded instead of whats in the engine.
#3
08/20/2004 (7:13 am)
Overriden by script? I doubt that, BUT it makes it all the more worth trying :)
#4
08/20/2004 (8:51 am)
You can certainly call animations via scripting, this is how the Realm Wars hand to hand animations are called into ation. I believe there are a variety of resources on this, based on the work that Paul Dana did for Realm Wars for the Hand to Hand combat (which is what originated this method).
#5
08/20/2004 (3:11 pm)
The RWs melee animations are played via a new C++ function in player.cc(called from script). The best way to do this is to add the animations to the pickActionAnimation method in player.cc. There more to it than that, but you should start there.
#6
08/20/2004 (8:10 pm)
I've had a look in script where animations are, and they all look suspciiously like callbacks from within engine code.. that is: not called from script. I imagine they are set up that way to make them customizable.

I tried putting a new setActionThread() in my script, but it was instantly overriden by the usual 'run' animation.. so I fear I'll have to delve into the engine code anyway.. from what I can tell, it's not trivial.
#7
08/21/2004 (11:03 am)
Ok..... You posted the same stuff twice. You need to go into the player.cc and player.h files, and add code the animations in. I would startby looking at the pickActionAnimation function.
#8
08/24/2004 (7:22 am)
Hrm.. I added the following in pickActionAnimation()

if( mDataBlock ) {
if(getDamageLevel() >= (mDataBlock->maxDamage)/2 ) {
if(action==PlayerData::RunForwardAnim) {
action=PlayerData::FallAnim; //i don't really care, just change it
}//endif
//Con::printf("should be moving slow--wounded");
}//endif
}//endif

right before setActionThread() at the bottom. I stepped through setActionThread and it seemed to work.. yet, the animation shown is just RunForwardAnim. Odd..
#9
08/25/2004 (1:25 am)
Ok, you are on the right track, look at my code, I've added the limp animations to the player and it works ok
...
			default:
				// Pick animation that is the best fit for our current velocity.
				{
					F32 curMax = 0.1;
					VectorF vel;
					mWorldToObj.mulV(mVelocity,&vel);

					for (U32 i = 1; i < PlayerData::NumMoveActionAnims; i++) 
					{
						PlayerData::ActionAnimation &anim = mDataBlock->actionList[i];

						if (anim.sequence != -1 && anim.speed) 
						{
							F32 d = mDot(vel, anim.dir);              			   
			   
							if (d > curMax) 
							{
								curMax = d;
								action = i;
								forward = true;
							}
						}
					}

					//Check if the legs are damaged and change the animation 
					ICArmor* pArmor = static_cast<ICArmor*>(mComponents[cmp_armor]);
					F32 dmg = 0, dmgR = 0, dmgL = 0;
					if (pArmor)
					{
						dmgR = pArmor->getDamagePerc(ICArmorData::Loc_RightLeg);
						dmgL = pArmor->getDamagePerc(ICArmorData::Loc_LeftLeg);
					}

					dmg = getMax(dmgR,dmgL);

					

					if (dmg > 0.25)		//change the animation only if the max damage is greater than 25%
					{
						switch (action)
						{
						case	PlayerData::RunForwardAnim:
							if (dmgR>dmgL)	action = PlayerData::RunLimpRight;
							else	action = PlayerData::RunLimpLeft;
							break;
						case	PlayerData::RunForwardAngleLeft:
							if (dmgR>dmgL) action = PlayerData::RunSideLeftLimpRight;
							else action = PlayerData::RunSideLeftLimpLeft;
							break;
						case	PlayerData::RunForwardAngleRight:
							if (dmgR>dmgL) action = PlayerData::RunSideRightLimpRight;
							else action = PlayerData::RunSideRightLimpLeft;
							break;
						case	PlayerData::RunBackwardAngleLeft:
							if (dmgR>dmgL) action = PlayerData::BackSideLeftLimpRight;
							else action = PlayerData::BackSideLeftLimpLeft;
							break;
						case	PlayerData::RunBackwardAngleRight:
							if (dmgR>dmgL) action = PlayerData::BackSideRightLimpRight;
							else action = PlayerData::BackSideRightLimpLeft;
							break;
						case	PlayerData::SideStepLeftAnim:
							if (dmgR>dmgL)	action = PlayerData::SideLeftLimpRight;
							else action = PlayerData::SideLeftLimpLeft;
							break;
						case	PlayerData::SideStepRightAnim:
							if (dmgR>dmgL)	action = PlayerData::SideRightLimpRight;
							else action = PlayerData::SideRightLimpLeft;
							break;
						case  PlayerData::BackBackwardAnim:
							if (dmgR>dmgL) action = PlayerData::BackLimpRight;
							else action = PlayerData::BackLimpLeft;
							break;
						}
					}
				}
				break;
			}
 
      }
   }

   setActionThread(action,forward,false,false);

}
#10
08/25/2004 (6:35 am)
Isn't that.. exactly what I did? Here's my code:
Here is the standard stuff (for context):

else
   {
      if (mContactTimer >= sContactTickTime) {
         // Nothing under our feet
         action = PlayerData::RootAnim;
      }
      else {
         // Our feet are on something
         // Pick animation that is the best fit for our current velocity.
         // Assumes that root is the first animation in the list.
         F32 curMax = 0.1;
         VectorF vel;
         mWorldToObj.mulV(mVelocity,&vel);
         for (U32 i = 1; i < PlayerData::NumMoveActionAnims; i++) {
            PlayerData::ActionAnimation &anim = mDataBlock->actionList[i];
            if (anim.sequence != -1 && anim.speed) {
               F32 d = mDot(vel, anim.dir);
               if (d > curMax) {
                  curMax = d;
                  action = i;
                  forward = true;
               }
               else
               {
                  // Special case, re-use slide left animation to slide right
                  if (i == PlayerData::SideLeftAnim && -d > curMax) {
                     curMax = -d;
                     action = i;
                     forward = false;
                  }
               }
            }
         }
      }
   }
And now my code:
//fairly straight forward.. override if wounded??
   if( mDataBlock ) {
	   if(getDamageLevel() >= (mDataBlock->maxDamage)/2 ) {
		   if(action==PlayerData::RunForwardAnim) {
			   action=PlayerData::FallAnim;	//i don't really care, just change it
		   }//endif
			//Con::printf("should be moving slow--wounded");
	   }//endif
   }//endif

   setActionThread(action,forward,false,false);
}

Apart from you having special limp animations for all cases, isn't mine the same? It sets the action= - then.. why does yours work?

I put a breakpoint right at action= and it hits that line, no trouble - it just doesn't actually do anything.

Or.. is there perhaps something special about the way the animations are made, or identified? You made a special animation for each one.. whereas I'm just piggybacking another animation..
#11
08/25/2004 (10:29 pm)
Hmm, yes, it should work, try using another animation instead of the FallAnim, because there is a line in the code that if you have the feet on the ground the FallAnim animation is stopped or something similar.
Anyway I can assure you that the code works perfectly :)
#12
08/27/2004 (9:31 am)
Maybe a "prettier" way of doing it could be exposing the animations for the default movements to the scripts? That way you could dynamically change the "animation set" for a given character at will.
#13
03/04/2005 (5:04 am)
Sorry, but this snippet could be useful to me to turn left/right handlebars of my bycicle?

Thanks in advance!