//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CItem::Spawn( void ) { if ( g_pGameRules->IsAllowedToSpawn( this ) == false ) { UTIL_Remove( this ); return; } SetMoveType( MOVETYPE_FLYGRAVITY ); SetSolid( SOLID_BBOX ); SetBlocksLOS( false ); AddEFlags( EFL_NO_ROTORWASH_PUSH ); if( IsX360() ) { AddEffects( EF_ITEM_BLINK ); } // This will make them not collide with the player, but will collide // against other items + weapons SetCollisionGroup( COLLISION_GROUP_WEAPON ); CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT ); SetTouch(&CItem::ItemTouch); if ( CreateItemVPhysicsObject() == false ) return; m_takedamage = DAMAGE_EVENTS_ONLY; #if !defined( CLIENT_DLL ) // Constrained start? if ( HasSpawnFlags( SF_ITEM_START_CONSTRAINED ) ) { //Constrain the weapon in place IPhysicsObject *pReferenceObject, *pAttachedObject; pReferenceObject = g_PhysWorldObject; pAttachedObject = VPhysicsGetObject(); if ( pReferenceObject && pAttachedObject ) { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject ); fixed.constraint.forceLimit = lbs2kg( 10000 ); fixed.constraint.torqueLimit = lbs2kg( 10000 ); m_pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed ); m_pConstraint->SetGameData( (void *) this ); } } #endif //CLIENT_DLL #if defined( HL2MP ) SetThink( &CItem::FallThink ); SetNextThink( gpGlobals->curtime + 0.1f ); #endif }
//==================================================================================== // FALL TO GROUND //==================================================================================== //----------------------------------------------------------------------------- // Purpose: Setup for the fall //----------------------------------------------------------------------------- void CBaseCombatWeapon::FallInit( void ) { SetModel( GetWorldModel() ); VPhysicsDestroyObject(); if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) ) { SetMoveType( MOVETYPE_FLYGRAVITY ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); } else { #if !defined( CLIENT_DLL ) // Constrained start? if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) ) { //Constrain the weapon in place IPhysicsObject *pReferenceObject, *pAttachedObject; pReferenceObject = g_PhysWorldObject; pAttachedObject = VPhysicsGetObject(); if ( pReferenceObject && pAttachedObject ) { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject ); fixed.constraint.forceLimit = lbs2kg( 10000 ); fixed.constraint.torqueLimit = lbs2kg( 10000 ); m_pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed ); m_pConstraint->SetGameData( (void *) this ); } } #endif //CLIENT_DLL } SetPickupTouch(); SetThink( &CBaseCombatWeapon::FallThink ); SetNextThink( gpGlobals->curtime + 0.1f ); }
void GetBreakParams( constraint_breakableparams_t ¶ms ) { params.Defaults(); params.forceLimit = lbs2kg(0); params.torqueLimit = lbs2kg(0); }
//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::SettleThink() { SetNextThink( gpGlobals->curtime + 0.05 ); StudioFrameAdvance(); if( GetParent() ) { // A scanner or something is carrying me. Just keep checking back. return; } // Not being carried. if( !VPhysicsGetObject() ) { // Probably was just dropped. Get physics going. CreateVPhysics(); if( !VPhysicsGetObject() ) { Msg("**** Can't create vphysics for combine_mine!\n" ); UTIL_Remove( this ); return; } VPhysicsGetObject()->Wake(); return; } if( !m_bDisarmed ) { if( VPhysicsGetObject()->IsAsleep() && !(VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD) ) { // If i'm not resting on the world, jump randomly. trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1024 ), MASK_SHOT|CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &tr ); bool bHop = false; if( tr.m_pEnt ) { IPhysicsObject *pPhysics = tr.m_pEnt->VPhysicsGetObject(); if( pPhysics && pPhysics->GetMass() <= 1000 ) { // Light physics objects can be moved out from under the mine. bHop = true; } else if( tr.m_pEnt->m_takedamage != DAMAGE_NO ) { // Things that can be harmed can likely be broken. bHop = true; } if( bHop ) { Vector vecForce; vecForce.x = random->RandomFloat( -1000, 1000 ); vecForce.y = random->RandomFloat( -1000, 1000 ); vecForce.z = 2500; AngularImpulse torque( 160, 0, 160 ); Flip( vecForce, torque ); return; } // Check for upside-down Vector vecUp; GetVectors( NULL, NULL, &vecUp ); if( vecUp.z <= 0.8 ) { // Landed upside down. Right self Vector vecForce( 0, 0, 2500 ); Flip( vecForce, AngularImpulse( 60, 0, 0 ) ); return; } } // Check to make sure I'm not in a forbidden location if( !IsValidLocation() ) { return; } // Lock to what I'm resting on constraint_ballsocketparams_t ballsocket; ballsocket.Defaults(); ballsocket.constraint.Defaults(); ballsocket.constraint.forceLimit = lbs2kg(1000); ballsocket.constraint.torqueLimit = lbs2kg(1000); ballsocket.InitWithCurrentObjectState( g_PhysWorldObject, VPhysicsGetObject(), GetAbsOrigin() ); m_pConstraint = physenv->CreateBallsocketConstraint( g_PhysWorldObject, VPhysicsGetObject(), NULL, ballsocket ); CloseHooks(); SetMineState( MINE_STATE_ARMED ); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPhysMagnet::Touch( CBaseEntity *pOther ) { // Ignore triggers if ( pOther->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) return; m_bHasHitSomething = true; // Don't pickup if we're not active if ( !m_bActive ) return; // Hit our maximum? if ( m_iMaxObjectsAttached && m_iMaxObjectsAttached <= GetNumAttachedObjects() ) return; // Make sure it's made of metal trace_t tr = GetTouchTrace(); char cTexType = TEXTURETYPE_Find( &tr ); if ( cTexType != CHAR_TEX_METAL && cTexType != CHAR_TEX_COMPUTER ) { // See if the model is set to be metal if ( Q_strncmp( Studio_GetDefaultSurfaceProps( GetModelPtr() ), "metal", 5 ) ) return; } IPhysicsObject *pPhysics = pOther->VPhysicsGetObject(); if ( pPhysics && pOther->GetMoveType() == MOVETYPE_VPHYSICS && pPhysics->IsMoveable() ) { // Make sure we haven't already got this sucker on the magnet int iCount = m_MagnettedEntities.Count(); for ( int i = 0; i < iCount; i++ ) { if ( m_MagnettedEntities[i].hEntity == pOther ) return; } // We want to cast a long way to ensure our shadow shows up pOther->SetShadowCastDistance( 2048 ); // Create a constraint between the magnet and this sucker IPhysicsObject *pMagnetPhysObject = VPhysicsGetObject(); Assert( pMagnetPhysObject ); magnetted_objects_t newEntityOnMagnet; newEntityOnMagnet.hEntity = pOther; // Use the right constraint if ( HasSpawnFlags( SF_MAGNET_ALLOWROTATION ) ) { constraint_ballsocketparams_t ballsocket; ballsocket.Defaults(); ballsocket.constraint.Defaults(); ballsocket.constraint.forceLimit = lbs2kg(m_forceLimit); ballsocket.constraint.torqueLimit = lbs2kg(m_torqueLimit); pMagnetPhysObject->WorldToLocal( ballsocket.constraintPosition[0], tr.endpos ); pPhysics->WorldToLocal( ballsocket.constraintPosition[1], tr.endpos ); //newEntityOnMagnet.pConstraint = physenv->CreateBallsocketConstraint( pMagnetPhysObject, pPhysics, m_pConstraintGroup, ballsocket ); newEntityOnMagnet.pConstraint = physenv->CreateBallsocketConstraint( pMagnetPhysObject, pPhysics, NULL, ballsocket ); } else { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pMagnetPhysObject, pPhysics ); fixed.constraint.Defaults(); fixed.constraint.forceLimit = lbs2kg(m_forceLimit); fixed.constraint.torqueLimit = lbs2kg(m_torqueLimit); // FIXME: Use the magnet's constraint group. //newEntityOnMagnet.pConstraint = physenv->CreateFixedConstraint( pMagnetPhysObject, pPhysics, m_pConstraintGroup, fixed ); newEntityOnMagnet.pConstraint = physenv->CreateFixedConstraint( pMagnetPhysObject, pPhysics, NULL, fixed ); } newEntityOnMagnet.pConstraint->SetGameData( (void *) this ); m_MagnettedEntities.AddToTail( newEntityOnMagnet ); m_flTotalMass += pPhysics->GetMass(); } DoMagnetSuck( pOther ); m_OnMagnetAttach.FireOutput( this, this ); }