Update to Kodji's Player Swimming/Drowning code 

By Bob

REV 2 (2-21-00)

 

I am sending code for adding a player drowning to GTest code. This will help give some ideas for using the detection of contents to others. The original code was from Kodji, I added a few updates to give it some more effects. With the original code the player would not die if the health ran out while in the water. This code change works well in my modified Gtest code that I use for testing.

Thanks. 

Bob

 

owner@leitmotivsoftware.com

http://www.leitmotivsoftware.com/

 

//    ====================================================================

Bold = New lines to add

 

In Gmain.c

Around line 76

static geBoolean Player_Drowned(GenVSI *VSI, void *PlayerData, float Time);

Around Line 160

GenVSI_ProcIndex(VSI, 22, Player_Drowned);

Around Line 180

GenVSI_ProcIndex(VSI, 22, Player_Drowned);

 

//=================================================================

//    Client_Control

//=================================================================

geBoolean Client_Control(GenVSI *VSI, void *PlayerData, float Time)

{

      geVec3d           LVect, InVect;

      float             Speed;

      GE_Contents       Contents;

      geVec3d           CMins, CMaxs;

 

      geVec3d           CameraMins, CameraMaxs;

 

      float             MoveSpeed;

      geBoolean         DoWalk = GE_FALSE;

      geXForm3d         XForm;

      GPlayer           *Player;

      GenVSI_CMove      *Move;

      geWorld           *World;

      uint32            ColFlags;

      CData             Data;

…………

.

// Get a box a little bigger than the player for doors, etc...

            CMins = Player->Mins;

            CMaxs = Player->Maxs;

            

      

            CMins.X -= 30 ;//caution : my own values in a rescaled Gtest

            CMins.Y -= 3;

            CMins.Z -= 30;

            CMaxs.X += 30 ;

            CMaxs.Y += 3;

            CMaxs.Z += 30;

 

 

//Insert this code right after the above

 

            CameraMins = Player->Mins;

            CameraMaxs = Player->Maxs;

      

            CameraMins.Y += 47;//caution : my own values in a rescaled Gtest

            CameraMaxs.Y -= 2 ;

            CameraMins.X += 8;

            CameraMaxs.X -= 8;

            CameraMins.Z += 8;

            CameraMaxs.Z -= 8;

            

      // (Rewrite here to add More sounds, Screen Notices and sure kill of player if they drowned)    

 

      

if (geWorld_GetContents(World, &Player->XForm.Translation, &CameraMins, 

        &CameraMaxs, GE_COLLIDE_MODELS, 0, NULL, NULL, &Contents))

            {

if (Contents.Contents & CONTENTS_WATER && Player->State == PSTATE_InWater)

            //camera AND player in water

GenVSI_PlaySound(VSI, SOUND_INDEX_WATERFALL,&Player->XForm.Translation);

            Player->TimeInWater += Time;

            }

      else if (Player->TimeInWater >= 7.0f)//player's head is no more under water

            {

      if (Player->State == PSTATE_InWater)//Player's body is in water

                  {

                  Player->TimeInWater = 0.0f;

                  GenVSI_SetClientHealth(VSI, Player->ClientHandle, Player->Health);

                  GenVSI_PlaySound(VSI, SOUND_INDEX_PICKUP_HEALTH,&Player->XForm.Translation);//breath

                  }

            }

 

else Player->TimeInWater = 0.0f; 

 

      if (Player->TimeInWater > 10.0f)

      {

      Player->Health -= 10;

GenVSI_ConsoleHeaderPrintf(VSI, Player->ClientHandle, GE_FALSE, "Go Get Some Air!");

      GenVSI_SetClientHealth(VSI, Player->ClientHandle, Player->Health);

      Player->TimeInWater = 7.0f;

}

      if (Player->Health <= 0) 

      {

GenVSI_ConsoleHeaderPrintf(VSI, Player->ClientHandle, GE_FALSE, "You Have Drowned Yourself!");

GenVSI_PlaySound(VSI, SOUND_INDEX_DIE,&Player->XForm.Translation);

      Player->Control = Player_Drowned;

      }     

 

 

 

 

 

 

Add to the very end of Gmain.c

 

//=====================================================================================

//    Player_Drowned

//=====================================================================================

static geBoolean Player_Drowned(GenVSI *VSI, void *PlayerData, float Time)

{

      GPlayer           *Player;

      GenVSI_CMove      *Move;

 

      Player = (GPlayer*)PlayerData;

 

      assert(Player->ClientHandle != CLIENT_NULL_HANDLE);

 

      Player->MotionIndex = ACTOR_MOTION_PLAYER_DIE;

      AnimatePlayer(VSI, Player, Player->MotionIndex, Time, GE_FALSE);

 

      Move = GenVSI_GetClientMove(VSI, Player->ClientHandle);

 

      Player->Roll -= 2.0f*Time;

 

      if (Player->Roll < -(3.14159f/2.0f))

      {

            Player->Roll = -(3.14159f/2.0f);

 

            if (Move->ButtonBits & HOST_BUTTON_FIRE)

            {

                  GPlayer     *DMStart;

                  

                  DMStart = (GPlayer*)GetDMSpawn(VSI);

 

                  Player->Roll = 0.0f;    

                  Player->Control = Client_Control;

                  Player->State = PSTATE_Normal;      

                  Player->MotionIndex = ACTOR_MOTION_PLAYER_RUN;

                  Player->FrameTime = 0.0f;

                  Player->ViewFlags &= ~VIEW_TYPE_FORCE_XFORM;

                  Player->XForm = DMStart->XForm;

                  GenVSI_SpawnFx(VSI, FX_EXPLODE2, &Player->XForm.Translation, SOUND_INDEX_PLAYER_SPAWN);

                  Player->Health = 100;

                  GenVSI_SetClientHealth(VSI, Player->ClientHandle, Player->Health);

                  return GE_TRUE;

            }

      }

 

      SetupPlayerXForm(VSI, Player, Time);

 

      PlayerPhysics(VSI, Player, PLAYER_GROUND_FRICTION, PLAYER_AIR_FRICTION, PLAYER_LIQUID_FRICTION, PLAYER_GRAVITY, 1.0f, GE_FALSE, Time);

 

      return GE_TRUE;

}

 

In Gmain.h around line 92

#define SOUND_INDEX_WATERFALL       31

 

In Level.c around line 104

GenVSI_SoundIndex(VSI, SOUND_INDEX_WATERFALL, "Wav\\Waterfal.Wav");

 

 

 

NB : you must add a variable in Gplayer.h

Float       TimeInWater ;           

 

Also you must add a water sound to your /wav directory called waterfal.wav

Or just kill/rename that part of the code.