コード例 #1
0
ファイル: sv_phys.c プロジェクト: ACIIL/Quake
/*
=============
SV_CheckWaterTransition

=============
*/
void SV_CheckWaterTransition (edict_t *ent)
{
	int		cont;

	cont = SV_PointContents (ent->v.origin);
	if (!ent->v.watertype)
	{	// just spawned here
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
		return;
	}
	
	if (cont <= CONTENTS_WATER)
	{
		if (ent->v.watertype == CONTENTS_EMPTY)
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}		
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
	}
	else
	{
		if (ent->v.watertype != CONTENTS_EMPTY)
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}		
		ent->v.watertype = CONTENTS_EMPTY;
		ent->v.waterlevel = cont;
	}
}
コード例 #2
0
ファイル: sv_phys.c プロジェクト: bazilio-ua/fxquake
/*
=============
SV_CheckWaterTransition

=============
*/
void SV_CheckWaterTransition (edict_t *ent)
{
	int		cont;

	cont = SV_PointContents (ent->v.origin);

	if (cont == CONTENTS_WATER || cont == CONTENTS_SLIME || cont == CONTENTS_LAVA)		
	{
		if (ent->v.watertype == CONTENTS_EMPTY)
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}		
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
	}
	else
	{
		if (ent->v.watertype == CONTENTS_WATER || ent->v.watertype == CONTENTS_SLIME || ent->v.watertype == CONTENTS_LAVA)
		{	// just crossed out of water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}		
		ent->v.watertype = CONTENTS_EMPTY;
		ent->v.waterlevel = 0; // EER1 fix
	}
}
コード例 #3
0
ファイル: sv_phys.c プロジェクト: MaddTheSane/TenebraeQuake
void SV_Physics_Step (edict_t *ent)
{
	qboolean	hitsound;

// freefall if not onground
	if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) )
	{
		if (ent->v.velocity[2] < sv_gravity.value*-0.1)
			hitsound = true;
		else
			hitsound = false;

		SV_AddGravity (ent);
		SV_CheckVelocity (ent);
		SV_FlyMove (ent, host_frametime, NULL);
		SV_LinkEdict (ent, true);

		if ( (int)ent->v.flags & FL_ONGROUND )	// just hit ground
		{
			if (hitsound)
				SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
		}
	}

// regular thinking
	SV_RunThink (ent);
	
	SV_CheckWaterTransition (ent);
}
コード例 #4
0
/*
=============
SV_Physics_Step

Monsters freefall when they don't have a ground entity, otherwise
all movement is done with discrete steps.

This is also used for objects that have become still on the ground, but
will fall if the floor is pulled out from under them.
FIXME: is this true?
=============
*/
void SV_Physics_Step (edict_t *ent)
{
    qbool	hitsound;

// frefall if not onground
    if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) )
    {
        if (ent->v.velocity[2] < sv.movevars.gravity*-0.1)
            hitsound = true;
        else
            hitsound = false;

        SV_AddGravity (ent, 1.0);
        SV_CheckVelocity (ent);
        // Tonik: the check for SOLID_NOT is to fix the way dead bodies and
        // gibs behave (should not be blocked by players & monsters);
        // The SOLID_TRIGGER check is disabled lest we break frikbots
        if (ent->v.solid == SOLID_NOT /* || ent->v.solid == SOLID_TRIGGER*/)
            SV_FlyMove (ent, sv_frametime, NULL, MOVE_NOMONSTERS);
        else
            SV_FlyMove (ent, sv_frametime, NULL, MOVE_NORMAL);
        SV_LinkEdict (ent, true);

        if ( (int)ent->v.flags & FL_ONGROUND )	// just hit ground
        {
            if (hitsound)
                SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1, NULL);
        }
    }

