diff --git a/app/data/ct.release/res.js b/app/data/ct.release/res.js index f00c43f40..eda58c295 100644 --- a/app/data/ct.release/res.js +++ b/app/data/ct.release/res.js @@ -15,6 +15,7 @@ sounds: {}, textures: {}, skeletons: {}, + groups: [/*@groups@*/][0], /** * Loads and executes a script by its URL * @param {string} url The URL of the script file, with its extension. diff --git a/src/node_requires/exporter/groups.ts b/src/node_requires/exporter/groups.ts new file mode 100644 index 000000000..63941761b --- /dev/null +++ b/src/node_requires/exporter/groups.ts @@ -0,0 +1,29 @@ +export const flattenGroups = (project: IProject): Record> => { + const out: Record> = {}; + let thing: keyof typeof project.groups; + for (thing in project.groups) { + out[thing] = { + '-1': 'ungrouped' + }; + for (const group of project.groups[thing]) { + out[thing][group.uid] = group.name; + } + } + return out; +}; +export const getGroups = (project: IProject): Record> => { + const out: Record> = {}; + let thing: keyof typeof project.groups; + const flattened = flattenGroups(project); + for (thing in project.groups) { + out[thing] = {}; + for (const groupId in flattened[thing]) { + out[thing][flattened[thing][groupId]] = []; + } + for (const asset of project[thing]) { + const groupName = asset.group ? flattened[thing][asset.group] : 'ungrouped'; + out[thing][groupName].push(('name' in asset) ? asset.name : asset.typefaceName); + } + } + return out; +}; diff --git a/src/node_requires/exporter/index.ts b/src/node_requires/exporter/index.ts index 56f677c89..1ef5577e9 100644 --- a/src/node_requires/exporter/index.ts +++ b/src/node_requires/exporter/index.ts @@ -18,6 +18,7 @@ const {stringifyContent} = require('./content'); import {bundleFonts, bakeBitmapFonts} from './fonts'; const {bakeFavicons} = require('./icons'); const {getUnwrappedExtends, getCleanKey} = require('./utils'); +import {getGroups} from './groups'; const ifMatcher = (varName: string, symbol = '@') => new RegExp(`/\\* ?if +${symbol}${varName}${symbol} ?\\*/([\\s\\S]*)(?:/\\* ?else +${symbol}${varName}${symbol} ?\\*/([\\s\\S]*?))?/\\* ?endif +${symbol}${varName}${symbol} ?\\*/`, 'g'); const varMatcher = (varName: string, symbol = '@') => new RegExp(`/\\* ?${symbol}${varName}${symbol} ?\\*/`, 'g'); @@ -363,7 +364,8 @@ const exportCtProject = async ( tiledImages, bitmapFonts, dbSkeletons: skeletons.skeletonsDB, - sounds + sounds, + groups: JSON.stringify(getGroups(project)) }, injections); buffer += '\n'; diff --git a/src/node_requires/exporter/rooms.ts b/src/node_requires/exporter/rooms.ts index 28e9f0827..d7719a0d2 100644 --- a/src/node_requires/exporter/rooms.ts +++ b/src/node_requires/exporter/rooms.ts @@ -2,6 +2,7 @@ const glob = require('./../glob'); const {getUnwrappedExtends} = require('./utils'); import {getBaseScripts} from './scriptableProcessor'; import {getTextureFromId} from '../resources/textures'; +import {flattenGroups} from './groups'; const getStartingRoom = (proj: IProject): IRoom => { let [startroom] = proj.rooms; // picks the first room by default @@ -70,6 +71,7 @@ type ExportedBg = { // eslint-disable-next-line max-lines-per-function const stringifyRooms = (proj: IProject): IScriptablesFragment => { + const groups = flattenGroups(proj).rooms; let roomsCode = ''; let rootRoomOnCreate = ''; let rootRoomOnStep = ''; @@ -142,6 +144,7 @@ const stringifyRooms = (proj: IProject): IScriptablesFragment => { roomsCode += ` ct.rooms.templates['${r.name}'] = { name: '${r.name}', + group: '${groups[r.group ? r.group.replace(/'/g, '\\\'') : -1]}', width: ${r.width}, height: ${r.height},` + /* JSON.parse is faster at loading big objects */` diff --git a/src/node_requires/exporter/templates.ts b/src/node_requires/exporter/templates.ts index ad52820be..f99b36d76 100644 --- a/src/node_requires/exporter/templates.ts +++ b/src/node_requires/exporter/templates.ts @@ -1,6 +1,8 @@ const {getTextureFromId} = require('../resources/textures'); const {getUnwrappedExtends} = require('./utils'); +import {flattenGroups} from './groups'; + import {getBaseScripts} from './scriptableProcessor'; interface IBlankTexture { @@ -25,7 +27,7 @@ const getTextureInfo = (blankTextures: IBlankTexture[], template: ITemplate) => }; const stringifyTemplates = function (proj: IProject): IScriptablesFragment { - /* Stringify templates */ + const groups = flattenGroups(proj).templates; let templates = ''; let rootRoomOnCreate = ''; let rootRoomOnStep = ''; @@ -52,6 +54,7 @@ ct.templates.templates["${template.name}"] = { animationFPS: ${template.animationFPS ?? 60}, playAnimationOnStart: ${Boolean(template.playAnimationOnStart)}, loopAnimation: ${Boolean(template.loopAnimation)}, + group: "${groups[template.group ? template.group.replace(/'/g, '\\\'') : -1]}", ${textureInfo} onStep: function () { ${scripts.thisOnStep}