void CHLSL_Image::CreateScreenshot( CNodeView *n, const char *filepath ) { Vector4D graphBounds; n->GetGraphBoundaries( graphBounds ); int vsize_x, vsize_y; n->GetSize( vsize_x, vsize_y ); const float zoomFactor = 1.0f / clamp( sedit_screenshot_zoom.GetFloat(), 0.01f, 100.0f ); float nodespace_width = graphBounds.z - graphBounds.x; float nodespace_height = graphBounds.w - graphBounds.y; float nodespace_width_pershot = vsize_x * zoomFactor; float nodespace_height_pershot = vsize_y * zoomFactor; int numshots_x = ceil( nodespace_width / nodespace_width_pershot ); int numshots_y = ceil( nodespace_height / nodespace_height_pershot ); Vector2D extraSpace; extraSpace.x = (nodespace_width_pershot*numshots_x) - nodespace_width; extraSpace.y = (nodespace_height_pershot*numshots_y) - nodespace_height; extraSpace *= 0.5f; n->vecScreenshotBounds.Init( graphBounds.x - extraSpace.x, graphBounds.y - extraSpace.y, graphBounds.z + extraSpace.x, graphBounds.w + extraSpace.y ); int tgapixels_x = numshots_x * vsize_x - numshots_x; int tgapixels_y = numshots_y * vsize_y - numshots_y; unsigned int targetSize = tgapixels_x * 3 * tgapixels_y; unsigned char *pTGA = ( unsigned char * )malloc( targetSize ); if ( !pTGA ) { Warning( "Not enough memory available (failed to malloc %u bytes).\n", targetSize ); } Vector2D pos_old = n->AccessViewPos(); float zoom_old = n->AccessViewZoom(); n->bRenderingScreenShot = true; n->AccessViewZoom() = zoomFactor; int vp_x, vp_y; vp_x = vp_y = 0; n->LocalToScreen( vp_x, vp_y ); int screen_sx, screen_sy; engine->GetScreenSize( screen_sx, screen_sy ); vp_x++; vp_y++; vsize_x--; vsize_y--; n->AccessViewPos().Init(); CViewSetup view2D; view2D.x = 0; view2D.y = 0; view2D.width = screen_sx; view2D.height = screen_sy; view2D.m_bRenderToSubrectOfLargerScreen = false; Frustum _fplanes; CMatRenderContextPtr pRenderContext( materials ); #ifdef SHADER_EDITOR_DLL_2006 render->Push2DView( view2D, 0, false, NULL, _fplanes ); #else render->Push2DView( view2D, 0, NULL, _fplanes ); #endif pRenderContext->PushRenderTargetAndViewport( NULL, view2D.x, view2D.y, view2D.width, view2D.height ); // bool bSuccess = TGAWriter::WriteDummyFileNoAlloc( filepath, tgapixels_x, tgapixels_y, IMAGE_FORMAT_RGBA8888 ); // Assert( bSuccess ); if ( pTGA ) { for ( int sX = 0; sX < numshots_x; sX ++ ) { for ( int sY = 0; sY < numshots_y; sY ++ ) { Vector2D basepos( graphBounds.x + nodespace_width_pershot * 0.5f, graphBounds.w - nodespace_height_pershot * 0.5f ); basepos.x += sX * nodespace_width_pershot; basepos.y -= sY * nodespace_height_pershot; basepos.x *= -1.0f; basepos += extraSpace; n->AccessViewPos() = basepos; pRenderContext->ClearColor4ub( 0, 0, 0, 0 ); pRenderContext->ClearBuffers( true, true ); vgui::ipanel()->PaintTraverse( n->GetVPanel(), true ); unsigned int sizeimg = vsize_x * 3 * vsize_y; unsigned char *pImage = ( unsigned char * )malloc( sizeimg ); if ( pImage ) { pRenderContext->ReadPixels( vp_x, vp_y, vsize_x, vsize_y, pImage, IMAGE_FORMAT_RGB888 ); for ( int pX = 0; pX < vsize_x; pX ++ ) { for ( int pY = 0; pY < vsize_y; pY ++ ) { int targetpixel = (sX * vsize_x + pX) * 3 + ( sY * vsize_y + pY ) * tgapixels_x * 3; int srcpixel = pX * 3 + pY * vsize_x * 3; Q_memcpy( &pTGA[targetpixel], &pImage[srcpixel], 3 ); } } #if 0 #if DEBUG bool bSuccess = #endif TGAWriter::WriteRectNoAlloc( pImage, filepath, sX * vsize_x, sY * vsize_y, vsize_x, vsize_y, 0, IMAGE_FORMAT_RGB888 ); #if DEBUG Assert( bSuccess ); #endif #endif free( pImage ); } else Warning( "Tiling error (failed to malloc %u bytes).\n", sizeimg ); } } } if ( pTGA ) { //unsigned int iMaxTGASize = 1024 + (tgapixels_x * tgapixels_y * 3); //void *pTGA_BUFFER = malloc( iMaxTGASize ); //if ( pTGA_BUFFER ) //{ // CUtlBuffer buffer( pTGA_BUFFER, iMaxTGASize ); // TGAWriter::WriteToBuffer( pTGA, buffer, tgapixels_x, tgapixels_y, IMAGE_FORMAT_RGB888, IMAGE_FORMAT_RGB888 ); // filesystem->AsyncWrite( filepath, buffer.Base(), buffer.TellPut(), true ); //} //else //{ // Warning( "Not enough memory available (failed to malloc %u bytes).\n", iMaxTGASize ); //} jpeg_compress_struct jInfo; ValveJpegErrorHandler_t jErr; jpeg_destination_mgr jDest; jInfo.err = jpeg_std_error( &jErr.m_Base ); jInfo.err->error_exit = &ValveJpegErrorHandler; jpeg_create_compress( &jInfo ); jInfo.dest = &jDest; jInfo.dest->init_destination = &jInit_destination; jInfo.dest->empty_output_buffer = &jEmpty_output_buffer; jInfo.dest->term_destination = &jTerm_destination; jInfo.image_width = tgapixels_x; jInfo.image_height = tgapixels_y; jInfo.input_components = 3; jInfo.in_color_space = JCS_RGB; jpeg_set_defaults( &jInfo ); jpeg_set_quality( &jInfo, clamp( sedit_screenshot_quali.GetInt(), 1, 100 ), FALSE ); jpeg_start_compress(&jInfo, TRUE); JSAMPROW row_pointer[1]; int row_stride; row_stride = jInfo.image_width * 3; while (jInfo.next_scanline < jInfo.image_height) { row_pointer[0] = &pTGA[jInfo.next_scanline * row_stride]; jpeg_write_scanlines(&jInfo, row_pointer, 1); } jpeg_finish_compress(&jInfo); jpeg_destroy_compress(&jInfo); void *pBUFFER = malloc( jOut.Count() ); Q_memcpy( pBUFFER, jOut.Base(), jOut.Count() ); filesystem->AsyncWrite( filepath, pBUFFER, jOut.Count(), true ); jOut.Purge(); free( pTGA ); } pRenderContext->PopRenderTargetAndViewport(); render->PopView( _fplanes ); n->bRenderingScreenShot = false; n->AccessViewPos() = pos_old; n->AccessViewZoom() = zoom_old; }
void CBuildModeDialogMgr::Remove( BuildModeDialog *pDlg ) { m_vecBuildDialogs.FindAndRemove( pDlg ); }
//----------------------------------------------------------------------------- // Purpose: Creates the build mode editing controls //----------------------------------------------------------------------------- void BuildModeDialog::CreateControls() { int i; m_pPanelList = new PanelList; m_pPanelList->m_pResourceData = new KeyValues( "BuildDialog" ); m_pPanelList->m_pControls = new PanelListPanel(this, "BuildModeControls"); // file to edit combo box is first m_pFileSelectionCombo = new ComboBox(this, "FileSelectionCombo", 10, false); for ( i = 0; i < m_pBuildGroup->GetRegisteredControlSettingsFileCount(); i++) { m_pFileSelectionCombo->AddItem(m_pBuildGroup->GetRegisteredControlSettingsFileByIndex(i), NULL); } if (m_pFileSelectionCombo->GetItemCount() < 2) { m_pFileSelectionCombo->SetEnabled(false); } int buttonH = 18; // status info at top of dialog m_pStatusLabel = new Label(this, "StatusLabel", "[nothing currently selected]"); m_pStatusLabel->SetTextColorState(Label::CS_DULL); m_pStatusLabel->SetTall( buttonH ); m_pDivider = new Divider(this, "Divider"); // drop-down combo box for adding new controls m_pAddNewControlCombo = new ComboBox(this, NULL, 30, false); m_pAddNewControlCombo->SetSize(116, buttonH); m_pAddNewControlCombo->SetOpenDirection(Menu::DOWN); m_pEditableParents = new CBuildModeNavCombo( this, NULL, 15, false, true, m_pBuildGroup->GetContextPanel() ); m_pEditableParents->SetSize(116, buttonH); m_pEditableParents->SetOpenDirection(Menu::DOWN); m_pEditableChildren = new CBuildModeNavCombo( this, NULL, 15, false, false, m_pBuildGroup->GetContextPanel() ); m_pEditableChildren->SetSize(116, buttonH); m_pEditableChildren->SetOpenDirection(Menu::DOWN); m_pNextChild = new Button( this, "NextChild", "Next", this ); m_pNextChild->SetCommand( new KeyValues( "OnChangeChild", "direction", 1 ) ); m_pPrevChild = new Button( this, "PrevChild", "Prev", this ); m_pPrevChild->SetCommand( new KeyValues( "OnChangeChild", "direction", -1 ) ); // controls that can be added // this list comes from controls EditablePanel can create by name. int defaultItem = m_pAddNewControlCombo->AddItem("None", NULL); CUtlVector< char const * > names; CBuildFactoryHelper::GetFactoryNames( names ); // Sort the names CUtlRBTree< char const *, int > sorted( 0, 0, StringLessThan ); for ( i = 0; i < names.Count(); ++i ) { sorted.Insert( names[ i ] ); } for ( i = sorted.FirstInorder(); i != sorted.InvalidIndex(); i = sorted.NextInorder( i ) ) { m_pAddNewControlCombo->AddItem( sorted[ i ], NULL ); } m_pAddNewControlCombo->ActivateItem(defaultItem); m_pExitButton = new Button(this, "ExitButton", "&Exit"); m_pExitButton->SetSize(64, buttonH); m_pSaveButton = new Button(this, "SaveButton", "&Save"); m_pSaveButton->SetSize(64, buttonH); m_pApplyButton = new Button(this, "ApplyButton", "&Apply"); m_pApplyButton->SetSize(64, buttonH); m_pReloadLocalization = new Button( this, "Localization", "&Reload Localization" ); m_pReloadLocalization->SetSize( 100, buttonH ); m_pExitButton->SetCommand("Exit"); m_pSaveButton->SetCommand("Save"); m_pApplyButton->SetCommand("Apply"); m_pReloadLocalization->SetCommand( new KeyValues( "ReloadLocalization" ) ); m_pDeleteButton = new Button(this, "DeletePanelButton", "Delete"); m_pDeleteButton->SetSize(64, buttonH); m_pDeleteButton->SetCommand("DeletePanel"); m_pVarsButton = new MenuButton(this, "VarsButton", "Variables"); m_pVarsButton->SetSize(72, buttonH); m_pVarsButton->SetOpenDirection(Menu::UP); // iterate the vars KeyValues *vars = m_pBuildGroup->GetDialogVariables(); if (vars && vars->GetFirstSubKey()) { // create the menu m_pVarsButton->SetEnabled(true); Menu *menu = new Menu(m_pVarsButton, "VarsMenu"); // set all the variables to be copied to the clipboard when selected for (KeyValues *kv = vars->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey()) { char buf[32]; _snprintf(buf, sizeof(buf), "%%%s%%", kv->GetName()); menu->AddMenuItem(kv->GetName(), new KeyValues("SetClipboardText", "text", buf), this); } m_pVarsButton->SetMenu(menu); } else { // no variables m_pVarsButton->SetEnabled(false); } m_pApplyButton->SetTabPosition(1); m_pPanelList->m_pControls->SetTabPosition(2); m_pVarsButton->SetTabPosition(3); m_pDeleteButton->SetTabPosition(4); m_pAddNewControlCombo->SetTabPosition(5); m_pSaveButton->SetTabPosition(6); m_pExitButton->SetTabPosition(7); m_pEditableParents->SetTabPosition( 8 ); m_pEditableChildren->SetTabPosition( 9 ); m_pPrevChild->SetTabPosition( 10 ); m_pNextChild->SetTabPosition( 11 ); m_pReloadLocalization->SetTabPosition( 12 ); }
int CGlobalEntityList::ResetDeleteList( void ) { int result = g_DeleteList.Count(); g_DeleteList.RemoveAll(); return result; }
void EndGroupingSounds() { g_GroupedSounds.Purge(); SetImpactSoundRoute( NULL ); }
// Add a leaf to my list of interesting leaves void CPlaneList::ReferenceLeaf( int leafIndex ) { m_leafList.AddToTail( leafIndex ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CEnvMicrophone::~CEnvMicrophone( void ) { s_Microphones.FindAndRemove( this ); }
void FoundryHelpers_AddEntityHighlightEffect( int iEntity ) { EHANDLE hEnt = cl_entitylist->GetBaseEntity( iEntity ); if ( hEnt.IsValid() ) g_EntityHighlightEffects.AddToTail( hEnt ); }
// add the sample to the list. If we exceed the maximum number of samples, the worst sample will // be discarded. This has the effect of converging on the best samples when enough are added. void AddSampleToList( CUtlVector<ambientsample_t> &list, const Vector &samplePosition, Vector *pCube ) { const int MAX_SAMPLES = 16; int index = list.AddToTail(); list[index].pos = samplePosition; for ( int i = 0; i < 6; i++ ) { list[index].cube[i] = pCube[i]; } if ( list.Count() <= MAX_SAMPLES ) return; int nearestNeighborIndex = 0; float nearestNeighborDist = FLT_MAX; float nearestNeighborTotal = 0; for ( int i = 0; i < list.Count(); i++ ) { int closestIndex = 0; float closestDist = FLT_MAX; float totalDC = 0; for ( int j = 0; j < list.Count(); j++ ) { if ( j == i ) continue; float dist = (list[i].pos - list[j].pos).Length(); float maxDC = 0; for ( int k = 0; k < 6; k++ ) { // color delta is computed per-component, per cube side for (int s = 0; s < 3; s++ ) { float dc = fabs(list[i].cube[k][s] - list[j].cube[k][s]); maxDC = max(maxDC,dc); } totalDC += maxDC; } // need a measurable difference in color or we'll just rely on position if ( maxDC < 1e-4f ) { maxDC = 0; } else if ( maxDC > 1.0f ) { maxDC = 1.0f; } // selection criteria is 10% distance, 90% color difference // choose samples that fill the space (large distance from each other) // and have largest color variation float distanceFactor = 0.1f + (maxDC * 0.9f); dist *= distanceFactor; // find the "closest" sample to this one if ( dist < closestDist ) { closestDist = dist; closestIndex = j; } } // the sample with the "closest" neighbor is rejected if ( closestDist < nearestNeighborDist || (closestDist == nearestNeighborDist && totalDC < nearestNeighborTotal) ) { nearestNeighborDist = closestDist; nearestNeighborIndex = i; } } list.FastRemove( nearestNeighborIndex ); }
//----------------------------------------------------------------------------- // Purpose: Applies dialog data to the list of selected faces. // Input : *pOnlyFace - // bAll - //----------------------------------------------------------------------------- void CFaceEditMaterialPage::Apply( CMapFace *pOnlyFace, int flags ) { int i; CString str; float fshiftX = NOT_INIT; float fshiftY = NOT_INIT; float fscaleX = NOT_INIT; float fscaleY = NOT_INIT; float frotate = NOT_INIT; int material = NOT_INIT; int nLightmapScale = NOT_INIT; IEditorTexture *pTex = m_TexturePic.GetTexture(); // // Get numeric data. // if (flags & FACE_APPLY_MAPPING) { TransferToFloat( &m_shiftX, fshiftX ); TransferToFloat( &m_shiftY, fshiftY ); TransferToFloat( &m_scaleX, fscaleX ); TransferToFloat( &m_scaleY, fscaleY ); TransferToFloat( &m_rotate, frotate ); } if (flags & FACE_APPLY_LIGHTMAP_SCALE) { TransferToInteger( &m_cLightmapScale, nLightmapScale ); } if ( !pOnlyFace ) { GetHistory()->MarkUndoPosition( NULL, "Apply Face Attributes" ); // make sure we apply everything in this case. flags |= FACE_APPLY_ALL; // Keep the solids that we are about to change. // In the pOnlyFace case we do the Keep before calling ClickFace. Why? CUtlVector<CMapSolid *> kept; CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent(); for( i = 0; i < pSheet->GetFaceListCount(); i++ ) { CMapSolid *pSolid = pSheet->GetFaceListDataSolid( i ); if ( kept.Find( pSolid ) == -1 ) { GetHistory()->Keep( pSolid ); kept.AddToTail( pSolid ); } } } // // Run thru stored faces & apply. // CFaceEditSheet *pSheet = ( CFaceEditSheet* )GetParent(); int faceCount = pSheet->GetFaceListCount(); for( i = 0; i < faceCount || pOnlyFace; i++ ) { CMapFace *pFace; if( pOnlyFace ) { pFace = pOnlyFace; } else { pFace = pSheet->GetFaceListDataFace( i ); } // // Get values for texture shift, scale, rotate, and material. // if ((flags & FACE_APPLY_MAPPING) && (!(flags & FACE_APPLY_ALIGN_EDGE))) { if ( fshiftX != NOT_INIT ) { pFace->texture.UAxis[3] = fshiftX; } if ( fshiftY != NOT_INIT ) { pFace->texture.VAxis[3] = fshiftY; } if ( fscaleX != NOT_INIT ) { pFace->texture.scale[0] = fscaleX; } if ( fscaleY != NOT_INIT ) { pFace->texture.scale[1] = fscaleY; } if ( frotate != NOT_INIT ) { pFace->RotateTextureAxes( frotate - pFace->texture.rotate ); pFace->texture.rotate = frotate; } } if (flags & FACE_APPLY_CONTENTS_DATA) { if ( material != NOT_INIT ) { pFace->texture.material = material; } } if (flags & FACE_APPLY_LIGHTMAP_SCALE) { if (nLightmapScale != NOT_INIT) { pFace->texture.nLightmapScale = max( nLightmapScale, 1 ); } } // // Update the texture and recalculate texture coordinates. // if ((flags & FACE_APPLY_MATERIAL) && (pTex != NULL)) { char szCurrentTexName[MAX_PATH]; char szNewTexName[MAX_PATH]; pFace->GetTextureName( szCurrentTexName ); pTex->GetShortName( szNewTexName ); if( stricmp( szCurrentTexName, szNewTexName ) != 0 ) { pFace->SetTexture( szNewTexName ); } } // // Copy texture coordinate system. // if ((flags & FACE_APPLY_ALIGN_EDGE) && (faceCount >= 1)) { CopyTCoordSystem( pSheet->GetFaceListDataFace( faceCount - 1 ), pFace ); } // // Recalculate texture coordinates. // pFace->CalcTextureCoords(); // // Update the face flags. // if (flags & FACE_APPLY_CONTENTS_DATA) { // // Copy the bits from this face into our variables. // m_FaceContents = pFace->texture.q2contents; m_FaceSurface = pFace->texture.q2surface; // // Update our variables based on the state of the checkboxes. // for( int nItem = 0; nItem < sizeof( FaceAttributes ) / sizeof( FaceAttributes[0] ); nItem++ ) { CButton *pButton = ( CButton* )GetDlgItem( FaceAttributes[nItem].uControlID ); if( pButton != NULL ) { int nSet = pButton->GetCheck(); if (nSet == 0) { *FaceAttributes[nItem].puAttribute &= ~FaceAttributes[nItem].uFlag; } else if (nSet == 1) { *FaceAttributes[nItem].puAttribute |= FaceAttributes[nItem].uFlag; } } } // // Copy our variables back into this face. // pFace->texture.q2contents = m_FaceContents; pFace->texture.q2surface = m_FaceSurface; } if( pOnlyFace ) { break; } } CMapDoc::GetActiveMapDoc()->SetModifiedFlag(); }
void FoundryHelpers_ClearEntityHighlightEffects() { g_EntityHighlightEffects.Purge(); }
void CMoveHelperClient::ResetTouchList( void ) { m_TouchList.RemoveAll(); }
//----------------------------------------------------------------------------- // Purpose: Compute the overall color & alpha of the fades //----------------------------------------------------------------------------- void CViewEffects::FadeCalculate( void ) { // Cycle through all fades and remove any that have finished (work backwards) int i; int iSize = m_FadeList.Size(); for (i = iSize-1; i >= 0; i-- ) { screenfade_t *pFade = m_FadeList[i]; // Keep pushing reset time out indefinitely if ( pFade->Flags & FFADE_STAYOUT ) { pFade->Reset = gpGlobals->curtime + 0.1; } // All done? if ( ( gpGlobals->curtime > pFade->Reset ) && ( gpGlobals->curtime > pFade->End ) ) { // User passed in a callback function, call it now if ( s_pfnFadeDoneCallback ) { s_pfnFadeDoneCallback( s_nCallbackParameter ); s_pfnFadeDoneCallback = NULL; s_nCallbackParameter = 0; } // Remove this Fade from the list m_FadeList.FindAndRemove( pFade ); delete pFade; } } m_bModulate = false; m_FadeColorRGBA[0] = m_FadeColorRGBA[1] = m_FadeColorRGBA[2] = m_FadeColorRGBA[3] = 0; // Cycle through all fades in the list and calculate the overall color/alpha for ( i = 0; i < m_FadeList.Size(); i++ ) { screenfade_t *pFade = m_FadeList[i]; // Color m_FadeColorRGBA[0] += pFade->r; m_FadeColorRGBA[1] += pFade->g; m_FadeColorRGBA[2] += pFade->b; // Fading... int iFadeAlpha; if ( pFade->Flags & (FFADE_OUT|FFADE_IN) ) { iFadeAlpha = pFade->Speed * ( pFade->End - gpGlobals->curtime ); if ( pFade->Flags & FFADE_OUT ) { iFadeAlpha += pFade->alpha; } iFadeAlpha = MIN( iFadeAlpha, pFade->alpha ); iFadeAlpha = MAX( 0, iFadeAlpha ); } else { iFadeAlpha = pFade->alpha; } // Use highest alpha if ( iFadeAlpha > m_FadeColorRGBA[3] ) { m_FadeColorRGBA[3] = iFadeAlpha; } // Modulate? if ( pFade->Flags & FFADE_MODULATE ) { m_bModulate = true; } } // Divide colors if ( m_FadeList.Size() ) { m_FadeColorRGBA[0] /= m_FadeList.Size(); m_FadeColorRGBA[1] /= m_FadeList.Size(); m_FadeColorRGBA[2] /= m_FadeList.Size(); } }
//----------------------------------------------------------------------------- // Purpose: Apply noise to the eye position. // UNDONE: Feedback a bit of this into the view model position. It shakes too much //----------------------------------------------------------------------------- void CViewEffects::CalcShake( void ) { float fraction, freq; // We'll accumulate the aggregate shake for this frame into these data members. m_vecShakeAppliedOffset.Init(0, 0, 0); m_flShakeAppliedAngle = 0; float flRumbleAngle = 0; // NVNT - haptic shake effect amplitude float hapticShakeAmp = 0; bool bShow = shake_show.GetBool(); int nShakeCount = m_ShakeList.Count(); for ( int nShake = nShakeCount - 1; nShake >= 0; nShake-- ) { screenshake_t *pShake = m_ShakeList.Element( nShake ); if ( pShake->endtime == 0 ) { // Shouldn't be any such shakes in the list. Assert( false ); continue; } if ( ( gpGlobals->curtime > pShake->endtime ) || pShake->duration <= 0 || pShake->amplitude <= 0 || pShake->frequency <= 0 ) { // Retire this shake. delete m_ShakeList.Element( nShake ); m_ShakeList.FastRemove( nShake ); continue; } if ( bShow ) { con_nprint_t np; np.time_to_live = 2.0f; np.fixed_width_font = true; np.color[0] = 1.0; np.color[1] = 0.8; np.color[2] = 0.1; np.index = nShake + 2; engine->Con_NXPrintf( &np, "%02d: dur(%8.2f) amp(%8.2f) freq(%8.2f)", nShake + 1, (double)pShake->duration, (double)pShake->amplitude, (double)pShake->frequency ); } if ( gpGlobals->curtime > pShake->nextShake ) { // Higher frequency means we recalc the extents more often and perturb the display again pShake->nextShake = gpGlobals->curtime + (1.0f / pShake->frequency); // Compute random shake extents (the shake will settle down from this) for (int i = 0; i < 3; i++ ) { pShake->offset[i] = random->RandomFloat( -pShake->amplitude, pShake->amplitude ); } pShake->angle = random->RandomFloat( -pShake->amplitude*0.25, pShake->amplitude*0.25 ); } // Ramp down amplitude over duration (fraction goes from 1 to 0 linearly with slope 1/duration) fraction = ( pShake->endtime - gpGlobals->curtime ) / pShake->duration; // Ramp up frequency over duration if ( fraction ) { freq = (pShake->frequency / fraction); } else { freq = 0; } // square fraction to approach zero more quickly fraction *= fraction; // Sine wave that slowly settles to zero float angle = gpGlobals->curtime * freq; if ( angle > 1e8 ) { angle = 1e8; } fraction = fraction * sin( angle ); if( pShake->command != SHAKE_START_NORUMBLE ) { // As long as this isn't a NO RUMBLE effect, then accumulate rumble flRumbleAngle += pShake->angle * fraction; } if( pShake->command != SHAKE_START_RUMBLEONLY ) { // As long as this isn't a RUMBLE ONLY effect, then accumulate screen shake // Add to view origin m_vecShakeAppliedOffset += pShake->offset * fraction; // Add to roll m_flShakeAppliedAngle += pShake->angle * fraction; } // Drop amplitude a bit, less for higher frequency shakes pShake->amplitude -= pShake->amplitude * ( gpGlobals->frametime / (pShake->duration * pShake->frequency) ); // NVNT - update our amplitude. hapticShakeAmp += pShake->amplitude*fraction; } // NVNT - apply our screen shake update if ( haptics ) haptics->SetShake(hapticShakeAmp,1); // Feed this to the rumble system! UpdateScreenShakeRumble( flRumbleAngle ); }
// adds a collision entry for this brush model static void ConvertModelToPhysCollide( CUtlVector<CPhysCollisionEntry *> &collisionList, int modelIndex, int contents, float shrinkSize, float mergeTolerance ) { int i; CPlaneList planes( shrinkSize, mergeTolerance ); planes.m_contentsMask = contents; dmodel_t *pModel = dmodels + modelIndex; VisitLeaves_r( planes, pModel->headnode ); planes.AddBrushes(); int count = planes.m_convex.Count(); convertconvexparams_t params; params.Defaults(); params.buildOuterConvexHull = count > 1 ? true : false; params.buildDragAxisAreas = true; Vector size = pModel->maxs - pModel->mins; float minSurfaceArea = -1.0f; for ( i = 0; i < 3; i++ ) { int other = (i+1)%3; int cross = (i+2)%3; float surfaceArea = size[other] * size[cross]; if ( minSurfaceArea < 0 || surfaceArea < minSurfaceArea ) { minSurfaceArea = surfaceArea; } } // this can be really slow with super-large models and a low error tolerance // Basically you get a ray cast through each square of epsilon surface area on each OBB side // So compute it for 1% error (on the smallest side, less on larger sides) params.dragAreaEpsilon = clamp( minSurfaceArea * 1e-2f, 1.0f, 1024.0f ); CPhysCollide *pCollide = physcollision->ConvertConvexToCollideParams( planes.m_convex.Base(), count, params ); if ( !pCollide ) return; struct { int prop; float area; } proplist[256]; int numprops = 1; proplist[0].prop = -1; proplist[0].area = 1; // compute the array of props on the surface of this model // NODRAW brushes no longer have any faces if ( !dmodels[modelIndex].numfaces ) { int sideIndex = planes.GetFirstBrushSide(); int texdata = texinfo[dbrushsides[sideIndex].texinfo].texdata; int prop = g_SurfaceProperties[texdata]; proplist[numprops].prop = prop; proplist[numprops].area = 2; numprops++; } for ( i = 0; i < dmodels[modelIndex].numfaces; i++ ) { dface_t *face = dfaces + i + dmodels[modelIndex].firstface; int texdata = texinfo[face->texinfo].texdata; int prop = g_SurfaceProperties[texdata]; int j; for ( j = 0; j < numprops; j++ ) { if ( proplist[j].prop == prop ) { proplist[j].area += face->area; break; } } if ( (!numprops || j >= numprops) && numprops < ARRAYSIZE(proplist) ) { proplist[numprops].prop = prop; proplist[numprops].area = face->area; numprops++; } } // choose the prop with the most surface area int maxIndex = -1; float maxArea = 0; float totalArea = 0; for ( i = 0; i < numprops; i++ ) { if ( proplist[i].area > maxArea ) { maxIndex = i; maxArea = proplist[i].area; } // add up the total surface area totalArea += proplist[i].area; } float mass = 1.0f; const char *pMaterial = "default"; if ( maxIndex >= 0 ) { int prop = proplist[maxIndex].prop; // use default if this material has no prop if ( prop < 0 ) prop = 0; pMaterial = physprops->GetPropName( prop ); float density, thickness; physprops->GetPhysicsProperties( prop, &density, &thickness, NULL, NULL ); // if this is a "shell" material (it is hollow and encloses some empty space) // compute the mass with a constant surface thickness if ( thickness != 0 ) { mass = totalArea * thickness * density * CUBIC_METERS_PER_CUBIC_INCH; } else { // material is completely solid, compute total mass as if constant density throughout. mass = planes.m_totalVolume * density * CUBIC_METERS_PER_CUBIC_INCH; } } // Clamp mass to 100,000 kg if ( mass > VPHYSICS_MAX_MASS ) { mass = VPHYSICS_MAX_MASS; } collisionList.AddToTail( new CPhysCollisionEntrySolid( pCollide, pMaterial, mass ) ); }
void ComputePerLeafAmbientLighting() { // Figure out which lights should go in the per-leaf ambient cubes. int nInAmbientCube = 0; int nSurfaceLights = 0; for ( int i=0; i < *pNumworldlights; i++ ) { dworldlight_t *wl = &dworldlights[i]; if ( IsLeafAmbientSurfaceLight( wl ) ) wl->flags |= DWL_FLAGS_INAMBIENTCUBE; else wl->flags &= ~DWL_FLAGS_INAMBIENTCUBE; if ( wl->type == emit_surface ) ++nSurfaceLights; if ( wl->flags & DWL_FLAGS_INAMBIENTCUBE ) ++nInAmbientCube; } Msg( "%d of %d (%d%% of) surface lights went in leaf ambient cubes.\n", nInAmbientCube, nSurfaceLights, nSurfaceLights ? ((nInAmbientCube*100) / nSurfaceLights) : 0 ); g_LeafAmbientSamples.SetCount(numleafs); if ( g_bUseMPI ) { // Distribute the work among the workers. VMPI_SetCurrentStage( "ComputeLeafAmbientLighting" ); DistributeWork( numleafs, VMPI_DISTRIBUTEWORK_PACKETID, VMPI_ProcessLeafAmbient, VMPI_ReceiveLeafAmbientResults ); } else { RunThreadsOn(numleafs, true, ThreadComputeLeafAmbient); } // now write out the data Msg("Writing leaf ambient..."); g_pLeafAmbientIndex->RemoveAll(); g_pLeafAmbientLighting->RemoveAll(); g_pLeafAmbientIndex->SetCount( numleafs ); g_pLeafAmbientLighting->EnsureCapacity( numleafs*4 ); for ( int leafID = 0; leafID < numleafs; leafID++ ) { const CUtlVector<ambientsample_t> &list = g_LeafAmbientSamples[leafID]; g_pLeafAmbientIndex->Element(leafID).ambientSampleCount = list.Count(); if ( !list.Count() ) { g_pLeafAmbientIndex->Element(leafID).firstAmbientSample = 0; } else { g_pLeafAmbientIndex->Element(leafID).firstAmbientSample = g_pLeafAmbientLighting->Count(); // compute the samples in disk format. Encode the positions in 8-bits using leaf bounds fractions for ( int i = 0; i < list.Count(); i++ ) { int outIndex = g_pLeafAmbientLighting->AddToTail(); dleafambientlighting_t &light = g_pLeafAmbientLighting->Element(outIndex); light.x = Fixed8Fraction( list[i].pos.x, dleafs[leafID].mins[0], dleafs[leafID].maxs[0] ); light.y = Fixed8Fraction( list[i].pos.y, dleafs[leafID].mins[1], dleafs[leafID].maxs[1] ); light.z = Fixed8Fraction( list[i].pos.z, dleafs[leafID].mins[2], dleafs[leafID].maxs[2] ); light.pad = 0; for ( int side = 0; side < 6; side++ ) { VectorToColorRGBExp32( list[i].cube[side], light.cube.m_Color[side] ); } } } } for ( int i = 0; i < numleafs; i++ ) { // UNDONE: Do this dynamically in the engine instead. This will allow us to sample across leaf // boundaries always which should improve the quality of lighting in general if ( g_pLeafAmbientIndex->Element(i).ambientSampleCount == 0 ) { if ( !(dleafs[i].contents & CONTENTS_SOLID) ) { Msg("Bad leaf ambient for leaf %d\n", i ); } int refLeaf = NearestNeighborWithLight(i); g_pLeafAmbientIndex->Element(i).ambientSampleCount = 0; g_pLeafAmbientIndex->Element(i).firstAmbientSample = refLeaf; } } Msg("done\n"); }
// This is the only public entry to this file. // The global data touched in the file is: // from bsplib.h: // g_pPhysCollide : This is an output from this file. // g_PhysCollideSize : This is set in this file. // g_numdispinfo : This is an input to this file. // g_dispinfo : This is an input to this file. // numnodewaterdata : This is an output from this file. // dleafwaterdata : This is an output from this file. // from vbsp.h: // g_SurfaceProperties : This is an input to this file. void EmitPhysCollision() { ClearLeafWaterData(); CreateInterfaceFn physicsFactory = GetPhysicsFactory(); if ( physicsFactory ) { physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL ); } if ( !physcollision ) { Warning("!!! WARNING: Can't build collision data!\n" ); return; } CUtlVector<CPhysCollisionEntry *> collisionList[MAX_MAP_MODELS]; CTextBuffer *pTextBuffer[MAX_MAP_MODELS]; int physModelCount = 0, totalSize = 0; int start = Plat_FloatTime(); Msg("Building Physics collision data...\n" ); int i, j; for ( i = 0; i < nummodels; i++ ) { // Build a list of collision models for this brush model section if ( i == 0 ) { // world is the only model that processes water separately. // other brushes are assumed to be completely solid or completely liquid BuildWorldPhysModel( collisionList[i], NO_SHRINK, VPHYSICS_MERGE); } else { ConvertModelToPhysCollide( collisionList[i], i, MASK_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|MASK_WATER, VPHYSICS_SHRINK, VPHYSICS_MERGE ); } pTextBuffer[i] = NULL; if ( !collisionList[i].Count() ) continue; // if we've got collision models, write their script for processing in the game pTextBuffer[i] = new CTextBuffer; for ( j = 0; j < collisionList[i].Count(); j++ ) { // dump a text file for visualization if ( dumpcollide ) { collisionList[i][j]->DumpCollide( pTextBuffer[i], i, j ); } // each model knows how to write its script collisionList[i][j]->WriteToTextBuffer( pTextBuffer[i], i, j ); // total up the binary section's size totalSize += collisionList[i][j]->GetCollisionBinarySize() + sizeof(int); } // These sections only appear in the world's collision text if ( i == 0 ) { if ( !g_bNoVirtualMesh && physcollision->SupportsVirtualMesh() ) { pTextBuffer[i]->WriteText("virtualterrain {}\n"); } if ( s_WorldPropList.Count() ) { pTextBuffer[i]->WriteText( "materialtable {\n" ); for ( j = 0; j < s_WorldPropList.Count(); j++ ) { int propIndex = s_WorldPropList[j]; if ( propIndex < 0 ) { pTextBuffer[i]->WriteIntKey( "default", j+1 ); } else { pTextBuffer[i]->WriteIntKey( physprops->GetPropName( propIndex ), j+1 ); } } pTextBuffer[i]->WriteText( "}\n" ); } } pTextBuffer[i]->Terminate(); // total lump size includes the text buffers (scripts) totalSize += pTextBuffer[i]->GetSize(); physModelCount++; } // add one for tail of list marker physModelCount++; // DWORD align the lump because AddLump assumes that it is DWORD aligned. byte *ptr ; g_PhysCollideSize = totalSize + (physModelCount * sizeof(dphysmodel_t)); g_pPhysCollide = (byte *)malloc(( g_PhysCollideSize + 3 ) & ~3 ); memset( g_pPhysCollide, 0, g_PhysCollideSize ); ptr = g_pPhysCollide; for ( i = 0; i < nummodels; i++ ) { if ( pTextBuffer[i] ) { int j; dphysmodel_t model; model.modelIndex = i; model.solidCount = collisionList[i].Count(); model.dataSize = sizeof(int) * model.solidCount; for ( j = 0; j < model.solidCount; j++ ) { model.dataSize += collisionList[i][j]->GetCollisionBinarySize(); } model.keydataSize = pTextBuffer[i]->GetSize(); // store the header memcpy( ptr, &model, sizeof(model) ); ptr += sizeof(model); for ( j = 0; j < model.solidCount; j++ ) { int collideSize = collisionList[i][j]->GetCollisionBinarySize(); // write size memcpy( ptr, &collideSize, sizeof(int) ); ptr += sizeof(int); // now write the collision model collisionList[i][j]->WriteCollisionBinary( reinterpret_cast<char *>(ptr) ); ptr += collideSize; } memcpy( ptr, pTextBuffer[i]->GetData(), pTextBuffer[i]->GetSize() ); ptr += pTextBuffer[i]->GetSize(); } delete pTextBuffer[i]; } dphysmodel_t model; // Mark end of list model.modelIndex = -1; model.dataSize = -1; model.keydataSize = 0; model.solidCount = 0; memcpy( ptr, &model, sizeof(model) ); ptr += sizeof(model); Assert( (ptr-g_pPhysCollide) == g_PhysCollideSize); Msg("done (%d) (%d bytes)\n", (int)(Plat_FloatTime() - start), g_PhysCollideSize ); // UNDONE: Collision models (collisionList) memory leak! }
void PhonemeEditor::CloseCaption_MergeSelected( void ) { CountSelected(); if ( m_nSelectedPhraseCount < 2 ) { Con_Printf( "CloseCaption_MergeSelected: requires 2 or more selected phrases\n" ); return; } if ( !CloseCaption_AreSelectedPhrasesContiguous() ) { Con_Printf( "CloseCaption_MergeSelected: selected phrases must be contiguous\n" ); return; } SetDirty( true ); PushUndo(); CUtlVector< CCloseCaptionPhrase * > selected; float beststart = 100000.0f; float bestend = -100000.0f; int c = m_Tags.GetCloseCaptionPhraseCount( CC_ENGLISH ); int i; int insertslot = c -1; // Walk backwards and remove for ( i = c - 1; i >= 0; i-- ) { CCloseCaptionPhrase *phrase = m_Tags.GetCloseCaptionPhrase( CC_ENGLISH, i ); if ( !phrase || !phrase->GetSelected() ) continue; if ( phrase->GetStartTime() < beststart ) { beststart = phrase->GetStartTime(); } if ( phrase->GetEndTime() > bestend ) { bestend = phrase->GetEndTime(); } selected.AddToHead( new CCloseCaptionPhrase( *phrase ) ); // Remember the earliest slot if ( i < insertslot ) { insertslot = i; } m_Tags.RemoveCloseCaptionPhrase( CC_ENGLISH, i ); } if ( selected.Count() <= 0 ) return; CCloseCaptionPhrase *newphrase = new CCloseCaptionPhrase( selected[ 0 ]->GetStream() ); Assert( newphrase ); wchar_t sz[ 4096 ]; delete selected[ 0 ]; for ( i = 1; i < selected.Count(); i++ ) { _snwprintf( sz, sizeof( sz ), newphrase->GetStream() ); // Phrases don't have leading/trailing spaces so it should be safe to just append a space here wcscat( sz, L" " ); wcscat( sz, selected[ i ]->GetStream() ); newphrase->SetStream( sz ); delete selected[ i ]; } selected.RemoveAll(); m_Tags.InsertCloseCaptionPhraseAtIndex( CC_ENGLISH, newphrase, insertslot ); newphrase->SetSelected( true ); newphrase->SetStartTime( beststart ); newphrase->SetEndTime( bestend ); PushRedo(); redraw(); }
//----------------------------------------------------------------------------- // Purpose: Hook for the sound system to tell us when a sound's been played //----------------------------------------------------------------------------- MicrophoneResult_t CEnvMicrophone::SoundPlayed( int entindex, const char *soundname, soundlevel_t soundlevel, float flVolume, int iFlags, int iPitch, const Vector *pOrigin, float soundtime, CUtlVector< Vector >& soundorigins ) { if ( m_bAvoidFeedback ) return MicrophoneResult_Ok; // Don't hear sounds that have already been heard by a microphone to avoid feedback! if ( iFlags & SND_SPEAKER ) return MicrophoneResult_Ok; #ifdef DEBUG_MICROPHONE Msg("%s heard %s: ", STRING(GetEntityName()), soundname ); #endif if ( !CanHearSound( entindex, soundlevel, flVolume, pOrigin ) ) return MicrophoneResult_Ok; // We've heard it. Play it out our speaker. If our speaker's gone away, we're done. if ( !m_hSpeaker ) { // First time, find our speaker. Done here, because finding it in Activate() wouldn't // find players, and we need to be able to specify !player for a speaker. if ( m_iszSpeakerName != NULL_STRING ) { m_hSpeaker = gEntList.FindEntityByName(NULL, STRING(m_iszSpeakerName) ); if ( !m_hSpeaker ) { Warning( "EnvMicrophone %s specifies a non-existent speaker name: %s\n", STRING(GetEntityName()), STRING(m_iszSpeakerName) ); m_iszSpeakerName = NULL_STRING; } } if ( !m_hSpeaker ) { return MicrophoneResult_Remove; } } m_bAvoidFeedback = true; // Add the speaker flag. Detected at playback and applies the speaker filter. iFlags |= SND_SPEAKER; CPASAttenuationFilter filter( m_hSpeaker ); EmitSound_t ep; ep.m_nChannel = CHAN_STATIC; ep.m_pSoundName = soundname; ep.m_flVolume = flVolume; ep.m_SoundLevel = soundlevel; ep.m_nFlags = iFlags; ep.m_nPitch = iPitch; ep.m_pOrigin = &m_hSpeaker->GetAbsOrigin(); ep.m_flSoundTime = soundtime; ep.m_nSpeakerEntity = entindex; CBaseEntity::EmitSound( filter, m_hSpeaker->entindex(), ep ); Q_strncpy( m_szLastSound, soundname, sizeof(m_szLastSound) ); m_OnRoutedSound.FireOutput( this, this, 0 ); m_bAvoidFeedback = false; // Copy emitted origin to soundorigins array for ( int i = 0; i < ep.m_UtlVecSoundOrigin.Count(); ++i ) { soundorigins.AddToTail( ep.m_UtlVecSoundOrigin[ i ] ); } // Do we want to allow the original sound to play? if ( m_spawnflags & SF_MICROPHONE_SWALLOW_ROUTED_SOUNDS ) { return MicrophoneResult_Swallow; } return MicrophoneResult_Ok; }
int CVGuiScreenEnumerator::GetScreenCount() { return m_VguiScreens.Count(); }
void CNotifyList::LevelShutdownPreEntity( void ) { gEntList.RemoveListenerEntity( this ); m_notifyList.Purge(); }
void CASWMissionChooserNPCs::PushEncountersApart( CMapLayout *pLayout ) { // get a list of valid rooms int iRooms = pLayout->m_PlacedRooms.Count(); CUtlVector<CRoom*> candidates; float flTotalWeight = 0; for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; if ( pRoom->GetSpawnWeight() > 0 && !pRoom->m_pRoomTemplate->IsEscapeRoom() && !pRoom->m_pRoomTemplate->IsStartRoom() && !pRoom->m_pRoomTemplate->IsBorderRoom() ) { // skip 1x1 rooms if ( pRoom->m_pRoomTemplate->GetTilesX() * pRoom->m_pRoomTemplate->GetTilesY() <= 1 ) continue; flTotalWeight += pRoom->GetSpawnWeight(); candidates.AddToTail( pRoom ); } } // push the encounters apart int iSteps = 6; for ( int i = 0; i < iSteps; i++ ) { int iEncounters = pLayout->m_Encounters.Count(); for ( int e = 0; e < iEncounters; e++ ) { Vector vecPush = vec3_origin; CASW_Encounter *pEncounter = pLayout->m_Encounters[ e ]; // accumulate a force from all other nearby encounters for ( int k = 0; k < iEncounters; k++ ) { if ( e == k ) continue; CASW_Encounter *pOther = pLayout->m_Encounters[ k ]; Vector dir = pEncounter->GetEncounterPosition() - pOther->GetEncounterPosition(); // direction from other to us float dist = dir.NormalizeInPlace(); float flMinDistance = asw_encounters_distance_min.GetFloat() + pEncounter->GetEncounterRadius() + pOther->GetEncounterRadius(); if ( dist < flMinDistance ) { float flPush = flMinDistance - dist; // push us exactly out of the min vecPush += dir * flPush; } } pEncounter->SetEncounterPosition( pEncounter->GetEncounterPosition() + vecPush ); // clamp encounters to room bounds CRoom *pClosestRoom = NULL; float flClosestDist = 65535.0f; bool bWithinARoom = false; Vector pos = pEncounter->GetEncounterPosition(); for ( int k = 0; k < candidates.Count(); k++ ) { CRoom *pRoom = candidates[k]; Vector vecMins, vecMaxs; pRoom->GetWorldBounds( &vecMins, &vecMaxs ); if ( pos.x >= vecMins.x && pos.x <= vecMaxs.x && pos.y >= vecMins.y && pos.y <= vecMaxs.y ) { bWithinARoom = true; break; } Vector vecMiddle = ( vecMins + vecMaxs ) * 0.5f; float flDist = vecMiddle.DistTo( pos ); if ( flDist < flClosestDist ) { flClosestDist = flDist; pClosestRoom = pRoom; } } // if encounter wasn't in any room, then clamp to the closest if ( !bWithinARoom && pClosestRoom ) { Vector vecMins, vecMaxs; pClosestRoom->GetWorldBounds( &vecMins, &vecMaxs ); pos.x = clamp( pos.x, vecMins.x, vecMaxs.x ); pos.y = clamp( pos.y, vecMins.y, vecMaxs.y ); pEncounter->SetEncounterPosition( pos ); } /* // put encounter in the center of its room for ( int k = 0; k < candidates.Count(); k++ ) { CRoom *pRoom = candidates[k]; Vector vecMins, vecMaxs; pRoom->GetWorldBounds( &vecMins, &vecMaxs ); if ( pos.x >= vecMins.x && pos.x <= vecMaxs.x && pos.y >= vecMins.y && pos.y <= vecMaxs.y ) { Vector mid = ( vecMins + vecMaxs ) * 0.5f; mid.z = 0; pEncounter->SetEncounterPosition ( mid ); break; } } */ } } }
void StartGroupingSounds() { Assert( g_GroupedSounds.Count() == 0 ); SetImpactSoundRoute( ShotgunImpactSoundGroup ); }
void CASWMissionChooserNPCs::InitFixedSpawns( CLayoutSystem *pLayoutSystem, CMapLayout *pLayout ) { // init the spawn set for this mission KeyValues *pGenerationOptions = pLayout->GetGenerationOptions(); if ( !pGenerationOptions ) { Warning( "Error placed fixed alien spawns, no generation options in this layout." ); return; } bool bChosenSpawnSet = false; const char *szNamedSpawnSet = pGenerationOptions->GetString( "AlienSpawnSet" ); if ( szNamedSpawnSet && szNamedSpawnSet[0] ) { bChosenSpawnSet = SpawnSelection()->SetCurrentSpawnSet( szNamedSpawnSet ); } if ( !bChosenSpawnSet ) { SpawnSelection()->SetCurrentSpawnSet( pGenerationOptions->GetInt( "Difficulty", 5 ) ); } // if we have any rooms with the alien encounter tag, then just use those for fixed spawn locations bool bAlienEncounterTag = false; int iRooms = pLayout->m_PlacedRooms.Count(); for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; if ( pRoom && pRoom->m_pRoomTemplate && pRoom->m_pRoomTemplate->HasTag( "AlienEncounter" ) ) { bAlienEncounterTag = true; CASW_Encounter *pEncounter = new CASW_Encounter(); // pick a random spot in this room Vector vecWorldMins, vecWorldMaxs; pRoom->GetWorldBounds( &vecWorldMins, &vecWorldMaxs ); Vector vecPos = vecWorldMins + pLayoutSystem->GetRandomFloat( 0, 1 ) * ( vecWorldMaxs - vecWorldMins ); vecPos.z = 0; pEncounter->SetEncounterPosition( vecPos ); pEncounter->SetEncounterRadius( pLayoutSystem->GetRandomFloat( asw_encounter_radius_min.GetFloat(), asw_encounter_radius_max.GetFloat() ) ); // add spawn defs // TODO: more spawns in bigger rooms? or rooms with higher weights? int iSpawnsPerEncounter = pLayoutSystem->GetRandomInt( CurrentSpawnSet()->GetMinSpawnsPerEncounter(), CurrentSpawnSet()->GetMaxSpawnsPerEncounter() ); for ( int i = 0; i < iSpawnsPerEncounter; i++ ) { CASW_Spawn_Definition* pSpawnDef = CurrentSpawnSet()->GetSpawnDef( ASW_NPC_SPAWN_TYPE_FIXED ); if ( !pSpawnDef ) continue; pEncounter->AddSpawnDef( pSpawnDef ); } pLayout->m_Encounters.AddToTail( pEncounter ); } } if ( bAlienEncounterTag ) { pLayout->MarkEncounterRooms(); return; } // find area of the mission int iTotalArea = 0; for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; iTotalArea += ( pRoom->m_pRoomTemplate->GetTilesX() * ASW_TILE_SIZE ) * ( pRoom->m_pRoomTemplate->GetTilesY() * ASW_TILE_SIZE ); } // decide how many encounters we want int iEncounters = pLayoutSystem->GetRandomInt( CurrentSpawnSet()->GetMinEncounters(), CurrentSpawnSet()->GetMaxEncounters() ); // distance between encounters //float flMinDistance = asw_encounters_distance_min.GetFloat(); // randomly pick rooms for the encounters to be in, using the room weights CUtlVector<CRoom*> candidates; float flTotalWeight = 0; for ( int i = 0; i < iRooms; i++ ) { CRoom *pRoom = pLayout->m_PlacedRooms[i]; if ( pRoom->GetSpawnWeight() > 0 && !pRoom->m_pRoomTemplate->IsEscapeRoom() && !pRoom->m_pRoomTemplate->IsStartRoom() && !pRoom->m_pRoomTemplate->IsBorderRoom() ) { flTotalWeight += pRoom->GetSpawnWeight(); candidates.AddToTail( pRoom ); } } for ( int e = 0; e < iEncounters; e++ ) { float flChosen = pLayoutSystem->GetRandomFloat( 0, flTotalWeight ); CRoom *pChosenRoom = NULL; for ( int i = 0; i < candidates.Count(); i++ ) { CRoom *pRoom = candidates[i]; flChosen -= pRoom->GetSpawnWeight(); if ( flChosen <= 0 ) { pChosenRoom = pRoom; break; } } if ( !pChosenRoom ) continue; CASW_Encounter *pEncounter = new CASW_Encounter(); // pick a random spot in this room Vector vecWorldMins, vecWorldMaxs; pChosenRoom->GetWorldBounds( &vecWorldMins, &vecWorldMaxs ); //Vector vecPos = vecWorldMins + pLayoutSystem->GetRandomFloat( 0, 1 ) * ( vecWorldMaxs - vecWorldMins ); Vector vecPos = ( vecWorldMins + vecWorldMaxs ) * 0.5f; // center of the room vecPos.z = 0; pEncounter->SetEncounterPosition( vecPos ); pEncounter->SetEncounterRadius( pLayoutSystem->GetRandomFloat( asw_encounter_radius_min.GetFloat(), asw_encounter_radius_max.GetFloat() ) ); // add spawn defs // TODO: more spawns in bigger rooms? or rooms with higher weights? int iSpawnsPerEncounter = pLayoutSystem->GetRandomInt( CurrentSpawnSet()->GetMinSpawnsPerEncounter(), CurrentSpawnSet()->GetMaxSpawnsPerEncounter() ); for ( int i = 0; i < iSpawnsPerEncounter; i++ ) { CASW_Spawn_Definition* pSpawnDef = CurrentSpawnSet()->GetSpawnDef( ASW_NPC_SPAWN_TYPE_FIXED ); if ( !pSpawnDef ) continue; pEncounter->AddSpawnDef( pSpawnDef ); } pLayout->m_Encounters.AddToTail( pEncounter ); } PushEncountersApart( pLayout ); pLayout->MarkEncounterRooms(); }
void CMoveHelperServer::ResetTouchList( void ) { m_TouchList.RemoveAll(); }
// Creates a list of watermodel_t for later processing by EmitPhysCollision void EmitWaterVolumesForBSP( dmodel_t *pModel, node_t *node ) { CUtlVector<node_t *> leafListAnyWater; // build the list of all leaves containing water EnumLeaves_r( leafListAnyWater, node, MASK_WATER ); // make a sorted list to flood fill CUtlVector<waterleaf_t> list; int i; for ( i = 0; i < leafListAnyWater.Count(); i++ ) { waterleaf_t waterLeaf; BuildWaterLeaf( leafListAnyWater[i], waterLeaf ); InsertSortWaterLeaf( list, waterLeaf ); } leafbitarray_t visited; CUtlVector<node_t *> waterAreaList; for ( i = 0; i < list.Count(); i++ ) { Flood_FindConnectedWaterVolumes_r( waterAreaList, list[i].pNode, list[i], visited ); // did we find a list of leaves connected to this one? // remember the list is sorted, so this one may have been attached to a previous // leaf. So it could have nothing hanging off of it. if ( waterAreaList.Count() ) { // yes, emit a watermodel watermodel_t tmp; tmp.modelIndex = nummodels; tmp.contents = list[i].pNode->contents; tmp.waterLeafData = list[i]; tmp.firstWaterLeafIndex = g_WaterLeafList.Count(); tmp.waterLeafCount = waterAreaList.Count(); float waterDepth = tmp.waterLeafData.surfaceDist - tmp.waterLeafData.minZ; if ( tmp.waterLeafData.surfaceTexInfo < 0 ) { // the map has probably leaked in this case, but output something anyway. Assert(list[i].pNode->planenum == PLANENUM_LEAF); tmp.waterLeafData.surfaceTexInfo = FirstWaterTexinfo( list[i].pNode->brushlist, tmp.contents ); } tmp.depthTexinfo = FindOrCreateWaterTexInfo( &texinfo[ tmp.waterLeafData.surfaceTexInfo ], waterDepth ); tmp.fogVolumeIndex = FindOrCreateLeafWaterData( tmp.waterLeafData.surfaceDist, tmp.waterLeafData.minZ, tmp.waterLeafData.surfaceTexInfo ); for ( int j = 0; j < waterAreaList.Count(); j++ ) { g_WaterLeafList.AddToTail( waterAreaList[j]->diskId ); } waterAreaList.RemoveAll(); g_WaterModels.AddToTail( tmp ); } } WriteFogVolumeIDs( pModel ); }
int CBuildModeDialogMgr::Count() const { return m_vecBuildDialogs.Count(); }
static void ConvertWaterModelToPhysCollide( CUtlVector<CPhysCollisionEntry *> &collisionList, int modelIndex, float shrinkSize, float mergeTolerance ) { dmodel_t *pModel = dmodels + modelIndex; for ( int i = 0; i < g_WaterModels.Count(); i++ ) { watermodel_t &waterModel = g_WaterModels[i]; if ( waterModel.modelIndex != modelIndex ) continue; CPlaneList planes( shrinkSize, mergeTolerance ); int firstLeaf = waterModel.firstWaterLeafIndex; planes.m_contentsMask = waterModel.contents; // push all of the leaves into the collision list for ( int j = 0; j < waterModel.waterLeafCount; j++ ) { int leafIndex = g_WaterLeafList[firstLeaf + j]; dleaf_t *pLeaf = dleafs + leafIndex; // fixup waterdata pLeaf->leafWaterDataID = waterModel.fogVolumeIndex; planes.ReferenceLeaf( leafIndex ); } // visit the referenced leaves that belong to this model VisitLeaves_r( planes, pModel->headnode ); // Now add the brushes from those leaves as convex // BUGBUG: NOTE: If your map has a brush that crosses the surface, it will be added to two water // volumes. This only happens with connected water volumes with multiple surface heights // UNDONE: Right now map makers must cut such brushes. It could be automatically cut by adding the // surface plane to the list for each brush before calling ConvexFromPlanes() planes.AddBrushes(); int count = planes.m_convex.Count(); if ( !count ) continue; // Save off the plane of the surface for this group as well as the collision model // for all convex objects in the group. CPhysCollide *pCollide = physcollision->ConvertConvexToCollide( planes.m_convex.Base(), count ); if ( pCollide ) { int waterSurfaceTexInfoID = -1; // use defaults const char *pSurfaceProp = "water"; float damping = 0.01; if ( waterSurfaceTexInfoID >= 0 ) { // material override int texdata = texinfo[waterSurfaceTexInfoID].texdata; int prop = g_SurfaceProperties[texdata]; pSurfaceProp = physprops->GetPropName( prop ); } if ( !waterModel.waterLeafData.hasSurface ) { waterModel.waterLeafData.surfaceNormal.Init( 0,0,1 ); Vector top = physcollision->CollideGetExtent( pCollide, vec3_origin, vec3_angle, waterModel.waterLeafData.surfaceNormal ); waterModel.waterLeafData.surfaceDist = top.z; } CPhysCollisionEntryFluid *pCollisionEntryFuild = new CPhysCollisionEntryFluid( pCollide, pSurfaceProp, damping, waterModel.waterLeafData.surfaceNormal, waterModel.waterLeafData.surfaceDist, waterModel.contents ); collisionList.AddToTail( pCollisionEntryFuild ); } } }
int main(int argc, char* argv[]) { SpewOutputFunc( MySpewFunc ); // Figure out a random port to use. CCycleCount cnt; cnt.Sample(); CUniformRandomStream randomStream; randomStream.SetSeed( cnt.GetMicroseconds() ); int iPort = randomStream.RandomInt( 20000, 30000 ); g_ClientPacketEvent.Init( false, false ); // Setup the "server". CHandlerCreator_Server serverHandler; CIPAddr addr( 127, 0, 0, 1, iPort ); ITCPConnectSocket *pListener = ThreadedTCP_CreateListener( &serverHandler, (unsigned short)iPort ); // Setup the "client". CHandlerCreator_Client clientCreator; ITCPConnectSocket *pConnector = ThreadedTCP_CreateConnector( CIPAddr( 127, 0, 0, 1, iPort ), CIPAddr(), &clientCreator ); // Wait for them to connect. while ( !g_pClientSocket ) { if ( !pConnector->Update( &g_pClientSocket ) ) { Error( "Error in client connector!\n" ); } } pConnector->Release(); while ( !g_pServerSocket ) { if ( !pListener->Update( &g_pServerSocket ) ) Error( "Error in server connector!\n" ); } pListener->Release(); // Send some data. __int64 totalBytes = 0; CCycleCount startTime; int iPacket = 1; startTime.Sample(); CUtlVector<char> buf; while ( (GetAsyncKeyState( VK_SHIFT ) & 0x8000) == 0 ) { int size = randomStream.RandomInt( 1024*0, 1024*320 ); if ( buf.Count() < size ) buf.SetSize( size ); if ( g_pClientSocket->Send( buf.Base(), size ) ) { // Server receives the data and echoes it back. Verify that the data is good. WaitForSingleObject( g_ClientPacketEvent.GetEventHandle(), INFINITE ); Assert( memcmp( g_ClientPacket.Base(), buf.Base(), size ) == 0 ); totalBytes += size; CCycleCount curTime, elapsed; curTime.Sample(); CCycleCount::Sub( curTime, startTime, elapsed ); double flSeconds = elapsed.GetSeconds(); Msg( "Packet %d, %d bytes, %dk/sec\n", iPacket++, size, (int)(((totalBytes+511)/1024) / flSeconds) ); } } g_pClientSocket->Release(); g_pServerSocket->Release(); return 0; }
void jTerm_destination(j_compress_ptr cinfo) { jOut.SetCountNonDestructively(jOut.Count() - cinfo->dest->free_in_buffer); }