UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

209 lines (172 loc) 4.91 kB
import IniFile from '../../ini/file'; /** * Trigger data needed to load a WTG file. */ export default class TriggerData { /** * */ constructor() { /** @member {Object<string, string>} */ this.types = {}; /** @member {Array<Object>} */ this.functions = [{}, {}, {}, {}]; /** @member {Object<string, string>} */ this.presets = {}; /** @member {Object<string, string>} */ this.externalTypes = {}; /** @member {Array<Object>} */ this.externalFunctions = [{}, {}, {}, {}]; /** @member {Object<string, string>} */ this.externalPresets = {}; } /** * @param {string} buffer * @param {boolean} isExternal */ addTriggerData(buffer, isExternal) { let types = this.types; let functions = this.functions; let presets = this.presets; if (isExternal) { types = this.externalTypes; functions = this.externalFunctions; presets = this.externalPresets; } let triggerData = new IniFile(); triggerData.load(buffer); this.addTriggerTypes(types, triggerData.getSection('TriggerTypes')); this.addTriggerDataFunctions(functions[0], triggerData.getSection('TriggerEvents'), 1); this.addTriggerDataFunctions(functions[1], triggerData.getSection('TriggerConditions'), 1); this.addTriggerDataFunctions(functions[2], triggerData.getSection('TriggerActions'), 1); this.addTriggerDataFunctions(functions[3], triggerData.getSection('TriggerCalls'), 3); this.addTriggerDataPresets(presets, triggerData.getSection('TriggerParams')); } /** * @param {Object} types * @param {Map<string, string>} section */ addTriggerTypes(types, section) { for (let [key, value] of section) { let tokens = value.split(','); types[key] = tokens[4] || ''; } } /** * @param {Object} functions * @param {Map<string, string>} section * @param {number} skipped */ addTriggerDataFunctions(functions, section, skipped) { for (let [key, value] of section) { // We don't care about metadata lines. if (key[0] !== '_') { let tokens = value.split(',').slice(skipped); let args = []; // Can be used by actions to make aliases. let scriptName = section.get(`_${key}_scriptname`) || null; for (let argument of tokens) { // We don't care about constants. if (isNaN(argument) && argument !== 'nothing' && argument !== '') { args.push(argument); } } functions[key] = {args, scriptName}; } } } /** * @param {Object} presets * @param {Map<string, string>} section */ addTriggerDataPresets(presets, section) { for (let [key, value] of section) { let tokens = value.split(','); // Note that the operators are enclosed by "" for some reason. // Note that string literals are enclosed by backticks. presets[key] = tokens[2].replace(/"/g, '').replace(/`/g, '"'); } } /** * Given a type, return its base type. * Returns the given type if its not a child type. * * @param {string} type * @return {string} */ getBaseType(type) { type = type.toLowerCase(); let base = this.types[type]; if (base === undefined) { base = this.externalTypes[type]; } // Same as !base, but be explicit to be clearer. if (base === '' || base === undefined) { return type; } return base; } /** * @param {number} type * @param {string} name * @return {boolean} */ isBaseFunction(type, name) { name = name.toLowerCase(); if (this.functions[type][name]) { return true; } return false; } /** * Gets the signature of the given function. * * @param {number} type * @param {string} name * @return {Array<string>} */ getFunction(type, name) { name = name.toLowerCase(); let args = this.functions[type][name]; if (!args) { args = this.externalFunctions[type][name]; if (!args) { throw new Error(`Tried to get signature for unknown function "${name}"`); } } return args; } /** * Gets a preset value. * * @param {string} name * @return {string} */ getPreset(name) { name = name.toLowerCase(); let preset = this.presets[name]; if (preset === undefined) { preset = this.externalPresets[name]; if (preset === undefined) { throw new Error(`Failed to find a preset: ${name}`); } } return preset; } /** * Is the given preset a custom or standard one? * * @param {string} name * @return {boolean} */ isCustomPreset(name) { name = name.toLowerCase(); if (this.presets[name] !== undefined) { return false; } if (this.externalPresets[name] !== undefined) { return true; } throw new Error(`Failed to find a preset: ${name}`); } }