//----------------------------------------------------------------------------- // Purpose: Items that have just spawned run this think to catch them when // they hit the ground. Once we're sure that the object is grounded, // we change its solid type to trigger and set it in a large box that // helps the player get it. //----------------------------------------------------------------------------- void CBaseCombatWeapon::FallThink ( void ) { SetNextThink( gpGlobals->curtime + 0.1f ); bool shouldMaterialize = false; IPhysicsObject *pPhysics = VPhysicsGetObject(); if ( pPhysics ) { shouldMaterialize = pPhysics->IsAsleep(); } else { shouldMaterialize = (GetFlags() & FL_ONGROUND) ? true : false; } if ( shouldMaterialize ) { // clatter if we have an owner (i.e., dropped by someone) // don't clatter if the gun is waiting to respawn (if it's waiting, it is invisible!) if ( GetOwnerEntity() ) { EmitSound( "BaseCombatWeapon.WeaponDrop" ); } Materialize(); } }
//----------------------------------------------------------------------------- // Purpose: Items that have just spawned run this think to catch them when // they hit the ground. Once we're sure that the object is grounded, // we change its solid type to trigger and set it in a large box that // helps the player get it. //----------------------------------------------------------------------------- void CItem::FallThink ( void ) { SetNextThink( gpGlobals->curtime + 0.1f ); bool shouldMaterialize = false; IPhysicsObject *pPhysics = VPhysicsGetObject(); if ( pPhysics ) { shouldMaterialize = pPhysics->IsAsleep(); } else { shouldMaterialize = (GetFlags() & FL_ONGROUND) ? true : false; } if ( shouldMaterialize ) { SetThink ( NULL ); m_vOriginalSpawnOrigin = GetAbsOrigin(); m_vOriginalSpawnAngles = GetAbsAngles(); HL2MPRules()->AddLevelDesignerPlacedObject( this ); } }
void CNPC_Portal_FloorTurret::InactiveThink( void ) { LaserOff(); RopesOff(); // Update our PVS state CheckPVSCondition(); SetNextThink( gpGlobals->curtime + 1.0f ); // Wake up if we're not on our side if ( !OnSide() && VPhysicsGetObject()->GetContactPoint( NULL, NULL ) && m_bEnabled ) { // Never return to life! SetCollisionGroup( COLLISION_GROUP_NONE ); //ReturnToLife(); } else { IPhysicsObject *pTurretPhys = VPhysicsGetObject(); if ( !(pTurretPhys->GetGameFlags() & FVPHYSICS_PLAYER_HELD) && pTurretPhys->IsAsleep() ) SetCollisionGroup( COLLISION_GROUP_DEBRIS_TRIGGER ); else SetCollisionGroup( COLLISION_GROUP_NONE ); } }
//----------------------------------------------------------------------------- // Computes the surrounding collision bounds based on the current sequence box //----------------------------------------------------------------------------- void CCollisionProperty::ComputeOBBBounds( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) { bool bUseVPhysics = false; if ( ( GetSolid() == SOLID_VPHYSICS ) && ( GetOuter()->GetMoveType() == MOVETYPE_VPHYSICS ) ) { // UNDONE: This may not be necessary any more. IPhysicsObject *pPhysics = GetOuter()->VPhysicsGetObject(); bUseVPhysics = pPhysics && pPhysics->IsAsleep(); } ComputeCollisionSurroundingBox( bUseVPhysics, pVecWorldMins, pVecWorldMaxs ); }
void CHL2MPRules::ManageObjectRelocation( void ) { int iTotal = m_hRespawnableItemsAndWeapons.Count(); if ( iTotal > 0 ) { for ( int i = 0; i < iTotal; i++ ) { CBaseEntity *pObject = m_hRespawnableItemsAndWeapons[i].Get(); if ( pObject ) { Vector vSpawOrigin; QAngle vSpawnAngles; if ( GetObjectsOriginalParameters( pObject, vSpawOrigin, vSpawnAngles ) == true ) { float flDistanceFromSpawn = (pObject->GetAbsOrigin() - vSpawOrigin ).Length(); if ( flDistanceFromSpawn > WEAPON_MAX_DISTANCE_FROM_SPAWN ) { bool shouldReset = false; IPhysicsObject *pPhysics = pObject->VPhysicsGetObject(); if ( pPhysics ) { shouldReset = pPhysics->IsAsleep(); } else { shouldReset = (pObject->GetFlags() & FL_ONGROUND) ? true : false; } if ( shouldReset ) { pObject->Teleport( &vSpawOrigin, &vSpawnAngles, NULL ); pObject->EmitSound( "AlyxEmp.Charge" ); IPhysicsObject *pPhys = pObject->VPhysicsGetObject(); if ( pPhys ) { pPhys->Wake(); } } } } } } } }
void CRagdollLRURetirement::Update( float frametime ) // Non-episodic version { VPROF( "CRagdollLRURetirement::Update" ); // Compress out dead items int i, next; int iMaxRagdollCount = m_iMaxRagdolls; if ( iMaxRagdollCount == -1 ) { iMaxRagdollCount = g_ragdoll_maxcount.GetInt(); } // fade them all for the low violence version if ( g_RagdollLVManager.IsLowViolence() ) { iMaxRagdollCount = 0; } m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); if ( pRagdoll ) { m_iRagdollCount++; IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if (pObject && !pObject->IsAsleep()) { m_iSimulatedRagdollCount++; } if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. if ( ShouldRemoveThisRagdoll( m_LRU[i] ) == true ) { #ifdef CLIENT_DLL m_LRU[ i ]->SUB_Remove(); #else m_LRU[ i ]->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); return; } } } else { m_LRU.Remove(i); } } ////////////////////////////// /// ORIGINAL ALGORITHM /// ////////////////////////////// // not episodic -- this is the original mechanism for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { if ( m_LRU.Count() <= iMaxRagdollCount ) break; next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); //Just ignore it until we're done burning/dissolving. if ( pRagdoll && pRagdoll->GetEffectEntity() ) continue; #ifdef CLIENT_DLL m_LRU[ i ]->SUB_Remove(); #else m_LRU[ i ]->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } }
void CRagdollLRURetirement::Update( float frametime ) // EPISODIC VERSION { VPROF( "CRagdollLRURetirement::Update" ); // Compress out dead items int i, next; int iMaxRagdollCount = m_iMaxRagdolls; if ( iMaxRagdollCount == -1 ) { iMaxRagdollCount = g_ragdoll_maxcount.GetInt(); } // fade them all for the low violence version if ( g_RagdollLVManager.IsLowViolence() ) { iMaxRagdollCount = 0; } m_iRagdollCount = 0; m_iSimulatedRagdollCount = 0; // First, find ragdolls that are good candidates for deletion because they are not // visible at all, or are in a culled visibility box for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); if ( pRagdoll ) { m_iRagdollCount++; IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if (pObject && !pObject->IsAsleep()) { m_iSimulatedRagdollCount++; } if ( m_LRU.Count() > iMaxRagdollCount ) { //Found one, we're done. if ( ShouldRemoveThisRagdoll( m_LRU[i] ) == true ) { #ifdef CLIENT_DLL m_LRU[ i ]->SUB_Remove(); #else m_LRU[ i ]->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); return; } } } else { m_LRU.Remove(i); } } ////////////////////////////// /// EPISODIC ALGORITHM /// ////////////////////////////// // If we get here, it means we couldn't find a suitable ragdoll to remove, // so just remove the furthest one. int furthestOne = m_LRU.Head(); float furthestDistSq = 0; #ifdef CLIENT_DLL C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); #else CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); #endif if (pPlayer && m_LRU.Count() > iMaxRagdollCount) // find the furthest one algorithm { Vector PlayerOrigin = pPlayer->GetAbsOrigin(); // const CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { CBaseAnimating *pRagdoll = m_LRU[i].Get(); next = m_LRU.Next(i); IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) ) continue; if ( pRagdoll ) { // float distToPlayer = (pPlayer->GetAbsOrigin() - pRagdoll->GetAbsOrigin()).LengthSqr(); float distToPlayer = (PlayerOrigin - pRagdoll->GetAbsOrigin()).LengthSqr(); if (distToPlayer > furthestDistSq) { furthestOne = i; furthestDistSq = distToPlayer; } } else // delete bad rags first. { furthestOne = i; break; } } #ifdef CLIENT_DLL m_LRU[ furthestOne ]->SUB_Remove(); #else m_LRU[ furthestOne ]->SUB_StartFadeOut( 0 ); #endif } else // fall back on old-style pick the oldest one algorithm { for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next ) { if ( m_LRU.Count() <= iMaxRagdollCount ) break; next = m_LRU.Next(i); CBaseAnimating *pRagdoll = m_LRU[i].Get(); //Just ignore it until we're done burning/dissolving. IPhysicsObject *pObject = pRagdoll->VPhysicsGetObject(); if ( pRagdoll && (pRagdoll->GetEffectEntity() || ( pObject && !pObject->IsAsleep()) ) ) continue; #ifdef CLIENT_DLL m_LRU[ i ]->SUB_Remove(); #else m_LRU[ i ]->SUB_StartFadeOut( 0 ); #endif m_LRU.Remove(i); } } }
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 ); } }
//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Dog::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_DOG_PICKUP_ITEM: { PullObject( false ); } break; case TASK_DOG_GET_PATH_TO_PHYSOBJ: { //Check this cause our object might have been deleted. if ( m_hPhysicsEnt == NULL ) FindPhysicsObject( NULL ); //And if we still can't find anything, then just go away. if ( m_hPhysicsEnt == NULL ) { TaskFail( "Can't find an object I like!" ); return; } IPhysicsObject *pPhysicsObject = m_hPhysicsEnt->VPhysicsGetObject(); Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; if ( m_hPhysicsEnt->GetOwnerEntity() == NULL ) m_hPhysicsEnt->SetOwnerEntity( this ); if ( pPhysicsObject ) pPhysicsObject->RecheckCollisionFilter(); vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); bool bBuiltRoute = false; //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; bBuiltRoute = GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); if ( bBuiltRoute == true ) TaskComplete(); else { m_flTimeToCatch = gpGlobals->curtime + 0.1; m_flNextRouteTime = gpGlobals->curtime + 0.3; m_flNextSwat = gpGlobals->curtime + 0.1; if ( m_hUnreachableObjects.Find( m_hPhysicsEnt ) == -1 ) m_hUnreachableObjects.AddToTail( m_hPhysicsEnt ); m_hPhysicsEnt = NULL; GetNavigator()->ClearGoal(); } } break; case TASK_WAIT: { if ( IsWaitFinished() ) { TaskComplete(); } if ( m_hPhysicsEnt ) { if ( m_bHasObject == false ) { GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() ); GetMotor()->UpdateYaw(); } } break; } case TASK_DOG_LAUNCH_ITEM: if( IsActivityFinished() ) { if ( m_hPhysicsEnt ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); } TaskComplete(); } break; case TASK_DOG_WAIT_FOR_TARGET_TO_FACE: { if ( CanTargetSeeMe() ) TaskComplete(); } break; case TASK_WAIT_FOR_MOVEMENT: { if ( GetState() == NPC_STATE_SCRIPT || IsInAScript() ) { BaseClass::RunTask( pTask ); return; } if ( m_hPhysicsEnt != NULL ) { IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( !pPhysObj ) { Warning( "npc_dog TASK_WAIT_FOR_MOVEMENT with NULL m_hPhysicsEnt->VPhysicsGetObject\n" ); } if ( pPhysObj && pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) TaskFail( "Player picked it up!" ); //If the object is moving then my old goal might not be valid //cancel the schedule and make it restart again in a bit. if ( pPhysObj && pPhysObj->IsAsleep() == false && GetNavigator()->IsGoalActive() == false ) { Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); GetNavigator()->ClearGoal(); float flDistance = (vecGoalPos - GetLocalOrigin()).Length(); //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); if ( flDistance <= DOG_PHYSOBJ_MOVE_TO_DIST ) { TaskComplete(); GetNavigator()->StopMoving(); } } } BaseClass::RunTask( pTask ); } break; case TASK_DOG_WAIT_FOR_OBJECT: { if ( m_hPhysicsEnt != NULL ) { if ( FVisible( m_hPhysicsEnt ) == false ) { m_flTimeToCatch = 0.0f; ClearBeams(); TaskFail( "Lost sight of the object!" ); m_hPhysicsEnt->SetOwnerEntity( NULL ); return; } m_hPhysicsEnt->SetOwnerEntity( this ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); Vector vGunPos; GetAttachment( m_iPhysGunAttachment, vGunPos ); Vector vToObject = m_hPhysicsEnt->WorldSpaceCenter() - vGunPos; float flDistance = vToObject.Length(); VectorNormalize( vToObject ); SetAim( m_hPhysicsEnt->WorldSpaceCenter() - GetAbsOrigin() ); #ifdef SecobMod__Enable_Fixed_Multiplayer_AI CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(this); #else CBasePlayer *pPlayer = AI_GetSinglePlayer(); #endif //SecobMod__Enable_Fixed_Multiplayer_AI float flDistanceToPlayer = flDistance; if ( pPlayer ) { flDistanceToPlayer = (pPlayer->GetAbsOrigin() - m_hPhysicsEnt->WorldSpaceCenter()).Length(); } IPhysicsObject *pPhysObj = m_hPhysicsEnt->VPhysicsGetObject(); if ( !pPhysObj ) { Warning( "npc_dog: TASK_DOG_WAIT_FOR_OBJECT with m_hPhysicsEnt->VPhysicsGetObject == NULL\n" ); } if ( pPhysObj && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) && flDistanceToPlayer > ( flDistance * 2 ) ) { if ( m_flTimeToPull <= gpGlobals->curtime ) { Vector vCurrentVel; float flCurrentVel; AngularImpulse vCurrentAI; pPhysObj->GetVelocity( &vCurrentVel, &vCurrentAI ); flCurrentVel = vCurrentVel.Length(); VectorNormalize( vCurrentVel ); if ( pPhysObj && flDistance <= DOG_PULL_DISTANCE ) { Vector vDir = ( vGunPos - m_hPhysicsEnt->WorldSpaceCenter() ); VectorNormalize( vDir ); vCurrentVel = vCurrentVel * ( flCurrentVel * DOG_PULL_VELOCITY_MOD ); vCurrentAI = vCurrentAI * DOG_PULL_ANGULARIMP_MOD; pPhysObj->SetVelocity( &vCurrentVel, &vCurrentAI ); vDir = vDir * flDistance * DOG_PULL_TO_GUN_VEL_MOD; Vector vAngle( 0, 0, 0 ); pPhysObj->AddVelocity( &vDir, &vAngle ); CreateBeams(); } float flDot = DotProduct( vCurrentVel, vForward ); if ( flDistance >= DOG_PULL_DISTANCE && flDistance <= ( DOG_PULL_DISTANCE * 2 ) && flDot > -0.3 ) { if ( pPhysObj->IsAsleep() == false && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) { Vector vecGoalPos; Vector vecDir; vecDir = GetLocalOrigin() - m_hPhysicsEnt->WorldSpaceCenter(); VectorNormalize(vecDir); vecDir.z = 0; vecGoalPos = m_hPhysicsEnt->WorldSpaceCenter() + (vecDir * DOG_PHYSOBJ_MOVE_TO_DIST ); GetNavigator()->ClearGoal(); //If I'm near my goal, then just walk to it. Activity aActivity = ACT_RUN; if ( ( vecGoalPos - GetLocalOrigin() ).Length() <= 128 ) aActivity = ACT_WALK; GetNavigator()->SetGoal( AI_NavGoal_t( vecGoalPos, aActivity ), AIN_NO_PATH_TASK_FAIL ); } } } } float flDirDot = DotProduct( vToObject, vForward ); if ( flDirDot < 0.2 ) { GetMotor()->SetIdealYawToTarget( m_hPhysicsEnt->GetAbsOrigin() ); GetMotor()->UpdateYaw(); } if ( m_flTimeToCatch < gpGlobals->curtime && m_bDoWaitforObjectBehavior == false ) { m_hPhysicsEnt->SetOwnerEntity( NULL ); m_flTimeToCatch = 0.0f; ClearBeams(); TaskFail( "Done waiting!" ); } else if ( pPhysObj && ( flDistance <= DOG_CATCH_DISTANCE && !( pPhysObj->GetGameFlags() & FVPHYSICS_PLAYER_HELD ) ) ) { AngularImpulse vZero( 0, 0, 0 ); pPhysObj->SetVelocity( &vec3_origin, &vZero ); GetNavigator()->StopMoving(); //Fire Output! m_OnCatch.FireOutput( this, this ); m_bHasObject = true; ClearBeams(); TaskComplete(); } } else { GetNavigator()->StopMoving(); ClearBeams(); TaskFail("No Physics Object!"); } } break; case TASK_DOG_CATCH_OBJECT: if( IsActivityFinished() ) { m_flTimeToCatch = 0.0f; TaskComplete(); } break; default: BaseClass::RunTask( pTask ); break; } }
//----------------------------------------------------------------------------- // Computes the surrounding collision bounds based on whatever algorithm we want... //----------------------------------------------------------------------------- void CCollisionProperty::ComputeSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) { if (( GetSolid() == SOLID_CUSTOM ) && (m_nSurroundType != USE_GAME_CODE )) { // NOTE: This can only happen in transition periods, say during network // reception on the client. We expect USE_GAME_CODE to be used with SOLID_CUSTOM *pVecWorldMins = GetCollisionOrigin(); *pVecWorldMaxs = *pVecWorldMins; return; } switch( m_nSurroundType ) { case USE_OBB_COLLISION_BOUNDS: { Assert( GetSolid() != SOLID_CUSTOM ); bool bUseVPhysics = false; if ( ( GetSolid() == SOLID_VPHYSICS ) && ( GetOuter()->GetMoveType() == MOVETYPE_VPHYSICS ) ) { // UNDONE: This may not be necessary any more. IPhysicsObject *pPhysics = GetOuter()->VPhysicsGetObject(); bUseVPhysics = pPhysics && pPhysics->IsAsleep(); } ComputeCollisionSurroundingBox( bUseVPhysics, pVecWorldMins, pVecWorldMaxs ); } break; case USE_BEST_COLLISION_BOUNDS: Assert( GetSolid() != SOLID_CUSTOM ); ComputeCollisionSurroundingBox( (GetSolid() == SOLID_VPHYSICS), pVecWorldMins, pVecWorldMaxs ); break; case USE_COLLISION_BOUNDS_NEVER_VPHYSICS: Assert( GetSolid() != SOLID_CUSTOM ); ComputeCollisionSurroundingBox( false, pVecWorldMins, pVecWorldMaxs ); break; case USE_HITBOXES: ComputeHitboxSurroundingBox( pVecWorldMins, pVecWorldMaxs ); break; case USE_ROTATION_EXPANDED_BOUNDS: ComputeRotationExpandedBounds( pVecWorldMins, pVecWorldMaxs ); break; case USE_SPECIFIED_BOUNDS: VectorAdd( GetCollisionOrigin(), m_vecSpecifiedSurroundingMins, *pVecWorldMins ); VectorAdd( GetCollisionOrigin(), m_vecSpecifiedSurroundingMaxs, *pVecWorldMaxs ); break; case USE_GAME_CODE: GetOuter()->ComputeWorldSpaceSurroundingBox( pVecWorldMins, pVecWorldMaxs ); Assert( pVecWorldMins->x <= pVecWorldMaxs->x ); Assert( pVecWorldMins->y <= pVecWorldMaxs->y ); Assert( pVecWorldMins->z <= pVecWorldMaxs->z ); return; } #ifdef DEBUG /* // For debugging purposes, make sure the bounds actually does surround the thing. // Otherwise the optimization we were using isn't really all that great, is it? Vector vecTestMins, vecTestMaxs; ComputeCollisionSurroundingBox( (GetSolid() == SOLID_VPHYSICS), &vecTestMins, &vecTestMaxs ); // Now that we have the basics, let's expand for hitboxes if appropriate Vector vecWorldHitboxMins, vecWorldHitboxMaxs; if ( ComputeHitboxSurroundingBox( &vecWorldHitboxMins, &vecWorldHitboxMaxs ) ) { VectorMin( vecWorldHitboxMaxs, vecTestMins, vecTestMins ); VectorMax( vecWorldHitboxMaxs, vecTestMaxs, vecTestMaxs ); } Assert( vecTestMins.x >= pVecWorldMins->x && vecTestMins.y >= pVecWorldMins->y && vecTestMins.z >= pVecWorldMins->z ); Assert( vecTestMaxs.x <= pVecWorldMaxs->x && vecTestMaxs.y <= pVecWorldMaxs->y && vecTestMaxs.z <= pVecWorldMaxs->z ); */ #endif }
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 ( tr.fraction != 1 ) { // too close to the player, drop the object if ( distance < 36 ) { DetachObject(); return; } } if ( m_hObject == NULL && tr.DidHitNonWorldEntity() ) { CBaseEntity *pEntity = tr.m_pEnt; AttachObject( pEntity, start, tr.endpos, distance ); m_lastYaw = pOwner->EyeAngles().y; } // Add the incremental player yaw to the target transform matrix3x4_t curMatrix, incMatrix, nextMatrix; AngleMatrix( m_gravCallback.m_targetRotation, curMatrix ); AngleMatrix( QAngle(0,pOwner->EyeAngles().y - m_lastYaw,0), incMatrix ); ConcatTransforms( incMatrix, curMatrix, nextMatrix ); MatrixAngles( nextMatrix, m_gravCallback.m_targetRotation ); m_lastYaw = pOwner->EyeAngles().y; 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 ); #ifdef CLIENT_DLL if ( gpGlobals->maxClients > 1 ) { gHUD.m_bSkipClear = false; } #endif } if ( pOwner->m_nButtons & IN_WEAPON2 ) { m_distance = Approach( 40, m_distance, m_distance * 0.1 ); #ifdef CLIENT_DLL if ( gpGlobals->maxClients > 1 ) { gHUD.m_bSkipClear = false; } #endif } IPhysicsObject *pPhys = pObject->VPhysicsGetObject(); if ( pPhys && 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; pObject->EntityToWorldSpace( m_worldPosition, &offset ); m_gravCallback.SetTargetPosition( newPosition + (pObject->GetAbsOrigin() - offset), m_gravCallback.m_targetRotation ); Vector dir = (newPosition - pObject->GetLocalOrigin()); m_movementLength = dir.Length(); } else { m_targetPosition = end; //m_gravCallback.SetTargetPosition( end, m_gravCallback.m_targetRotation ); } }