Game Development Community

dev|Pro Game Development Curriculum

Crouch Energy Drain

by Glenn Bermingham · 06/04/2013 (11:42 am) · 2 comments

Currently crouching has no effect on energy, I wanted to reward the player for getting into cover and movement down to a crawl speed by giving them increased energy regen. At first I thought it'd be a simple matter of adding crouchEnergyDrain = -0.25; minCrouchEnergy = 0; to my playerdata but it turns out there is no code for it.

In your compiler of choice (I'm using Visual C++ 2010 Express)

Add in Player.h
F32 crouchForce;                 ///< Force used to accelerate player while crouching
   F32 crouchEnergyDrain;           ///< Energy drain/tick - Added
   F32 minCrouchEnergy;             ///< Minimum energy required to crouch - Added
   F32 maxCrouchForwardSpeed;       ///< Maximum forward speed when crouching
   F32 maxCrouchBackwardSpeed;      ///< Maximum backward speed when crouching
   F32 maxCrouchSideSpeed;          ///< Maximum side speed when crouching

Now in Player.cpp add in:
PlayerData::PlayerData()
...

   // Crouching
   crouchForce = 45.0f * 9.0f;
   crouchEnergyDrain = 0.0f;   //Added
   minCrouchEnergy = 0.0f;   //Added
   maxCrouchForwardSpeed = 4.0f;
   maxCrouchBackwardSpeed = 4.0f;
   maxCrouchSideSpeed = 4.0f;

void PlayerData::initPersistFields()
...

   addGroup( "Movement: Crouching" );

      addField( "crouchForce", TypeF32, Offset(crouchForce, PlayerData),
         "@brief Force used to accelerate the player when crouching.nn" );
//Added ->
      addField( "crouchEnergyDrain", TypeF32, Offset(crouchEnergyDrain, PlayerData),
         "@brief Energy value drained each tick that the player is crouching.nn"
         "The player will not be able to move when his energy falls below "
         "crouchEnergyDrain.n"
         "@note Setting this to zero will disable any energy drain.n"
         "@see minCrouchEnergyn");
      addField( "minCrouchEnergy", TypeF32, Offset(minCrouchEnergy, PlayerData),
         "@brief Minimum energy level required to sprint.nn"
         "@see crouchEnergyDrainn");
//Added <-
      addField( "maxCrouchForwardSpeed", TypeF32, Offset(maxCrouchForwardSpeed, PlayerData),
         "@brief Maximum forward speed when crouching.nn" );
      addField( "maxCrouchBackwardSpeed", TypeF32, Offset(maxCrouchBackwardSpeed, PlayerData),
         "@brief Maximum backward speed when crouching.nn" );
      addField( "maxCrouchSideSpeed", TypeF32, Offset(maxCrouchSideSpeed, PlayerData),
         "@brief Maximum sideways speed when crouching.nn" );

void PlayerData::packData(BitStream* stream)
...

   // Crouching
   stream->write(crouchForce); 
   stream->write(crouchEnergyDrain);   //Added
   stream->write(minCrouchEnergy);     //Added
   stream->write(maxCrouchForwardSpeed);
   stream->write(maxCrouchBackwardSpeed);
   stream->write(maxCrouchSideSpeed);

void PlayerData::unpackData(BitStream* stream)
...

   // Crouching
   stream->read(&crouchForce);
   stream->read(&crouchEnergyDrain);   //Added
   stream->read(&minCrouchEnergy);   //Added
   stream->read(&maxCrouchForwardSpeed);
   stream->read(&maxCrouchBackwardSpeed);
   stream->read(&maxCrouchSideSpeed);

Still in Player.cpp About Line 2516, there is 2 ways you can do this.
void Player::updateMove(const Move* move)
...

      // Force a 0 move if there is no energy, and only drain
      // move energy if we're moving.
      VectorF pv;
      if (mPose == SprintPose && mEnergy >= mDataBlock->minSprintEnergy) {
         if (moveSpeed)
            mEnergy -= mDataBlock->sprintEnergyDrain;
         pv = moveVec;
      }
//Added ->
      else if (mPose == CrouchPose && mEnergy >= mDataBlock->minCrouchEnergy) {
            mEnergy -= mDataBlock->crouchEnergyDrain;
         pv = moveVec;
      }
//Added <-
      else if (mEnergy >= mDataBlock->minRunEnergy) {
         if (moveSpeed)
            mEnergy -= mDataBlock->runEnergyDrain;
         pv = moveVec;
      }
      else
         pv.set(0.0f, 0.0f, 0.0f);
In the code above, when the player crouching (regardless of moving) will trigger the energy drain. This works if you wish players to crouch to regain energy as you simply give the energy drain in the PlayerData a negative value which will enhance the regeneration speed.

If you want the energy drain to react in the same way sprinting does (Based on movement) then simply add to the previous section:
//Added ->
      else if (mPose == CrouchPose && mEnergy >= mDataBlock->minCrouchEnergy) {
         if (moveSpeed) // Drain on movement
            mEnergy -= mDataBlock->crouchEnergyDrain;
         pv = moveVec;
      }
//Added <-

Add the following to Art/datablocks/player.cs
datablock PlayerData(DefaultPlayerData)
...

   crouchForce = 405;
   crouchEnergyDrain = -0.25; //Added - This negitive value will increase the recharge speed
   minCrouchEnergy = 0;  // Added - Disable crouching while below this value
   maxCrouchForwardSpeed = 1.0;
   maxCrouchBackwardSpeed = 1.0;
   maxCrouchSideSpeed = 1.0;

And you're done. Now when you crouch you'll ether have an increased regeneration of energy if you used a negative value or a faster drain while crouching if using a positive value.

#1
06/07/2013 (1:40 pm)
Cool, thanks! Reminds me of Crysis where your suit's power drains slower when crouched.
#2
06/09/2013 (6:18 pm)
With the only exception, that you don't have a nanosuit with superpower in Torque.