//------------------------------------------------------------------------------ // Pow! //------------------------------------------------------------------------------ void CPropAPC2::ExplodeAndThrowChunk( const Vector &vecExplosionPos ) { ExplosionCreate( vecExplosionPos, vec3_angle, this, 1000, 500.0f, SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE | SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 ); UTIL_ScreenShake( vecExplosionPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); // Drop a flaming, smoking chunk. CGib *pChunk = CREATE_ENTITY( CGib, "gib" ); pChunk->Spawn( "models/gibs/hgibs.mdl" ); pChunk->SetBloodColor( DONT_BLEED ); QAngle vecSpawnAngles; vecSpawnAngles.Random( -90, 90 ); pChunk->SetAbsOrigin( vecExplosionPos ); pChunk->SetAbsAngles( vecSpawnAngles ); int nGib = random->RandomInt( 0, APC_MAX_CHUNKS - 1 ); pChunk->Spawn( s_pChunkModelName[nGib] ); pChunk->SetOwnerEntity( this ); pChunk->m_lifeTime = random->RandomFloat( 6.0f, 8.0f ); pChunk->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); IPhysicsObject *pPhysicsObject = pChunk->VPhysicsInitNormal( SOLID_VPHYSICS, pChunk->GetSolidFlags(), false ); // Set the velocity if ( pPhysicsObject ) { pPhysicsObject->EnableMotion( true ); Vector vecVelocity; QAngle angles; angles.x = random->RandomFloat( -40, 0 ); angles.y = random->RandomFloat( 0, 360 ); angles.z = 0.0f; AngleVectors( angles, &vecVelocity ); vecVelocity *= random->RandomFloat( 300, 900 ); vecVelocity += GetAbsVelocity(); AngularImpulse angImpulse; angImpulse = RandomAngularImpulse( -180, 180 ); pChunk->SetAbsVelocity( vecVelocity ); pPhysicsObject->SetVelocity(&vecVelocity, &angImpulse ); } CEntityFlame *pFlame = CEntityFlame::Create( pChunk, false ); if ( pFlame != NULL ) { pFlame->SetLifetime( pChunk->m_lifeTime ); } pChunk->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); }
//========================================================= // RunTask //========================================================= void CGargantua::RunTask( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_DIE: if ( gpGlobals->time > m_flWaitFinished ) { pev->renderfx = kRenderFxExplode; pev->rendercolor.x = 255; pev->rendercolor.y = 0; pev->rendercolor.z = 0; StopAnimation(); pev->nextthink = gpGlobals->time + 0.15; SetThink( SUB_Remove ); int i; int parts = MODEL_FRAMES( gGargGibModel ); for ( i = 0; i < 10; i++ ) { CGib *pGib = GetClassPtr( (CGib *)NULL ); pGib->Spawn( GARG_GIB_MODEL ); int bodyPart = 0; if ( parts > 1 ) bodyPart = RANDOM_LONG( 0, pev->body-1 ); pGib->pev->body = bodyPart; pGib->m_bloodColor = BLOOD_COLOR_YELLOW; pGib->m_material = matNone; pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsVelocity( UTIL_RandomBloodVector() * RANDOM_FLOAT( 300, 500 )); pGib->SetNextThink( 1.25 ); pGib->SetThink( SUB_FadeOut ); } Vector vecOrigin = GetAbsOrigin(); MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin ); WRITE_BYTE( TE_BREAKMODEL); // position WRITE_COORD( vecOrigin.x ); WRITE_COORD( vecOrigin.y ); WRITE_COORD( vecOrigin.z ); // size WRITE_COORD( 200 ); WRITE_COORD( 200 ); WRITE_COORD( 128 ); // velocity WRITE_COORD( 0 ); WRITE_COORD( 0 ); WRITE_COORD( 0 ); // randomization WRITE_BYTE( 200 ); // Model WRITE_SHORT( gGargGibModel ); //model id# // # of shards WRITE_BYTE( 50 ); // duration WRITE_BYTE( 20 );// 3.0 seconds // flags WRITE_BYTE( BREAK_FLESH ); MESSAGE_END(); return; } else CBaseMonster::RunTask(pTask); break; case TASK_FLAME_SWEEP: if ( gpGlobals->time > m_flWaitFinished ) { FlameDestroy(); TaskComplete(); FlameControls( 0, 0 ); SetBoneController( 0, 0 ); SetBoneController( 1, 0 ); } else { BOOL cancel = FALSE; Vector angles = g_vecZero; FlameUpdate(); CBaseEntity *pEnemy = m_hEnemy; if ( pEnemy ) { Vector org = GetAbsOrigin(); org.z += 64; Vector dir = pEnemy->BodyTarget(org) - org; angles = UTIL_VecToAngles( dir ); angles.y -= GetAbsAngles().y; if ( dir.Length() > 400 ) cancel = TRUE; } if ( fabs(angles.y) > 60 ) cancel = TRUE; if ( cancel ) { m_flWaitFinished -= 0.5; m_flameTime -= 0.5; } // FlameControls( angles.x + 2 * sin(gpGlobals->time*8), angles.y + 28 * sin(gpGlobals->time*8.5) ); FlameControls( angles.x, angles.y ); } break; default: CBaseMonster::RunTask( pTask ); break; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropAPC::Event_Killed( const CTakeDamageInfo &info ) { m_OnDeath.FireOutput( info.GetAttacker(), this ); Vector vecAbsMins, vecAbsMaxs; CollisionProp()->WorldSpaceAABB( &vecAbsMins, &vecAbsMaxs ); Vector vecNormalizedMins, vecNormalizedMaxs; CollisionProp()->WorldToNormalizedSpace( vecAbsMins, &vecNormalizedMins ); CollisionProp()->WorldToNormalizedSpace( vecAbsMaxs, &vecNormalizedMaxs ); Vector vecAbsPoint; CPASFilter filter( GetAbsOrigin() ); for (int i = 0; i < 5; i++) { CollisionProp()->RandomPointInBounds( vecNormalizedMins, vecNormalizedMaxs, &vecAbsPoint ); te->Explosion( filter, random->RandomFloat( 0.0, 1.0 ), &vecAbsPoint, g_sModelIndexFireball, random->RandomInt( 4, 10 ), random->RandomInt( 8, 15 ), ( i < 2 ) ? TE_EXPLFLAG_NODLIGHTS : TE_EXPLFLAG_NOPARTICLES | TE_EXPLFLAG_NOFIREBALLSMOKE | TE_EXPLFLAG_NODLIGHTS, 100, 0 ); } // TODO: make the gibs spawn in sync with the delayed explosions int nGibs = random->RandomInt( 1, 4 ); for ( int i = 0; i < nGibs; i++) { // Throw a flaming, smoking chunk. CGib *pChunk = CREATE_ENTITY( CGib, "gib" ); pChunk->Spawn( "models/gibs/hgibs.mdl" ); pChunk->SetBloodColor( DONT_BLEED ); QAngle vecSpawnAngles; vecSpawnAngles.Random( -90, 90 ); pChunk->SetAbsOrigin( vecAbsPoint ); pChunk->SetAbsAngles( vecSpawnAngles ); int nGib = random->RandomInt( 0, APC_MAX_CHUNKS - 1 ); pChunk->Spawn( s_pChunkModelName[nGib] ); pChunk->SetOwnerEntity( this ); pChunk->m_lifeTime = random->RandomFloat( 6.0f, 8.0f ); pChunk->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); IPhysicsObject *pPhysicsObject = pChunk->VPhysicsInitNormal( SOLID_VPHYSICS, pChunk->GetSolidFlags(), false ); // Set the velocity if ( pPhysicsObject ) { pPhysicsObject->EnableMotion( true ); Vector vecVelocity; QAngle angles; angles.x = random->RandomFloat( -20, 20 ); angles.y = random->RandomFloat( 0, 360 ); angles.z = 0.0f; AngleVectors( angles, &vecVelocity ); vecVelocity *= random->RandomFloat( 300, 900 ); vecVelocity += GetAbsVelocity(); AngularImpulse angImpulse; angImpulse = RandomAngularImpulse( -180, 180 ); pChunk->SetAbsVelocity( vecVelocity ); pPhysicsObject->SetVelocity(&vecVelocity, &angImpulse ); } CEntityFlame *pFlame = CEntityFlame::Create( pChunk, false ); if ( pFlame != NULL ) { pFlame->SetLifetime( pChunk->m_lifeTime ); } } UTIL_ScreenShake( vecAbsPoint, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); if( hl2_episodic.GetBool() ) { // EP1 perf hit Ignite( 6, false ); } else { Ignite( 60, false ); } m_lifeState = LIFE_DYING; // Spawn a lesser amount if the player is close m_iRocketSalvoLeft = DEATH_VOLLEY_ROCKET_COUNT; m_flRocketTime = gpGlobals->curtime; }
//========================================================= // RunTask //========================================================= void CNPC_Gargantua::RunTask( const Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_DIE: if ( gpGlobals->curtime > m_flWaitFinished ) { //TEMP TEMP m_nRenderFX = kRenderFxExplode; SetRenderColor( 255, 0, 0 , 255 ); StopAnimation(); SetNextThink( gpGlobals->curtime + 0.15 ); SetThink( &CBaseEntity::SUB_Remove ); int i; int parts = modelinfo->GetModelFrameCount( modelinfo->GetModel( gGargGibModel ) ); for ( i = 0; i < 10; i++ ) { CGib *pGib = CREATE_ENTITY( CGib, "gib" ); pGib->Spawn( GARG_GIB_MODEL); int bodyPart = 0; if ( parts > 1 ) bodyPart = random->RandomInt( 0, parts-1 ); pGib->SetBodygroup( 0, bodyPart ); pGib->SetBloodColor( BLOOD_COLOR_YELLOW ); pGib->m_material = matNone; pGib->SetAbsOrigin( GetAbsOrigin() ); pGib->SetAbsVelocity( UTIL_RandomBloodVector() * random->RandomFloat( 300, 500 ) ); pGib->SetNextThink( gpGlobals->curtime + 1.25 ); pGib->SetThink( &CBaseEntity::SUB_FadeOut ); } Vector vecSize = Vector( 200, 200, 128 ); CPVSFilter filter( GetAbsOrigin() ); te->BreakModel( filter, 0.0, GetAbsOrigin(), vec3_angle, vecSize, vec3_origin, gGargGibModel, 200, 50, 3.0, BREAK_FLESH ); return; } else BaseClass::RunTask( pTask ); break; case TASK_FLAME_SWEEP: if ( gpGlobals->curtime > m_flWaitFinished ) { //TEMP TEMP FlameDestroy(); TaskComplete(); FlameControls( 0, 0 ); SetBoneController( 0, 0 ); SetBoneController( 1, 0 ); } else { bool cancel = false; QAngle angles = QAngle( 0, 0, 0 ); //TEMP TEMP FlameUpdate(); CBaseEntity *pEnemy = GetEnemy(); if ( pEnemy ) { Vector org = GetAbsOrigin(); org.z += 64; Vector dir = pEnemy->BodyTarget(org) - org; VectorAngles( dir, angles ); angles.x = -angles.x; angles.y -= GetAbsAngles().y; if ( dir.Length() > 400 ) cancel = true; } if ( fabs(angles.y) > 60 ) cancel = true; if ( cancel ) { m_flWaitFinished -= 0.5; m_flameTime -= 0.5; } //TEMP TEMP //FlameControls( angles.x + 2 * sin(gpGlobals->curtime*8), angles.y + 28 * sin(gpGlobals->curtime*8.5) ); FlameControls( angles.x, angles.y ); } break; default: BaseClass::RunTask( pTask ); break; } }