Remember last opened level in editor; prevent deleting the current level
This commit is contained in:
parent
ac9b702eaa
commit
b9037c1ce1
@ -183,22 +183,31 @@ export class DialogOverlay extends Overlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Informational popup dialog
|
||||||
|
export class AlertOverlay extends DialogOverlay {
|
||||||
|
constructor(conductor, message, title = "heads up") {
|
||||||
|
super(conductor);
|
||||||
|
this.set_title(title);
|
||||||
|
this.main.append(mk('p', {}, message));
|
||||||
|
this.add_button("a'ight", ev => {
|
||||||
|
this.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Yes/no popup dialog
|
// Yes/no popup dialog
|
||||||
export class ConfirmOverlay extends DialogOverlay {
|
export class ConfirmOverlay extends DialogOverlay {
|
||||||
constructor(conductor, message, what) {
|
constructor(conductor, message, what) {
|
||||||
super(conductor);
|
super(conductor);
|
||||||
this.set_title("just checking");
|
this.set_title("just checking");
|
||||||
this.main.append(mk('p', {}, message));
|
this.main.append(mk('p', {}, message));
|
||||||
let yes = mk('button', {type: 'button'}, "yep");
|
this.add_button("yep", ev => {
|
||||||
let no = mk('button', {type: 'button'}, "nope");
|
|
||||||
yes.addEventListener('click', ev => {
|
|
||||||
this.close();
|
this.close();
|
||||||
what();
|
what();
|
||||||
});
|
});
|
||||||
no.addEventListener('click', ev => {
|
this.add_button("nope", ev => {
|
||||||
this.close();
|
this.close();
|
||||||
});
|
});
|
||||||
this.footer.append(yes, no);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { DIRECTIONS, LAYERS, TICS_PER_SECOND } from './defs.js';
|
|||||||
import { TILES_WITH_PROPS } from './editor-tile-overlays.js';
|
import { TILES_WITH_PROPS } from './editor-tile-overlays.js';
|
||||||
import * as format_base from './format-base.js';
|
import * as format_base from './format-base.js';
|
||||||
import * as c2g from './format-c2g.js';
|
import * as c2g from './format-c2g.js';
|
||||||
import { PrimaryView, TransientOverlay, DialogOverlay, flash_button, load_json_from_storage, save_json_to_storage } from './main-base.js';
|
import { PrimaryView, TransientOverlay, DialogOverlay, AlertOverlay, flash_button, load_json_from_storage, save_json_to_storage } from './main-base.js';
|
||||||
import CanvasRenderer from './renderer-canvas.js';
|
import CanvasRenderer from './renderer-canvas.js';
|
||||||
import TILE_TYPES from './tiletypes.js';
|
import TILE_TYPES from './tiletypes.js';
|
||||||
import { SVG_NS, mk, mk_button, mk_svg, string_from_buffer_ascii, bytestring_to_buffer, walk_grid } from './util.js';
|
import { SVG_NS, mk, mk_button, mk_svg, string_from_buffer_ascii, bytestring_to_buffer, walk_grid } from './util.js';
|
||||||
@ -285,7 +285,7 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
this.add_button("create", ev => {
|
this.add_button("create", ev => {
|
||||||
let index = this.selection + 1;
|
let index = this.selection + 1;
|
||||||
let stored_level = this.conductor.editor._make_empty_level(index + 1, 32, 32);
|
let stored_level = this.conductor.editor._make_empty_level(index + 1, 32, 32);
|
||||||
this.conductor.editor.insert_level(stored_level, index);
|
this.conductor.editor.move_level(stored_level, index);
|
||||||
this._after_insert_level(stored_level, index);
|
this._after_insert_level(stored_level, index);
|
||||||
|
|
||||||
this.undo_stack.push(() => {
|
this.undo_stack.push(() => {
|
||||||
@ -303,10 +303,10 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
});
|
});
|
||||||
this.undo_button.disabled = false;
|
this.undo_button.disabled = false;
|
||||||
});
|
});
|
||||||
this.add_button("delete", ev => {
|
this.delete_button = this.add_button("delete", ev => {
|
||||||
let index = this.selection;
|
let index = this.selection;
|
||||||
if (index === this.conductor.level_index) {
|
if (index === this.conductor.level_index) {
|
||||||
// FIXME complain, or disable button
|
new AlertOverlay(this.conductor, "You can't delete the level you have open.").open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
this.undo_stack.push(() => {
|
this.undo_stack.push(() => {
|
||||||
let stored_level = meta.stored_level ?? c2g.parse_level(
|
let stored_level = meta.stored_level ?? c2g.parse_level(
|
||||||
bytestring_to_buffer(serialized_level), index + 1);
|
bytestring_to_buffer(serialized_level), index + 1);
|
||||||
this.conductor.editor.insert_level(stored_level, index);
|
this.conductor.editor.move_level(stored_level, index);
|
||||||
if (this.selection >= index) {
|
if (this.selection >= index) {
|
||||||
this.selection += 1;
|
this.selection += 1;
|
||||||
}
|
}
|
||||||
@ -328,6 +328,7 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
});
|
});
|
||||||
this.undo_button.disabled = false;
|
this.undo_button.disabled = false;
|
||||||
});
|
});
|
||||||
|
this._update_delete_button();
|
||||||
|
|
||||||
// Right buttons
|
// Right buttons
|
||||||
this.add_button_gap();
|
this.add_button_gap();
|
||||||
@ -381,6 +382,11 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
this.list.childNodes[this.selection].classList.remove('--selected');
|
this.list.childNodes[this.selection].classList.remove('--selected');
|
||||||
this.selection = index;
|
this.selection = index;
|
||||||
this.list.childNodes[this.selection].classList.add('--selected');
|
this.list.childNodes[this.selection].classList.add('--selected');
|
||||||
|
this._update_delete_button();
|
||||||
|
}
|
||||||
|
|
||||||
|
_update_delete_button() {
|
||||||
|
this.delete_button.disabled = !! (this.selection === this.conductor.level_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_level_render() {
|
schedule_level_render() {
|
||||||
@ -421,7 +427,7 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
|
|
||||||
_delete_level(index) {
|
_delete_level(index) {
|
||||||
let num_levels = this.conductor.stored_game.level_metadata.length;
|
let num_levels = this.conductor.stored_game.level_metadata.length;
|
||||||
let stored_level = this.conductor.editor.delete_level(index);
|
let stored_level = this.conductor.editor.move_level(index, null);
|
||||||
|
|
||||||
this.list.childNodes[this.selection].classList.remove('--selected');
|
this.list.childNodes[this.selection].classList.remove('--selected');
|
||||||
this.list.childNodes[index].remove();
|
this.list.childNodes[index].remove();
|
||||||
@ -457,6 +463,7 @@ class EditorLevelBrowserOverlay extends DialogOverlay {
|
|||||||
else {
|
else {
|
||||||
this.selection = selection;
|
this.selection = selection;
|
||||||
}
|
}
|
||||||
|
this._update_delete_button();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2983,7 +2990,7 @@ export class Editor extends PrimaryView {
|
|||||||
return stored_level;
|
return stored_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
_save_pack_to_stash(stored_pack, current_level) {
|
_save_pack_to_stash(stored_pack) {
|
||||||
if (! stored_pack.editor_metadata) {
|
if (! stored_pack.editor_metadata) {
|
||||||
console.error("Asked to save a stored pack that's not part of the editor", stored_pack);
|
console.error("Asked to save a stored pack that's not part of the editor", stored_pack);
|
||||||
return;
|
return;
|
||||||
@ -2997,9 +3004,7 @@ export class Editor extends PrimaryView {
|
|||||||
this.stash.packs[pack_key] = {
|
this.stash.packs[pack_key] = {
|
||||||
title: stored_pack.title,
|
title: stored_pack.title,
|
||||||
level_count: stored_pack.level_metadata.length,
|
level_count: stored_pack.level_metadata.length,
|
||||||
// FIXME i want to update current_level on browse but don't want to affect last_modified
|
|
||||||
last_modified: Date.now(),
|
last_modified: Date.now(),
|
||||||
current_level: current_level,
|
|
||||||
};
|
};
|
||||||
save_json_to_storage("Lexy's Labyrinth editor", this.stash);
|
save_json_to_storage("Lexy's Labyrinth editor", this.stash);
|
||||||
}
|
}
|
||||||
@ -3052,7 +3057,7 @@ export class Editor extends PrimaryView {
|
|||||||
});
|
});
|
||||||
this.conductor.load_game(stored_pack);
|
this.conductor.load_game(stored_pack);
|
||||||
|
|
||||||
this._save_pack_to_stash(stored_pack, 0);
|
this._save_pack_to_stash(stored_pack);
|
||||||
|
|
||||||
save_json_to_storage(pack_key, {
|
save_json_to_storage(pack_key, {
|
||||||
levels: [{
|
levels: [{
|
||||||
@ -3060,6 +3065,7 @@ export class Editor extends PrimaryView {
|
|||||||
title: stored_level.title,
|
title: stored_level.title,
|
||||||
last_modified: Date.now(),
|
last_modified: Date.now(),
|
||||||
}],
|
}],
|
||||||
|
current_level_index: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
this._save_level_to_storage(stored_level);
|
this._save_level_to_storage(stored_level);
|
||||||
@ -3092,7 +3098,7 @@ export class Editor extends PrimaryView {
|
|||||||
number: i + 1,
|
number: i + 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.conductor.load_game(stored_pack);
|
this.conductor.load_game(stored_pack, null, pack_stash.current_level_index);
|
||||||
|
|
||||||
this.conductor.switch_to_editor();
|
this.conductor.switch_to_editor();
|
||||||
}
|
}
|
||||||
@ -3101,7 +3107,7 @@ export class Editor extends PrimaryView {
|
|||||||
// source is a number, it's an index; otherwise, it's a level, assumed to be newly-created, and
|
// source is a number, it's an index; otherwise, it's a level, assumed to be newly-created, and
|
||||||
// will be given a new key and saved to localStorage. (Passing null and a level will,
|
// will be given a new key and saved to localStorage. (Passing null and a level will,
|
||||||
// of course, do nothing. Passing an out of bounds source index will also do nothing.)
|
// of course, do nothing. Passing an out of bounds source index will also do nothing.)
|
||||||
_move_level(source, dest_index) {
|
move_level(source, dest_index) {
|
||||||
let stored_pack = this.conductor.stored_game;
|
let stored_pack = this.conductor.stored_game;
|
||||||
if (! stored_pack.editor_metadata) {
|
if (! stored_pack.editor_metadata) {
|
||||||
return;
|
return;
|
||||||
@ -3171,8 +3177,6 @@ export class Editor extends PrimaryView {
|
|||||||
stored_pack.level_metadata.splice(dest_index, 0, level_metadata);
|
stored_pack.level_metadata.splice(dest_index, 0, level_metadata);
|
||||||
pack_stash.levels.splice(dest_index, 0, pack_stash_entry);
|
pack_stash.levels.splice(dest_index, 0, pack_stash_entry);
|
||||||
}
|
}
|
||||||
// This is done with now; the pack stash has no numbering
|
|
||||||
save_json_to_storage(stored_pack.editor_metadata.key, pack_stash);
|
|
||||||
|
|
||||||
// Renumber levels as necessary
|
// Renumber levels as necessary
|
||||||
let delta, start_index, end_index;
|
let delta, start_index, end_index;
|
||||||
@ -3216,7 +3220,10 @@ export class Editor extends PrimaryView {
|
|||||||
// FIXME refuse to delete the current level
|
// FIXME refuse to delete the current level
|
||||||
this.conductor.level_index = dest_index;
|
this.conductor.level_index = dest_index;
|
||||||
}
|
}
|
||||||
else if (start_index <= this.conductor.level_index && this.conductor.level_index <= end_index) {
|
else if (
|
||||||
|
this.conductor.level_index === dest_index ||
|
||||||
|
(start_index <= this.conductor.level_index && this.conductor.level_index <= end_index))
|
||||||
|
{
|
||||||
this.conductor.level_index += delta;
|
this.conductor.level_index += delta;
|
||||||
// Update the current level if it's not stored in the metadata yet
|
// Update the current level if it's not stored in the metadata yet
|
||||||
if (! stored_level) {
|
if (! stored_level) {
|
||||||
@ -3229,20 +3236,14 @@ export class Editor extends PrimaryView {
|
|||||||
this.conductor.update_level_title();
|
this.conductor.update_level_title();
|
||||||
this.conductor.update_nav_buttons();
|
this.conductor.update_nav_buttons();
|
||||||
|
|
||||||
// Save the pack to the editor stash, and we should be done!
|
// Save the pack stash and editor stash, and we should be done!
|
||||||
this._save_pack_to_stash(stored_pack, this.conductor.level_index);
|
pack_stash.current_level_index = this.conductor.level_index;
|
||||||
|
save_json_to_storage(stored_pack.editor_metadata.key, pack_stash);
|
||||||
|
this._save_pack_to_stash(stored_pack);
|
||||||
|
|
||||||
return stored_level;
|
return stored_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_level(stored_level, index) {
|
|
||||||
return this._move_level(stored_level, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
move_level(from_index, to_index) {
|
|
||||||
return this._move_level(from_index, to_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
duplicate_level(index) {
|
duplicate_level(index) {
|
||||||
// The most reliable way to clone a level is to reserialize its current state
|
// The most reliable way to clone a level is to reserialize its current state
|
||||||
// TODO with autosave this shouldn't be necessary, just copy the existing serialization
|
// TODO with autosave this shouldn't be necessary, just copy the existing serialization
|
||||||
@ -3250,10 +3251,6 @@ export class Editor extends PrimaryView {
|
|||||||
return this._move_level(stored_level, index + 1);
|
return this._move_level(stored_level, index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_level(index) {
|
|
||||||
return this._move_level(index, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
save_level() {
|
save_level() {
|
||||||
// TODO need feedback. or maybe not bc this should be replaced with autosave later
|
// TODO need feedback. or maybe not bc this should be replaced with autosave later
|
||||||
// TODO also need to update the pack data's last modified time
|
// TODO also need to update the pack data's last modified time
|
||||||
@ -3275,7 +3272,7 @@ export class Editor extends PrimaryView {
|
|||||||
// out of sync
|
// out of sync
|
||||||
this._save_level_to_storage(this.stored_level);
|
this._save_level_to_storage(this.stored_level);
|
||||||
save_json_to_storage(pack_key, pack_stash);
|
save_json_to_storage(pack_key, pack_stash);
|
||||||
this._save_pack_to_stash(stored_pack, this.conductor.level_index);
|
this._save_pack_to_stash(stored_pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Level loading
|
// Level loading
|
||||||
@ -3289,6 +3286,14 @@ export class Editor extends PrimaryView {
|
|||||||
this.update_viewport_size();
|
this.update_viewport_size();
|
||||||
this.update_cell_coordinates();
|
this.update_cell_coordinates();
|
||||||
|
|
||||||
|
// Remember current level for an editor level
|
||||||
|
if (this.conductor.stored_game.editor_metadata) {
|
||||||
|
let pack_key = this.conductor.stored_game.editor_metadata.key;
|
||||||
|
let pack_stash = load_json_from_storage(pack_key);
|
||||||
|
pack_stash.current_level_index = this.conductor.level_index;
|
||||||
|
save_json_to_storage(pack_key, pack_stash);
|
||||||
|
}
|
||||||
|
|
||||||
// Load connections
|
// Load connections
|
||||||
this.connections_g.textContent = '';
|
this.connections_g.textContent = '';
|
||||||
for (let [src, dest] of Object.entries(this.stored_level.custom_trap_wiring)) {
|
for (let [src, dest] of Object.entries(this.stored_level.custom_trap_wiring)) {
|
||||||
|
|||||||
@ -3668,7 +3668,7 @@ class Conductor {
|
|||||||
return this.tilesets['ll'];
|
return this.tilesets['ll'];
|
||||||
}
|
}
|
||||||
|
|
||||||
load_game(stored_game, identifier = null) {
|
load_game(stored_game, identifier = null, level_index = null) {
|
||||||
this.stored_game = stored_game;
|
this.stored_game = stored_game;
|
||||||
this._pack_test_dialog = null;
|
this._pack_test_dialog = null;
|
||||||
|
|
||||||
@ -3742,7 +3742,7 @@ class Conductor {
|
|||||||
this.player.load_game(stored_game);
|
this.player.load_game(stored_game);
|
||||||
this.editor.load_game(stored_game);
|
this.editor.load_game(stored_game);
|
||||||
|
|
||||||
return this.change_level((this.current_pack_savefile.current_level ?? 1) - 1);
|
return this.change_level(level_index ?? (this.current_pack_savefile.current_level ?? 1) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
change_level(level_index) {
|
change_level(level_index) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user