terraforming a new button/buttonable now connects it

This commit is contained in:
Timothy Stiles 2021-02-14 21:47:04 +11:00
parent 11747f0d6e
commit 7d36d09715
2 changed files with 103 additions and 58 deletions

View File

@ -526,62 +526,7 @@ export class Level extends LevelInterface {
// Connect buttons and teleporters // Connect buttons and teleporters
let num_cells = this.width * this.height; let num_cells = this.width * this.height;
for (let connectable of connectables) { for (let connectable of connectables) {
let cell = connectable.cell; this.connect_button(connectable);
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;
}
} }
// Build circuits out of connected wires // Build circuits out of connected wires
@ -717,6 +662,92 @@ export class Level extends LevelInterface {
this.pending_undo = this.create_undo_entry(); 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() { can_accept_input() {
// We can accept input anytime the player can move, i.e. when they're not already moving and // We can accept input anytime the player can move, i.e. when they're not already moving and
// not in an un-overrideable slide. // not in an un-overrideable slide.
@ -2478,9 +2509,19 @@ export class Level extends LevelInterface {
//add to end of array //add to end of array
this.static_on_tic_tiles.push(tile); this.static_on_tic_tiles.push(tile);
} }
}
//TODO: update circuit networks? //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?
}
} }
// Have an actor try to pick up a particular tile; it's prevented if there's a no sign, and the // Have an actor try to pick up a particular tile; it's prevented if there's a no sign, and the

View File

@ -1376,6 +1376,7 @@ const TILE_TYPES = {
cloner: { cloner: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid, blocks_collision: COLLISION.real_player | COLLISION.block_cc1 | COLLISION.monster_solid,
connected_from: 'button_red',
traps(me, actor) { traps(me, actor) {
return ! actor._clone_release; return ! actor._clone_release;
}, },
@ -1428,6 +1429,7 @@ const TILE_TYPES = {
}, },
trap: { trap: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
connected_from: 'button_brown',
add_press_ready(me, level, other) { add_press_ready(me, level, other) {
// Same as below, but without ejection // Same as below, but without ejection
me.presses = (me.presses ?? 0) + 1; me.presses = (me.presses ?? 0) + 1;
@ -1721,6 +1723,7 @@ const TILE_TYPES = {
// - Gray button toggles it permanently // - Gray button toggles it permanently
flame_jet_off: { flame_jet_off: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
connected_from: 'button_orange',
activate(me, level) { activate(me, level) {
level.transmute_tile(me, 'flame_jet_on'); 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 // 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: { flame_jet_on: {
layer: LAYERS.terrain, layer: LAYERS.terrain,
connected_from: 'button_orange',
activate(me, level) { activate(me, level) {
level.transmute_tile(me, 'flame_jet_off'); level.transmute_tile(me, 'flame_jet_off');
}, },