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.