Copy a level's title to the right places in the editor so it shows in the level browser

This commit is contained in:
Eevee (Evelyn Woods) 2021-01-01 12:44:20 -07:00
parent 4454970564
commit c8686f9d66
3 changed files with 81 additions and 32 deletions

View File

@ -162,6 +162,7 @@ class EditorLevelMetaOverlay extends DialogOverlay {
let title = els.title.value;
if (title !== stored_level.title) {
stored_level.title = title;
this.conductor.stored_game.level_metadata[this.conductor.level_index].title = title;
this.conductor.update_level_title();
}
let author = els.author.value;
@ -2543,34 +2544,7 @@ export class Editor extends PrimaryView {
new EditorLevelMetaOverlay(this.conductor, this.stored_level).open();
});
this.save_button = _make_button("Save", ev => {
// 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
let stored_game = this.conductor.stored_game;
if (! stored_game.editor_metadata)
return;
// Update the pack index; we need to do this to update the last modified time anyway, so
// there's no point in checking whether anything actually changed
let pack_key = stored_game.editor_metadata.key;
this.stash.packs[pack_key].title = stored_game.title;
this.stash.packs[pack_key].last_modified = Date.now();
// Update the pack itself
// TODO maybe should keep this around, but there's a tricky order of operations thing
// with it
let pack_stash = load_json_from_storage(pack_key);
pack_stash.title = stored_game.title;
pack_stash.last_modified = Date.now();
// Serialize the level itself
let buf = c2g.synthesize_level(this.stored_level);
let stringy_buf = string_from_buffer_ascii(buf);
// Save everything at once, level first, to minimize chances of an error getting things
// out of sync
window.localStorage.setItem(this.stored_level.editor_metadata.key, stringy_buf);
save_json_to_storage(pack_key, pack_stash);
save_json_to_storage("Lexy's Labyrinth editor", this.stash);
this.save_level();
});
if (this.stored_level) {
this.save_button.disabled = ! this.conductor.stored_game.editor_metadata;
@ -2672,6 +2646,8 @@ export class Editor extends PrimaryView {
this.renderer.draw();
}
// Level creation, management, and saving
_make_cell() {
let cell = new format_base.StoredCell;
cell.push({type: TILE_TYPES['floor']});
@ -2820,6 +2796,39 @@ export class Editor extends PrimaryView {
this.conductor.change_level(index);
}
save_level() {
// 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
let stored_game = this.conductor.stored_game;
if (! stored_game.editor_metadata)
return;
// Update the pack index; we need to do this to update the last modified time anyway, so
// there's no point in checking whether anything actually changed
let pack_key = stored_game.editor_metadata.key;
this.stash.packs[pack_key].title = stored_game.title;
this.stash.packs[pack_key].last_modified = Date.now();
// Update the pack itself
// TODO maybe should keep this around, but there's a tricky order of operations thing
// with it
let pack_stash = load_json_from_storage(pack_key);
pack_stash.title = stored_game.title;
pack_stash.last_modified = Date.now();
pack_stash.levels[this.conductor.level_index].title = this.stored_level.title;
pack_stash.levels[this.conductor.level_index].last_modified = Date.now();
// Serialize the level itself
let buf = c2g.synthesize_level(this.stored_level);
let stringy_buf = string_from_buffer_ascii(buf);
// Save everything at once, level first, to minimize chances of an error getting things
// out of sync
window.localStorage.setItem(this.stored_level.editor_metadata.key, stringy_buf);
save_json_to_storage(pack_key, pack_stash);
save_json_to_storage("Lexy's Labyrinth editor", this.stash);
}
load_game(stored_game) {
}

View File

@ -446,11 +446,37 @@ class Player extends PrimaryView {
return;
}
// Per-tic navigation; only useful if the game isn't running
// FIXME these are funky in turn-based mode still. don't update the debug panel timer,
// and don't show us at the end of the tic
if (ev.key === ',') {
if (this.state === 'stopped' || this.state === 'paused' || this.turn_mode > 0) {
this.undo();
this._redraw();
this.set_state('paused');
}
return;
}
if (ev.key === '.') {
if (this.state === 'waiting' || this.state === 'paused' || this.turn_mode > 0) {
this.advance_by(1, true);
this._redraw();
if (this.state === 'waiting' || this.turn_mode === 1) {
this.set_state('paused');
}
}
return;
}
if (ev.key === ' ') {
if (this.state === 'waiting') {
// Start without moving
this.set_state('playing');
}
else if (this.state === 'paused') {
// Turns out I do this an awful lot expecting it to work, so
this.set_state('playing');
}
else if (this.state === 'stopped') {
if (this.level.state === 'success') {
// Advance to the next level
@ -656,7 +682,7 @@ class Player extends PrimaryView {
}
this.set_state('paused');
this.advance_by(dt);
this.advance_by(dt, true);
}
else if (dt < 0) {
if (this.state === 'waiting') {
@ -1084,7 +1110,7 @@ class Player extends PrimaryView {
return input;
}
advance_by(tics) {
advance_by(tics, force = false) {
for (let i = 0; i < tics; i++) {
// FIXME turn-based mode should be disabled during a replay
let input = this.get_input();
@ -1107,7 +1133,7 @@ class Player extends PrimaryView {
let has_input = wait || input;
// Turn-based mode complicates this slightly; it aligns us to the middle of a tic
if (this.turn_mode === 2) {
if (has_input) {
if (has_input || force) {
// Finish the current tic, then continue as usual. This means the end of the
// tic doesn't count against the number of tics to advance -- because it already
// did, the first time we tried it
@ -1121,7 +1147,7 @@ class Player extends PrimaryView {
// We should now be at the start of a tic
this.level.begin_tic(input);
if (this.turn_mode > 0 && this.level.can_accept_input() && !input) {
if (this.turn_mode > 0 && this.level.can_accept_input() && ! has_input) {
// If we're in turn-based mode and could provide input here, but don't have any,
// then wait until we do
this.turn_mode = 2;
@ -1207,6 +1233,10 @@ class Player extends PrimaryView {
if (this.turn_mode === 2) {
// We're dawdling between tics, so nothing is actually animating, but the clock hasn't
// advanced yet; pretend whatever's currently animating has finished
// FIXME this creates bizarre side effects like actors making a huge first step when
// stepping forwards one tic at a time, but without it you get force floors animating
// and then abruptly reversing in turn-based mode (maybe we should just not interpolate
// at all in that case??)
tic_offset = 0.999;
}
else if (this.use_interpolation) {
@ -1224,6 +1254,7 @@ class Player extends PrimaryView {
// Check for a stopped game *after* drawing, so that if the game ends, we still draw its
// final result before stopping the draw loop
// TODO for bonus points, also finish the player animation (but don't advance the game any further)
// TODO stop redrawing when in turn-based mode 2?
if (this.state === 'playing' || this.state === 'rewinding') {
this._redraw_handle = requestAnimationFrame(this._redraw_bound);
}
@ -1334,6 +1365,11 @@ class Player extends PrimaryView {
}
autopause() {
if (this.turn_mode > 0) {
// Turn-based mode doesn't need this
return;
}
this.set_state('paused');
}

View File

@ -1306,6 +1306,10 @@ export class Tileset {
}
coords = coords[Math.floor(i * coords.length)];
}
else if (tile && tile.type.movement_speed) {
// This is an actor that's not moving, so use the first frame
coords = coords[0];
}
else {
// This tile animates on a global timer, one cycle every quarter of a second
coords = coords[Math.floor(tic / this.animation_slowdown % 5 / 5 * coords.length)];