arx-level-generator
Version:
A tool for creating Arx Fatalis maps
121 lines • 4.36 kB
JavaScript
import { ScriptCommand } from './scripting/ScriptCommand.js';
import { isUsesTextures } from './scripting/interfaces/UsesTextures.js';
export class Script {
static EOL = '\r\n';
static targetPath = 'graph/obj3d/interactive';
isRoot = false;
filename;
properties = [];
subroutines = [];
eventHandlers = {
'::before': [],
'::after': [],
init: [],
};
constructor(props) {
this.filename = props.filename;
}
toArxData() {
const eventStrings = [];
const eventHandlerPairs = Object.entries(this.eventHandlers);
for (const [eventName, handlers] of eventHandlerPairs) {
if (eventName === '::before' || eventName === '::after') {
continue;
}
let eventString = '';
if (eventName === 'init') {
eventString += this.properties.map((property) => ` ${property.toString()}\n`).join('');
}
for (const handler of handlers) {
eventString += Script.handlerToString(handler);
}
if (eventString.trim() !== '') {
eventStrings.push(`on ${eventName} {\n${eventString} accept\n}`);
}
}
const subroutines = [];
for (const subroutine of this.subroutines) {
subroutines.push(subroutine.toString());
}
const beforeScripts = this.eventHandlers['::before'].map((script) => Script.handlerToString(script));
const afterScripts = this.eventHandlers['::after'].map((script) => Script.handlerToString(script));
const scriptSections = [
beforeScripts.join('\n'),
eventStrings.join('\n'),
subroutines.join('\n'),
afterScripts.join('\n'),
];
return scriptSections.filter((section) => section !== '').join('\n\n');
}
on(eventName, handler) {
this.eventHandlers[eventName] = this.eventHandlers[eventName] ?? [];
this.eventHandlers[eventName].push(handler);
return this;
}
async exportTextures(settings) {
let files = {};
const handlers = Object.values(this.eventHandlers).flat(1).filter(isUsesTextures);
for (const handler of handlers) {
files = {
...files,
...(await handler.exportTextures(settings)),
};
}
return files;
}
makeIntoRoot() {
this.isRoot = true;
return this;
}
prependRaw(handler) {
this.on('::before', handler);
}
appendRaw(handler) {
this.on('::after', handler);
}
static handlerToString(handler) {
const isHandlerNotAFunction = typeof handler === 'string' || handler instanceof ScriptCommand || Array.isArray(handler);
const tmp = isHandlerNotAFunction ? handler : handler();
const tmp2 = (Array.isArray(tmp) ? tmp : [tmp]);
let result = '';
for (const h of tmp2) {
const handlerResult = h instanceof ScriptCommand ? h.toString() : h;
const handlerResults = (Array.isArray(handlerResult) ? handlerResult : [handlerResult]);
result += handlerResults.filter((r) => r.trim() !== '').join('\n') + '\n';
}
return result;
}
whenRoot() {
const preparedObject = {
on: (eventName, handler) => {
this.on(eventName, () => {
if (!this.isRoot) {
return '';
}
return Script.handlerToString(handler);
});
return preparedObject;
},
prependRaw: (handler) => {
this.prependRaw(() => {
if (!this.isRoot) {
return '';
}
return Script.handlerToString(handler);
});
return preparedObject;
},
appendRaw: (handler) => {
this.appendRaw(() => {
if (!this.isRoot) {
return '';
}
return Script.handlerToString(handler);
});
return preparedObject;
},
};
return preparedObject;
}
}
//# sourceMappingURL=Script.js.map