// regular thinking
    SV_RunThink (ent);

    SV_CheckWaterTransition (ent);
}
コード例 #5
0
ファイル: host.c プロジェクト: ptitSeb/xash3d
/*
=================
Host_RestartAmbientSounds

Write ambient sounds into demo
=================
*/
void Host_RestartAmbientSounds( void )
{
	soundlist_t	soundInfo[64];
	string		curtrack, looptrack;
	int		i, nSounds;
	fs_offset_t	position;

	if( !SV_Active( ))
	{
		return;
	}

	nSounds = S_GetCurrentStaticSounds( soundInfo, 64 );
	
	for( i = 0; i < nSounds; i++ )
	{
		if( !soundInfo[i].looping || soundInfo[i].entnum == -1 )
			continue;

		MsgDev( D_NOTE, "Restarting sound %s...\n", soundInfo[i].name );
		S_StopSound( soundInfo[i].entnum, soundInfo[i].channel, soundInfo[i].name );
		SV_StartSound( pfnPEntityOfEntIndex( soundInfo[i].entnum ), CHAN_STATIC, soundInfo[i].name,
		soundInfo[i].volume, soundInfo[i].attenuation, 0, soundInfo[i].pitch );
	}

	// restart soundtrack
	if( S_StreamGetCurrentState( curtrack, looptrack, &position ))
	{
		SV_StartMusic( curtrack, looptrack, position );
	}
}
コード例 #6
0
ファイル: sv_phys.c プロジェクト: Blzut3/Engoo
/*
=============
SV_CheckWaterTransition

=============
*/
void SV_CheckWaterTransition (edict_t *ent)
{
	int		cont;
	vec3_t	point;

	point[0] = ent->v.origin[0];
	point[1] = ent->v.origin[1];
	point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;
	cont = SV_PointContents (ent->v.origin);

	if (!ent->v.watertype)
	{	// just spawned here
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
		return;
	}

	if (cont <= CONTENTS_WATER)
	{
		if (ent->v.watertype == CONTENTS_EMPTY)
		{	// just crossed into water

			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		
		}
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
	}
	else
	{
		if (ent->v.watertype != CONTENTS_EMPTY)
		{	// just crossed into water
		//	vec3_t nothin;
	//		nothin[0] = ent->v.velocity[0] * -0.1;
	//		nothin[1] = ent->v.velocity[1] * -0.1;
	//		nothin[2] = ent->v.velocity[2] * -0.5;
	//		R_ParticleBloodSplash(point, nothin, 44);
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
			//R_Splash(point, ent->v.velocity, 85, 36, ent->v.velocity[2]);
			
			
		}
		ent->v.watertype = CONTENTS_EMPTY;
		ent->v.waterlevel = cont;
	}
	
}
コード例 #7
0
ファイル: sv_pmove.c プロジェクト: steadyfield/xash3d
static void pfnPlaySound( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch )
{
    edict_t	*ent;

    ent = EDICT_NUM( svgame.pmove->player_index + 1 );
    if( !SV_IsValidEdict( ent )) return;

    SV_StartSound( ent, channel, sample, volume, attenuation, fFlags, pitch );
}
コード例 #8
0
ファイル: sv_phys.c プロジェクト: MaddTheSane/TenebraeQuake
/*
=============
SV_CheckWaterTransition

=============
*/
void SV_CheckWaterTransition (edict_t *ent)
{
	int		cont;
#ifdef QUAKE2
	vec3_t	point;
	
	point[0] = ent->v.origin[0];
	point[1] = ent->v.origin[1];
	point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;	
	cont = SV_PointContents (point);
#else
	cont = SV_PointContents (ent->v.origin);
#endif
	if (!ent->v.watertype)
	{	// just spawned here
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
		return;
	}
	
	if (cont <= CONTENTS_WATER)
	{
		if (ent->v.watertype == CONTENTS_EMPTY)
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}		
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
	}
	else
	{
		if ((ent->v.watertype != CONTENTS_EMPTY)&&(ent->v.watertype != CONTENTS_SOLID)) 
		//Added extra check to stop splashing bug (thx to DrLabMan for tip) - Eradicator
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}		
		ent->v.watertype = CONTENTS_EMPTY;
		ent->v.waterlevel = cont;
	}
}
コード例 #9
0
ファイル: sv_phys.c プロジェクト: st1x51/QuartalEngine
/*
=============
SV_CheckWaterTransition

=============
*/
void SV_CheckWaterTransition (edict_t *ent)
{
	int		cont;
#ifdef QUAKE2
	vec3_t	point;

	point[0] = ent->v.origin[0];
	point[1] = ent->v.origin[1];
	point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;
	cont = SV_PointContents (point);
#else
	cont = SV_PointContents (ent->v.origin);
#endif
	if (!ent->v.watertype)
	{	// just spawned here
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
		return;
	}

	if (cont <= CONTENTS_WATER)
	{
		if (ent->v.watertype == CONTENTS_EMPTY)
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
	}
	else
	{
		if (ent->v.watertype != CONTENTS_EMPTY)
		{	// just crossed into water
			SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
		}
		ent->v.watertype = CONTENTS_EMPTY;
		ent->v.waterlevel = cont;
	}
}
コード例 #10
0
ファイル: sv_phys.c プロジェクト: SpiritQuaddicted/reQuiem
/*
=============
SV_Physics_Step

Monsters freefall when they don't have a ground entity, otherwise
all movement is done with discrete steps.

This is also used for objects that have become still on the ground, but
will fall if the floor is pulled out from under them.
=============
*/
void SV_Physics_Step (edict_t *ent)
{
	qboolean	hitsound;
	char		*snd;

// freefall if not onground
	if (!((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM)))
	{
		if (ent->v.velocity[2] < sv_gravity.value*-0.1)
			hitsound = true;
		else
			hitsound = false;

		SV_AddGravity (ent);
		SV_CheckVelocity (ent);
		SV_FlyMove (ent, host_frametime, NULL);
		SV_LinkEdict (ent, true);

		if ((int)ent->v.flags & FL_ONGROUND)	// just hit ground
#ifdef HEXEN2_SUPPORT
		if (!hexen2 || (!ent->v.flags & FL_MONSTER))
#endif
		{
			if (hitsound)
			{
			#ifdef HEXEN2_SUPPORT
				if (hexen2)
					snd = "fx/thngland.wav";
				else
			#endif
				snd = "demon/dland2.wav";
				SV_StartSound (ent, 0, snd, 255, 1);
			}
		}
	}

// regular thinking
	SV_RunThink (ent);
	
	SV_CheckWaterTransition (ent);
}
コード例 #11
0
ファイル: sv_phys.c プロジェクト: MaddTheSane/TenebraeQuake
void SV_Physics_Step (edict_t *ent)
{
	qboolean	wasonground;
	qboolean	inwater;
	qboolean	hitsound = false;
	float		*vel;
	float		speed, newspeed, control;
	float		friction;
	edict_t		*groundentity;

	groundentity = PROG_TO_EDICT(ent->v.groundentity);
	if ((int)groundentity->v.flags & FL_CONVEYOR)
		VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity);
	else
		VectorCopy(vec_origin, ent->v.basevelocity);
