static void WriteRecordingFile() { // Store the command size *(int*)&g_pRecordingBuffer[g_CommandStartIdx] = g_pRecordingBuffer.Size() - g_CommandStartIdx; #ifndef CRASH_RECORDING // When not crash recording, flush when buffer gets too big, // or when Present() is called if ((g_pRecordingBuffer.Size() < COMMAND_BUFFER_SIZE) && (g_pRecordingBuffer[g_CommandStartIdx+4] != DX8_PRESENT)) return; #endif FILE* fp = OpenRecordingFile(); if (fp) { // store the command size fwrite( g_pRecordingBuffer.Base(), 1, g_pRecordingBuffer.Size(), fp ); fflush( fp ); #ifndef CRASH_RECORDING fclose( fp ); #endif } g_pRecordingBuffer.RemoveAll(); }
void CVradStaticPropMgr::Shutdown() { // Remove all static props from the tree for (int i = m_StaticProps.Size(); --i >= 0; ) { RemovePropFromTree( i ); } // Remove all static prop model data for (int i = m_StaticPropDict.Size(); --i >= 0; ) { studiohdr_t *pStudioHdr = m_StaticPropDict[i].m_pStudioHdr; if ( pStudioHdr ) { if ( pStudioHdr->pVertexBase ) { free( pStudioHdr->pVertexBase ); } free( pStudioHdr ); } } m_pBSPTreeData->Shutdown(); m_StaticProps.Purge(); m_StaticPropDict.Purge(); }
void CVradStaticPropMgr::StartRayTest( PropTested_t& propTested ) { if (m_StaticProps.Size() > 0) { if (propTested.m_pTested == 0) { propTested.m_pTested = new int[m_StaticProps.Size()]; memset( propTested.m_pTested, 0, m_StaticProps.Size() * sizeof(int) ); propTested.m_Enum = 0; propTested.pThreadedCollision = s_pPhysCollision->ThreadContextCreate(); } ++propTested.m_Enum; } }
bool CConfigFile::Write( char const *pFilename ) { FILE *fp = fopen( pFilename, "wt" ); if( !fp ) return false; fprintf( fp, "ssdatabase %s\n", m_SSDatabase ); fprintf( fp, "resourcepath %s\n", m_SSResourcePath ); fprintf( fp, "bsppath %s\n", m_SSBSPPath ); for( int i=0; i < m_Entries.Size(); i++ ) { CConfigFile::Entry *pEntry = &m_Entries[i]; fprintf( fp, "file %s %s %d", pEntry->m_Filename, pEntry->m_VMFPath, pEntry->m_VMFTime ); for( int e=0; e < pEntry->m_nEMailAddresses; e++ ) fprintf( fp, " -email %s", pEntry->m_EMailAddresses[e].m_EMailAddress ); if( pEntry->m_bFastVis ) fprintf( fp, " -fast" ); fprintf( fp, "\n" ); } fclose( fp ); return true; }
//----------------------------------------------------------------------------- // Writes the detail lighting lump //----------------------------------------------------------------------------- static void WriteDetailLightingLump( int lumpID, int lumpVersion, CUtlVector<DetailPropLightstylesLump_t> &lumpData ) { GameLumpHandle_t handle = g_GameLumps.GetGameLumpHandle(lumpID); if (handle != g_GameLumps.InvalidGameLump()) g_GameLumps.DestroyGameLump(handle); int lightsize = lumpData.Size() * sizeof(DetailPropLightstylesLump_t); int lumpsize = lightsize + sizeof(int); handle = g_GameLumps.CreateGameLump( lumpID, lumpsize, 0, lumpVersion ); // Serialize the data CUtlBuffer buf( g_GameLumps.GetGameLump(handle), lumpsize ); buf.PutInt( lumpData.Size() ); if (lightsize) buf.Put( lumpData.Base(), lightsize ); }
bool CMoveHelperServer::AddToTouched( const trace_t &tr, const Vector& impactvelocity ) { Assert( m_pHostPlayer ); // Trace missed if ( !tr.m_pEnt ) return false; if ( tr.m_pEnt == m_pHostPlayer ) { Assert( !"CMoveHelperServer::AddToTouched: Tried to add self to touchlist!!!" ); return false; } // Check for duplicate entities for ( int j = m_TouchList.Size(); --j >= 0; ) { if ( m_TouchList[j].trace.m_pEnt == tr.m_pEnt ) { return false; } } int i = m_TouchList.AddToTail(); m_TouchList[i].trace = tr; VectorCopy( impactvelocity, m_TouchList[i].deltavelocity ); return true; }
//----------------------------------------------------------------------------- // Computes a convex hull from the studio model //----------------------------------------------------------------------------- CPhysCollide* ComputeConvexHull( studiohdr_t* pStudioHdr ) { CUtlVector<CPhysConvex*> convexHulls; for (int body = 0; body < pStudioHdr->numbodyparts; ++body ) { mstudiobodyparts_t *pBodyPart = pStudioHdr->pBodypart( body ); for( int model = 0; model < pBodyPart->nummodels; ++model ) { mstudiomodel_t *pStudioModel = pBodyPart->pModel( model ); for( int mesh = 0; mesh < pStudioModel->nummeshes; ++mesh ) { // Make a convex hull for each mesh // NOTE: This won't work unless the model has been compiled // with $staticprop mstudiomesh_t *pStudioMesh = pStudioModel->pMesh( mesh ); convexHulls.AddToTail( ComputeConvexHull( pStudioMesh ) ); } } } // Convert an array of convex elements to a compiled collision model // (this deletes the convex elements) return s_pPhysCollision->ConvertConvexToCollide( convexHulls.Base(), convexHulls.Size() ); }
void CSDKGameRules::CalculateSlowMoForPlayer(CSDKPlayer* pPlayer) { if (!pPlayer) return; if (!pPlayer->IsAlive()) { pPlayer->SetSlowMoType(SLOWMO_NONE); return; } // If I activated slow then I get to keep my slow level. if (pPlayer->GetSlowMoType() == SLOWMO_ACTIVATED) return; if (pPlayer->GetSlowMoType() == SLOWMO_STYLESKILL) return; // Players who haven't activated anything are at the whims of those who have. bool bOtherInSlow = false; CUtlVector<CSDKPlayer*> apOthersInPVS; CBaseEntity* pOther = NULL; while ((pOther = UTIL_EntitiesInPVS(pPlayer, pOther)) != NULL) { CSDKPlayer* pOtherPlayer = ToSDKPlayer(pOther); if (!pOtherPlayer) continue; if (pOtherPlayer == pPlayer) continue; apOthersInPVS.AddToTail(pOtherPlayer); } for (int i = 0; i < apOthersInPVS.Size(); i++) { CSDKPlayer* pOtherPlayer = apOthersInPVS[i]; if (!pOtherPlayer->IsAlive()) continue; if (pOtherPlayer->GetSlowMoType() != SLOWMO_NONE) { bOtherInSlow = true; break; } } // If any of these players are in slow then I'm in slow too. if (bOtherInSlow) pPlayer->SetSlowMoType(SLOWMO_PASSIVE); else pPlayer->SetSlowMoType(SLOWMO_NONE); }
//----------------------------------------------------------------------------- // Purpose: Purge & delete all fades in the queue //----------------------------------------------------------------------------- void CViewEffects::ClearAllFades( void ) { int iSize = m_FadeList.Size(); for (int i = iSize-1; i >= 0; i-- ) { delete m_FadeList[i]; } m_FadeList.Purge(); }
CConfigFile::Entry* CConfigFile::FindEntryByFilename( char const *pFilename ) { for( int i=0; i < m_Entries.Size(); i++ ) { if( stricmp( m_Entries[i].m_Filename, pFilename ) == 0 ) return &m_Entries[i]; } return NULL; }
//----------------------------------------------------------------------------- // Purpose: Get the team of the specified player //----------------------------------------------------------------------------- C_Team *GetPlayersTeam( int iPlayerIndex ) { for (int i = 0; i < g_Teams.Size(); i++ ) { if ( g_Teams[i]->ContainsPlayer( iPlayerIndex ) ) return g_Teams[i]; } return NULL; }
//----------------------------------------------------------------------------- // Purpose: Returns true if the two specified players are on the same team //----------------------------------------------------------------------------- bool ArePlayersOnSameTeam( int iPlayerIndex1, int iPlayerIndex2 ) { for (int i = 0; i < g_Teams.Size(); i++ ) { if ( g_Teams[i]->ContainsPlayer( iPlayerIndex1 ) && g_Teams[i]->ContainsPlayer( iPlayerIndex2 ) ) return true; } return false; }
//----------------------------------------------------------------------------- // Purpose: Get the C_Team for the specified team number //----------------------------------------------------------------------------- C_Team *GetGlobalTeam( int iTeamNumber ) { for (int i = 0; i < g_Teams.Size(); i++ ) { if ( g_Teams[i]->GetTeamNumber() == iTeamNumber ) return g_Teams[i]; } return NULL; }
//----------------------------------------------------------------------------- // System to update prop opacity //----------------------------------------------------------------------------- void CStaticPropMgr::ComputePropOpacity( const Vector &viewOrigin ) { // We need to recompute translucency information for all static props int i; #ifndef SWDS for (i = m_StaticPropDict.Size(); --i >= 0; ) { if (modelinfoclient->ModelHasMaterialProxy( m_StaticPropDict[i].m_pModel )) { modelinfoclient->RecomputeTranslucency( m_StaticPropDict[i].m_pModel ); } } #endif // Distance-based fading. // Step over the list of all things that want to be faded out and recompute alpha // Not sure if this is a fast enough way of doing it // but it's easy for now; we'll have to test later how large this list gets. // If it's <100 or so, we should be fine Vector v; for ( i = m_StaticPropFade.Count(); --i >= 0; ) { StaticPropFade_t& fade = m_StaticPropFade[i]; CStaticProp& prop = m_StaticProps[fade.m_Model]; // Calculate distance (badly) VectorSubtract( prop.GetRenderOrigin(), viewOrigin, v ); #ifndef SWDS ClientRenderHandle_t renderHandle = prop.GetRenderHandle(); float sqDist = v.LengthSqr(); if ( sqDist < fade.m_MaxDistSq ) { if ((fade.m_MinDistSq >= 0) && (sqDist > fade.m_MinDistSq)) { clientleafsystem->ChangeRenderableRenderGroup( renderHandle, RENDER_GROUP_TRANSLUCENT_ENTITY ); prop.SetAlpha( fade.m_FalloffFactor * (fade.m_MaxDistSq - sqDist) ); } else { // We can stick the prop into the opaque list clientleafsystem->ChangeRenderableRenderGroup( renderHandle, RENDER_GROUP_OPAQUE_ENTITY ); prop.SetAlpha( 255 ); } } else { // We can stick the prop into the opaque list now; we're not drawing it! clientleafsystem->ChangeRenderableRenderGroup( renderHandle, RENDER_GROUP_OPAQUE_ENTITY ); prop.SetAlpha( 0 ); } #endif } }
//----------------------------------------------------------------------------- // After we built the touch list, deal with all the impacts... //----------------------------------------------------------------------------- void CMoveHelperServer::ProcessImpacts( void ) { Assert( m_pHostPlayer ); // Relink in order to build absorigin and absmin/max to reflect any changes // from prediction. Relink will early out on SOLID_NOT engine->RelinkEntity( m_pHostPlayer->pev, true ); // Don't bother if the player ain't solid if ( m_pHostPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) { return; } // Save off the velocity, cause we need to temporarily reset it Vector vel = m_pHostPlayer->GetAbsVelocity(); // Touch other objects that were intersected during the movement. for (int i = 0 ; i < m_TouchList.Size(); i++) { CBaseHandle entindex = m_TouchList[i].trace.m_pEnt->GetRefEHandle(); // We should have culled negative indices by now Assert( entindex.IsValid() ); edict_t* ent = GetEdict( entindex ); if (!ent) continue; // Run the impact function as if we had run it during movement. CBaseEntity *entity = GetContainingEntity( ent ); if ( !entity ) continue; Assert( entity != m_pHostPlayer ); // Don't ever collide with self!!!! if ( entity == m_pHostPlayer ) continue; // Reconstruct trace results. m_TouchList[i].trace.m_pEnt = CBaseEntity::Instance( ent ); // Use the velocity we had when we collided, so boxes will move, etc. m_pHostPlayer->SetAbsVelocity( m_TouchList[i].deltavelocity ); entity->PhysicsImpact( m_pHostPlayer, m_TouchList[i].trace ); } // Restore the velocity m_pHostPlayer->SetAbsVelocity( vel ); // So no stuff is ever left over, sigh... ResetTouchList(); }
void CSDKGameRules::GiveSlowMoToNearbyPlayers(CSDKPlayer* pPlayer) { if (!pPlayer) return; if (!pPlayer->IsAlive()) { pPlayer->SetSlowMoType(SLOWMO_NONE); return; } if (pPlayer->GetSlowMoType() == SLOWMO_NONE) return; // I have some slowmo on me. Pass it to other players nearby. CUtlVector<CSDKPlayer*> apOthersInPVS; CBaseEntity* pOther = NULL; while ((pOther = UTIL_EntitiesInPVS(pPlayer, pOther)) != NULL) { CSDKPlayer* pOtherPlayer = ToSDKPlayer(pOther); if (!pOtherPlayer) continue; if (pOtherPlayer == pPlayer) continue; // If they already have slow mo, we don't need to pass it to them. if (pOtherPlayer->GetSlowMoType() == SLOWMO_STYLESKILL) continue; if (pOtherPlayer->GetSlowMoType() == SLOWMO_ACTIVATED) continue; if (pOtherPlayer->GetSlowMoType() == SLOWMO_PASSIVE) continue; apOthersInPVS.AddToTail(pOtherPlayer); } for (int i = 0; i < apOthersInPVS.Size(); i++) { CSDKPlayer* pOtherPlayer = apOthersInPVS[i]; // It could have been already done by a previous iteration of the recursion below. if (pOtherPlayer->GetSlowMoType() != SLOWMO_NONE) continue; pOtherPlayer->SetSlowMoType(SLOWMO_PASSIVE); GiveSlowMoToNearbyPlayers(pOtherPlayer); } }
void RecordArgument( void const* pMemory, int size ) { if( !g_bDoRecord ) { return; } Assert( g_ArgsRemaining > 0 ); int tail = g_pRecordingBuffer.Size(); g_pRecordingBuffer.AddMultipleToTail( size ); memcpy( &g_pRecordingBuffer[tail], pMemory, size ); if (--g_ArgsRemaining == 0) WriteRecordingFile(); }
// Get the database entry for an index static eventlist_t *ListFromEvent( int eventIndex ) { // ugly linear search for ( int i = 0; i < g_EventList.Size(); i++ ) { if ( g_EventList[i].eventIndex == eventIndex ) { return &g_EventList[i]; } } return NULL; }
void RemoveAll( void ) { for ( int i = 0; i < m_PanelList.Size(); i++ ) { PanelItem_t *item = &m_PanelList[i]; delete item->m_EditLabel; delete item->m_EditPanel; delete item->m_EditButton; } m_PanelList.RemoveAll(); m_pControls->RemoveAll(); }
void CVradStaticPropMgr::Shutdown() { // Remove all static props from the tree for (int i = m_StaticProps.Size(); --i >= 0; ) { RemovePropFromTree( i ); } m_pBSPTreeData->Shutdown(); m_StaticProps.Purge(); m_StaticPropDict.Purge(); }
static int AddStaticPropDictLump( char const* pModelName ) { StaticPropDictLump_t dictLump; strncpy( dictLump.m_Name, pModelName, DETAIL_NAME_LENGTH ); for (int i = s_StaticPropDictLump.Size(); --i >= 0; ) { if (!memcmp(&s_StaticPropDictLump[i], &dictLump, sizeof(dictLump) )) return i; } return s_StaticPropDictLump.AddToTail( dictLump ); }
// Write the buffered crap out on shutdown. void FinishRecording() { #ifndef CRASH_RECORDING FILE* fp = OpenRecordingFile(); if (fp) { // store the command size fwrite( g_pRecordingBuffer.Base(), 1, g_pRecordingBuffer.Size(), fp ); fflush( fp ); } g_pRecordingBuffer.RemoveAll(); #endif }
//----------------------------------------------------------------------------- // Purpose: Finds a random hint within the requested radious of the npc // Builds a list of all suitable hints and chooses randomly from amongst them. // Input : *pNPC - // nHintType - // nFlags - // flMaxDist - // Output : CAI_Hint //----------------------------------------------------------------------------- CAI_Hint *CAI_HintManager::FindHintRandom( CAI_BaseNPC *pNPC, const Vector &position, const CHintCriteria &hintCriteria ) { CUtlVector<CAI_Hint *> hintList; if ( FindAllHints( pNPC, position, hintCriteria, &hintList ) > 0 ) { // Pick one randomly return ( CAI_HintManager::AddFoundHint( hintList[ random->RandomInt( 0, hintList.Size() - 1 ) ] ) ); } // start at the top of the list for the next search CAI_HintManager::ResetFoundHints(); return NULL; }
//----------------------------------------------------------------------------- // Places Static Props in the level //----------------------------------------------------------------------------- static void AddStaticPropToLump( StaticPropBuild_t const& build ) { // Get the collision model CPhysCollide* pConvexHull = GetCollisionModel( build.m_pModelName ); if (!pConvexHull) return; // Compute the leaves the static prop's convex hull hits CUtlVector< unsigned short > leafList; ComputeStaticPropLeaves( pConvexHull, build.m_Origin, build.m_Angles, leafList ); if ( !leafList.Count() ) { Warning( "Static prop %s outside the map (%.2f, %.2f, %.2f)\n", build.m_pModelName, build.m_Origin.x, build.m_Origin.y, build.m_Origin.z ); return; } // Insert an element into the lump data... int i = s_StaticPropLump.AddToTail( ); StaticPropLump_t& propLump = s_StaticPropLump[i]; propLump.m_PropType = AddStaticPropDictLump( build.m_pModelName ); VectorCopy( build.m_Origin, propLump.m_Origin ); VectorCopy( build.m_Angles, propLump.m_Angles ); propLump.m_FirstLeaf = s_StaticPropLeafLump.Count(); propLump.m_LeafCount = leafList.Count(); propLump.m_Solid = build.m_Solid; propLump.m_Skin = build.m_Skin; propLump.m_Flags = build.m_Flags; if (build.m_FadesOut) propLump.m_Flags |= STATIC_PROP_FLAG_FADES; propLump.m_FadeMinDist = build.m_FadeMinDist; propLump.m_FadeMaxDist = build.m_FadeMaxDist; propLump.m_flForcedFadeScale = build.m_flForcedFadeScale; if (build.m_pLightingOrigin && *build.m_pLightingOrigin) { if (ComputeLightingOrigin( build, propLump.m_LightingOrigin )) { propLump.m_Flags |= STATIC_PROP_USE_LIGHTING_ORIGIN; } } // Add the leaves to the leaf lump for (int j = 0; j < leafList.Size(); ++j) { StaticPropLeafLump_t insert; insert.m_Leaf = leafList[j]; s_StaticPropLeafLump.AddToTail( insert ); } }
//----------------------------------------------------------------------------- // Purpose: Clear only the permanent fades in our fade list //----------------------------------------------------------------------------- void CViewEffects::ClearPermanentFades( void ) { int iSize = m_FadeList.Size(); for (int i = iSize-1; i >= 0; i-- ) { screenfade_t *pFade = m_FadeList[i]; if ( pFade->Flags & FFADE_STAYOUT ) { // Destroy this fade m_FadeList.FindAndRemove( pFade ); delete pFade; } } }
//----------------------------------------------------------------------------- // Adds decals to static props, returns point of decal in trace_t //----------------------------------------------------------------------------- void CStaticPropMgr::AddDecalToStaticProp( Vector const& rayStart, Vector const& rayEnd, int staticPropIndex, int decalIndex, bool doTrace, trace_t& tr ) { #ifndef SWDS // Invalid static prop? Blow it off! if (staticPropIndex >= m_StaticProps.Size()) { memset( &tr, 0, sizeof(trace_t) ); tr.fraction = 1.0f; return; } Ray_t ray; ray.Init( rayStart, rayEnd ); if (doTrace) { // Trace the ray against the prop TraceRayAgainstStaticProp( ray, staticPropIndex, tr ); if (tr.fraction == 1.0f) return; } // Get the prop CStaticProp& prop = m_StaticProps[staticPropIndex]; // Found the point, now lets apply the decals if (prop.GetModelInstance() == MODEL_INSTANCE_INVALID) { prop.SetModelInstance( modelrender->CreateInstance( &prop ) ); } // Choose a new ray along which to project the decal based on // surface normal. This prevents decal skewing bool noPokethru = false; if (doTrace && (prop.GetSolid() == SOLID_VPHYSICS) && !tr.startsolid && !tr.allsolid) { Vector temp; VectorSubtract( tr.endpos, tr.plane.normal, temp ); ray.Init( tr.endpos, temp ); noPokethru = true; } // FIXME: Pass in decal up? // FIXME: What to do about the body parameter? Vector up(0, 0, 1); modelrender->AddDecal( prop.GetModelInstance(), ray, up, decalIndex, 0, noPokethru ); #endif }
void CMoveHelperClient::ProcessImpacts( void ) { C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) return; // Relink in order to build absorigin and absmin/max to reflect any changes // from prediction. Relink will early out on SOLID_NOT // TODO: Touch triggers on the client //pPlayer->PhysicsTouchTriggers(); // Don't bother if the player ain't solid if ( pPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) return; // Save off the velocity, cause we need to temporarily reset it Vector vel = pPlayer->GetAbsVelocity(); // Touch other objects that were intersected during the movement. for (int i = 0 ; i < m_TouchList.Size(); i++) { // Run the impact function as if we had run it during movement. C_BaseEntity *entity = ClientEntityList().GetEnt( m_TouchList[i].trace.m_pEnt->entindex() ); if ( !entity ) continue; Assert( entity != pPlayer ); // Don't ever collide with self!!!! if ( entity == pPlayer ) continue; // Reconstruct trace results. m_TouchList[i].trace.m_pEnt = entity; // Use the velocity we had when we collided, so boxes will move, etc. pPlayer->SetAbsVelocity( m_TouchList[i].deltavelocity ); entity->PhysicsImpact( pPlayer, m_TouchList[i].trace ); } // Restore the velocity pPlayer->SetAbsVelocity( vel ); // So no stuff is ever left over, sigh... ResetTouchList(); }
bool CMoveHelperClient::AddToTouched( const trace_t& tr, const Vector& impactvelocity ) { int i; // Look for duplicates for (i = 0; i < m_TouchList.Size(); i++) { if (m_TouchList[i].trace.m_pEnt == tr.m_pEnt) { return false; } } i = m_TouchList.AddToTail(); m_TouchList[i].trace = tr; VectorCopy( impactvelocity, m_TouchList[i].deltavelocity ); return true; }
//----------------------------------------------------------------------------- // Gets the lighting + material color of a static prop //----------------------------------------------------------------------------- void CStaticPropMgr::GetStaticPropMaterialColorAndLighting( trace_t* pTrace, int staticPropIndex, Vector& lighting, Vector& matColor ) { #ifndef SWDS // Invalid static prop? Blow it off! if (staticPropIndex >= m_StaticProps.Size()) { lighting.Init( 0, 0, 0 ); matColor.Init( 1, 1, 1 ); return; } // Get the prop CStaticProp& prop = m_StaticProps[staticPropIndex]; // Ask the model info about what we need to know modelinfoclient->GetModelMaterialColorAndLighting( (model_t*)prop.GetModel(), prop.GetRenderOrigin(), prop.GetRenderAngles(), pTrace, lighting, matColor ); #endif }
// need to do this so that if we are building HDR data, the LDR data is intact, and vice versa.s void UnserializeDetailPropLighting( int lumpID, int lumpVersion, CUtlVector<DetailPropLightstylesLump_t> &lumpData ) { GameLumpHandle_t handle = g_GameLumps.GetGameLumpHandle( lumpID ); if( handle == g_GameLumps.InvalidGameLump() ) { return; } if (g_GameLumps.GetGameLumpVersion(handle) != lumpVersion) return; // Unserialize CUtlBuffer buf( g_GameLumps.GetGameLump(handle), g_GameLumps.GameLumpSize( handle ), CUtlBuffer::READ_ONLY ); int count = buf.GetInt(); if( !count ) { return; } lumpData.SetCount( count ); int lightsize = lumpData.Size() * sizeof(DetailPropLightstylesLump_t); buf.Get( lumpData.Base(), lightsize ); }