void CNPC_ControllerZapBall::ExplodeTouch( CBaseEntity *pOther )
{
	if (m_takedamage = DAMAGE_YES )
	{
		trace_t tr;
		tr = GetTouchTrace( );

		ClearMultiDamage( );

		Vector vecAttackDir = GetAbsVelocity();
		VectorNormalize( vecAttackDir );

		if (m_hOwner != NULL)
		{
			CTakeDamageInfo info( this, m_hOwner, sk_controller_dmgball.GetFloat(), DMG_ENERGYBEAM );
			CalculateMeleeDamageForce( &info, vecAttackDir, tr.endpos );
			pOther->DispatchTraceAttack( info, vecAttackDir, &tr );
		}
		else
		{
			CTakeDamageInfo info( this, this, sk_controller_dmgball.GetFloat(), DMG_ENERGYBEAM );
			CalculateMeleeDamageForce( &info, vecAttackDir, tr.endpos );
			pOther->DispatchTraceAttack( info, vecAttackDir, &tr );
		}

		ApplyMultiDamage();

	//	void UTIL_EmitAmbientSound( CBaseEntity *entity, const Vector &vecOrigin, const char *samp, float vol, soundlevel_t soundlevel, int fFlags, int pitch, float soundtime /*= 0.0f*/ )

		UTIL_EmitAmbientSound( GetSoundSourceIndex(), tr.endpos, "Controller.ElectroSound", 0.3, SNDLVL_NORM, 0, random->RandomInt( 90, 99 ) );
	}

	Kill();
}
Beispiel #2
0
void CNPC_Infected::MeleeAttack( float distance, float damage, QAngle &viewPunch, Vector &shove )
{
	Vector vecForceDir;

	// Always hurt bullseyes for now
	if ( ( GetEnemy() != NULL ) && ( GetEnemy()->Classify() == CLASS_BULLSEYE ) )
	{
		vecForceDir = (GetEnemy()->GetAbsOrigin() - GetAbsOrigin());
		CTakeDamageInfo info( this, this, damage, DMG_SLASH );
		CalculateMeleeDamageForce( &info, vecForceDir, GetEnemy()->GetAbsOrigin() );
		GetEnemy()->TakeDamage( info );
		return;
	}

	CBaseEntity *pHurt = CheckTraceHullAttack( distance, -Vector(16,16,32), Vector(16,16,32), damage, DMG_SLASH, 5.0f );

	if ( pHurt )
	{
		vecForceDir = ( pHurt->WorldSpaceCenter() - WorldSpaceCenter() );

		//FIXME: Until the interaction is setup, kill combine soldiers in one hit -- jdw
		if ( FClassnameIs( pHurt, "npc_combine_s" ) )
		{
			CTakeDamageInfo	dmgInfo( this, this, pHurt->m_iHealth+25, DMG_SLASH );
			CalculateMeleeDamageForce( &dmgInfo, vecForceDir, pHurt->GetAbsOrigin() );
			pHurt->TakeDamage( dmgInfo );
			return;
		}

		CBasePlayer *pPlayer = ToBasePlayer( pHurt );

		if ( pPlayer != NULL )
		{
			//Kick the player angles
			if ( !(pPlayer->GetFlags() & FL_GODMODE ) && pPlayer->GetMoveType() != MOVETYPE_NOCLIP )
			{
				pPlayer->ViewPunch( viewPunch );

				Vector	dir = pHurt->GetAbsOrigin() - GetAbsOrigin();
				VectorNormalize(dir);

				QAngle angles;
				VectorAngles( dir, angles );
				Vector forward, right;
				AngleVectors( angles, &forward, &right, NULL );

				//Push the target back
				pHurt->ApplyAbsVelocityImpulse( - right * shove[1] - forward * shove[0] );
			}
		}

		// Play a random attack hit sound
		EmitSound( "Zombie.Punch" );
	}
	else
	{
		EmitSound( "Zombie.AttackMiss" );
	}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerClassCommando::BullRushTouch( CBaseEntity *pTouched )
{
	if ( pTouched->IsPlayer() && !pTouched->InSameTeam( m_pPlayer ) )
	{
		// Get the player.
		CBaseTFPlayer *pTFPlayer = ( CBaseTFPlayer* )pTouched;

		// Check to see if we have "touched" this player already this bullrush cycle.
		if ( m_aHitPlayers.Find( pTFPlayer ) != -1 )
			return;

		// Hitting the player now.
		m_aHitPlayers.AddToTail( pTFPlayer );

		// ROBIN: Bullrush now instantly kills again
		float flDamage = 200;
		// Calculate the damage a player takes based on distance(time).
		//float flDamage = 1.0f - ( ( COMMANDO_BULLRUSH_TIME - m_ClassData.m_flBullRushTime ) * ( 1.0f / COMMANDO_BULLRUSH_TIME ) );
		//flDamage *= 115.0f; // max bullrush damage

		trace_t tr = m_pPlayer->GetTouchTrace();
		CTakeDamageInfo info( m_pPlayer, m_pPlayer, flDamage, DMG_CLUB, DMG_KILL_BULLRUSH );
		CalculateMeleeDamageForce( &info, (tr.endpos - tr.startpos), tr.endpos );
		pTFPlayer->TakeDamage( info );

		CPASAttenuationFilter filter( m_pPlayer, "Commando.BullRushFlesh" );
		CBaseEntity::EmitSound( filter, m_pPlayer->entindex(), "Commando.BullRushFlesh" );

		pTFPlayer->Touch( m_pPlayer ); 
	}
}
void CNPC_Hydra::Stab( CBaseEntity *pOther, const Vector &vecSpeed, trace_t &tr )
{
	if (pOther->m_takedamage == DAMAGE_YES && !pOther->IsPlayer())
	{
		Vector dir = vecSpeed;
		VectorNormalize( dir );

		if ( !sv_hydraTestSpike.GetInt() )
		{
			ClearMultiDamage();
			// FIXME: this is bogus
			CTakeDamageInfo info( this, this, pOther->m_iHealth+25, DMG_SLASH );
			CalculateMeleeDamageForce( &info, dir, tr.endpos );
			pOther->DispatchTraceAttack( info, dir, &tr );
			ApplyMultiDamage();
		}
		else
		{
			CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating *>(pOther);
			if ( pAnimating )
			{
				AttachStabbedEntity( pAnimating, vecSpeed * 30, tr );
			}
		}
	}
	else
	{
		Nudge( pOther, tr.endpos, vecSpeed );
	}
}
//=====================================================================================//
// Purpose: Performs the screen shake and it checks to see if we hit an entity to
//          handle the proper damage
//			An entity here can be another player or a wood plank
//=====================================================================================//
void CTDPBludgeonWeaponBase::Hit( trace_t &tr, Activity nHitActivity )
{
	// Do we have a valid owner holding the weapon?
	CTDPPlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

	// Let's shake the screen a little
	AddViewKick();

	// if tr.m_pEnt is not NULL it means we have hit a target
	if ( tr.m_pEnt != NULL )
	{
		Vector vForward;
		pPlayer->EyeVectors( &vForward, NULL, NULL );
		VectorNormalize( vForward );

		// Process the damage and send it to the entity we just hit
		CTakeDamageInfo dmgInfo( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );
		CalculateMeleeDamageForce( &dmgInfo, vForward, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( dmgInfo, vForward, &tr );
		ApplyMultiDamage();

#if defined( GAME_DLL )
		// Now hit all triggers along the ray that...
		TraceAttackToTriggers( dmgInfo, tr.startpos, tr.endpos, vForward );
#endif
	}

	// Apply an impact effect
	ImpactEffect( tr );
}
void CGrenadeEnergy::GrenadeEnergyTouch( CBaseEntity *pOther )
{
	if ( pOther->m_takedamage )
	{
		float flLifeLeft = 1-(gpGlobals->curtime  - m_flLaunchTime)/ENERGY_GRENADE_LIFETIME;

		if ( pOther->GetFlags() & (FL_CLIENT) )
		{
			CBasePlayer *pPlayer = ( CBasePlayer * )pOther;
			float		flKick	 = 120 * flLifeLeft;
			pPlayer->m_Local.m_vecPunchAngle.SetX( flKick * (random->RandomInt(0,1) == 1) ? -1 : 1 );
			pPlayer->m_Local.m_vecPunchAngle.SetY( flKick * (random->RandomInt(0,1) == 1) ? -1 : 1 );
		}
		float flDamage = m_flDamage * flLifeLeft;
		if (flDamage < 1) 
		{
			flDamage = 1;
		}

		trace_t tr;
		tr = GetTouchTrace();
		CTakeDamageInfo info( this, GetThrower(), m_flDamage * flLifeLeft, DMG_SONIC );
		CalculateMeleeDamageForce( &info, (tr.endpos - tr.startpos), tr.endpos );
		pOther->TakeDamage( info );
	}
	Detonate();
}
//------------------------------------------------------------------------------
// Purpose: Implement impact function
//------------------------------------------------------------------------------
void CWeaponCrowbar::Hit( void )
{
	//Make sound for the AI
#ifndef CLIENT_DLL

	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

	CSoundEnt::InsertSound( SOUND_BULLET_IMPACT, m_traceHit.endpos, 400, 0.2f, pPlayer );

	CBaseEntity	*pHitEntity = m_traceHit.m_pEnt;

	//Apply damage to a hit target
	if ( pHitEntity != NULL )
	{
		Vector hitDirection;
		pPlayer->EyeVectors( &hitDirection, NULL, NULL );
		VectorNormalize( hitDirection );

		ClearMultiDamage();
		CTakeDamageInfo info( GetOwner(), GetOwner(), sk_plr_dmg_crowbar.GetFloat(), DMG_CLUB );
		CalculateMeleeDamageForce( &info, hitDirection, m_traceHit.endpos );
		pHitEntity->DispatchTraceAttack( info, hitDirection, &m_traceHit ); 
		ApplyMultiDamage();

		// Now hit all triggers along the ray that... 
		TraceAttackToTriggers( CTakeDamageInfo( GetOwner(), GetOwner(), sk_plr_dmg_crowbar.GetFloat(), DMG_CLUB ), m_traceHit.startpos, m_traceHit.endpos, hitDirection );

		//Play an impact sound	
		ImpactSound( pHitEntity );
	}
#endif

	//Apply an impact effect
	ImpactEffect();
}
// Overridden for Gargantua because his swing starts lower as
// a percentage of his height (otherwise he swings over the
// players head)
//=========================================================
CBaseEntity* CNPC_Gargantua::GargantuaCheckTraceHullAttack(float flDist, int iDamage, int iDmgType)
{
	trace_t tr;

	Vector vForward, vUp;
	AngleVectors( GetAbsAngles(), &vForward, NULL, &vUp );

	Vector vecStart = GetAbsOrigin();
	vecStart.z += 64;
	Vector vecEnd = vecStart + ( vForward * flDist) - ( vUp * flDist * 0.3);

	//UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr );

	UTIL_TraceEntity( this, GetAbsOrigin(), vecEnd, MASK_SOLID, &tr );
	
	if ( tr.m_pEnt )
	{
		CBaseEntity *pEntity = tr.m_pEnt;

		if ( iDamage > 0 )
		{
			CTakeDamageInfo info( this, this, iDamage, iDmgType );
			CalculateMeleeDamageForce( &info, vForward, tr.endpos );
			pEntity->TakeDamage( info );
		}

		return pEntity;
	}

	return NULL;
}
void CNPC_Tentacle::HitTouch( CBaseEntity *pOther )
{
	if (m_flHitTime > gpGlobals->curtime)
		return;

	// only look at the ones where the player hit me
	if( pOther == NULL || pOther->GetModelIndex() == GetModelIndex() || ( pOther->GetSolidFlags() & FSOLID_TRIGGER ) )
		 return;

	//Right now the BoneFollower will always be hit in box 0, and 
	//will pass that to us. Make *any* touch by the physics objects a kill
	//as the ragdoll only covers the top portion of the tentacle.
	if ( pOther->m_takedamage )
	{
		CTakeDamageInfo info( this, this, m_iHitDmg, DMG_CLUB );

		Vector vDamageForce = pOther->GetAbsOrigin() - GetAbsOrigin();
		VectorNormalize( vDamageForce );

		CalculateMeleeDamageForce( &info, vDamageForce, pOther->GetAbsOrigin() );
		pOther->TakeDamage( info );

		m_flHitTime = gpGlobals->curtime + 0.5;
	}
}
//-----------------------------------------------------------------------------
// 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 );
}
int CASW_Parasite::CalcDamageInfo( CTakeDamageInfo *pInfo )
{
	Assert(ASWGameRules());
	pInfo->Set( this, this, asw_parasite_defanged_damage.GetFloat(), DMG_ACID );
	CalculateMeleeDamageForce( pInfo, GetAbsVelocity(), GetAbsOrigin() );
	return pInfo->GetDamage();
}
void CStomp::Think( void )
{
	trace_t tr;

	SetNextThink( gpGlobals->curtime + 0.1 );

	// Do damage for this frame
	Vector vecStart = GetAbsOrigin();
	vecStart.z += 30;
	Vector vecEnd = vecStart + (m_vecMoveDir * m_flSpeed * gpGlobals->frametime);

	UTIL_TraceHull( vecStart, vecEnd, Vector(-32, -32, -32), Vector(32, 32, 32), MASK_SOLID, m_pOwner, COLLISION_GROUP_NONE, &tr );
//	NDebugOverlay::Line( vecStart, vecEnd, 0, 255, 0, false, 10.0f );
	
	if ( tr.m_pEnt )
	{
		CBaseEntity *pEntity = tr.m_pEnt;
		CTakeDamageInfo info( this, this, 50, DMG_SONIC );
		CalculateMeleeDamageForce( &info, m_vecMoveDir, tr.endpos );
		pEntity->TakeDamage( info );
	}

	// Accelerate the effect
	m_flSpeed += (gpGlobals->frametime) * m_uiFramerate;
	m_uiFramerate += (gpGlobals->frametime) * 2000;
	
	// Move and spawn trails
	while ( gpGlobals->curtime - m_flDmgTime > STOMP_INTERVAL )
	{
		SetAbsOrigin( GetAbsOrigin() + m_vecMoveDir * m_flSpeed * STOMP_INTERVAL );
		for ( int i = 0; i < 2; i++ )
		{
			CSprite *pSprite = CSprite::SpriteCreate( GARG_STOMP_SPRITE_NAME, GetAbsOrigin(), TRUE );
			if ( pSprite )
			{
				UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,500), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
				pSprite->SetAbsOrigin( tr.endpos );
//				pSprite->pev->velocity = Vector(RandomFloat(-200,200),RandomFloat(-200,200),175);
				pSprite->SetNextThink( gpGlobals->curtime + 0.3 );
				pSprite->SetThink( &CSprite::SUB_Remove );
				pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxFadeFast );
			}
			g_pEffects->EnergySplash( tr.endpos, tr.plane.normal );
		}
		m_flDmgTime += STOMP_INTERVAL;
		// Scale has the "life" of this effect
		m_flScale -= STOMP_INTERVAL * m_flSpeed;
		if ( m_flScale <= 0 )
		{
			// Life has run out
			UTIL_Remove(this);
//			STOP_SOUND( edict(), CHAN_BODY, GARG_STOMP_BUZZ_SOUND );
			CPASAttenuationFilter filter( this );
			StopSound( entindex(), CHAN_STATIC, GARG_STOMP_BUZZ_SOUND );

		}

	}
}
Beispiel #13
0
//---------------------------------------------------------
//---------------------------------------------------------
void CNPC_Assassin::HandleAnimEvent( animevent_t *pEvent )
{
	
	if ( pEvent->event == AE_ASSASIN_FIRE_PISTOL_RIGHT )
	{
		FirePistol( 0 );
		return;
	}

	if ( pEvent->event == AE_ASSASIN_FIRE_PISTOL_LEFT )
	{
		FirePistol( 1 );
		return;
	}
	
	if ( pEvent->event == AE_ASSASIN_KICK_HIT )
	{
		Vector	attackDir = BodyDirection2D();
		Vector	attackPos = WorldSpaceCenter() + ( attackDir * 64.0f );

		trace_t	tr;
		UTIL_TraceHull( WorldSpaceCenter(), attackPos, -Vector(8,8,8), Vector(8,8,8), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr );

		if ( ( tr.m_pEnt != NULL ) && ( tr.DidHitWorld() == false ) )
		{
			if ( tr.m_pEnt->m_takedamage != DAMAGE_NO )
			{
				CTakeDamageInfo info( this, this, 5, DMG_CLUB );
				CalculateMeleeDamageForce( &info, (tr.endpos - tr.startpos), tr.endpos );
				tr.m_pEnt->TakeDamage( info );

				CBasePlayer	*pPlayer = ToBasePlayer( tr.m_pEnt );

				if ( pPlayer != NULL )
				{
					//Kick the player angles
					pPlayer->ViewPunch( QAngle( -30, 40, 10 ) );
				}

				EmitSound( "Zombie.AttackHit" );
				//EmitSound( "Assassin.AttackHit" );
			}
		}
		else
		{
			EmitSound( "Assassin.AttackMiss" );
			//EmitSound( "Assassin.AttackMiss" );
		}

		return;
	}

	BaseClass::HandleAnimEvent( pEvent );
}
Beispiel #14
0
//=========================================================
// ArmBeam - small beam from arm to nearby geometry
//=========================================================
void CNPC_Vortigaunt::ArmBeam( int side )
{
    trace_t tr;
    float flDist = 1.0;

    if ( m_iBeams >= VORTIGAUNT_MAX_BEAMS )
        return;

    Vector forward, right, up;
    Vector vecAim;
    AngleVectors( GetAbsAngles(), &forward, &right, &up );
    Vector vecSrc = GetAbsOrigin() + up * 36 + right * side * 16 + forward * 32;

    for (int i = 0; i < 3; i++)
    {
        vecAim = right * side * random->RandomFloat( 0, 1 ) + up * random->RandomFloat( -1, 1 );
        trace_t tr1;
        UTIL_TraceLine ( vecSrc, vecSrc + vecAim * 512, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr1);
        if (flDist > tr1.fraction)
        {
            tr = tr1;
            flDist = tr.fraction;
        }
    }

    // Couldn't find anything close enough
    if ( flDist == 1.0 )
        return;

    if( tr.m_pEnt && tr.m_pEnt->m_takedamage )
    {
        CTakeDamageInfo info( this, this, 10, DMG_SHOCK );
        CalculateMeleeDamageForce( &info, vecAim, tr.endpos );

        tr.m_pEnt->TakeDamage( info );
    }

    UTIL_ImpactTrace( &tr, DMG_CLUB );

    m_pBeam[m_iBeams] = CBeam::BeamCreate( "sprites/lgtning.vmt", 3.0f );

    if ( m_pBeam[m_iBeams] == NULL )
        return;

    m_pBeam[m_iBeams]->PointEntInit( tr.endpos, this );
    m_pBeam[m_iBeams]->SetEndAttachment( side < 0 ? 2 : 1 );

    m_pBeam[m_iBeams]->SetColor( 96, 128, 16 );

    m_pBeam[m_iBeams]->SetBrightness( 64 );
    m_pBeam[m_iBeams]->SetNoise( 12.8 );

    m_iBeams++;
}
Beispiel #15
0
//-----------------------------------------------------------------------------
// Purpose: Try and guess the physics force to use.
//			This shouldn't be used for any damage where the damage force is unknown.
//			i.e. only use it for mapmaker specified damages.
//-----------------------------------------------------------------------------
void GuessDamageForce( CTakeDamageInfo *info, const Vector &vecForceDir, const Vector &vecForceOrigin, float flScale )
{
	if ( info->GetDamageType() & DMG_BULLET )
	{
		CalculateBulletDamageForce( info, GetAmmoDef()->Index("SMG1"), vecForceDir, vecForceOrigin, flScale );
	}
	else if ( info->GetDamageType() & DMG_BLAST )
	{
		CalculateExplosiveDamageForce( info, vecForceDir, vecForceOrigin, flScale );
	}
	else
	{
		CalculateMeleeDamageForce( info, vecForceDir, vecForceOrigin, flScale );
	}
}
//------------------------------------------------------------------------------
// Purpose: Implement impact function
//------------------------------------------------------------------------------
void CBaseSDKBludgeonWeapon::Hit( trace_t &traceHit, Activity nHitActivity, bool bIsSecondary )
{
	CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );
	
	//Do view kick
	AddViewKick();

	//Make sound for the AI
	CSoundEnt::InsertSound( SOUND_BULLET_IMPACT, traceHit.endpos, 400, 0.2f, pPlayer );

	// This isn't great, but it's something for when the crowbar hits.
	pPlayer->RumbleEffect( RUMBLE_AR2, 0, RUMBLE_FLAG_RESTART );

	CBaseEntity	*pHitEntity = traceHit.m_pEnt;

	//Apply damage to a hit target
	if ( pHitEntity != NULL )
	{
		Vector hitDirection;
		pPlayer->EyeVectors( &hitDirection, NULL, NULL );
		VectorNormalize( hitDirection );

		CTakeDamageInfo info( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );

		if( pPlayer && pHitEntity->IsNPC() )
		{
			// If bonking an NPC, adjust damage.
			info.AdjustPlayerDamageInflictedForSkillLevel();
		}

		CalculateMeleeDamageForce( &info, hitDirection, traceHit.endpos );

		pHitEntity->DispatchTraceAttack( info, hitDirection, &traceHit ); 
		ApplyMultiDamage();

		// Now hit all triggers along the ray that... 
		TraceAttackToTriggers( info, traceHit.startpos, traceHit.endpos, hitDirection );

		if ( ToBaseCombatCharacter( pHitEntity ) )
		{
			gamestats->Event_WeaponHit( pPlayer, !bIsSecondary, GetClassname(), info );
		}
	}

	// Apply an impact effect
	ImpactEffect( traceHit );
}
void CBreakable::BreakTouch( CBaseEntity *pOther )
{
	float flDamage;
	
	// only players can break these right now
	if ( !pOther->IsPlayer() || !IsBreakable() )
	{
        return;
	}

	// can I be broken when run into?
	if ( HasSpawnFlags( SF_BREAK_TOUCH ) )
	{
		flDamage = pOther->GetSmoothedVelocity().Length() * 0.01;

		if (flDamage >= m_iHealth)
		{
			m_takedamage = DAMAGE_YES;

			SetTouch( NULL );
			OnTakeDamage( CTakeDamageInfo( pOther, pOther, flDamage, DMG_CRUSH ) );

			// do a little damage to player if we broke glass or computer
			CTakeDamageInfo info( pOther, pOther, flDamage/4, DMG_SLASH );
			CalculateMeleeDamageForce( &info, (pOther->GetAbsOrigin() - GetAbsOrigin()), GetAbsOrigin() );
			pOther->TakeDamage( info );
		}
	}

	// can I be broken when stood upon?
	if ( HasSpawnFlags( SF_BREAK_PRESSURE ) && pOther->GetGroundEntity() == this )
	{
		// play creaking sound here.
		DamageSound();

		m_hBreaker = pOther;

		SetThink ( &CBreakable::Die );
		SetTouch( NULL );
		
		// Add optional delay 
		SetNextThink( gpGlobals->curtime + m_flPressureDelay );

	}
}
//------------------------------------------------------------------------------
// Purpose: Implement impact function
//------------------------------------------------------------------------------
void CBaseHL2MPBludgeonWeapon::Hit( trace_t &traceHit, Activity nHitActivity )
{
    CBasePlayer *pPlayer = ToBasePlayer( GetOwner() );

    //Do view kick
//	AddViewKick();

    CBaseEntity	*pHitEntity = traceHit.m_pEnt;

    //Apply damage to a hit target
    if ( pHitEntity != NULL )
    {
        Vector hitDirection;
        pPlayer->EyeVectors( &hitDirection, NULL, NULL );
        VectorNormalize( hitDirection );

#ifndef CLIENT_DLL
        CTakeDamageInfo info( GetOwner(), GetOwner(), GetDamageForActivity( nHitActivity ), DMG_CLUB );

        if( pPlayer && pHitEntity->IsNPC() )
        {
            // If bonking an NPC, adjust damage.
            info.AdjustPlayerDamageInflictedForSkillLevel();
        }

        CalculateMeleeDamageForce( &info, hitDirection, traceHit.endpos );

        pHitEntity->DispatchTraceAttack( info, hitDirection, &traceHit );
        ApplyMultiDamage();

        // Now hit all triggers along the ray that...
        TraceAttackToTriggers( info, traceHit.startpos, traceHit.endpos, hitDirection );
#endif
        //DHL - Skillet
        if ( pHitEntity->entindex() == 0 )
            WeaponSound( MELEE_HIT_WORLD );
        else
            WeaponSound( MELEE_HIT );
    }

    // Apply an impact effect
    ImpactEffect( traceHit );
}
Beispiel #19
0
void CASW_Harvester::StartTouch( CBaseEntity *pOther )
{
	BaseClass::StartTouch( pOther );

	CASW_Marine *pMarine = CASW_Marine::AsMarine( pOther );
	if (pMarine)
	{
		// don't hurt him if he was hurt recently
		if (m_fLastTouchHurtTime + 0.6f > gpGlobals->curtime)
		{
			return;
		}
		// hurt the marine
		Vector vecForceDir = (pMarine->GetAbsOrigin() - GetAbsOrigin());
		CTakeDamageInfo info( this, this, asw_harvester_touch_damage.GetInt(), DMG_SLASH );
		CalculateMeleeDamageForce( &info, vecForceDir, pMarine->GetAbsOrigin() );
		pMarine->TakeDamage( info );
		m_fLastTouchHurtTime = gpGlobals->curtime;
	}
}
//-----------------------------------------------------------------------------
// Purpose: Damages anything in the beam.
// Input  : ptr - 
//-----------------------------------------------------------------------------
void CBeam::BeamDamage( trace_t *ptr )
{
	RelinkBeam();
#if !defined( CLIENT_DLL )
	if ( ptr->fraction != 1.0 && ptr->m_pEnt != NULL )
	{
		CBaseEntity *pHit = ptr->m_pEnt;
		if ( pHit )
		{
			ClearMultiDamage();
			Vector dir = ptr->endpos - GetAbsOrigin();
			VectorNormalize( dir );
			int nDamageType = DMG_ENERGYBEAM;

#ifndef HL1_DLL
			if (m_nDissolveType == 0)
			{
				nDamageType = DMG_DISSOLVE;
			}
			else if ( m_nDissolveType > 0 )
			{
				nDamageType = DMG_DISSOLVE | DMG_SHOCK; 
			}
#endif

			CTakeDamageInfo info( this, this, m_flDamage * (gpGlobals->curtime - m_flFireTime), nDamageType );
			CalculateMeleeDamageForce( &info, dir, ptr->endpos );
			pHit->DispatchTraceAttack( info, dir, ptr );
			ApplyMultiDamage();
			if ( HasSpawnFlags( SF_BEAM_DECALS ) )
			{
				if ( pHit->IsBSPModel() )
				{
					UTIL_DecalTrace( ptr, GetDecalName() );
				}
			}
		}
	}
#endif
	m_flFireTime = gpGlobals->curtime;
}
Beispiel #21
0
//softcopy: ignited/explode marine by boomer on touch/on fire touch, 1=melee, 2=touch, 3=All
void CASW_Boomer::StartTouch( CBaseEntity *pOther )
{
	BaseClass::StartTouch( pOther );
	CASW_Marine *pMarine = CASW_Marine::AsMarine( pOther );
	if ( pMarine )
	{
		m_TouchExplosionDamage = asw_boomer_touch_damage.GetInt();
		CTakeDamageInfo info( this, this, m_TouchExplosionDamage, DMG_SLASH );
		damageTypes = "on touch";
		if (asw_boomer_ignite.GetInt() >= 2 || (m_bOnFire && asw_boomer_touch_onfire.GetBool()))
			MarineIgnite(pMarine, info, alienLabel, damageTypes);
		if ( m_fLastTouchHurtTime + 0.35f /*0.6f*/ > gpGlobals->curtime || m_TouchExplosionDamage <=0 )	//don't hurt him if he was hurt recently
			return;
		Vector vecForceDir = ( pMarine->GetAbsOrigin() - GetAbsOrigin() );	// hurt the marine
		CalculateMeleeDamageForce( &info, vecForceDir, pMarine->GetAbsOrigin() );
		pMarine->TakeDamage( info );
		if (asw_boomer_explode.GetInt() >= 2 )
			MarineExplode(pMarine, alienLabel, damageTypes);

		m_fLastTouchHurtTime = gpGlobals->curtime;
	}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input  :
// Output :
//-----------------------------------------------------------------------------
void CGrenade_Brickbat::BrickbatTouch( CBaseEntity *pOther )
{
	// -----------------------------------------------------------
	// Might be physically simulated so get my velocity manually
	// -----------------------------------------------------------
	Vector vVelocity;
	GetVelocity(&vVelocity,NULL);

	// -----------------------------------
	// Do damage if we moving fairly fast
	// -----------------------------------
	if (vVelocity.Length() > 100)
	{
		if (GetThrower())
		{
			trace_t tr;
			tr = CBaseEntity::GetTouchTrace( );
			ClearMultiDamage( );
			Vector forward;
			AngleVectors( GetLocalAngles(), &forward );

			CTakeDamageInfo info( this, GetThrower(), m_flDamage, DMG_CRUSH );
			CalculateMeleeDamageForce( &info, forward, tr.endpos );
			pOther->DispatchTraceAttack( info, forward, &tr );
			ApplyMultiDamage();
		}
		// If this thrown item explodes, blow it up
		if (m_bExplodes) 
		{
			Detonate();
			return;
		}
	}
	else if (pOther->GetFlags() & FL_CLIENT)
	{
		SpawnBrickbatWeapon();
		return;
	}
}
//-----------------------------------------------------------------------------
// Purpose: Automatic Melee Attack
//-----------------------------------------------------------------------------
void CPlayerClassCommando::Boot( CBaseTFPlayer *pTarget )
{
	CPASAttenuationFilter filter( m_pPlayer, "Commando.BootSwing" );

	CBaseEntity::EmitSound( filter, m_pPlayer->entindex(), "Commando.BootSwing" );
	CBaseEntity::EmitSound( filter, m_pPlayer->entindex(), "Commando.BootHit" );

	// Damage the target
	CTakeDamageInfo info( m_pPlayer, m_pPlayer, 25, DMG_CLUB );
	CalculateMeleeDamageForce( &info, (pTarget->GetAbsOrigin() - m_pPlayer->GetAbsOrigin()), pTarget->GetAbsOrigin() );
	pTarget->TakeDamage( info );

	Vector vecForward;
	AngleVectors( m_pPlayer->GetLocalAngles(), &vecForward );
	// Give it a lot of "in the air"
	vecForward.z = max( 0.8, vecForward.z );
	VectorNormalize( vecForward );

	// Knock the target to the ground for a few seconds (use default duration)
	pTarget->KnockDownPlayer( vecForward, 500.0f, tf_knockdowntime.GetFloat() );

}
Beispiel #24
0
//=========================================================
// ZapBeam - heavy damage directly forward
//=========================================================
void CNPC_Vortigaunt::ZapBeam( int side )
{
    Vector vecSrc, vecAim;
    trace_t tr;
    CBaseEntity *pEntity;

    if ( m_iBeams >= VORTIGAUNT_MAX_BEAMS )
        return;

    Vector forward, right, up;
    AngleVectors( GetAbsAngles(), &forward, &right, &up );

    vecSrc = GetAbsOrigin() + up * 36;
    vecAim = GetShootEnemyDir( vecSrc );
    float deflection = 0.01;
    vecAim = vecAim + side * right * random->RandomFloat( 0, deflection ) + up * random->RandomFloat( -deflection, deflection );
    UTIL_TraceLine ( vecSrc, vecSrc + vecAim * 1024, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);

    m_pBeam[m_iBeams] = CBeam::BeamCreate( "sprites/lgtning.vmt", 5.0f );
    if ( m_pBeam[m_iBeams] == NULL )
        return;

    m_pBeam[m_iBeams]->PointEntInit( tr.endpos, this );
    m_pBeam[m_iBeams]->SetEndAttachment( side < 0 ? 2 : 1 );
    m_pBeam[m_iBeams]->SetColor( 180, 255, 96 );
    m_pBeam[m_iBeams]->SetBrightness( 255 );
    m_pBeam[m_iBeams]->SetNoise( 3.2f );
    m_iBeams++;

    pEntity = tr.m_pEnt;

    if ( pEntity != NULL && m_takedamage )
    {
        CTakeDamageInfo info( this, this, sk_islave_dmg_zap.GetFloat(), DMG_SHOCK );
        CalculateMeleeDamageForce( &info, vecAim, tr.endpos );
        pEntity->DispatchTraceAttack( info, vecAim, &tr );
    }
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Ichthyosaur::Bite( void )
{
	//Don't allow another bite too soon
	if ( m_flNextBiteTime > gpGlobals->curtime )
		return;

	CBaseEntity *pHurt;
	
	//FIXME: E3 HACK - Always damage bullseyes if we're scripted to hit them
	if ( ( GetEnemy() != NULL ) && ( GetEnemy()->Classify() == CLASS_BULLSEYE ) )
	{
		pHurt = GetEnemy();
	}
	else
	{
		pHurt = CheckTraceHullAttack( 108, Vector(-32,-32,-32), Vector(32,32,32), 0, DMG_CLUB );
	}

	//Hit something
	if ( pHurt != NULL )
	{
		CTakeDamageInfo info( this, this, sk_ichthyosaur_melee_dmg.GetInt(), DMG_CLUB );

		if ( pHurt->IsPlayer() )
		{
			CBasePlayer *pPlayer = ToBasePlayer( pHurt );

			if ( pPlayer )
			{
				if ( ( ( m_flHoldTime < gpGlobals->curtime ) && ( pPlayer->m_iHealth < (pPlayer->m_iMaxHealth*0.5f)) ) || ( pPlayer->GetWaterLevel() < 1 ) )
				{
					//EnsnareVictim( pHurt );
				}
				else
				{
					info.SetDamage( sk_ichthyosaur_melee_dmg.GetInt() * 3 );
				}
				CalculateMeleeDamageForce( &info, GetAbsVelocity(), pHurt->GetAbsOrigin() );
				pHurt->TakeDamage( info );

				color32 red = {64, 0, 0, 255};
				UTIL_ScreenFade( pPlayer, red, 0.5, 0, FFADE_IN  );

				//Disorient the player
				QAngle angles = pPlayer->GetLocalAngles();

				angles.x += random->RandomInt( 60, 25 );
				angles.y += random->RandomInt( 60, 25 );
				angles.z = 0.0f;

				pPlayer->SetLocalAngles( angles );

				pPlayer->SnapEyeAngles( angles );
			}
		}
		else
		{
			CalculateMeleeDamageForce( &info, GetAbsVelocity(), pHurt->GetAbsOrigin() );
			pHurt->TakeDamage( info );
		}

		m_flNextBiteTime = gpGlobals->curtime + random->RandomFloat( 2.0f, 4.0f );

		//Bubbles!
		UTIL_Bubbles( pHurt->GetAbsOrigin()+Vector(-32.0f,-32.0f,-32.0f), pHurt->GetAbsOrigin()+Vector(32.0f,32.0f,0.0f), random->RandomInt( 16, 32 ) );
		
		// Play a random attack hit sound
		EmitSound( "NPC_Ichthyosaur.Bite" );

		if ( GetActivity() == ACT_MELEE_ATTACK1 )
		{
			SetActivity( (Activity) ACT_ICH_BITE_HIT );
		}
		
		return;
	}

	//Play the miss animation and sound
	if ( GetActivity() == ACT_MELEE_ATTACK1 )
	{
		SetActivity( (Activity) ACT_ICH_BITE_MISS );
	}

	//Miss sound
	EmitSound( "NPC_Ichthyosaur.BiteMiss" );
}
void CSnark::SuperBounceTouch( CBaseEntity *pOther )
{
	float	flpitch;
	trace_t tr = CBaseEntity::GetTouchTrace( );

	// don't hit the guy that launched this grenade
	if ( m_hOwner && ( pOther == m_hOwner ) )
		return;

	// at least until we've bounced once
	m_hOwner = NULL;

	QAngle angles = GetAbsAngles();
	angles.x = 0;
	angles.z = 0;
	SetAbsAngles( angles );

	// avoid bouncing too much
	if ( m_flNextHit > gpGlobals->curtime) 
		return;

	// higher pitch as squeeker gets closer to detonation time
	flpitch = 155.0 - 60.0 * ( ( m_flDie - gpGlobals->curtime ) / SQUEEK_DETONATE_DELAY );

	if ( pOther->m_takedamage && m_flNextAttack < gpGlobals->curtime )
	{
		// attack!

		// make sure it's me who has touched them
		if ( tr.m_pEnt == pOther )
		{
			// and it's not another squeakgrenade
			if ( tr.m_pEnt->GetModelIndex() != GetModelIndex() )
			{
				// ALERT( at_console, "hit enemy\n");
				ClearMultiDamage();

				Vector vecForward;
				AngleVectors( GetAbsAngles(), &vecForward );

				if ( m_hOwner != NULL )
				{
					CTakeDamageInfo info( this, m_hOwner, sk_snark_dmg_bite.GetFloat(), DMG_SLASH );
					CalculateMeleeDamageForce( &info, vecForward, tr.endpos );
					pOther->DispatchTraceAttack( info, vecForward, &tr );
				}
				else
				{
					CTakeDamageInfo info( this, this, sk_snark_dmg_bite.GetFloat(), DMG_SLASH );
					CalculateMeleeDamageForce( &info, vecForward, tr.endpos );
					pOther->DispatchTraceAttack( info, vecForward, &tr );
				}

				ApplyMultiDamage();

				SetDamage( GetDamage() + sk_snark_dmg_pop.GetFloat() ); // add more explosion damage
				// m_flDie += 2.0; // add more life

				// make bite sound
				CPASAttenuationFilter filter( this );
				enginesound->EmitSound( filter, entindex(), CHAN_WEAPON, "squeek/sqk_deploy1.wav", 1, ATTN_NORM, 0, (int)flpitch );
				m_flNextAttack = gpGlobals->curtime + 0.5;
			}
		}
		else
		{
			// ALERT( at_console, "been hit\n");
		}
	}

	m_flNextHit = gpGlobals->curtime + 0.1;
	m_flNextHunt = gpGlobals->curtime;

	if ( g_pGameRules->IsMultiplayer() )
	{
		// in multiplayer, we limit how often snarks can make their bounce sounds to prevent overflows.
		if ( gpGlobals->curtime < m_flNextBounceSoundTime )
		{
			// too soon!
			return;
		}
	}

	if ( !( GetFlags() & FL_ONGROUND ) )
	{
		// play bounce sound
		CPASAttenuationFilter filter2( this );
		switch ( random->RandomInt( 0, 2 ) )
		{
		case 0:
			enginesound->EmitSound( filter2, entindex(), CHAN_VOICE, "squeek/sqk_hunt1.wav", 1, ATTN_NORM, 0, (int)flpitch );	break;
		case 1:
			enginesound->EmitSound( filter2, entindex(), CHAN_VOICE, "squeek/sqk_hunt2.wav", 1, ATTN_NORM, 0, (int)flpitch );	break;
		case 2:
			enginesound->EmitSound( filter2, entindex(), CHAN_VOICE, "squeek/sqk_hunt3.wav", 1, ATTN_NORM, 0, (int)flpitch );	break;
		}

		CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 256, 0.25 );
	}
	else
	{
		// skittering sound
		CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 100, 0.1 );
	}

	m_flNextBounceSoundTime = gpGlobals->curtime + 0.5;// half second.
}
// Основная атака огнеметом
// This is the cremator's main attack, or more precisely, its damage function.
void CNPC_Cremator::DispatchSpray( CBaseEntity *pEntity )
{ 
	Vector vecSrc, vecAim;
	trace_t tr;	

	//const char *entityname = pEntity->GetClassname();

	Vector forward, right, up;
	AngleVectors( GetAbsAngles(), &forward, &right, &up );

	vecSrc = GetAbsOrigin() + up * 36;
	vecAim = GetShootEnemyDir( vecSrc );
	float deflection = 0.01;	
	vecAim = vecAim + 1 * right * random->RandomFloat( 0, deflection ) + up * random->RandomFloat( -deflection, deflection );
	UTIL_TraceLine ( vecSrc, vecSrc + vecAim * 512, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr);
			
/*	if ( tr.DidHitWorld() ) // spawn flames on solid surfaces. 
							// It's not very important since it is extremely rare for a cremator to
							// hit brush geometry but might be a nice feature for a close-space combat
							// it also works fine but again is EXTREMELY hard to get in-game
	{
		Vector	ofsDir = ( tr.endpos - GetAbsOrigin() );
		float	offset = VectorNormalize( ofsDir );

		if ( offset > 128 )
			offset = 128;

		float scale	 = 0.1f + ( 0.75f * ( 1.0f - ( offset / 128.0f ) ) );
		float growth = 0.1f + ( 0.75f * (offset / 128.0f ) );

		if ( tr.surface.flags & CONTENTS_GRATE ) // get smaller flames on grates since they have a smaller burning area
		{
			scale = 0.1f + ( 0.15f * ( 1.0f - ( offset / 128.0f ) ) );
		}
		else
		{
			scale = 0.1f + ( 0.75f * ( 1.0f - ( offset / 128.0f ) ) );
		}
		FireSystem_StartFire( tr.endpos, scale, growth, 8.0, 10.0f, (SF_FIRE_START_ON|SF_FIRE_START_FULL), (CBaseEntity*) this, FIRE_NATURAL );

	}	
*/

	pEntity = tr.m_pEnt;

	if ( pEntity != NULL && m_takedamage )
	{
		CTakeDamageInfo firedamage( this, this, sk_cremator_firedamage.GetFloat(), DMG_BURN );
		CTakeDamageInfo radiusdamage( this, this, sk_cremator_radiusdamage.GetFloat(), DMG_PLASMA ); 
		CalculateMeleeDamageForce( &firedamage, vecAim, tr.endpos );
		RadiusDamage ( CTakeDamageInfo ( this, this, 2, DMG_PLASMA ), // AOE; this stuff makes cremators absurdly powerfull sometimes btw
			tr.endpos,
			64.0f,
			CLASS_NONE,
			NULL );

		pEntity->DispatchTraceAttack( ( firedamage ), vecAim, &tr );
		
		Vector flEnemyLKP = pEntity->GetAbsOrigin();
		GetMotor()->SetIdealYawToTargetAndUpdate( flEnemyLKP );

		ClearMultiDamage();
	}	

	m_iAmmo --;
}
// -----------------------------------------------------------------------------
// Purpose:
// Note: Think function to delay the impact decal until the animation is finished 
//       playing.
// -----------------------------------------------------------------------------
void CTFWeaponBaseMelee::Smack( void )
{
	trace_t trace;

	CBasePlayer *pPlayer = GetPlayerOwner();
	if ( !pPlayer )
		return;

#if !defined (CLIENT_DLL)
	// Move other players back to history positions based on local player's lag
	lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() );
