UNPKG

mdx-m3-viewer

Version:

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

132 lines (105 loc) 4.84 kB
import War3Map from '../../parsers/w3x/map'; import TriggerData from '../../parsers/w3x/wtg/triggerdata'; import CustomTextTrigger from '../../parsers/w3x/wct/customtexttrigger'; import WeuData from './data'; import { processTrigger } from './processing'; import { convertTrigger } from './conversions'; export default function convertWeu(map: War3Map, customTriggerData: TriggerData, weTriggerData: TriggerData) { let wtg; let wct; let wts; // Try to read the triggers file using the custom trigger data. try { wtg = map.readTriggers(customTriggerData); } catch (e) { return { ok: false, error: `Failed to read the triggers file: ${e}` }; } if (!wtg) { return { ok: false, error: `The triggers file doesn't exist. This means this map is most likely protected/optimized.` }; } // Try to read the custom text triggers file. try { wct = map.readCustomTextTriggers(); } catch (e) { return { ok: false, error: `Failed to read the custom text triggers file: ${e}` }; } if (!wct) { return { ok: false, error: `The custom text triggers file doesn't exist` }; } // Try to read the string table. try { wts = map.readStringTable(); } catch (e) { return { ok: false, error: `Failed to read the string table file: ${e}` }; } if (!wts) { return { ok: false, error: `The string table file doesn't exist` }; } let data = new WeuData(customTriggerData, wts); let triggers = wtg.triggers; let customTextTriggers = wct.triggers; let mapHeader = wct.trigger; // If there are less custom text triggers than triggers, WE does not crash, however it doesn't load the map. if (customTextTriggers.length < triggers.length) { for (let i = 0, l = triggers.length - customTextTriggers.length; i < l; i++) { customTextTriggers.push(new CustomTextTrigger()); } } // Process and convert the triggers as needed. for (let i = 0, l = triggers.length; i < l; i++) { let trigger = triggers[i]; // Any callbacks that are generated due to conversions for this trigger will end up here. let callbacks: string[] = []; try { // Process the trigger. // If things inside it need to be converted, this will convert them. let result = processTrigger(data, trigger, callbacks); // If the trigger itself needs to be converted, convert it. if (result.convert) { data.push(trigger); // The trigger body. let body = convertTrigger(data, trigger, callbacks); // If any callbacks were generated when converting the trigger, add them to the trigger. if (callbacks.length) { body = `${callbacks.join('\r\n')}\r\n${body}`; } customTextTriggers[i].text = body; trigger.ecas.length = 0; trigger.isCustom = 1; data.change('convertedtrigger', result.reason, customTextTriggers[i].text); data.pop(); } else if (callbacks.length) { let callbacksText = callbacks.join('\r\n'); // If the trigger didn't need to be converted, but callbacks were generated due to things inside it being converted, add them to the map header. mapHeader.text += `// Callbacks generated for trigger "${trigger.name}" due to conversions\r\n${callbacksText}\r\n`; data.change('generatedcallbacks', trigger.name, callbacksText); } } catch (e) { return { ok: false, error: `Error at ${data.stackToString()}: ${e}` }; } } // WE will only generate global variables for preplaced objects that are referenced directly by GUI. // Referencing them in custom text ECAs or custom text triggers doesn't cut it. // This function saves such references if they are deemed to be lost due to the conversion. // It does this by adding a new trigger called PreplacedObjectReferences, which is not initially on. // In it an ECA is added for each reference. // Note that this is not the case for all preplaced objects. // For example, triggers and regions seem to always be available. // For now only units and destructibles are checked. data.saveGUIReferences(triggers, customTextTriggers); // Save the triggers file back. map.set('war3map.wtg', wtg.save()); // Save the custom text triggers file back. map.set('war3map.wct', wct.save()); // Now try to re-read the triggers file, but using the normal WE trigger data. // If this fails, WE will fail too. try { wtg = map.readTriggers(weTriggerData); } catch (e) { return { ok: false, error: `Failed to validate the triggers file: ${e}` } } if (!wtg) { return { ok: false, error: `Failed to re-read the triggers file` }; } return { ok: true, changes: data.changes }; }