This code automates the process of standardizing or customizing textures in Quake 3 map files by replacing texture references with predefined replacements from a list of common textures and a custom override dictionary.
npm run import -- "replace common textures in map"
var fs = require('fs')
var path = require('path')
var importer = require('../Core')
var common = [
'areaportal', 'botclip',
'caulk', 'clip',
'clusterportal', 'cushion',
'donotenter', 'full_clip',
'hint', 'ladderclip',
'ladderclip', 'lightgrid',
'metalclip', 'missileclip',
'nodraw', 'nodrawnonsolid',
'nodrop', 'nolightmap',
'origin', 'qer_mirror',
'qer_portal', 'slick',
'terrain', 'trigger',
'weapclip', 'white'
];
var textures = {
}
function replaceTextures(file) {
var used = []
if(typeof file === 'string' && fs.existsSync(file)) {
file = fs.readFileSync(file).toString('utf-8')
}
// get a list of common textures
if(!common) {
var files = fs.readdirSync('/Users/briancullinan/planet_quake_data/quake3-baseq3/common-spog.pk3dir/textures/common')
common = files.map(f => f.substr(0, f.length - path.extname(f).length));
}
// get all brushes in map, leaf nodes with at least one vertex
var brushes = importer.regexToArray(/\{[\s\S^}]*?\}/ig, file)
// replace all brushes with textures from common or berserker overrides
brushes.forEach(b => {
var newBrush = b
Object.keys(textures).forEach(k => {
newBrush = newBrush.replace(new RegExp('\\) ([^\\/\\)\\(]*?\\/)*?' + k, 'ig'),
(str, $1) => (') ' + textures[k]))
})
common.forEach(k => {
newBrush = newBrush.replace(new RegExp('\\) ([^\\/\\)\\(]*?\\/)*?' + k, 'ig'),
(str, $1) => (') common/' + (k === 'clip' ? 'hint' : k)))
})
// fix water, don't mix textures because
// trenchbroom rearranges verteces so water isn't always applied
if(newBrush.includes('wter')) {
newBrush = newBrush
.replace(/\)\s+([^\)\(]*?)\s+((\s*[0-9\.-]+){5,8})/igm,
(str, $1, $2) => (') e1u1/bluwter ' + $2))
}
var texts = importer.regexToArray(/\)\s+([^\)\(]*?)\s+((\s*[0-9\.-]+){5,8})/igm, b, 1)
texts.forEach($1 => {
if(used.indexOf(path.dirname($1)) === -1) used.push(path.dirname($1))
})
file = file.replace(b, newBrush)
})
used = used.map(u => 'textures/' + u.replace('^\/|\/$|^\s*|\s*