//----------------------------------------------------------------------------- // Purpose: Attempts to kill an NPC if it's within range and other criteria // Input : *pVictim - NPC to assess // **pPhysObj - pointer to the ragdoll created if the NPC is killed // Output : bool - whether or not the NPC was killed and the returned pointer is valid //----------------------------------------------------------------------------- bool CGravityVortexController::KillNPCInRange( CBaseEntity *pVictim, IPhysicsObject **pPhysObj ) { CBaseCombatCharacter *pBCC = pVictim->MyCombatCharacterPointer(); // See if we can ragdoll if ( pBCC != NULL && pBCC->CanBecomeRagdoll() ) { // Don't bother with striders if ( FClassnameIs( pBCC, "npc_strider" ) ) return false; // TODO: Make this an interaction between the NPC and the vortex // Become ragdoll CTakeDamageInfo info( this, this, 1.0f, DMG_GENERIC ); CBaseEntity *pRagdoll = CreateServerRagdoll( pBCC, 0, info, COLLISION_GROUP_INTERACTIVE_DEBRIS, true ); pRagdoll->SetCollisionBounds( pVictim->CollisionProp()->OBBMins(), pVictim->CollisionProp()->OBBMaxs() ); // Necessary to cause it to do the appropriate death cleanup CTakeDamageInfo ragdollInfo( this, this, 10000.0, DMG_GENERIC | DMG_REMOVENORAGDOLL ); pVictim->TakeDamage( ragdollInfo ); // Return the pointer to the ragdoll *pPhysObj = pRagdoll->VPhysicsGetObject(); return true; } // Wasn't able to ragdoll this target *pPhysObj = NULL; return false; }
//----------------------------------------------------------------------------- // Purpose: Creates a flame and attaches it to a target entity. // Input : pTarget - //----------------------------------------------------------------------------- CEntityDissolve *CEntityDissolve::Create( CBaseEntity *pTarget, const char *pMaterialName, float flStartTime, int nDissolveType, bool *pRagdollCreated ) { if ( pRagdollCreated ) { *pRagdollCreated = false; } if ( !pMaterialName ) { pMaterialName = DISSOLVE_SPRITE_NAME; } if ( pTarget->IsPlayer() ) { // Simply immediately kill the player. CBasePlayer *pPlayer = assert_cast< CBasePlayer* >( pTarget ); pPlayer->SetArmorValue( 0 ); CTakeDamageInfo info( pPlayer, pPlayer, pPlayer->GetHealth(), DMG_GENERIC | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); pPlayer->TakeDamage( info ); return NULL; } CEntityDissolve *pDissolve = (CEntityDissolve *) CreateEntityByName( "env_entity_dissolver" ); if ( pDissolve == NULL ) return NULL; pDissolve->m_nDissolveType = nDissolveType; if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) { if ( pTarget->IsNPC() && pTarget->MyNPCPointer()->CanBecomeRagdoll() ) { CTakeDamageInfo info; CBaseEntity *pRagdoll = CreateServerRagdoll( pTarget->MyNPCPointer(), 0, info, COLLISION_GROUP_DEBRIS, true ); pRagdoll->SetCollisionBounds( pTarget->CollisionProp()->OBBMins(), pTarget->CollisionProp()->OBBMaxs() ); // Necessary to cause it to do the appropriate death cleanup if ( pTarget->m_lifeState == LIFE_ALIVE ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex( 1 ); CTakeDamageInfo ragdollInfo( pPlayer, pPlayer, 10000.0, DMG_SHOCK | DMG_REMOVENORAGDOLL | DMG_PREVENT_PHYSICS_FORCE ); pTarget->TakeDamage( ragdollInfo ); } if ( pRagdollCreated ) { *pRagdollCreated = true; } UTIL_Remove( pTarget ); pTarget = pRagdoll; } } pDissolve->SetModelName( AllocPooledString(pMaterialName) ); pDissolve->AttachToEntity( pTarget ); pDissolve->SetStartTime( flStartTime ); pDissolve->Spawn(); // Send to the client even though we don't have a model pDissolve->AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); // Play any appropriate noises when we start to dissolve if ( (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) { pTarget->DispatchResponse( "TLK_ELECTROCUTESCREAM" ); } else { pTarget->DispatchResponse( "TLK_DISSOLVESCREAM" ); } return pDissolve; }