void CBlobElement::ModifyVelocityForSurface( float flInterval, float flSpeed ) { trace_t tr; Vector vecStart = GetAbsOrigin(); Vector up = Vector( 0, 0, BLOB_TRACE_HEIGHT ); Vector vecWishedGoal = vecStart + (GetAbsVelocity() * flInterval); UTIL_TraceLine( vecStart + up, vecWishedGoal + up, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); //NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 0, 0, false, 0.1f ); m_bOnWall = false; if( tr.fraction == 1.0f ) { UTIL_TraceLine( vecWishedGoal + up, vecWishedGoal - (up * 2.0f), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); //NDebugOverlay::Line( tr.startpos, tr.endpos, 255, 255, 0, false, 0.1f ); tr.endpos.z += MOVE_HEIGHT_EPSILON; } else { //NDebugOverlay::Cross3D( GetAbsOrigin(), 16, 255, 255, 0, false, 0.025f ); m_bOnWall = true; if( tr.m_pEnt != NULL && !tr.m_pEnt->IsWorld() ) { IPhysicsObject *pPhysics = tr.m_pEnt->VPhysicsGetObject(); if( pPhysics != NULL ) { Vector vecMassCenter; Vector vecMassCenterWorld; vecMassCenter = pPhysics->GetMassCenterLocalSpace(); pPhysics->LocalToWorld( &vecMassCenterWorld, vecMassCenter ); if( tr.endpos.z > vecMassCenterWorld.z ) { pPhysics->ApplyForceOffset( (-150.0f * m_flRandomEightyPercent) * tr.plane.normal, tr.endpos ); } } } } Vector vecDir = tr.endpos - vecStart; VectorNormalize( vecDir ); SetElementVelocity( vecDir * flSpeed, false ); }
void CWeaponGravityGun::EffectUpdate( void ) { Vector start, forward, right; trace_t tr; CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if ( !pOwner ) return; pOwner->EyeVectors( &forward, &right, NULL ); start = pOwner->Weapon_ShootPosition(); TraceLine( &tr ); Vector end = tr.endpos; float distance = tr.fraction * 4096; if ( m_hObject == NULL && tr.DidHitNonWorldEntity() ) { CBaseEntity *pEntity = tr.m_pEnt; AttachObject( pEntity, GetPhysObjFromPhysicsBone( pEntity, tr.physicsbone ), tr.physicsbone, start, tr.endpos, distance ); } // Add the incremental player yaw to the target transform QAngle angles = m_gravCallback.TransformAnglesFromPlayerSpace( m_gravCallback.m_targetRotation, pOwner ); CBaseEntity *pObject = m_hObject; if ( pObject ) { if ( m_useDown ) { if ( pOwner->m_afButtonPressed & IN_USE ) { m_useDown = false; } } else { if ( pOwner->m_afButtonPressed & IN_USE ) { m_useDown = true; } } if ( m_useDown ) { #ifndef CLIENT_DLL pOwner->SetPhysicsFlag( PFLAG_DIROVERRIDE, true ); #endif if ( pOwner->m_nButtons & IN_FORWARD ) { m_distance = Approach( 1024, m_distance, gpGlobals->frametime * 100 ); } if ( pOwner->m_nButtons & IN_BACK ) { m_distance = Approach( 40, m_distance, gpGlobals->frametime * 100 ); } } if ( pOwner->m_nButtons & IN_WEAPON1 ) { m_distance = Approach( 1024, m_distance, m_distance * 0.1 ); } if ( pOwner->m_nButtons & IN_WEAPON2 ) { m_distance = Approach( 40, m_distance, m_distance * 0.1 ); } IPhysicsObject *pPhys = GetPhysObjFromPhysicsBone( pObject, m_physicsBone ); if ( pPhys ) { if ( pPhys->IsAsleep() ) { // on the odd chance that it's gone to sleep while under anti-gravity pPhys->Wake(); } Vector newPosition = start + forward * m_distance; Vector offset; pPhys->LocalToWorld( &offset, m_worldPosition ); Vector vecOrigin; pPhys->GetPosition( &vecOrigin, NULL ); m_gravCallback.SetTargetPosition( newPosition + (vecOrigin - offset), angles ); Vector dir = (newPosition - pObject->GetLocalOrigin()); m_movementLength = dir.Length(); } } else { m_targetPosition = end; //m_gravCallback.SetTargetPosition( end, m_gravCallback.m_targetRotation ); } }