//@@
	pr_global_struct->time = sv.time;
	pr_global_struct->self = EDICT_TO_PROG(ent);
	PF_WaterMove();

	SV_CheckVelocity (ent);

	wasonground = (int)ent->v.flags & FL_ONGROUND;
//	ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;

	// add gravity except:
	//   flying monsters
	//   swimming monsters who are in the water
	inwater = SV_CheckWater(ent);
	if (! wasonground)
		if (!((int)ent->v.flags & FL_FLY))
			if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0)))
			{
				if (ent->v.velocity[2] < sv_gravity.value*-0.1)
					hitsound = true;
				if (!inwater)
					SV_AddGravity (ent);
			}

	if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin))
	{
		ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
		// apply friction
		// let dead monsters who aren't completely onground slide
		if (wasonground)
			if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent)))
			{
				vel = ent->v.velocity;
				speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
				if (speed)
				{
					friction = sv_friction.value;

					control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
					newspeed = speed - host_frametime*control*friction;

					if (newspeed < 0)
						newspeed = 0;
					newspeed /= speed;

					vel[0] = vel[0] * newspeed;
					vel[1] = vel[1] * newspeed;
				}
			}

		VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
		SV_FlyMove (ent, host_frametime, NULL);
		VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);

		// determine if it's on solid ground at all
		{
			vec3_t	mins, maxs, point;
			int		x, y;
		
			VectorAdd (ent->v.origin, ent->v.mins, mins);
			VectorAdd (ent->v.origin, ent->v.maxs, maxs);

			point[2] = mins[2] - 1;
			for	(x=0 ; x<=1 ; x++)
				for	(y=0 ; y<=1 ; y++)
				{
					point[0] = x ? maxs[0] : mins[0];
					point[1] = y ? maxs[1] : mins[1];
					if (SV_PointContents (point) == CONTENTS_SOLID)
					{
						ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
						break;
					}
				}

		}

		SV_LinkEdict (ent, true);

		if ((int)ent->v.flags & FL_ONGROUND)
			if (!wasonground)
				if (hitsound)
					SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
	}

