//------------------------------------------------------------------------------ // 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 ); }
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); }