quake 3 | replace known classes in map | add skybox to map | Search

This code standardizes entity references in Quake 2 map files by replacing generic entity names with corresponding model names from a predefined entities definition file.

Run example

npm run import -- "replace entities in map"

replace entities in map

var fs = require('fs')
var importer = require('../Core')

var MATCH_MODELS = /QUAKED\s+([^\s]*)\s+[\s\S]*?model="([^"]*)"/i;

var ents;
function replaceEntities(file, entities) {
    if(!entities) {
        entities = '/Users/briancullinan/planet_quake_data/quake2-baseq2/scripts/entities.def'
    }
    
    // parse entities definition
    if(!ents) {
        var entityStr = fs.readFileSync(entities).toString('utf-8')
        var matches = importer.regexToArray(/QUAKED\s+.*/ig, entityStr)
        ents = matches.reduce((obj, m, i, arr) => {
            var start = entityStr.indexOf(m)
            var end = entityStr.indexOf(arr[i + 1])
            if(end === -1) end = entityStr.length
            var groups = MATCH_MODELS.exec(entityStr.substring(start, end))
            if(!groups) return obj
            obj[groups[1]] = groups[2]
            return obj
        }, {})
    }
    
    if(typeof file === 'string' && fs.existsSync(file)) {
        file = fs.readFileSync(file).toString('utf-8')
    }
    
    // replace entities
    file = file.replace(/"misc_([^"]*)"/ig, ($0) => `"misc_model"\n "model" ${$0}`)
    
    var noises = importer.regexToArray(/noise.*?"\s*"(.*?)"/ig, file, false)
    noises.forEach(n => {
        if(!n[1].includes('sound/')) {
            file = file.replace(n[0], `noise" "sound/${n[1]}"`)
        }
    })
    
    // replace misc_ with models from ent
    Object.keys(ents).forEach(k => {
        if(!k.includes('misc_')) return
        file = file.replace(new RegExp('"' + k + '"', 'ig'), '"' + ents[k] + '"')
    })
    return file
}

module.exports = replaceEntities;

What the code could have been:

const fs = require('fs');
const importer = require('../Core');

const MATCH_MODELS = /QUAKED\s+([^\s]*)\s+[\s\S]*?model="([^"]*)"/i;

class Entities {
  constructor() {
    this.ents = {};
    this.entitiesFile = '/Users/briancullinan/planet_quake_data/quake2-baseq2/scripts/entities.def';
  }

  async parseEntitiesFile() {
    if (Object.keys(this.ents).length === 0) {
      const fileContent = await fs.promises.readFile(this.entitiesFile, 'utf-8');
      const matches = importer.regexToArray(/QUAKED\s+.*/ig, fileContent);
      matches.reduce((obj, m, i, arr) => {
        const start = fileContent.indexOf(m);
        const end = fileContent.indexOf(arr[i + 1]);
        if (end === -1) end = fileContent.length;
        const groups = MATCH_MODELS.exec(fileContent.substring(start, end));
        if (!groups) return obj;
        obj[groups[1]] = groups[2];
        return obj;
      }, this.ents);
    }
  }

  async replaceEntities(file) {
    await this.parseEntitiesFile();
    if (typeof file ==='string' && fs.existsSync(file)) {
      file = await fs.promises.readFile(file, 'utf-8');
    }

    // replace entities
    file = file.replace(/"misc_([^"]*)"/ig, ($0) => `"misc_model"\n "model" ${$0}`);

    // replace noise with sound
    const noises = importer.regexToArray(/noise.*?"\s*"(.*?)"/ig, file, false);
    noises.forEach((n) => {
      if (!n[1].includes('sound/')) {
        file = file.replace(n[0], `noise" "sound/${n[1]}"`);
      }
    });

    // replace misc_ with models from ent
    Object.keys(this.ents).forEach((k) => {
      if (!k.includes('misc_')) return;
      file = file.replace(new RegExp('"' + k + '"', 'ig'), '"' + this.ents[k] + '"');
    });
    return file;
  }
}

module.exports = Entities;

This code snippet modifies a Quake 2 map file by replacing entity references with corresponding model names from a predefined entities definition file.

Here's a breakdown:

  1. Initialization:

  2. replaceEntities Function:

  3. File Processing:

  4. Output:

Purpose:

This code automates the process of standardizing entity references in Quake 2 map files by replacing generic "misc_" entities with specific model names defined in the entities definition file. This ensures consistency and accuracy in the map's entity representation.