#endif

	// We hit, setup the smack.
	if ( DoSwingTrace( trace ) )
	{
		// Hit sound - immediate.
		if( trace.m_pEnt->IsPlayer()  )
		{
			WeaponSound( MELEE_HIT );
		}
		else
		{
			WeaponSound( MELEE_HIT_WORLD );
		}

		// Get the current player.
		CTFPlayer *pPlayer = GetTFPlayerOwner();
		if ( !pPlayer )
			return;

		Vector vecForward; 
		AngleVectors( pPlayer->EyeAngles(), &vecForward );
		Vector vecSwingStart = pPlayer->Weapon_ShootPosition();
		Vector vecSwingEnd = vecSwingStart + vecForward * 48;

#ifndef CLIENT_DLL
		// Do Damage.
		int iCustomDamage = TF_DMG_CUSTOM_NONE;
		float flDamage = GetMeleeDamage( trace.m_pEnt, iCustomDamage );
		int iDmgType = DMG_BULLET | DMG_NEVERGIB | DMG_CLUB;
		if ( IsCurrentAttackACrit() )
		{
			// TODO: Not removing the old critical path yet, but the new custom damage is marking criticals as well for melee now.
			iDmgType |= DMG_CRITICAL;
		}
		CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon();
		CTFUbersaw *pUbersaw = dynamic_cast<CTFUbersaw*>(pWpn);
		CWeaponMedigun *pMedigun = static_cast<CWeaponMedigun*>(pPlayer->Weapon_OwnsThisID(TF_WEAPON_MEDIGUN));
		if (pMedigun && pUbersaw)
		{
			if(trace.m_pEnt->IsPlayer() && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber())
			{
				pMedigun->AddCharge();
			}
		}
		CWeaponKritzkrieg *pKritzkrieg = static_cast<CWeaponKritzkrieg*>(pPlayer->Weapon_OwnsThisID(TF_WEAPON_KRITZKRIEG));
		if (pKritzkrieg && pUbersaw)
		{
			if(trace.m_pEnt->IsPlayer() && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber())
			{
				pKritzkrieg->AddCharge();
			}
		}
		CTakeDamageInfo info( pPlayer, pPlayer, flDamage, iDmgType, iCustomDamage );
		CalculateMeleeDamageForce( &info, vecForward, vecSwingEnd, 1.0f / flDamage * tf_meleeattackforcescale.GetFloat() );
		trace.m_pEnt->DispatchTraceAttack( info, vecForward, &trace ); 
		ApplyMultiDamage();

		OnEntityHit( trace.m_pEnt );
#endif
		// Don't impact trace friendly players or objects
		if ( trace.m_pEnt && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber() )
		{
#ifdef CLIENT_DLL
			UTIL_ImpactTrace( &trace, DMG_CLUB );
#endif
			m_bConnected = true;
		}

	}

