void CASW_Queen_Divers::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr ) { if ( m_takedamage == DAMAGE_NO ) return; CTakeDamageInfo subInfo = info; m_nForceBone = ptr->physicsbone; // save this bone for physics forces Assert( m_nForceBone > -255 && m_nForceBone < 256 ); if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK ) && !(subInfo.GetDamageType() & DMG_BURN )) { UTIL_ASW_DroneBleed( ptr->endpos, vecDir, 4 ); ASWTraceBleed( subInfo.GetDamage(), vecDir, ptr, subInfo.GetDamageType() ); } if( info.GetInflictor() ) { subInfo.SetInflictor( info.GetInflictor() ); } else { subInfo.SetInflictor( info.GetAttacker() ); } AddMultiDamage( subInfo, this ); }
void CASW_Simple_Alien::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr ) { if ( m_takedamage == DAMAGE_NO ) return; CTakeDamageInfo subInfo = info; m_nForceBone = ptr->physicsbone; // save this bone for physics forces Assert( m_nForceBone > -255 && m_nForceBone < 256 ); if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK ) && !(subInfo.GetDamageType() & DMG_BURN )) { // NPC's always bleed. Players only bleed in multiplayer. //SpawnBlood( ptr->endpos, vecDir, BloodColor(), subInfo.GetDamage() );// a little surface blood. UTIL_ASW_DroneBleed( ptr->endpos, vecDir, 4 ); // + m_LagCompensation.GetLagCompensationOffset() ASWTraceBleed( subInfo.GetDamage(), vecDir, ptr, subInfo.GetDamageType() ); } if( info.GetInflictor() ) { subInfo.SetInflictor( info.GetInflictor() ); } else { subInfo.SetInflictor( info.GetAttacker() ); } AddMultiDamage( subInfo, this ); }
void QUA_helicopter::Event_Killed( const CTakeDamageInfo &info ) { //m_lifeState=LIFE_DYING; // Calculate death force m_vecTotalBulletForce = CalcDamageForceVector( info ); CBasePlayer *pPlayer = m_hPlayer; if ( pPlayer ) { pPlayer->LeaveVehicle(); // Force exit vehicle CBaseEntity *pAPC=this->GetBaseEntity(); CTakeDamageInfo playerinfo; if (info.GetAttacker()==pAPC && info.GetInflictor()==pAPC) { playerinfo.SetAttacker(pPlayer); playerinfo.SetInflictor(pPlayer); playerinfo.SetDamage(10000); playerinfo.SetDamageType(DMG_BLAST); } else { playerinfo.SetAttacker(info.GetAttacker()); playerinfo.SetInflictor(info.GetInflictor()); playerinfo.SetDamage(10000); playerinfo.SetDamageType(DMG_BLAST); } playerinfo.SetDamagePosition( pPlayer->WorldSpaceCenter() ); playerinfo.SetDamageForce( Vector(0,0,-1) ); pPlayer->TakeDamage( playerinfo ); m_hPlayer = NULL; } m_OnDeath.FireOutput( info.GetAttacker(), this ); //StopSmoking(); 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 ); } // Aqui destruiremos todo StopLoopingSounds(); BecomeRagdoll( info, m_vecTotalBulletForce ); UTIL_ScreenShake( vecAbsPoint, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); CreateCorpse(); //BecomeRagdoll( info, m_vecTotalBulletForce ); //BecomeRagdollOnClient(m_vecTotalBulletForce); //Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseProjectile::ProjectileTouch( CBaseEntity *pOther ) { // Verify a correct "other." Assert( pOther ); if ( !pOther->IsSolid() || pOther->IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) ) return; // Handle hitting skybox (disappear). const trace_t *pTrace = &CBaseEntity::GetTouchTrace(); trace_t *pNewTrace = const_cast<trace_t*>( pTrace ); if( pTrace->surface.flags & SURF_SKY ) { UTIL_Remove( this ); return; } CTakeDamageInfo info; info.SetAttacker( GetOwnerEntity() ); info.SetInflictor( this ); info.SetDamage( GetDamage() ); info.SetDamageType( GetDamageType() ); CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin(), GetDamageScale() ); Vector dir; AngleVectors( GetAbsAngles(), &dir ); pOther->DispatchTraceAttack( info, dir, pNewTrace ); ApplyMultiDamage(); UTIL_Remove( this ); }
void CGEPropDynamic::InputDestroy(inputdata_t &inputdata) { CTakeDamageInfo destroyinfo; destroyinfo.SetDamage(m_iHealth); destroyinfo.SetAttacker(inputdata.pActivator); destroyinfo.SetInflictor(this); TakeDamage(destroyinfo); }
void CNPC_Sentry::SentryTouch( CBaseEntity *pOther ) { //trigger the sentry to turn on if a monster or player touches it if ( pOther && (pOther->IsPlayer() || FBitSet ( pOther->GetFlags(), FL_NPC )) ) { CTakeDamageInfo info; info.SetAttacker( pOther ); info.SetInflictor( pOther ); info.SetDamage( 0 ); TakeDamage(info); } }
//----------------------------------------------------------------------------- // Purpose: // Input : *pOther - //----------------------------------------------------------------------------- void CDODBaseRocket::RocketTouch( CBaseEntity *pOther ) { Assert( pOther ); if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) ) return; if ( pOther->GetCollisionGroup() == COLLISION_GROUP_WEAPON ) return; // if we hit the skybox, just disappear const trace_t &tr = CBaseEntity::GetTouchTrace(); const trace_t *p = &tr; trace_t *newTrace = const_cast<trace_t*>(p); if( tr.surface.flags & SURF_SKY ) { UTIL_Remove( this ); return; } if( !pOther->IsPlayer() ) { CTakeDamageInfo info; info.SetAttacker( this ); info.SetInflictor( this ); info.SetDamage( 50 ); info.SetDamageForce( vec3_origin ); // don't worry about this not having a damage force. // It will explode on touch and impart its own forces info.SetDamageType( DMG_CLUB ); Vector dir; AngleVectors( GetAbsAngles(), &dir ); pOther->DispatchTraceAttack( info, dir, newTrace ); ApplyMultiDamage(); } if( pOther->IsAlive() ) { Explode(); } // else we will continue our movement }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CWeaponStriderBuster::BusterDetachThink() { SetNextThink( gpGlobals->curtime + 0.1f ); trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1200), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); if( fabs(tr.startpos.z - tr.endpos.z) < 240.0f ) { SetThink(NULL); EmitSound( "Weapon_StriderBuster.Dud_Detonate" ); DispatchParticleEffect( "striderbuster_break_flechette", GetAbsOrigin(), GetAbsAngles() ); SetHealth( 0 ); CTakeDamageInfo info; info.SetDamage( 1.0f ); info.SetAttacker( this ); info.SetInflictor( this ); Shatter(this); } }
//----------------------------------------------------------------------------- // Purpose: Slowly destroy the object I'm attached to //----------------------------------------------------------------------------- void CObjectSapper::SapperThink( void ) { if ( !GetTeam() ) return; CBaseObject *pObject = GetParentObject(); if ( !pObject ) { DestroyObject(); return; } SetNextThink( gpGlobals->curtime + 0.1, SAPPER_THINK_CONTEXT ); // Don't bring objects back from the dead if ( !pObject->IsAlive() || pObject->IsDying() ) return; // how much damage to give this think? float flTimeSinceLastThink = gpGlobals->curtime - m_flLastThinkTime; float flDamageToGive = ( flTimeSinceLastThink ) * obj_sapper_amount.GetFloat(); // add to accumulator m_flSapperDamageAccumulator += flDamageToGive; int iDamage = (int)m_flSapperDamageAccumulator; m_flSapperDamageAccumulator -= iDamage; CTakeDamageInfo info; info.SetDamage( iDamage ); info.SetAttacker( this ); info.SetInflictor( this ); info.SetDamageType( DMG_CRUSH ); pObject->TakeDamage( info ); m_flLastThinkTime = gpGlobals->curtime; }
//========================================================= // Pensamiento: Nectar //========================================================= void CFR_Player::NectarThink() { // Menos nectar para tu cuerpo. if ( random->RandomInt(0, 5) <= 2 && m_iNectar > 0 ) --m_iNectar; DevMsg("m_iEmptyNectarSeconds: %i \r\n", m_iEmptyNectarSeconds); // ¡Te has quedado sin nectar! if ( m_iNectar <= 0 ) { // Todavia te quedan unos segundos para recuperar el nectar perdido. if ( m_iEmptyNectarSeconds > 0 ) --m_iEmptyNectarSeconds; // Sin nectar y sin segundos. Le quitamos salud cada 5 segs. else if ( GetLastDamageTime() < (gpGlobals->curtime - 5) ) { CTakeDamageInfo damage; damage.SetAttacker(this); damage.SetInflictor(this); damage.SetDamageType(DMG_GENERIC); damage.SetDamage(random->RandomInt(10, 30)); // Entre 10 a 30 de daño. TakeDamage(damage); } } // Tienes nectar, restaurar los segundos para recuperarlo. else if ( m_iEmptyNectarSeconds != fr_emptynectar_seconds.GetInt() ) m_iEmptyNectarSeconds = fr_emptynectar_seconds.GetInt(); m_HL2Local.m_iNectar = GetNectar(); SetNextThink(gpGlobals->curtime + 1, "NectarContext"); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Blob::RunAI() { BaseClass::RunAI(); if( !m_bInitialized ) { // m_bInitialized is set to false in the constructor. So this bit of // code runs one time, the first time I think. Msg("I need to initialize\n"); InitializeElements(); m_bInitialized = true; return; } int iIdealNumElements = blob_numelements.GetInt(); if( iIdealNumElements != m_iNumElements ) { int delta = iIdealNumElements - m_iNumElements; if( delta < 0 ) { delta = -delta; delta = MIN(delta, 5 ); RemoveExcessElements( delta ); if( m_iReconfigureElement > m_iNumElements ) { // Start this index over at zero, if it is past the new end of the utlvector. m_iReconfigureElement = 0; } } else { delta = MIN(delta, 5 ); AddNewElements( delta ); } RecomputeIdealElementDist(); } ComputeCentroid(); if( npc_blob_show_centroid.GetBool() ) { NDebugOverlay::Cross3D( m_vecCentroid + Vector( 0, 0, 12 ), 32, 0, 255, 0, false, 0.025f ); } if( npc_blob_use_threading.GetBool() ) { IterRangeParallel( this, &CNPC_Blob::DoBlobBatchedAI, 0, m_Elements.Count() ); } else { DoBlobBatchedAI( 0, m_Elements.Count() ); } if( GetEnemy() != NULL ) { float flEnemyDistSqr = m_vecCentroid.DistToSqr( GetEnemy()->GetAbsOrigin() ); if( flEnemyDistSqr <= Square( 32.0f ) ) { if( GetEnemy()->Classify() == CLASS_COMBINE ) { if( !m_bEatCombineHack ) { variant_t var; var.SetFloat( 0 ); g_EventQueue.AddEvent( GetEnemy(), "HitByBugBait", 0.0f, this, this ); g_EventQueue.AddEvent( GetEnemy(), "SetHealth", var, 3.0f, this, this ); m_bEatCombineHack = true; blob_radius.SetValue( 48.0f ); RecomputeIdealElementDist(); } } else { CTakeDamageInfo info; info.SetAttacker( this ); info.SetInflictor( this ); info.SetDamage( 5 ); info.SetDamageType( DMG_SLASH ); info.SetDamageForce( Vector( 0, 0, 1 ) ); GetEnemy()->TakeDamage( info ); } } } SetNextThink( gpGlobals->curtime + npc_blob_think_interval.GetFloat() ); }
void CASW_Alien::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr ) { #ifdef GAME_DLL m_fNoDamageDecal = false; if ( m_takedamage == DAMAGE_NO ) return; #endif CTakeDamageInfo subInfo = info; #ifdef GAME_DLL SetLastHitGroup( ptr->hitgroup ); m_nForceBone = ptr->physicsbone; // save this bone for physics forces #endif Assert( m_nForceBone > -255 && m_nForceBone < 256 ); // mining laser does reduced damage if ( info.GetDamageType() & DMG_ENERGYBEAM ) { subInfo.ScaleDamage( asw_alien_mining_laser_damage_scale.GetFloat() ); } if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK ) && !( subInfo.GetDamageType() & DMG_BURN ) ) { #ifdef GAME_DLL Bleed( subInfo, ptr->endpos + m_LagCompensation.GetLagCompensationOffset(), vecDir, ptr ); if ( ptr->hitgroup == HITGROUP_HEAD && m_iHealth - subInfo.GetDamage() > 0 ) { m_fNoDamageDecal = true; } #else Bleed( subInfo, ptr->endpos, vecDir, ptr ); //OnHurt(); #endif } if( !info.GetInflictor() ) { subInfo.SetInflictor( info.GetAttacker() ); } AddMultiDamage( subInfo, this ); #ifdef GAME_DLL #else CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>( subInfo.GetAttacker() ); CASW_Player *pPlayerAttacker = NULL; if ( pMarine ) { pPlayerAttacker = pMarine->GetCommander(); } IGameEvent * event = gameeventmanager->CreateEvent( "alien_hurt" ); if ( event ) { event->SetInt( "attacker", ( pPlayerAttacker ? pPlayerAttacker->GetUserID() : 0 ) ); event->SetInt( "entindex", entindex() ); event->SetInt( "amount", subInfo.GetDamage() ); gameeventmanager->FireEventClientSide( event ); } UTIL_ASW_ClientFloatingDamageNumber( subInfo ); #endif }
//========================================================= // ActiveThink - //========================================================= void CNPC_BaseTurret::ActiveThink(void) { int fAttack = 0; SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance( ); if ( (!m_iOn) || (GetEnemy() == NULL) ) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } // if it's dead, look for something new if ( !GetEnemy()->IsAlive() ) { if (!m_flLastSight) { m_flLastSight = gpGlobals->curtime + 0.5; // continue-shooting timeout } else { if (gpGlobals->curtime > m_flLastSight) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } } } Vector vecMid = GetAbsOrigin() + GetViewOffset(); Vector vecMidEnemy = GetEnemy()->BodyTarget( vecMid, false ); // Look for our current enemy int fEnemyVisible = FBoxVisible(this, GetEnemy(), vecMidEnemy ); //We want to look at the enemy's eyes so we don't jitter Vector vecDirToEnemyEyes = vecMidEnemy - vecMid; float flDistToEnemy = vecDirToEnemyEyes.Length(); VectorNormalize( vecDirToEnemyEyes ); QAngle vecAnglesToEnemy; VectorAngles( vecDirToEnemyEyes, vecAnglesToEnemy ); // Current enmey is not visible. if (!fEnemyVisible || (flDistToEnemy > TURRET_RANGE)) { if (!m_flLastSight) m_flLastSight = gpGlobals->curtime + 0.5; else { // Should we look for a new target? if (gpGlobals->curtime > m_flLastSight) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } } fEnemyVisible = 0; } else { m_vecLastSight = vecMidEnemy; } //ALERT( at_console, "%.0f %.0f : %.2f %.2f %.2f\n", // m_vecCurAngles.x, m_vecCurAngles.y, // gpGlobals->v_forward.x, gpGlobals->v_forward.y, gpGlobals->v_forward.z ); Vector vecLOS = vecDirToEnemyEyes; //vecMid - m_vecLastSight; VectorNormalize( vecLOS ); Vector vecMuzzle, vecMuzzleDir; QAngle vecMuzzleAng; GetAttachment( 1, vecMuzzle, vecMuzzleAng ); AngleVectors( vecMuzzleAng, &vecMuzzleDir ); // Is the Gun looking at the target if (DotProduct(vecLOS, vecMuzzleDir) <= 0.866) // 30 degree slop fAttack = FALSE; else fAttack = TRUE; //forward // NDebugOverlay::Line(vecMuzzle, vecMid + ( vecMuzzleDir * 200 ), 255,0,0, false, 0.1); //LOS // NDebugOverlay::Line(vecMuzzle, vecMid + ( vecLOS * 200 ), 0,0,255, false, 0.1); // fire the gun if (m_iSpin && ((fAttack) || (m_fBeserk))) { Vector vecOrigin; QAngle vecAngles; GetAttachment( 1, vecOrigin, vecAngles ); Shoot(vecOrigin, vecMuzzleDir ); SetTurretAnim(TURRET_ANIM_FIRE); } else { SetTurretAnim(TURRET_ANIM_SPIN); } //move the gun if (m_fBeserk) { if (random->RandomInt(0,9) == 0) { m_vecGoalAngles.y = random->RandomFloat(0,360); m_vecGoalAngles.x = random->RandomFloat(0,90) - 90 * m_iOrientation; CTakeDamageInfo info; info.SetAttacker(this); info.SetInflictor(this); info.SetDamage( 1 ); info.SetDamageType( DMG_GENERIC ); TakeDamage( info ); // don't beserk forever return; } } else if (fEnemyVisible) { if (vecAnglesToEnemy.y > 360) vecAnglesToEnemy.y -= 360; if (vecAnglesToEnemy.y < 0) vecAnglesToEnemy.y += 360; //ALERT(at_console, "[%.2f]", vec.x); if (vecAnglesToEnemy.x < -180) vecAnglesToEnemy.x += 360; if (vecAnglesToEnemy.x > 180) vecAnglesToEnemy.x -= 360; // now all numbers should be in [1...360] // pin to turret limitations to [-90...14] if (m_iOrientation == TURRET_ORIENTATION_FLOOR) { if (vecAnglesToEnemy.x > 90) vecAnglesToEnemy.x = 90; else if (vecAnglesToEnemy.x < m_iMinPitch) vecAnglesToEnemy.x = m_iMinPitch; } else { if (vecAnglesToEnemy.x < -90) vecAnglesToEnemy.x = -90; else if (vecAnglesToEnemy.x > -m_iMinPitch) vecAnglesToEnemy.x = -m_iMinPitch; } //DevMsg( 1, "->[%.2f]\n", vec.x); m_vecGoalAngles.y = vecAnglesToEnemy.y; m_vecGoalAngles.x = vecAnglesToEnemy.x; } SpinUpCall(); MoveTurret(); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CRagdollProp::HandleFirstCollisionInteractions( int index, gamevcollisionevent_t *pEvent ) { IPhysicsObject *pObj = VPhysicsGetObject(); if ( !pObj) return; if( HasPhysgunInteraction( "onfirstimpact", "break" ) ) { // Looks like it's best to break by having the object damage itself. CTakeDamageInfo info; info.SetDamage( m_iHealth ); info.SetAttacker( this ); info.SetInflictor( this ); info.SetDamageType( DMG_GENERIC ); Vector vecPosition; Vector vecVelocity; VPhysicsGetObject()->GetVelocity( &vecVelocity, NULL ); VPhysicsGetObject()->GetPosition( &vecPosition, NULL ); info.SetDamageForce( vecVelocity ); info.SetDamagePosition( vecPosition ); TakeDamage( info ); return; } if( HasPhysgunInteraction( "onfirstimpact", "paintsplat" ) ) { IPhysicsObject *pObj = VPhysicsGetObject(); Vector vecPos; pObj->GetPosition( &vecPos, NULL ); trace_t tr; UTIL_TraceLine( vecPos, vecPos + pEvent->preVelocity[0] * 1.5, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); switch( random->RandomInt( 1, 3 ) ) { case 1: UTIL_DecalTrace( &tr, "PaintSplatBlue" ); break; case 2: UTIL_DecalTrace( &tr, "PaintSplatGreen" ); break; case 3: UTIL_DecalTrace( &tr, "PaintSplatPink" ); break; } } bool bAlienBloodSplat = HasPhysgunInteraction( "onfirstimpact", "alienbloodsplat" ); if( bAlienBloodSplat || HasPhysgunInteraction( "onfirstimpact", "bloodsplat" ) ) { IPhysicsObject *pObj = VPhysicsGetObject(); Vector vecPos; pObj->GetPosition( &vecPos, NULL ); trace_t tr; UTIL_TraceLine( vecPos, vecPos + pEvent->preVelocity[0] * 1.5, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); UTIL_BloodDecalTrace( &tr, bAlienBloodSplat ? BLOOD_COLOR_GREEN : BLOOD_COLOR_RED ); } }
// make the bleeding more pronounced void CASW_Zombie::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr ) { m_fNoDamageDecal = false; if ( m_takedamage == DAMAGE_NO ) return; CTakeDamageInfo subInfo = info; SetLastHitGroup( ptr->hitgroup ); m_nForceBone = ptr->physicsbone; // save this bone for physics forces Assert( m_nForceBone > -255 && m_nForceBone < 256 ); bool bDebug = showhitlocation.GetBool(); switch ( ptr->hitgroup ) { case HITGROUP_GENERIC: if( bDebug ) DevMsg("Hit Location: Generic\n"); break; // hit gear, react but don't bleed case HITGROUP_GEAR: subInfo.SetDamage( 0.01 ); ptr->hitgroup = HITGROUP_GENERIC; if( bDebug ) DevMsg("Hit Location: Gear\n"); break; case HITGROUP_HEAD: subInfo.ScaleDamage( GetHitgroupDamageMultiplier(ptr->hitgroup, info) ); if( bDebug ) DevMsg("Hit Location: Head\n"); break; case HITGROUP_CHEST: subInfo.ScaleDamage( GetHitgroupDamageMultiplier(ptr->hitgroup, info) ); if( bDebug ) DevMsg("Hit Location: Chest\n"); break; case HITGROUP_STOMACH: subInfo.ScaleDamage( GetHitgroupDamageMultiplier(ptr->hitgroup, info) ); if( bDebug ) DevMsg("Hit Location: Stomach\n"); break; case HITGROUP_LEFTARM: case HITGROUP_RIGHTARM: subInfo.ScaleDamage( GetHitgroupDamageMultiplier(ptr->hitgroup, info) ); if( bDebug ) DevMsg("Hit Location: Left/Right Arm\n"); break ; case HITGROUP_LEFTLEG: case HITGROUP_RIGHTLEG: subInfo.ScaleDamage( GetHitgroupDamageMultiplier(ptr->hitgroup, info) ); if( bDebug ) DevMsg("Hit Location: Left/Right Leg\n"); break; default: if( bDebug ) DevMsg("Hit Location: UNKNOWN\n"); break; } if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK ) ) { if( !IsPlayer() || ( IsPlayer() && gpGlobals->maxClients > 1 ) ) { // NPC's always bleed. Players only bleed in multiplayer. //SpawnBlood( ptr->endpos, vecDir, BloodColor(), subInfo.GetDamage() );// a little surface blood. //UTIL_ASW_DroneBleed( ptr->endpos, vecDir, 4 ); UTIL_ASW_BloodDrips( GetAbsOrigin()+Vector(0,0,60)+vecDir*3, vecDir, BloodColor(), 5 ); } TraceBleed( subInfo.GetDamage(), vecDir, ptr, subInfo.GetDamageType() ); if ( ptr->hitgroup == HITGROUP_HEAD && m_iHealth - subInfo.GetDamage() > 0 ) { m_fNoDamageDecal = true; } } // Airboat gun will impart major force if it's about to kill him.... if ( info.GetDamageType() & DMG_AIRBOAT ) { if ( subInfo.GetDamage() >= GetHealth() ) { float flMagnitude = subInfo.GetDamageForce().Length(); if ( (flMagnitude != 0.0f) && (flMagnitude < 400.0f * 65.0f) ) { subInfo.ScaleDamageForce( 400.0f * 65.0f / flMagnitude ); } } } if( info.GetInflictor() ) { subInfo.SetInflictor( info.GetInflictor() ); } else { subInfo.SetInflictor( info.GetAttacker() ); } AddMultiDamage( subInfo, this ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropAPC2::Event_Killed( const CTakeDamageInfo &info ) { CBasePlayer *pPlayer = m_hPlayer; if ( pPlayer ) { pPlayer->LeaveVehicle(); // Force exit vehicle CBaseEntity *pAPC=this->GetBaseEntity(); CTakeDamageInfo playerinfo; if (info.GetAttacker()==pAPC && info.GetInflictor()==pAPC) { playerinfo.SetAttacker(pPlayer); playerinfo.SetInflictor(pPlayer); playerinfo.SetDamage(10000); playerinfo.SetDamageType(DMG_BLAST); } else { playerinfo.SetAttacker(info.GetAttacker()); playerinfo.SetInflictor(info.GetInflictor()); playerinfo.SetDamage(10000); playerinfo.SetDamageType(DMG_BLAST); } playerinfo.SetDamagePosition( pPlayer->WorldSpaceCenter() ); playerinfo.SetDamageForce( Vector(0,0,-1) ); pPlayer->TakeDamage( playerinfo ); m_hPlayer = NULL; } 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 < 3; 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 ( 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 ); // } // pChunk->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); //} UTIL_ScreenShake( vecAbsPoint, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); //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;*/ CreateCorpse(); }