From 7d36d097157f547e7b3290fea031bcf646946346 Mon Sep 17 00:00:00 2001 From: Timothy Stiles Date: Sun, 14 Feb 2021 21:47:04 +1100 Subject: [PATCH] terraforming a new button/buttonable now connects it --- js/game.js | 157 ++++++++++++++++++++++++++++++------------------ js/tiletypes.js | 4 ++ 2 files changed, 103 insertions(+), 58 deletions(-) diff --git a/js/game.js b/js/game.js index 5e24e15..878f981 100644 --- a/js/game.js +++ b/js/game.js @@ -526,62 +526,7 @@ export class Level extends LevelInterface { // Connect buttons and teleporters let num_cells = this.width * this.height; for (let connectable of connectables) { - let cell = connectable.cell; - let x = cell.x; - let y = cell.y; - // FIXME this is a single string for red/brown buttons (to match iter_tiles_in_RO) but a - // set for orange buttons (because flame jet states are separate tiles), which sucks ass - let goals = connectable.type.connects_to; - - // Check for custom wiring, for MSCC .DAT levels - // TODO would be neat if this applied to orange buttons too - if (this.stored_level.has_custom_connections) { - let n = this.stored_level.coords_to_scalar(x, y); - let target_cell_n = null; - if (connectable.type.name === 'button_brown') { - target_cell_n = this.stored_level.custom_trap_wiring[n] ?? null; - } - else if (connectable.type.name === 'button_red') { - target_cell_n = this.stored_level.custom_cloner_wiring[n] ?? null; - } - if (target_cell_n && target_cell_n < this.width * this.height) { - let [tx, ty] = this.stored_level.scalar_to_coords(target_cell_n); - for (let tile of this.cell(tx, ty)) { - if (tile && goals === tile.type.name) { - connectable.connection = tile; - break; - } - } - } - continue; - } - - // Orange buttons do a really weird diamond search - if (connectable.type.connect_order === 'diamond') { - for (let cell of this.iter_cells_in_diamond(connectable.cell)) { - let target = null; - for (let tile of cell) { - if (tile && goals.has(tile.type.name)) { - target = tile; - break; - } - } - if (target !== null) { - connectable.connection = target; - break; - } - } - continue; - } - - // Otherwise, look in reading order - for (let tile of this.iter_tiles_in_reading_order(cell, goals)) { - // TODO ideally this should be a weak connection somehow, since dynamite can destroy - // empty cloners and probably traps too - connectable.connection = tile; - // Just grab the first - break; - } + this.connect_button(connectable); } // Build circuits out of connected wires @@ -716,6 +661,92 @@ export class Level extends LevelInterface { // Erase undo, in case any on_ready added to it (we don't want to undo initialization!) this.pending_undo = this.create_undo_entry(); } + + connect_button(connectable) { + let cell = connectable.cell; + let x = cell.x; + let y = cell.y; + // FIXME this is a single string for red/brown buttons (to match iter_tiles_in_RO) but a + // set for orange buttons (because flame jet states are separate tiles), which sucks ass + let goals = connectable.type.connects_to; + + // Check for custom wiring, for MSCC .DAT levels + // TODO would be neat if this applied to orange buttons too + if (this.stored_level.has_custom_connections) { + let n = this.stored_level.coords_to_scalar(x, y); + let target_cell_n = null; + if (connectable.type.name === 'button_brown') { + target_cell_n = this.stored_level.custom_trap_wiring[n] ?? null; + } + else if (connectable.type.name === 'button_red') { + target_cell_n = this.stored_level.custom_cloner_wiring[n] ?? null; + } + if (target_cell_n && target_cell_n < this.width * this.height) { + let [tx, ty] = this.stored_level.scalar_to_coords(target_cell_n); + for (let tile of this.cell(tx, ty)) { + if (tile && goals === tile.type.name) { + connectable.connection = tile; + break; + } + } + } + return; + } + + // Orange buttons do a really weird diamond search + if (connectable.type.connect_order === 'diamond') { + for (let cell of this.iter_cells_in_diamond(connectable.cell)) { + let target = null; + for (let tile of cell) { + if (tile && goals.has(tile.type.name)) { + target = tile; + break; + } + } + if (target !== null) { + connectable.connection = target; + break; + } + } + return; + } + + // Otherwise, look in reading order + for (let tile of this.iter_tiles_in_reading_order(cell, goals)) { + // TODO ideally this should be a weak connection somehow, since dynamite can destroy + // empty cloners and probably traps too + connectable.connection = tile; + // Just grab the first + break; + } + } + + connect_buttons_to(tile) { + //iterate all terrain in the level for things that can connect to this + //if they didn't before and now do, commit and make an undo for it. + //otherwise, change it back (so we don't accidentally rewire other things) + for (var i = 0; i < this.width; ++i) + { + for (var j = 0; j < this.height; ++j) + { + let terrain = this.cell(i, j).get_terrain(); + if (terrain.type.name === tile.type.connected_from) + { + let old_connection = terrain.connection; + this.connect_button(terrain); + if (terrain.connection === tile) + { + terrain.connection = old_connection; + this._set_tile_prop(terrain, 'connection', tile); + } + else + { + terrain.connection = old_connection; + } + } + } + } + } can_accept_input() { // We can accept input anytime the player can move, i.e. when they're not already moving and @@ -2478,9 +2509,19 @@ export class Level extends LevelInterface { //add to end of array this.static_on_tic_tiles.push(tile); } + + //if we made a button or something that's buttonable, update accordingly + if (new_type.connects_to) + { + this.connect_button(tile); + } + else if (new_type.connected_from) + { + this.connect_buttons_to(tile); + } + + //TODO: update circuit networks? } - - //TODO: update circuit networks? } // Have an actor try to pick up a particular tile; it's prevented if there's a no sign, and the diff --git a/js/tiletypes.js b/js/tiletypes.js index d502451..cecad9f 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -1376,6 +1376,7 @@ const TILE_TYPES = { cloner: { layer: LAYERS.terrain, blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid, + connected_from: 'button_red', traps(me, actor) { return ! actor._clone_release; }, @@ -1428,6 +1429,7 @@ const TILE_TYPES = { }, trap: { layer: LAYERS.terrain, + connected_from: 'button_brown', add_press_ready(me, level, other) { // Same as below, but without ejection me.presses = (me.presses ?? 0) + 1; @@ -1721,6 +1723,7 @@ const TILE_TYPES = { // - Gray button toggles it permanently flame_jet_off: { layer: LAYERS.terrain, + connected_from: 'button_orange', activate(me, level) { level.transmute_tile(me, 'flame_jet_on'); // Do NOT immediately nuke anything on us, or it'd be impossible to push a block off an @@ -1738,6 +1741,7 @@ const TILE_TYPES = { }, flame_jet_on: { layer: LAYERS.terrain, + connected_from: 'button_orange', activate(me, level) { level.transmute_tile(me, 'flame_jet_off'); },