#if !defined (CLIENT_DLL)
	lagcompensation->FinishLagCompensation( pPlayer );
#endif
}
//=========================================================
// HandleAnimEvent - catches the monster-specific messages
// that occur when tagged animation frames are played.
//
// Returns number of events handled, 0 if none.
//=========================================================
void CNPC_BigMomma::HandleAnimEvent( animevent_t *pEvent )
{
	CPASAttenuationFilter filter( this );

	Vector vecFwd, vecRight, vecUp;
	QAngle angles;
	angles = GetAbsAngles();
	AngleVectors( angles, &vecFwd, &vecRight, &vecUp );

	switch( pEvent->event )
	{
		case BIG_AE_MELEE_ATTACKBR:
		case BIG_AE_MELEE_ATTACKBL:
		case BIG_AE_MELEE_ATTACK1:
		{
			Vector center = GetAbsOrigin() + vecFwd * 128;
			Vector mins = center - Vector( 64, 64, 0 );
			Vector maxs = center + Vector( 64, 64, 64 );

			CBaseEntity *pList[8];
			int count = UTIL_EntitiesInBox( pList, 8, mins, maxs, FL_NPC | FL_CLIENT );
			CBaseEntity *pHurt = NULL;

			for ( int i = 0; i < count && !pHurt; i++ )
			{
				if ( pList[i] != this )
				{
					if ( pList[i]->GetOwnerEntity() != this )
					{
						pHurt = pList[i];
					}
				}
			}
					
			if ( pHurt )
			{
				CTakeDamageInfo info( this, this, 15, DMG_CLUB | DMG_SLASH );
				CalculateMeleeDamageForce( &info, (pHurt->GetAbsOrigin() - GetAbsOrigin()), pHurt->GetAbsOrigin() );
				pHurt->TakeDamage( info );
				QAngle newAngles = angles;
				newAngles.x = 15;
				if ( pHurt->IsPlayer() )
				{
					((CBasePlayer *)pHurt)->SetPunchAngle( newAngles );
				}
				switch( pEvent->event )
				{
					case BIG_AE_MELEE_ATTACKBR:
//						pHurt->pev->velocity = pHurt->pev->velocity + (vecFwd * 150) + Vector(0,0,250) - (vecRight * 200);
						pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (vecFwd * 150) + Vector(0,0,250) - (vecRight * 200) );
					break;

					case BIG_AE_MELEE_ATTACKBL:
						pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (vecFwd * 150) + Vector(0,0,250) + (vecRight * 200) );
					break;

					case BIG_AE_MELEE_ATTACK1:
						pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (vecFwd * 220) + Vector(0,0,200) );
					break;
				}

				pHurt->SetGroundEntity( NULL );
				EmitSound( filter, entindex(), "BigMomma.AttackHit" );
			}
		}
		break;
		
		case BIG_AE_SCREAM:
			EmitSound( filter, entindex(), "BigMomma.Alert" );
			break;
		
		case BIG_AE_PAIN_SOUND:
			EmitSound( filter, entindex(), "BigMomma.Pain" );
			break;
		
		case BIG_AE_ATTACK_SOUND:
			EmitSound( filter, entindex(), "BigMomma.Attack" );
			break;

		case BIG_AE_BIRTH_SOUND:
			EmitSound( filter, entindex(), "BigMomma.Birth" );
			break;

		case BIG_AE_SACK:
			if ( RandomInt(0,100) < 30 )
			{
				EmitSound( filter, entindex(), "BigMomma.Sack" );
			}
			break;

		case BIG_AE_DEATHSOUND:
			EmitSound( filter, entindex(), "BigMomma.Die" );
			break;

		case BIG_AE_STEP1:		// Footstep left
		case BIG_AE_STEP3:		// Footstep back left
			EmitSound( filter, entindex(), "BigMomma.FootstepLeft" );
			break;

		case BIG_AE_STEP4:		// Footstep back right
		case BIG_AE_STEP2:		// Footstep right
			EmitSound( filter, entindex(), "BigMomma.FootstepRight" );
			break;

		case BIG_AE_MORTAR_ATTACK1:
			LaunchMortar();
			break;

		case BIG_AE_LAY_CRAB:
			LayHeadcrab();
			break;

		case BIG_AE_JUMP_FORWARD:
			SetGroundEntity( NULL );
			SetAbsOrigin(GetAbsOrigin() + Vector ( 0 , 0 , 1) );// take him off ground so engine doesn't instantly reset onground 
			SetAbsVelocity(vecFwd * 200 + vecUp * 500 );
			break;

		case BIG_AE_EARLY_TARGET:
			{
				CInfoBM *pTarget = (CInfoBM*) GetTarget();

				if ( pTarget )
				{
					pTarget->m_OnAnimationEvent.FireOutput( this, this );
				}
				
				Remember( bits_MEMORY_FIRED_NODE );
			}
			break;

		default:
			BaseClass::HandleAnimEvent( pEvent );
			break;
	}
}
Beispiel #30
0
void CBaseGrenade::BounceTouch( CBaseEntity *pOther )
{
	if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER | FSOLID_VOLUME_CONTENTS) )
		return;

	// don't hit the guy that launched this grenade
	if ( pOther == GetThrower() )
		return;

	// only do damage if we're moving fairly fast
	if ( (pOther->m_takedamage != DAMAGE_NO) && (m_flNextAttack < gpGlobals->curtime && GetAbsVelocity().Length() > 100))
	{
		if (m_hThrower)
		{
#if !defined( CLIENT_DLL )
			trace_t tr;
			tr = CBaseEntity::GetTouchTrace( );
			ClearMultiDamage( );
			Vector forward;
			AngleVectors( GetLocalAngles(), &forward, NULL, NULL );
			CTakeDamageInfo info( this, m_hThrower, 1, DMG_CLUB );
			CalculateMeleeDamageForce( &info, GetAbsVelocity(), GetAbsOrigin() );
			pOther->DispatchTraceAttack( info, forward, &tr ); 
			ApplyMultiDamage();
#endif
		}
		m_flNextAttack = gpGlobals->curtime + 1.0; // debounce
	}

	Vector vecTestVelocity;
	// m_vecAngVelocity = Vector (300, 300, 300);

	// this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical
	// or thrown very far tend to slow down too quickly for me to always catch just by testing velocity. 
	// trimming the Z velocity a bit seems to help quite a bit.
	vecTestVelocity = GetAbsVelocity(); 
	vecTestVelocity.z *= 0.45;

	if ( !m_bHasWarnedAI && vecTestVelocity.Length() <= 60 )
	{
		// grenade is moving really slow. It's probably very close to where it will ultimately stop moving. 
		// emit the danger sound.
		
		// register a radius louder than the explosion, so we make sure everyone gets out of the way
#if !defined( CLIENT_DLL )
		CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), m_flDamage / 0.4, 0.3, this );
#endif
		m_bHasWarnedAI = true;
	}

	if (GetFlags() & FL_ONGROUND)
	{
		// add a bit of static friction
//		SetAbsVelocity( GetAbsVelocity() * 0.8 );

		// SetSequence( random->RandomInt( 1, 1 ) ); // FIXME: missing tumble animations
	}
	else
	{
		// play bounce sound
		BounceSound();
	}
	m_flPlaybackRate = GetAbsVelocity().Length() / 200.0;
	if (GetPlaybackRate() > 1.0)
		m_flPlaybackRate = 1;
	else if (GetPlaybackRate() < 0.5)
		m_flPlaybackRate = 0;

}