// regular thinking
	SV_RunThink (ent);
	SV_CheckWaterTransition (ent);
}
コード例 #12
0
void EXT_FUNC SV_StartSound_api(int recipients, edict_t *entity, int channel, const char *sample, int volume, float attenuation, int flags, int pitch) {
	SV_StartSound(recipients, entity, channel, sample, volume, attenuation, flags, pitch);
}
コード例 #13
0
ファイル: sv_phys.c プロジェクト: THE-Swank/xash3d
/*
=============
SV_CheckWaterTransition

=============
*/
void SV_CheckWaterTransition( edict_t *ent )
{
	int	cont;
	vec3_t	halfmax;

	halfmax[0] = (ent->v.absmax[0] + ent->v.absmin[0]) * 0.5f;
	halfmax[1] = (ent->v.absmax[1] + ent->v.absmin[1]) * 0.5f;
	halfmax[2] = (ent->v.absmin[2] + 1.0f);

	svs.groupmask = ent->v.groupinfo;
	cont = SV_PointContents( halfmax );

	if( !ent->v.watertype )
	{
		// just spawned here
		ent->v.watertype = cont;
		ent->v.waterlevel = 1;
		return;
	}

	if( cont > CONTENTS_WATER || cont <= CONTENTS_TRANSLUCENT )
	{
		if( ent->v.watertype != CONTENTS_EMPTY )
		{
			SV_StartSound( ent, CHAN_AUTO, "player/pl_wade2.wav", 1.0f, ATTN_NORM, 0, 100 );
		}

		ent->v.watertype = CONTENTS_EMPTY;
		ent->v.waterlevel = 0;
		return;
	}

	if( ent->v.watertype == CONTENTS_EMPTY )
	{
		SV_StartSound( ent, CHAN_AUTO, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 );
		ent->v.velocity[2] *= 0.5f;
	}

	ent->v.watertype = cont;
	ent->v.waterlevel = 1;

	if( ent->v.absmin[2] == ent->v.absmax[2] )
	{
		// a point entity
		ent->v.waterlevel = 3;
	}

	halfmax[2] = (ent->v.absmin[2] + ent->v.absmax[2]) * 0.5f;

	svs.groupmask = ent->v.groupinfo;
	cont = SV_PointContents( halfmax );

	if( cont > CONTENTS_WATER || cont <= CONTENTS_TRANSLUCENT )
		return;

	ent->v.waterlevel = 2;
	VectorAdd( halfmax, ent->v.view_ofs, halfmax );

	svs.groupmask = ent->v.groupinfo;
	cont = SV_PointContents( halfmax );

	if( cont > CONTENTS_WATER || cont <= CONTENTS_TRANSLUCENT )
		return;

	ent->v.waterlevel = 3;
}
コード例 #14
0
void PF_WaterMove(edict_t * ent) {

   double var_10;
   int var_4_flags;
   int var_8_waterlevel;
   int var_c_watertype;
  // double var_14; //some sort of damage counter, but it keeps not being used...


   if(ent->v.movetype == MOVETYPE_NOCLIP) {

      ent->v.air_finished = 12 + global_sv.time0c;
      return;
   }

   if(ent->v.health <= 0) { return; }

   if(ent->v.deadflag == 0) {
      var_10 = 3;
   }
   else {
      var_10 = 1;
   }

   var_4_flags = ent->v.flags;
   var_8_waterlevel = ent->v.waterlevel;
   var_c_watertype = ent->v.watertype;

   //This area is almost but not quite entirely unlike the drowning code in the SDK.
   if((var_4_flags & (FL_IMMUNE_WATER | FL_GODMODE)) == 0) { //Gods don't drown, unless they're Bruce Willis

      if(((var_4_flags & FL_SWIM) && var_8_waterlevel > var_10) ||
         var_8_waterlevel <= var_10) {

         if(ent->v.air_finished > global_sv.time0c && ent->v.pain_finished > global_sv.time0c) {

            ent->v.dmg += 2;
            if(ent->v.dmg < 15) {

               ent->v.dmg = 10; //wha?
            }

            //var_14 = ent->v.dmg;
            ent->v.pain_finished = 1 + global_sv.time0c;
         }
      }
      else {

        // if(ent->v.air_finished <= global_sv.time0c) {
        //    if(ent->v.air_finished <= 0 + global_sv.time0c) { }
        // }

         ent->v.air_finished = 12 + global_sv.time0c;
         ent->v.dmg = 2;
      }
   }

   //This is asmess
   if(var_8_waterlevel == 0) {

      if((var_4_flags & FL_INWATER) != 0) {

         //Leave the water.
         switch(RandomLong(0, 3)) {

         case 0:
            SV_StartSound(0, ent, 4, "player/pl_wade1.wav", 255, 0.8, 0, 100);
            break;

         case 1:
            SV_StartSound(0, ent, 4, "player/pl_wade2.wav", 255, 0.8, 0, 100);
            break;

         case 2:
            SV_StartSound(0, ent, 4, "player/pl_wade3.wav", 255, 0.8, 0, 100);
            break;

         case 3:
            SV_StartSound(0, ent, 4, "player/pl_wade4.wav", 255, 0.8, 0, 100);
            break;
         }

         ent->v.flags = var_4_flags & ~FL_INWATER;
      }
      ent->v.air_finished = 12 + global_sv.time0c;
      return;
   }


   if(var_c_watertype == Q1CONTENTS_LAVA) { //aah, it stings and burns
      if(((var_4_flags & (FL_IMMUNE_LAVA | FL_GODMODE)) == 0) &&
         ent->v.dmgtime < global_sv.time0c) {

         if(ent->v.radsuit_finished < global_sv.time0c) {
            ent->v.dmgtime = global_sv.time0c + 0.2;
         }
         else {
            ent->v.dmgtime = global_sv.time0c + 1.0;
         }
        // var_14 = var_8_waterlevel * 10;
      }
   }
   else if(var_c_watertype == Q1CONTENTS_SLIME) {

      if(((var_4_flags & (FL_IMMUNE_SLIME | FL_GODMODE)) == 0) &&
           ent->v.dmgtime < global_sv.time0c &&
           ent->v.radsuit_finished < global_sv.time0c) {

         ent->v.dmgtime = global_sv.time0c + 1.0;
        // var_14 = var_8_waterlevel * 4;
      }
   }

   if((var_4_flags & FL_INWATER) == 0) {

      if(var_c_watertype == Q1CONTENTS_WATER) {

         switch(RandomLong(0, 3)) {

         case 0:
            SV_StartSound(0, ent, 4, "player/pl_wade1.wav", 255, 0.8, 0, 100);
            break;

         case 1:
            SV_StartSound(0, ent, 4, "player/pl_wade2.wav", 255, 0.8, 0, 100);
            break;

         case 2:
            SV_StartSound(0, ent, 4, "player/pl_wade3.wav", 255, 0.8, 0, 100);
            break;

         case 3:
            SV_StartSound(0, ent, 4, "player/pl_wade4.wav", 255, 0.8, 0, 100);
            break;
         }
      }

      ent->v.flags = var_4_flags | FL_INWATER;
      ent->v.dmgtime = 0;
   }

   if((var_4_flags & FL_WATERJUMP) == 0) {

      VectorMA(ent->v.velocity, (ent->v.waterlevel * -0.8 * host_frametime), ent->v.velocity, ent->v.velocity);
   }
}
コード例 #15
0
ファイル: sv_move.c プロジェクト: DeadZoneLuna/xash3d
void SV_WaterMove( edict_t *ent )
{
	float	drownlevel;
	int	waterlevel;
	int	watertype;
	int	flags;

	if( ent->v.movetype == MOVETYPE_NOCLIP )
	{
		ent->v.air_finished = sv.time + 12.0f;
		return;
	}

	// no watermove for monsters but pushables
	if(( ent->v.flags & FL_MONSTER ) && ent->v.health <= 0.0f )
		return;

	drownlevel = (ent->v.deadflag == DEAD_NO) ? 3.0 : 1.0;
	waterlevel = ent->v.waterlevel;
	watertype = ent->v.watertype;
	flags = ent->v.flags;

	if( !( flags & ( FL_IMMUNE_WATER|FL_GODMODE )))
	{
		if((( flags & FL_SWIM ) && waterlevel > drownlevel ) || waterlevel <= drownlevel )
		{
			if( ent->v.air_finished > sv.time && ent->v.pain_finished > sv.time )
			{
				ent->v.dmg += 2;

				if( ent->v.dmg < 15 )
					ent->v.dmg = 10; // quake1 original code
				ent->v.pain_finished = sv.time + 1.0f;
			}
		}
		else
		{
			ent->v.air_finished = sv.time + 12.0f;
			ent->v.dmg = 2;
		}
	}

	if( !waterlevel )
	{
		if( flags & FL_INWATER )
		{
			// leave the water.
			switch( Com_RandomLong( 0, 3 ))
			{
			case 0:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			case 1:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade2.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			case 2:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade3.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			case 3:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade4.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			}

			ent->v.flags = flags & ~FL_INWATER;
		}

		ent->v.air_finished = sv.time + 12.0f;
		return;
	}

	if( watertype == CONTENTS_LAVA )
	{
		if((!( flags & ( FL_IMMUNE_LAVA|FL_GODMODE ))) && ent->v.dmgtime < sv.time )
		{
			if( ent->v.radsuit_finished < sv.time )
				ent->v.dmgtime = sv.time + 0.2f;
			else ent->v.dmgtime = sv.time + 1.0f;
		}
	}
	else if( watertype == CONTENTS_SLIME )
	{
		if((!( flags & ( FL_IMMUNE_SLIME|FL_GODMODE ))) && ent->v.dmgtime < sv.time )
		{
			if( ent->v.radsuit_finished < sv.time )
				ent->v.dmgtime = sv.time + 1.0;
			// otherwise radsuit is fully protect entity from slime
		}
	}

	if( !( flags & FL_INWATER ))
	{
		if( watertype == CONTENTS_WATER )
		{
			// entering the water
			switch( Com_RandomLong( 0, 3 ))
			{
			case 0:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade1.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			case 1:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade2.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			case 2:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade3.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			case 3:
				SV_StartSound( ent, CHAN_BODY, "player/pl_wade4.wav", 1.0f, ATTN_NORM, 0, 100 );
				break;
			}
		}

		ent->v.flags = flags | FL_INWATER;
		ent->v.dmgtime = 0.0f;
	}

	if( !( flags & FL_WATERJUMP ))
	{
		VectorMA( ent->v.velocity, ( ent->v.waterlevel * -0.8f * host.frametime ), ent->v.velocity, ent->v.velocity );
	}
}