diff --git a/js/editor/dialogs.js b/js/editor/dialogs.js index 336eaae..8449dd6 100644 --- a/js/editor/dialogs.js +++ b/js/editor/dialogs.js @@ -14,8 +14,13 @@ export class EditorPackMetaOverlay extends DialogOverlay { dl.append( mk('dt', "Title"), mk('dd', mk('input', {name: 'title', type: 'text', value: stored_pack.title})), + mk('dt', "Author"), + mk('dd', mk('input', {name: 'author', type: 'text', value: stored_pack.metadata.by ?? ""})), + mk('dt', "Description"), + mk('dd.-textarea', mk('textarea', {name: 'description'}, stored_pack.metadata.description ?? "")), + mk('dt', "Difficulty"), + mk('dd', mk('input', {name: 'difficulty', type: 'number', min: 1, max: 5, step: 0.5, value: stored_pack.metadata.difficulty ?? 3}), " (between 1 and 5)"), ); - // TODO...? what else is a property of the pack itself this.add_button("save", () => { let els = this.root.elements; @@ -25,6 +30,9 @@ export class EditorPackMetaOverlay extends DialogOverlay { stored_pack.title = title; this.conductor.update_level_title(); } + stored_pack.metadata.by = els.author.value || undefined; + stored_pack.metadata.description = els.description.value || undefined; + stored_pack.metadata.difficulty = parseFloat(els.difficulty.value); this.close(); }); diff --git a/js/editor/main.js b/js/editor/main.js index 5ece19b..b04d135 100644 --- a/js/editor/main.js +++ b/js/editor/main.js @@ -500,6 +500,9 @@ export class Editor extends PrimaryView { let lines = []; let safe_title = (stored_pack.title || "untitled").replace(/[""]/g, "'").replace(/[\x00-\x1f]+/g, "_"); lines.push(`game "${safe_title}"`); + for (let [key, value] of Object.entries(stored_pack.metadata)) { + lines.push(`; meta ${key}: ${value}`); + } let files = {}; let count = stored_pack.level_metadata.length; @@ -732,6 +735,7 @@ export class Editor extends PrimaryView { let pack_key = stored_pack.editor_metadata.key; this.stash.packs[pack_key] = { title: stored_pack.title, + metadata: stored_pack.metadata, level_count: stored_pack.level_metadata.length, last_modified: Date.now(), }; @@ -815,6 +819,7 @@ export class Editor extends PrimaryView { }); // TODO should this also be in the pack's stash...? stored_pack.title = this.stash.packs[pack_key].title; + stored_pack.metadata = this.stash.packs[pack_key].metadata ?? {}; stored_pack.editor_metadata = { key: pack_key, }; diff --git a/js/format-base.js b/js/format-base.js index a7a91d5..dc76d6a 100644 --- a/js/format-base.js +++ b/js/format-base.js @@ -174,6 +174,7 @@ export class StoredPack { // This isn't very strongly defined, but it's used to distinguish scores for packs and URLs this.identifier = identifier; this.title = ""; + this.metadata = {}; this._level_loader = level_loader; // Simple objects containing keys that are usually: diff --git a/js/format-c2g.js b/js/format-c2g.js index fea227d..5bad29d 100644 --- a/js/format-c2g.js +++ b/js/format-c2g.js @@ -2117,6 +2117,18 @@ class Parser { } } + +function parse_pack_metadata(string) { + let metadata = {}; + for (let match of string.matchAll(/; meta (.+?): (.+)/g)) { + metadata[match[1]] = match[2]; + } + if (metadata.difficulty) { + metadata.difficulty = parseFloat(metadata.difficulty); + } + return metadata; +} + // C2G is a Chip's Challenge 2 format that describes the structure of a level set, which is helpful // since CC2 levels are all stored in separate files // XXX observations i have made about this hell format: @@ -2180,6 +2192,7 @@ const MAX_SIMULTANEOUS_REQUESTS = 5; // FIXME and right off the bat we have an Issue: this is a text format so i want a string, not // an arraybuffer! let contents = util.string_from_buffer_ascii(buf); + game.metadata = parse_pack_metadata(contents); parser = new Parser(contents); let statements = []; let level_number = 1;