New Paste :: Recent Pastes:: Add Line Numbers
Combine Destruction code by Helk
//Taken from prop_combine_ball.cpp //----------------------------------------------------------------------------- // Purpose: Starts the lifetime countdown on the ball // Input : flDuration - number of seconds to live before exploding //----------------------------------------------------------------------------- void CPropCombineBall::StartLifetime( float flDuration ) { SetContextThink( &CPropCombineBall::ExplodeThink, gpGlobals->curtime + flDuration, s_pExplodeTimerContext ); } //When lifetime is expired: void CPropCombineBall::ExplodeThink( void ) { DoExplosion(); } //When we touch something void CPropCombineBall::OnHitEntity( CBaseEntity *pHitEntity, float flSpeed, int index, gamevcollisionevent_t *pEvent ) { // Detonate on the strider + the bone followers in the strider if ( FClassnameIs( pHitEntity, "npc_strider" ) || (pHitEntity->GetOwnerEntity() && FClassnameIs( pHitEntity->GetOwnerEntity(), "npc_strider" )) ) { DoExplosion(); return; } CTakeDamageInfo info( this, GetOwnerEntity(), GetAbsVelocity(), GetAbsOrigin(), sk_npc_dmg_combineball.GetFloat(), DMG_DISSOLVE ); bool bIsDissolving = (pHitEntity->GetFlags() & FL_DISSOLVING) != 0; if ( !bIsDissolving && pHitEntity->PassesDamageFilter( info ) ) { if( WasFiredByNPC() ) { // Since Combine balls fired by NPCs do a metered dose of damage per impact, we have to ignore touches // for a little while after we hit someone, or the ball will immediately touch them again and do more // damage. if( gpGlobals->curtime >= m_flNextDamageTime ) { pHitEntity->TakeDamage( info ); // Ignore touches briefly. m_flNextDamageTime = gpGlobals->curtime + 0.1f; } } else { if ( (m_nState == STATE_THROWN) && (pHitEntity->IsNPC() || dynamic_cast<CRagdollProp*>(pHitEntity) )) { EmitSound( "NPC_CombineBall.KillImpact" ); } if ( (m_nState != STATE_HOLDING) ) { DissolveEntity( pHitEntity ); } } } Vector vecFinalVelocity; if ( IsInField() ) { // Don't deflect when in a spawner field vecFinalVelocity = pEvent->preVelocity[index]; } else { // Don't slow down when hitting other entities. vecFinalVelocity = pEvent->postVelocity[index]; VectorNormalize( vecFinalVelocity ); vecFinalVelocity *= GetSpeed(); } PhysCallbackSetVelocity( pEvent->pObjects[index], vecFinalVelocity ); } void CPropCombineBall::DoImpactEffect( const Vector &preVelocity, int index, gamevcollisionevent_t *pEvent ) { // Do that crazy impact effect! trace_t tr; CollisionEventToTrace( !index, pEvent, tr ); CBaseEntity *pTraceEntity = pEvent->pEntities[index]; UTIL_TraceLine( tr.startpos - preVelocity * 2.0f, tr.startpos + preVelocity * 2.0f, MASK_SOLID, pTraceEntity, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0f ) { // See if we hit the sky if ( tr.surface.flags & SURF_SKY ) { DoExplosion(); return; } // Send the effect over CEffectData data; data.m_flRadius = 16; data.m_vNormal = tr.plane.normal; data.m_vOrigin = tr.endpos + tr.plane.normal * 1.0f; DispatchEffect( "cball_bounce", data ); } EmitSound( "NPC_CombineBall.Impact" ); } //The actual explosion code (just an effect) void CPropCombineBall::DoExplosion( ) { // Tell the respawner to make a new one if ( GetSpawner() ) { GetSpawner()->RespawnBallPostExplosion(); } EmitSound( "NPC_CombineBall.Explosion" ); UTIL_ScreenShake( GetAbsOrigin(), 20.0f, 150.0, 1.0, 1250.0f, SHAKE_START ); CEffectData data; data.m_vOrigin = GetAbsOrigin(); DispatchEffect( "cball_explode", data ); //Shockring CBroadcastRecipientFilter filter2; te->BeamRingPoint( filter2, 0, GetAbsOrigin(), //origin m_flRadius, //start radius 1024, //end radius s_nExplosionTexture, //texture 0, //halo index 0, //start frame 2, //framerate 0.2f, //life 64, //width 0, //spread 0, //amplitude 255, //r 255, //g 225, //b 32, //a 0, //speed FBEAM_FADEOUT ); //Shockring te->BeamRingPoint( filter2, 0, GetAbsOrigin(), //origin m_flRadius, //start radius 1024, //end radius s_nExplosionTexture, //texture 0, //halo index 0, //start frame 2, //framerate 0.5f, //life 64, //width 0, //spread 0, //amplitude 255, //r 255, //g 225, //b 64, //a 0, //speed FBEAM_FADEOUT ); // Turn us off and wait because we need our trails to finish up properly SetAbsVelocity( vec3_origin ); SetMoveType( MOVETYPE_NONE ); AddSolidFlags( FSOLID_NOT_SOLID ); m_bEmit = false; SetContextThink( &CPropCombineBall::SUB_Remove, gpGlobals->curtime + 0.5f, s_pRemoveContext ); StopLoopingSounds(); }