//----------------------------------------------------------------------------- // Patches a single keyvalue in a material //----------------------------------------------------------------------------- void CreateMaterialPatch( const char *pOriginalMaterialName, const char *pNewMaterialName, const char *pNewKey, const char *pNewValue, MaterialPatchType_t nPatchType ) { MaterialPatchInfo_t info; info.m_pKey = pNewKey; info.m_pValue = pNewValue; CreateMaterialPatch( pOriginalMaterialName, pNewMaterialName, 1, &info, nPatchType ); }
//----------------------------------------------------------------------------- // Patches the $envmap for a material and all its dependents, returns true if any patching happened //----------------------------------------------------------------------------- static bool PatchEnvmapForMaterialAndDependents( const char *pMaterialName, const PatchInfo_t &info, const char *pCubemapTexture ) { // Do *NOT* patch the material if there is an $envmap specified and it's not 'env_cubemap' // FIXME: It's theoretically ok to patch the material if $envmap is not specified, // because we're using the 'replace' block, which will only add the env_cubemap if // $envmap is specified in the source material. But it will fail if someone adds // a specific non-env_cubemap $envmap to the source material at a later point. Bleah // See if we have an $envmap to patch bool bShouldPatchEnvCubemap = DoesMaterialHaveKeyValuePair( pMaterialName, "$envmap", "env_cubemap" ); // See if we have a dependent material to patch bool bDependentMaterialPatched = false; const char *pDependentMaterialVar = NULL; const char *pDependentMaterial = FindDependentMaterial( pMaterialName, &pDependentMaterialVar ); if ( pDependentMaterial ) { bDependentMaterialPatched = PatchEnvmapForMaterialAndDependents( pDependentMaterial, info, pCubemapTexture ); } // If we have neither to patch, we're done if ( !bShouldPatchEnvCubemap && !bDependentMaterialPatched ) return false; // Otherwise we have to make a patched version of ourselves char pPatchedMaterialName[1024]; GeneratePatchedName( pMaterialName, info, true, pPatchedMaterialName, 1024 ); MaterialPatchInfo_t pPatchInfo[2]; int nPatchCount = 0; if ( bShouldPatchEnvCubemap ) { pPatchInfo[nPatchCount].m_pKey = "$envmap"; pPatchInfo[nPatchCount].m_pRequiredOriginalValue = "env_cubemap"; pPatchInfo[nPatchCount].m_pValue = pCubemapTexture; ++nPatchCount; } char pDependentPatchedMaterialName[1024]; if ( bDependentMaterialPatched ) { // FIXME: Annoying! I either have to pass back the patched dependent material name // or reconstruct it. Both are sucky. GeneratePatchedName( pDependentMaterial, info, true, pDependentPatchedMaterialName, 1024 ); pPatchInfo[nPatchCount].m_pKey = pDependentMaterialVar; pPatchInfo[nPatchCount].m_pValue = pDependentPatchedMaterialName; ++nPatchCount; } CreateMaterialPatch( pMaterialName, pPatchedMaterialName, nPatchCount, pPatchInfo, PATCH_REPLACE ); return true; }
//----------------------------------------------------------------------------- // Purpose: Called to write procedural materials in the rb tree to the embedded // pak file for this .bsp //----------------------------------------------------------------------------- void EmitWaterMaterialFile( WaterTexInfo *wti ) { char waterTextureName[512]; if ( !wti ) { return; } GetWaterTextureName( mapbase, wti->m_MaterialName.String(), ( int )wti->m_nWaterDepth, waterTextureName ); // Convert to string char szDepth[ 32 ]; sprintf( szDepth, "%i", wti->m_nWaterDepth ); CreateMaterialPatch( wti->m_MaterialName.String(), waterTextureName, "$waterdepth", szDepth, PATCH_INSERT ); }