//------------------------------------------------------------------------------
// Purpose : Drop a window pane entity
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBreakableSurface::DropPane(int nWidth, int nHeight)
{
	// Check parameter range
	if (nWidth < 0  || nWidth  >= m_nNumWide) return;
	if (nHeight < 0 || nHeight >= m_nNumHigh) return;

	if (!IsBroken(nWidth,nHeight))
	{
		BreakPane(nWidth,nHeight);

		QAngle vAngles;
		VectorAngles(-1*m_vNormal,vAngles);
		
		Vector vWidthDir,vHeightDir;
		AngleVectors(vAngles,NULL,&vWidthDir,&vHeightDir);
		Vector vBreakPos	= m_vCorner + 
								(nWidth*vWidthDir*m_flPanelWidth) + 
								(nHeight*vHeightDir*m_flPanelHeight);

		CreateShards(vBreakPos, vAngles, vec3_origin, vec3_origin,
						WINDOW_PANEL_SIZE,	WINDOW_PANEL_SIZE,
						WINDOW_SMALL_SHARD_SIZE);

		DamageSound();

		CWindowPane *pPane = CWindowPane::CreateWindowPane(vBreakPos, vAngles);
		if (pPane)
		{
			pPane->SetLocalAngularVelocity( RandomAngle(-120,120) );
		}
	}
}
Ejemplo n.º 2
0
void CBreakable::BreakTouch(CBaseEntity *pOther)
{
	float flDamage;
	entvars_t *pevToucher = pOther->pev;

	// only players can break these right now
	if (!pOther->IsPlayer() || !IsBreakable())
	{
		if (pev->rendermode == kRenderNormal || !FClassnameIs(pOther->pev, "grenade"))
			return;

		pev->angles.y = m_angle;
		UTIL_MakeVectors(pev->angles);

		g_vecAttackDir = gpGlobals->v_forward;

		pev->takedamage = DAMAGE_NO;
		pev->deadflag = DEAD_DEAD;
		pev->effects = EF_NODRAW;
		Die();
	}

	// can be broken when run into
	if (pev->spawnflags & SF_BREAK_TOUCH)
	{
		flDamage = pevToucher->velocity.Length() * 0.01f;

		if (flDamage >= pev->health)
		{
			SetTouch(NULL);
			TakeDamage(pevToucher, pevToucher, flDamage, DMG_CRUSH);

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

	// can be broken when stood upon
	if ((pev->spawnflags & SF_BREAK_PRESSURE) && pevToucher->absmin.z >= pev->maxs.z - 2)
	{
		// play creaking sound here.
		DamageSound();

		SetThink(&CBreakable::Die);
		SetTouch(NULL);

		// BUGBUG: why doesn't zero delay work?
		if (m_flDelay == 0.0f)
		{
			m_flDelay = 0.1f;
		}

		pev->nextthink = pev->ltime + m_flDelay;
	}
}
Ejemplo n.º 3
0
//=========================================================
// Special takedamage for func_breakable. Allows us to make
// exceptions that are breakable-specific
// bitsDamageType indicates the type of damage sustained ie: DMG_CRUSH
//=========================================================
int CBreakable :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
{
	Vector	vecTemp;

	// if Attacker == Inflictor, the attack was a melee or other instant-hit attack.
	// (that is, no actual entity projectile was involved in the attack so use the shooter's origin). 
	if ( pevAttacker == pevInflictor )	
	{
		vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) );
		
		// if a client hit the breakable with a crowbar, and breakable is crowbar-sensitive, break it now.
		if ( FBitSet ( pevAttacker->flags, FL_CLIENT ) &&
				 FBitSet ( pev->spawnflags, SF_BREAK_CROWBAR ) && (bitsDamageType & DMG_CLUB))
			flDamage = pev->health;
	}
	else
	// an actual missile was involved.
	{
		vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) );
	}
	
	if (!IsBreakable())
		return 0;

	// Breakables take double damage from the crowbar
	if ( bitsDamageType & DMG_CLUB )
		flDamage *= 2;

	// Boxes / glass / etc. don't take much poison damage, just the impact of the dart - consider that 10%
	if ( bitsDamageType & DMG_POISON )
		flDamage *= 0.1;

// this global is still used for glass and other non-monster killables, along with decals.
	g_vecAttackDir = vecTemp.Normalize();
		
