Undo inventory changes with tile props

This removes almost all of the remaining undo closures.
This commit is contained in:
Eevee (Evelyn Woods) 2024-05-06 12:57:58 -06:00
parent 20b19c53ff
commit b891d6f38c

View File

@ -273,6 +273,15 @@ class UndoEntry {
this.actor_splices = []; this.actor_splices = [];
this.toggle_green_tiles = false; this.toggle_green_tiles = false;
} }
tile_changes_for(tile) {
let changes = this.tile_changes.get(tile);
if (! changes) {
changes = {};
this.tile_changes.set(tile, changes);
}
return changes;
}
} }
@ -2238,8 +2247,8 @@ export class Level extends LevelInterface {
// Cycle leftwards, i.e., the oldest item moves to the end of the list // Cycle leftwards, i.e., the oldest item moves to the end of the list
if (actor.toolbelt && actor.toolbelt.length > 1) { if (actor.toolbelt && actor.toolbelt.length > 1) {
this._stash_toolbelt(actor);
actor.toolbelt.push(actor.toolbelt.shift()); actor.toolbelt.push(actor.toolbelt.shift());
this._push_pending_undo(() => actor.toolbelt.unshift(actor.toolbelt.pop()));
} }
} }
@ -2254,8 +2263,8 @@ export class Level extends LevelInterface {
// Drop the oldest item, i.e. the first one // Drop the oldest item, i.e. the first one
let name = actor.toolbelt[0]; let name = actor.toolbelt[0];
if (this._place_dropped_item(name, actor.cell, actor)) { if (this._place_dropped_item(name, actor.cell, actor)) {
this._stash_toolbelt(actor);
actor.toolbelt.shift(); actor.toolbelt.shift();
this._push_pending_undo(() => actor.toolbelt.unshift(name));
return true; return true;
} }
return false; return false;
@ -2610,11 +2619,7 @@ export class Level extends LevelInterface {
if (tile[key] === val) if (tile[key] === val)
return; return;
let changes = this.pending_undo.tile_changes.get(tile); let changes = this.pending_undo.tile_changes_for(tile);
if (! changes) {
changes = {};
this.pending_undo.tile_changes.set(tile, changes);
}
// If we haven't yet done so, log the original value // If we haven't yet done so, log the original value
if (! Object.hasOwn(changes, key)) { if (! Object.hasOwn(changes, key)) {
@ -2629,6 +2634,26 @@ export class Level extends LevelInterface {
tile[key] = val; tile[key] = val;
} }
_stash_toolbelt(actor) {
if (! this.undo_enabled)
return;
let changes = this.pending_undo.tile_changes_for(actor);
if (! ('toolbelt' in changes)) {
changes.toolbelt = Array.from(actor.toolbelt);
}
}
_stash_keyring(actor) {
if (! this.undo_enabled)
return;
let changes = this.pending_undo.tile_changes_for(actor);
if (! ('keyring' in changes)) {
changes.keyring = {...actor.keyring};
}
}
collect_chip(actor) { collect_chip(actor) {
if (this.chips_remaining > 0) { if (this.chips_remaining > 0) {
if (this.chips_remaining > 1) { if (this.chips_remaining > 1) {
@ -2969,8 +2994,8 @@ export class Level extends LevelInterface {
} }
// Otherwise, it's either an item or a yellow teleporter we're allowed to drop, so steal // Otherwise, it's either an item or a yellow teleporter we're allowed to drop, so steal
// it out of their inventory to be dropped later // it out of their inventory to be dropped later
this._stash_toolbelt(actor);
dropped_item = actor.toolbelt.shift(); dropped_item = actor.toolbelt.shift();
this._push_pending_undo(() => actor.toolbelt.unshift(dropped_item));
} }
if (this.give_actor(actor, tile.type.name)) { if (this.give_actor(actor, tile.type.name)) {
@ -3007,8 +3032,8 @@ export class Level extends LevelInterface {
if (! actor.keyring) { if (! actor.keyring) {
actor.keyring = {}; actor.keyring = {};
} }
this._stash_keyring(actor);
actor.keyring[name] = (actor.keyring[name] ?? 0) + 1; actor.keyring[name] = (actor.keyring[name] ?? 0) + 1;
this._push_pending_undo(() => actor.keyring[name] -= 1);
} }
else { else {
// tool, presumably // tool, presumably
@ -3023,9 +3048,7 @@ export class Level extends LevelInterface {
if (i < 0) if (i < 0)
return false; return false;
if (! actor.toolbelt[i]) { this._stash_toolbelt(actor);
this._push_pending_undo(() => actor.toolbelt[i] = null);
}
actor.toolbelt[i] = name; actor.toolbelt[i] = name;
} }
else { else {
@ -3038,8 +3061,8 @@ export class Level extends LevelInterface {
return false; return false;
} }
this._stash_toolbelt(actor);
actor.toolbelt.push(name); actor.toolbelt.push(name);
this._push_pending_undo(() => actor.toolbelt.pop());
} }
} }
return true; return true;
@ -3052,7 +3075,7 @@ export class Level extends LevelInterface {
return true; return true;
} }
this._push_pending_undo(() => actor.keyring[name] += 1); this._stash_keyring(actor);
actor.keyring[name] -= 1; actor.keyring[name] -= 1;
return true; return true;
} }
@ -3065,8 +3088,8 @@ export class Level extends LevelInterface {
if (actor.toolbelt) { if (actor.toolbelt) {
let index = actor.toolbelt.indexOf(name); let index = actor.toolbelt.indexOf(name);
if (index >= 0) { if (index >= 0) {
this._stash_toolbelt(actor);
actor.toolbelt.splice(index, 1); actor.toolbelt.splice(index, 1);
this._push_pending_undo(() => actor.toolbelt.splice(index, 0, name));
return true; return true;
} }
} }
@ -3076,8 +3099,7 @@ export class Level extends LevelInterface {
take_all_keys_from_actor(actor) { take_all_keys_from_actor(actor) {
if (actor.keyring && Object.values(actor.keyring).some(n => n > 0)) { if (actor.keyring && Object.values(actor.keyring).some(n => n > 0)) {
let keyring = actor.keyring; this._stash_keyring(actor);
this._push_pending_undo(() => actor.keyring = keyring);
actor.keyring = {}; actor.keyring = {};
return true; return true;
} }
@ -3085,8 +3107,7 @@ export class Level extends LevelInterface {
take_all_tools_from_actor(actor) { take_all_tools_from_actor(actor) {
if (actor.toolbelt && actor.toolbelt.length > 0) { if (actor.toolbelt && actor.toolbelt.length > 0) {
let toolbelt = actor.toolbelt; this._stash_toolbelt(actor);
this._push_pending_undo(() => actor.toolbelt = toolbelt);
actor.toolbelt = []; actor.toolbelt = [];
return true; return true;
} }