int LocationEditor::DoesRayHitBuilding(Vector3 const &rayStart, Vector3 const &rayDir) { Location *location = g_app->m_location; for (int i = 0; i < location->m_levelFile->m_buildings.Size(); i++) { if (!location->m_levelFile->m_buildings.ValidIndex(i)) continue; Building *building = location->m_levelFile->m_buildings.GetData(i); bool result = building->DoesRayHit(rayStart, rayDir); if (result) { return building->m_id.GetUniqueId(); } } return -1; }
Vector3 Entity::PushFromObstructions( Vector3 const &pos, bool killem ) { Vector3 result = pos; if( m_onGround ) { result.y = g_app->m_location->m_landscape.m_heightMap->GetValue( result.x, result.z ); } Matrix34 transform( m_front, g_upVector, result ); // // Push from Water if( result.y <= 1.0 ) { double pushAngle = syncsfrand(1.0); double distance = 0.0; while( distance < 50.0 ) { double angle = distance * pushAngle * M_PI; Vector3 offset( iv_cos(angle) * distance, 0.0, iv_sin(angle) * distance ); Vector3 newPos = result + offset; double height = g_app->m_location->m_landscape.m_heightMap->GetValue( newPos.x, newPos.z ); if( height > 1.0 ) { result = newPos; result.y = height; break; } distance += 1.0; } } // // Push from buildings LList<int> *buildings = g_app->m_location->m_obstructionGrid->GetBuildings( result.x, result.z ); for( int b = 0; b < buildings->Size(); ++b ) { int buildingId = buildings->GetData(b); Building *building = g_app->m_location->GetBuilding( buildingId ); if( building ) { bool hit = false; if( m_shape && building->DoesShapeHit( m_shape, transform ) ) hit = true; if( (!m_shape || m_type == TypeOfficer ) && building->DoesSphereHit( result, 1.0 ) ) hit = true; // cheap hack, but no point overriding the entire function for this one line if( !hit ) { Vector3 oldPos = m_pos - m_vel * SERVER_ADVANCE_PERIOD; if( building->DoesRayHit( oldPos, m_front, (m_pos - oldPos).Mag() ) ) hit = true; } if( hit ) { if( building->m_type == Building::TypeLaserFence && killem && ((LaserFence *) building)->IsEnabled()) { if( !g_app->m_location->IsFriend(building->m_id.GetTeamId(), m_id.GetTeamId() ) ) { ChangeHealth( -9999 ); ((LaserFence *) building)->Electrocute( m_pos ); } } else { Vector3 pushForce = (building->m_pos - result); pushForce.y = 0.0f; pushForce.SetLength(4.0f); while( building->DoesSphereHit( result, 2.0f ) ) { result -= pushForce; //result.y = g_app->m_location->m_landscape.m_heightMap->GetValue( result.x, result.z ); } } } } } return result; }