// функция отрывания и выбрасывания головы // Cremator's head is separated from the body and dropped on death. // Input: head's velocity. // TODO: make it part of brickbat ammo list. void CNPC_Cremator::DropHead( int iVelocity ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( GetHeadpropModel() ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); float flRandomVel = random->RandomFloat( 35, 75 ); vecVelocity *= (iVelocity * flRandomVel) / 15; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_INTERACTIVE ); }
bool CAI_BaseHumanoid::OnMoveBlocked( AIMoveResult_t *pResult ) { if ( *pResult != AIMR_BLOCKED_NPC && GetNavigator()->GetBlockingEntity() && !GetNavigator()->GetBlockingEntity()->IsNPC() ) { CBaseEntity *pBlocker = GetNavigator()->GetBlockingEntity(); float massBonus = ( IsNavigationUrgent() ) ? 40.0 : 0; if ( pBlocker->GetMoveType() == MOVETYPE_VPHYSICS && pBlocker != GetGroundEntity() && !pBlocker->IsNavIgnored() && !dynamic_cast<CBasePropDoor *>(pBlocker) && pBlocker->VPhysicsGetObject() && pBlocker->VPhysicsGetObject()->IsMoveable() && ( pBlocker->VPhysicsGetObject()->GetMass() <= 35.0 + massBonus + 0.1 || ( pBlocker->VPhysicsGetObject()->GetMass() <= 50.0 + massBonus + 0.1 && IsSmall( pBlocker ) ) ) ) { DbgNavMsg1( this, "Setting ignore on object %s", pBlocker->GetDebugName() ); pBlocker->SetNavIgnore( 2.5 ); } #if 0 else { CPhysicsProp *pProp = dynamic_cast<CPhysicsProp*>( pBlocker ); if ( pProp && pProp->GetHealth() && pProp->GetExplosiveDamage() == 0.0 && GetActiveWeapon() && !GetActiveWeapon()->ClassMatches( "weapon_rpg" ) ) { Msg( "!\n" ); // Destroy! } } #endif } return BaseClass::OnMoveBlocked( pResult ); }
//----------------------------------------------------------------------------- // Is this an object that the player is allowed to lift to a position // directly overhead? The default behavior prevents lifting objects directly // overhead, but there are exceptions for gameplay purposes. //----------------------------------------------------------------------------- bool CGrabController::IsObjectAllowedOverhead( CBaseEntity *pEntity ) { // Allow props that are specifically flagged as such CPhysicsProp *pPhysProp = dynamic_cast<CPhysicsProp *>(pEntity); if ( pPhysProp != NULL && pPhysProp->HasInteraction( PROPINTER_PHYSGUN_ALLOW_OVERHEAD ) ) return true; // String checks are fine here, we only run this code one time- when the object is picked up. if( pEntity->ClassMatches("grenade_helicopter") ) return true; if( pEntity->ClassMatches("weapon_striderbuster") ) return true; return false; }
virtual bool ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) { // Only skip ourselves (not things we own) if ( pHandleEntity == m_pTraceOwner ) return false; // Get the entity referenced by this handle CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); if ( pEntity == NULL ) return false; // Handle grate entities differently if ( HasContentsGrate( pEntity ) ) { // See if it's a grabbable physics prop CPhysicsProp *pPhysProp = dynamic_cast<CPhysicsProp *>(pEntity); if ( pPhysProp != NULL ) return pPhysProp->CanBePickedUpByPhyscannon(); // See if it's a grabbable physics prop if ( FClassnameIs( pEntity, "prop_physics" ) ) { CPhysicsProp *pPhysProp = dynamic_cast<CPhysicsProp *>(pEntity); if ( pPhysProp != NULL ) return pPhysProp->CanBePickedUpByPhyscannon(); // Somehow had a classname that didn't match the class! Assert(0); } else if ( FClassnameIs( pEntity, "func_physbox" ) ) { // Must be a moveable physbox CPhysBox *pPhysBox = dynamic_cast<CPhysBox *>(pEntity); if ( pPhysBox ) return pPhysBox->CanBePickedUpByPhyscannon(); // Somehow had a classname that didn't match the class! Assert(0); } // Don't bother with any other sort of grated entity return false; } // Use the default rules return BaseClass::ShouldHitEntity( pHandleEntity, contentsMask ); }
void CGrabController::AttachEntity( CBasePlayer *pPlayer, CBaseEntity *pEntity, IPhysicsObject *pPhys, bool bIsMegaPhysCannon, const Vector &vGrabPosition, bool bUseGrabPosition ) { // play the impact sound of the object hitting the player // used as feedback to let the player know he picked up the object int hitMaterial = pPhys->GetMaterialIndex(); int playerMaterial = pPlayer->VPhysicsGetObject() ? pPlayer->VPhysicsGetObject()->GetMaterialIndex() : hitMaterial; PhysicsImpactSound( pPlayer, pPhys, CHAN_STATIC, hitMaterial, playerMaterial, 1.0, 64 ); Vector position; QAngle angles; pPhys->GetPosition( &position, &angles ); // If it has a preferred orientation, use that instead. Pickup_GetPreferredCarryAngles( pEntity, pPlayer, pPlayer->EntityToWorldTransform(), angles ); // ComputeMaxSpeed( pEntity, pPhys ); // If we haven't been killed by a grab, we allow the gun to grab the nearest part of a ragdoll if ( bUseGrabPosition ) { IPhysicsObject *pChild = GetRagdollChildAtPosition( pEntity, vGrabPosition ); if ( pChild ) { pPhys = pChild; } } // Carried entities can never block LOS m_bCarriedEntityBlocksLOS = pEntity->BlocksLOS(); pEntity->SetBlocksLOS( false ); m_controller = physenv->CreateMotionController( this ); m_controller->AttachObject( pPhys, true ); // Don't do this, it's causing trouble with constraint solvers. //m_controller->SetPriority( IPhysicsMotionController::HIGH_PRIORITY ); pPhys->Wake(); PhysSetGameFlags( pPhys, FVPHYSICS_PLAYER_HELD ); SetTargetPosition( position, angles ); m_attachedEntity = pEntity; IPhysicsObject *pList[VPHYSICS_MAX_OBJECT_LIST_COUNT]; int count = pEntity->VPhysicsGetObjectList( pList, ARRAYSIZE(pList) ); m_flLoadWeight = 0; float damping = 10; float flFactor = count / 7.5f; if ( flFactor < 1.0f ) { flFactor = 1.0f; } for ( int i = 0; i < count; i++ ) { float mass = pList[i]->GetMass(); pList[i]->GetDamping( NULL, &m_savedRotDamping[i] ); m_flLoadWeight += mass; m_savedMass[i] = mass; // reduce the mass to prevent the player from adding crazy amounts of energy to the system pList[i]->SetMass( REDUCED_CARRY_MASS / flFactor ); pList[i]->SetDamping( NULL, &damping ); } // Give extra mass to the phys object we're actually picking up pPhys->SetMass( REDUCED_CARRY_MASS ); pPhys->EnableDrag( false ); m_errorTime = bIsMegaPhysCannon ? -1.5f : -1.0f; // 1 seconds until error starts accumulating m_error = 0; m_contactAmount = 0; m_attachedAnglesPlayerSpace = TransformAnglesToPlayerSpace( angles, pPlayer ); if ( m_angleAlignment != 0 ) { m_attachedAnglesPlayerSpace = AlignAngles( m_attachedAnglesPlayerSpace, m_angleAlignment ); } // Ragdolls don't offset this way if ( dynamic_cast<CRagdollProp*>(pEntity) ) { m_attachedPositionObjectSpace.Init(); } else { VectorITransform( pEntity->WorldSpaceCenter(), pEntity->EntityToWorldTransform(), m_attachedPositionObjectSpace ); } // If it's a prop, see if it has desired carry angles CPhysicsProp *pProp = dynamic_cast<CPhysicsProp *>(pEntity); if ( pProp ) { m_bHasPreferredCarryAngles = pProp->GetPropDataAngles( "preferred_carryangles", m_vecPreferredCarryAngles ); m_flDistanceOffset = pProp->GetCarryDistanceOffset(); } else { m_bHasPreferredCarryAngles = false; m_flDistanceOffset = 0; } m_bAllowObjectOverhead = IsObjectAllowedOverhead( pEntity ); }
//----------------------------------------------------------------------------- // Create a corpse //----------------------------------------------------------------------------- void CPropAPC::CreateCorpse( ) { m_lifeState = LIFE_DEAD; for ( int i = 0; i < APC_MAX_GIBS; ++i ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( s_pGibModelName[i] ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); float flMass = pGib->GetMass(); if ( flMass < 200 ) { Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); // Apply a force that would make a 100kg mass travel 150 - 300 m/s float flRandomVel = random->RandomFloat( 150, 300 ); vecVelocity *= (100 * flRandomVel) / flMass; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } if( hl2_episodic.GetBool() ) { // EP1 perf hit pGib->Ignite( 6, false ); } else { pGib->Ignite( 60, false ); } } AddSolidFlags( FSOLID_NOT_SOLID ); AddEffects( EF_NODRAW ); UTIL_Remove( this ); }
void UpdateVPhysicsObjects() { int nPhysicsObjectInterval = sv_benchmark_numticks.GetInt() / s_nBenchmarkPhysicsObjects; int nNextSpawnTick = m_nLastPhysicsObjectTick + nPhysicsObjectInterval; if ( GetTickOffset() >= nNextSpawnTick ) { m_nLastPhysicsObjectTick = nNextSpawnTick; if ( m_PhysicsObjects.Count() < s_nBenchmarkPhysicsObjects ) { // Find a bot to spawn it from. CUtlVector<CBasePlayer*> curPlayers; for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) ) { curPlayers.AddToTail( pPlayer ); } } if ( curPlayers.Count() > 0 && m_PhysicsModelNames.Count() > 0 ) { int iModelName = this->RandomInt( 0, m_PhysicsModelNames.Count() - 1 ); const char *pModelName = m_PhysicsModelNames[iModelName]; int iPlayer = this->RandomInt( 0, curPlayers.Count() - 1 ); Vector vSpawnPos = curPlayers[iPlayer]->EyePosition() + Vector( 0, 0, 50 ); // We'll try 15 locations around the player to spawn this thing. for ( int i=0; i < 15; i++ ) { Vector vOffset( this->RandomFloat( -2000, 2000 ), this->RandomFloat( -2000, 2000 ), 0 ); CPhysicsProp *pProp = CreatePhysicsProp( pModelName, vSpawnPos, vSpawnPos+vOffset, curPlayers[iPlayer], false, "prop_physics_multiplayer" ); if ( pProp ) { m_PhysicsObjects.AddToTail( pProp ); pProp->SetAbsVelocity( Vector( this->RandomFloat(-500,500), this->RandomFloat(-500,500), this->RandomFloat(-500,500) ) ); break; } } } } } // Give them all a boost periodically. int nPhysicsForceInterval = sv_benchmark_numticks.GetInt() / 20; int nNextForceTick = m_nLastPhysicsForceTick + nPhysicsForceInterval; if ( GetTickOffset() >= nNextForceTick ) { m_nLastPhysicsForceTick = nNextForceTick; for ( int i=0; i < m_PhysicsObjects.Count(); i++ ) { CBaseEntity *pEnt = m_PhysicsObjects[i]; if ( pEnt ) { IPhysicsObject *pPhysicsObject = pEnt->VPhysicsGetObject(); if ( pPhysicsObject ) { float flAngImpulse = 300000; float flForce = 500000; AngularImpulse vAngularImpulse( this->RandomFloat(-flAngImpulse,flAngImpulse), this->RandomFloat(-flAngImpulse,flAngImpulse), this->RandomFloat(flAngImpulse,flAngImpulse) ); pPhysicsObject->ApplyForceCenter( Vector( this->RandomFloat(-flForce,flForce), this->RandomFloat(-flForce,flForce), this->RandomFloat(0,flForce) ) ); } } } } }
void QUA_helicopter::CreateCorpse( ) { m_lifeState = LIFE_DEAD; for ( int i = 0; i < HELICOPTER_MAX_GIBS; ++i ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics_multiplayer" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( s_pGibModelName[i] ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); float flMass = pGib->GetMass(); /*if ( flMass < 200 ) {*/ Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); // Apply a force that would make a 100kg mass travel 150 - 300 m/s float flRandomVel = random->RandomFloat( 150, 300 ); vecVelocity *= (100 * flRandomVel) / flMass; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); /*}*/ pGib->Ignite( 60, false ); pGib->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } AddSolidFlags( FSOLID_NOT_SOLID ); AddEffects( EF_NODRAW ); UTIL_RemoveImmediate( this ); }
//----------------------------------------------------------------------------- // Create a corpse //----------------------------------------------------------------------------- void CPropAPC2::CreateCorpse( ) { m_lifeState = LIFE_DEAD; for ( int i = 0; i < APC_MAX_GIBS; ++i ) { CPhysicsProp *pGib = assert_cast<CPhysicsProp*>(CreateEntityByName( "prop_physics_multiplayer" )); pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsAngles( GetAbsAngles() ); pGib->SetAbsVelocity( GetAbsVelocity() ); pGib->SetModel( s_pGibModelName[i] ); pGib->Spawn(); pGib->SetMoveType( MOVETYPE_VPHYSICS ); float flMass = pGib->GetMass(); /*if ( flMass < 200 ) {*/ Vector vecVelocity; pGib->GetMassCenter( &vecVelocity ); vecVelocity -= WorldSpaceCenter(); vecVelocity.z = fabs(vecVelocity.z); VectorNormalize( vecVelocity ); // Apply a force that would make a 100kg mass travel 150 - 300 m/s float flRandomVel = random->RandomFloat( 150, 300 ); vecVelocity *= (100 * flRandomVel) / flMass; vecVelocity.z += 100.0f; AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); IPhysicsObject *pObj = pGib->VPhysicsGetObject(); if ( pObj != NULL ) { pObj->AddVelocity( &vecVelocity, &angImpulse ); } pGib->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); /*}*/ //pGib->Ignite( 60, false ); pGib->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } // CPropAPC2 *pAPC = (CPropAPC2 *)CreateEntityByName( "prop_vehicle_apc2" ); if ( pAPC ) { pAPC->InicialSpawn=m_vOriginalSpawnOrigin; pAPC->InicialAngle=m_vOriginalSpawnAngles; pAPC->m_bSpawn=true; pAPC->SetThink( &CPropAPC2::Materialize ); pAPC->SetContextThink( &CPropAPC2::Materialize, gpGlobals->curtime + 5.0f, "RESPAWNING" ); pAPC->SetNextThink( gpGlobals->curtime + 5.0f ); } else { Warning("Respawn failed to create %s!\n", GetClassname() ); } // AddSolidFlags( FSOLID_NOT_SOLID ); AddEffects( EF_NODRAW ); UTIL_Remove( this ); }