UNPKG

mdx-m3-viewer

Version:

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

194 lines 8.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.processECA = exports.processTrigger = void 0; const utils_1 = require("./utils"); const conversions_1 = require("./conversions"); const functions_1 = require("./transformations/functions"); const presets_1 = require("./transformations/presets"); function processTrigger(data, trigger, callbacks) { data.push(trigger); const eventsAndConditions = []; const actions = []; for (const eca of trigger.ecas) { const type = eca.type; if (type === 0 || type === 1) { eventsAndConditions.push(eca); } else if (type === 2) { actions.push(eca); } } const outputEcas = []; for (const eventOrCondition of eventsAndConditions) { const result = processECA(data, eventOrCondition, callbacks); if (result.convert) { data.pop(); return result; } outputEcas.push(eventOrCondition); } for (const action of actions) { const result = processECA(data, action, callbacks); if (result.convert) { const customScripts = (0, conversions_1.convertFunctionCall)(data, action, callbacks); data.change('inlinecustomscript', result.reason, customScripts.map((eca) => eca.parameters[0].value).join('\n')); outputEcas.push(...customScripts); } else { outputEcas.push(action); } } trigger.ecas = (0, utils_1.ensureCustomScriptCodeSafety)(outputEcas); data.pop(); return { convert: false, reason: '' }; } exports.processTrigger = processTrigger; function processECA(data, eca, callbacks) { data.push(eca); // Test if this function call, or anything down its hierarchy, needs to be converted to custom script. const result = processFunctionCall(data, eca, callbacks); if (result.convert) { const reason = result.reason; // If conversion is needed, try first to see if this is a RoC control flow ECA, and convert it to its TFT equivalent. // This includes things like IfThenElse (RoC) and IfThenElseMultiple (TFT). // This allows to potentially only convert to custom script one part of the control flow block, rather than all of it. if ((0, utils_1.convertSingleToMultiple)(eca)) { // If the test passes here (that is, false is returned), the TFT conversion allowed to handle the conversion down the hierarchy. // In this case, this ECA no longer needs to be converted to custom script. const result = processFunctionCall(data, eca, callbacks); if (result.convert) { data.pop(); return result; } else { data.change('singletomultiple', reason, eca.name); } } else { data.pop(); return result; } } const outputEcas = []; // Test the child ECAs if there are any. for (const child of eca.ecas) { const result = processECA(data, child, callbacks); if (result.convert) { let customScripts; // If this is a condition ECA, make a custom script condition. if ((0, utils_1.isConditionECA)(eca.name, child.group)) { let condition = (0, conversions_1.convertFunctionCall)(data, child, callbacks)[0].parameters[0].value; // Normally type 2 (function) ECAs have the call keyword prepended to them. // If one was added, remove it now, since this is a condition. if (condition.startsWith('call ')) { condition = condition.slice(5); } let finalCondition; let returnValue; // IfThenElseMultiple and AndMultiple return false if any condition is false. // OrMultiple needs to return true if any condition is true. if (eca.name === 'OrMultiple') { finalCondition = condition; returnValue = 'true'; } else { finalCondition = `not (${condition})`; returnValue = 'false'; } customScripts = [ (0, utils_1.createCustomScriptECA)(`if ${finalCondition} then`), (0, utils_1.createCustomScriptECA)(`return ${returnValue}`), (0, utils_1.createCustomScriptECA)('endif'), ]; } else { customScripts = (0, conversions_1.convertFunctionCall)(data, child, callbacks); } // All of the custom scripts should be in the same group as the original child. for (const script of customScripts) { script.group = child.group; } data.change('inlinecustomscript', result.reason, customScripts.map((eca) => eca.parameters[0].value).join('\n')); outputEcas.push(...customScripts); } else { outputEcas.push(child); } } eca.ecas = (0, utils_1.ensureCustomScriptCodeSafety)(outputEcas); data.pop(); return { convert: false, reason: '' }; } exports.processECA = processECA; function processFunctionCall(data, object, callbacks) { const name = object.name; // Check if this object can be converted back to normal GUI. // If it's already normal GUI, nothing will happen. if ((0, functions_1.default)(data, object)) { data.change('inlinegui', name, object.name); } // If this function is not from normal GUI, it has to be converted. if (!data.triggerData.isBaseFunction(object.type, object.name)) { return { convert: true, reason: object.name }; } // Check the parameters. // Note that they will also be checked if GUI was inlined. // This is needed, because the inline functions don't check the parameters, only move them around. for (const parameter of object.parameters) { // Check for custom presets. if (parameter.type === 0 && data.triggerData.isCustomPreset(parameter.value)) { const value = parameter.value; if ((0, presets_1.default)(data, parameter)) { data.change('inlinepreset', value, parameter.value); } else { return { convert: true, reason: value }; } } const result = processParameter(data, parameter, callbacks); if (result.convert) { return result; } } return { convert: false, reason: '' }; } function processParameter(data, parameter, callbacks) { data.push(parameter); const type = parameter.type; const value = parameter.value; if (type === 1) { if (value.startsWith('gg_')) { // Used to track global generated variables and their status. data.updateGUIReference(value, true); } } else if (type === 2) { const result = processSubParameters(data, parameter.subParameters, callbacks); if (result.convert) { data.pop(); return result; } } // If this is an array element, test the array index. const index = parameter.arrayIndex; if (index) { const result = processParameter(data, index, callbacks); if (result.convert) { data.pop(); return result; } } data.pop(); return { convert: false, reason: '' }; } function processSubParameters(data, subParameters, callbacks) { data.push(subParameters); const result = processFunctionCall(data, subParameters, callbacks); if (result.convert) { data.pop(); return result; } data.pop(); return { convert: false, reason: '' }; } //# sourceMappingURL=processing.js.map