// do the damage
	pev->health -= flDamage;
	if (pev->health <= 0)
	{
// LRC - Die() does everything necessary
//		if (!m_iRespawnTime)
//		{
//			Killed( pevAttacker, GIB_NORMAL );
//		}
		Die();
		return 0;
	}

	// Make a shard noise each time func breakable is hit.
	// Don't play shard noise if cbreakable actually died.

	DamageSound();

	return 1;
}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
// Purpose: Allows us to make damage exceptions that are breakable-specific.
//-----------------------------------------------------------------------------
int CBreakable::OnTakeDamage( const CTakeDamageInfo &info )
{
	Vector	vecTemp;

	CTakeDamageInfo subInfo = info;

	// If attacker can't do at least the min required damage to us, don't take any damage from them
	if ( m_takedamage == DAMAGE_NO || info.GetDamage() < m_iMinHealthDmg )
		return 0;

	// Check our damage filter
	if ( !PassesDamageFilter(subInfo) )
	{
		m_bTookPhysicsDamage = false;
		return 1;
	}

	vecTemp = subInfo.GetInflictor()->GetAbsOrigin() - WorldSpaceCenter();

	if (!IsBreakable())
		return 0;

	float flPropDamage = GetBreakableDamage( subInfo, assert_cast<IBreakableWithPropData*>(this) );
	subInfo.SetDamage( flPropDamage );
	
	int iPrevHealth = m_iHealth;
	BaseClass::OnTakeDamage( subInfo );

	// HACK: slam health back to what it was so UpdateHealth can do its thing
	int iNewHealth = m_iHealth;
	m_iHealth = iPrevHealth;
	if ( !UpdateHealth( iNewHealth, info.GetAttacker() ) )
		return 1;

	// Make a shard noise each time func breakable is hit, if it's capable of taking damage
	if ( m_takedamage == DAMAGE_YES )
	{
		// Don't play shard noise if being burned.
		// Don't play shard noise if cbreakable actually died.
		if ( ( subInfo.GetDamageType() & DMG_BURN ) == false )
		{
			DamageSound();
		}
	}

	return 1;
}
Ejemplo n.º 5
0
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 );

	}
}
Ejemplo n.º 6
0
void CBreakable::BreakTouch( CBaseEntity *pOther )
{
	float flDamage;
	entvars_t*	pevToucher = pOther->pev;
	
	// only players can break these right now
	if ( !pOther->IsPlayer() || !IsBreakable() )
	{
        return;
	}

	if ( FBitSet ( pev->spawnflags, SF_BREAK_TOUCH ) )
	{// can be broken when run into 
		flDamage = pevToucher->velocity.Length() * 0.01;

		if (flDamage >= pev->health)
		{
			SetTouch( NULL );
			TakeDamage(pevToucher, pevToucher, flDamage, DMG_CRUSH);

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

	if ( FBitSet ( pev->spawnflags, SF_BREAK_PRESSURE ) && pevToucher->absmin.z >= pev->maxs.z - 2 )
	{// can be broken when stood upon
		
		// play creaking sound here.
		DamageSound();

		SetThink ( &CBreakable::Die );
		SetTouch( NULL );
		
		if ( m_flDelay == 0 )
		{// !!!BUGBUG - why doesn't zero delay work?
			m_flDelay = 0.1;
		}

		pev->nextthink = pev->ltime + m_flDelay;

	}

}
//------------------------------------------------------------------------------
// Purpose : Break a panel
// Input   :
// Output  :
//------------------------------------------------------------------------------
bool CBreakableSurface::ShatterPane(int nWidth, int nHeight, const Vector &vForce, const Vector &vForcePos)
{
	// Check parameter range
	if (nWidth < 0  || nWidth  >= m_nNumWide) return false;
	if (nHeight < 0 || nHeight >= m_nNumHigh) return false;

	if ( IsBroken(nWidth,nHeight) )
		return false;

	BreakPane(nWidth,nHeight);

	QAngle vAngles;
	VectorAngles(-1*m_vNormal,vAngles);
	Vector vWidthDir,vHeightDir;
	AngleVectors(vAngles,NULL,&vWidthDir,&vHeightDir);
	Vector vBreakPos	= m_vCorner + 
						(nWidth*vWidthDir*m_flPanelWidth) + 
						(nHeight*vHeightDir*m_flPanelHeight);

	CreateShards(vBreakPos, vAngles,vForce,	vForcePos, m_flPanelWidth, m_flPanelHeight, WINDOW_SMALL_SHARD_SIZE);

	DamageSound();
	return true;
}
Ejemplo n.º 8
0
int CBreakable::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
{
	Vector vecTemp;

	// if Attacker == Inflictor, the attack was a melee or other instant-hit attack.
	// (that is, no actual entity projectile was involved in the attack so use the shooter's origin).
	if (pevAttacker == pevInflictor)
	{
		vecTemp = pevInflictor->origin - (pev->absmin + (pev->size * 0.5f));

		// if a client hit the breakable with a crowbar, and breakable is crowbar-sensitive, break it now.
		if ((pevAttacker->flags & FL_CLIENT) && (pev->spawnflags & SF_BREAK_CROWBAR) && (bitsDamageType & DMG_CLUB))
		{
			flDamage = pev->health;
		}
	}
	else
	{
		// an actual missile was involved.
		vecTemp = pevInflictor->origin - (pev->absmin + (pev->size * 0.5f));
	}

	if (!IsBreakable())
		return 0;

	// Breakables take double damage from the crowbar
	if (bitsDamageType & DMG_CLUB)
	{
		flDamage *= 2.0f;
	}

	// Boxes / glass / etc. don't take much poison damage, just the impact of the dart - consider that 10%
	if (bitsDamageType & DMG_POISON)
	{
		flDamage *= 0.1f;
	}

	// this global is still used for glass and other non-monster killables, along with decals.
	g_vecAttackDir = vecTemp.Normalize();

	// do the damage
	pev->health -= flDamage;

	if (pev->health <= 0)
	{
		pev->takedamage = DAMAGE_NO;
		pev->deadflag = DEAD_DEAD;
		pev->effects = EF_NODRAW;

		Die();

		if (m_flDelay == 0.0f)
		{
			m_flDelay = 0.1f;
		}

		pev->nextthink = pev->ltime + m_flDelay;
		return 0;
	}

	// Make a shard noise each time func breakable is hit.
	// Don't play shard noise if cbreakable actually died.
	DamageSound();
	return 1;
}