//------------------------------------------------------------------------------
// Purpose : Itterate through the panels and make sure none have become
//			 unstable
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBreakableSurface::BreakThink(void)
{
	// Don't calculate support if I'm tile
	if (m_nSurfaceType == SHATTERSURFACE_TILE)
	{
		return;
	}

	// -----------------------
	// Recalculate all support
	// -----------------------
	int w;
	float flSupport[MAX_NUM_PANELS][MAX_NUM_PANELS];
	for (w=0;w<m_nNumWide;w++)
	{
		for (int h=0;h<m_nNumHigh;h++)
		{
			if (!IsBroken(w,h))
			{
				flSupport[w][h] = RecalcSupport(w,h);
			}
		}
	}

	// ----------------------------------------------------
	//  Set support and break inadequately supported panes
	// ----------------------------------------------------
	float flBreakValue = WINDOW_BREAK_SUPPORT*(m_nFragility/100.0);
	for (w=0;w<m_nNumWide;w++)
	{
		for (int h=0;h<m_nNumHigh;h++)
		{
			if (!IsBroken(w,h))
			{
				SetSupport( w, h, flSupport[w][h]/WINDOW_MAX_SUPPORT );
				if (m_flSupport[w][h] < flBreakValue)
				{
					// Occasionaly drop a pane
					if (random->RandomInt(0,1))
					{
						DropPane(w,h);
					}
					// Otherwise just shatter the glass
					else
					{
						ShatterPane(w,h,vec3_origin,vec3_origin);
					}
					SetNextThink( gpGlobals->curtime );
				}
			}
		}
	}
}
//------------------------------------------------------------------------------
// Purpose : Drop a window pane entity
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CBreakableSurface::BreakPane(int nWidth, int nHeight)
{
	// Check parameter range
	if (nWidth < 0  || nWidth  >= m_nNumWide) return;
	if (nHeight < 0 || nHeight >= m_nNumHigh) return;

	// Count how many panes have been broken or dropped
	m_nNumBrokenPanes++;
	SetSupport( nWidth, nHeight, WINDOW_PANE_BROKEN );

	SetThink(&CBreakableSurface::BreakThink);
	SetNextThink( gpGlobals->curtime );
}
Пример #3
0
u_int64_t cs_accountflagmap(reguser *rup) {
  authname a2, *a = &a2;
  a->flags = 0;

  if(UIsOper(rup))
    SetOperFlag(a);

  if(UIsDev(rup))
    SetDeveloper(a);

  if(UIsAdmin(rup))
    SetAdmin(a);

  if(UIsStaff(rup))
    SetStaff(a);

  if(UIsHelper(rup))
    SetSupport(a);

  return a->flags;
}
//------------------------------------------------------------------------------
// Purpose: Break into panels
// Input  : pBreaker - 
//			vDir - 
//-----------------------------------------------------------------------------
void CBreakableSurface::Die( CBaseEntity *pBreaker, const Vector &vAttackDir )
{
	if ( m_bIsBroken )
		return;

	// Play a break sound
	PhysBreakSound( this, VPhysicsGetObject(), GetAbsOrigin() );

	m_bIsBroken = true;
	m_iHealth = 0.0f;

	if (pBreaker)
	{
		m_OnBreak.FireOutput( pBreaker, this );
	}
	else
	{
		m_OnBreak.FireOutput( this, this );
	}

	float flDir = -1;

	if ( vAttackDir.LengthSqr() > 0.001 )
	{
		float flDot = DotProduct( m_vNormal, vAttackDir );
		if (flDot < 0)
		{
			m_vLLVertex += m_vNormal;
			m_vLRVertex += m_vNormal;
			m_vULVertex += m_vNormal;
			m_vURVertex += m_vNormal;
			m_vNormal	*= -1;
			flDir		=   1;
		}
	}

	// -------------------------------------------------------
	// The surface has two sides, when we are killed pick 
	// the side that the damage came from 
	// -------------------------------------------------------
	Vector vWidth		= m_vLLVertex - m_vLRVertex;
	Vector vHeight		= m_vLLVertex - m_vULVertex;
	CrossProduct( vWidth, vHeight, m_vNormal.GetForModify() );
	VectorNormalize(m_vNormal.GetForModify());

	// ---------------------------------------------------
	//  Make sure width and height are oriented correctly
	// ---------------------------------------------------
	QAngle vAngles;
	VectorAngles(-1*m_vNormal,vAngles);
	Vector vWidthDir,vHeightDir;
	AngleVectors(vAngles,NULL,&vWidthDir,&vHeightDir);

	float flWDist = DotProduct(vWidthDir,vWidth);
	if (fabs(flWDist)<0.5)
	{
		Vector vSaveHeight	= vHeight;
		vHeight				= vWidth * flDir;
		vWidth				= vSaveHeight * flDir;
	}

	// -------------------------------------------------
	// Find which corner to use
	// -------------------------------------------------
	bool bLeft  = (DotProduct(vWidthDir,vWidth)   < 0);
	bool bLower = (DotProduct(vHeightDir,vHeight) < 0);
	if (bLeft)
	{
		m_vCorner = bLower ? m_vLLVertex : m_vULVertex;
	}
	else 
	{
		m_vCorner = bLower ? m_vLRVertex : m_vURVertex;
	}

	// -------------------------------------------------
	//  Calculate the number of panels
	// -------------------------------------------------
	float flWidth		= vWidth.Length();
	float flHeight		= vHeight.Length();
	m_nNumWide			= flWidth  / WINDOW_PANEL_SIZE;
	m_nNumHigh			= flHeight / WINDOW_PANEL_SIZE;

	// If to many panels make panel size bigger
	if (m_nNumWide > MAX_NUM_PANELS) m_nNumWide = MAX_NUM_PANELS;
	if (m_nNumHigh > MAX_NUM_PANELS) m_nNumHigh = MAX_NUM_PANELS;

	m_flPanelWidth	= flWidth  / m_nNumWide;
	m_flPanelHeight	= flHeight / m_nNumHigh;
	
	// Initialize panels
	for (int w=0;w<MAX_NUM_PANELS;w++)
	{ 
		for (int h=0;h<MAX_NUM_PANELS;h++)
		{
			SetSupport( w, h, WINDOW_PANE_HEALTHY );
		}
	}

	// Reset onground flags for any entity that may 
	// have been standing on me
	ResetOnGroundFlags();

	VPhysicsDestroyObject();
	AddSolidFlags( FSOLID_TRIGGER );
	AddSolidFlags( FSOLID_NOT_SOLID );
	SetTouch(&CBreakableSurface::SurfaceTouch);
}