/* ============= 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 ); } }
/* ================ 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; }