/*
=============
idPhysics_Actor::SetWaterLevel
=============
*/
void idPhysics_Actor::SetWaterLevel( void ) {
	idVec3		point;
	idVec3		origin;
	idBounds	bounds;
	int			contents;

	// get waterlevel, accounting for ducking
	waterLevel = WATERLEVEL_NONE;
	waterType = 0;

	origin = GetOrigin();
	bounds = clipModel->GetBounds();

	// check at feet level
	point = origin - ( bounds[0][2] + 1.0f ) * gravityNormal;
	contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self );
	if ( contents & MASK_WATER ) {
		// sets water entity
		SetWaterLevelf();

		waterType = contents;
		waterLevel = WATERLEVEL_FEET;

		// check at waist level
		point = origin - ( bounds[1][2] - bounds[0][2] ) * 0.5f * gravityNormal;
		contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self );
		if ( contents & MASK_WATER ) {
			waterLevel = WATERLEVEL_WAIST;

			// check at head level
			point = origin - ( bounds[1][2] - 1.0f ) * gravityNormal;
			contents = gameLocal.clip.Contents( point, NULL, mat3_identity, -1, self );
			if ( contents & MASK_WATER ) {
				waterLevel = WATERLEVEL_HEAD;
			}
		}
	} else {
		SetWater( NULL );
	}
}
Esempio n. 2
0
/*
================
idPhysics_Base::SetWaterLevelf

	Returns 1.0f if the object is in a liquid, 0.0f otherwise.

	If the object's not in a liquid it double checks to make sure it's really not.
	Normally we only set this->water when an object collides with a water material but
	what happens if an object spawns inside a liquid or something?  Nothing, it'll just sit
	there.  This function sets the water level for an object that's already inside the water.

	This was most noticeable when I had monsters walking into the water and of course, they'd 
	sink to the bottom.  After I'd kill them they'd die normally and not float.  After adding
	this function they float after they're killed.

================
*/
float idPhysics_Base::SetWaterLevelf() {
	if( this->water == NULL ) {
		idEntity *e[2];
		trace_t result;
		idBounds bounds = this->GetBounds();

		bounds += this->GetOrigin();

		// trace for a water contact
		// Tels: TODO This additional trace might be expensive because it is done every frame
		if( gameLocal.clip.EntitiesTouchingBounds(bounds,MASK_WATER,e,2) ) {
			if( e[0]->GetPhysics()->IsType(idPhysics_Liquid::Type) ) {
				SetWater( static_cast<idPhysics_Liquid *>(e[0]->GetPhysics()), e[0]->spawnArgs.GetFloat("murkiness", "0") );
				return 1.0f;
			}
		}

		this->m_fWaterMurkiness = 0.0f;
		return 0.0f;
	}
	else
		return 1.0f;
}