Add partial wiring support
This commit is contained in:
parent
4cd0585d0b
commit
8adb630862
@ -69,6 +69,7 @@ class CC2Demo {
|
|||||||
let modifier_wire = {
|
let modifier_wire = {
|
||||||
decode(tile, modifier) {
|
decode(tile, modifier) {
|
||||||
tile.wire_directions = modifier & 0x0f;
|
tile.wire_directions = modifier & 0x0f;
|
||||||
|
// TODO wait, what happens if you use wire tunnels on steel or something other than floor?
|
||||||
tile.wire_tunnel_directions = (modifier & 0xf0) >> 4;
|
tile.wire_tunnel_directions = (modifier & 0xf0) >> 4;
|
||||||
},
|
},
|
||||||
encode(tile) {
|
encode(tile) {
|
||||||
|
|||||||
144
js/game.js
144
js/game.js
@ -125,6 +125,17 @@ export class Cell extends Array {
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_wired_tile() {
|
||||||
|
let ret = null;
|
||||||
|
for (let tile of this) {
|
||||||
|
if (tile.wire_directions || tile.wire_tunnel_directions) {
|
||||||
|
ret = tile;
|
||||||
|
// Don't break; we want the topmost tile!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
blocks_leaving(actor, direction) {
|
blocks_leaving(actor, direction) {
|
||||||
for (let tile of this) {
|
for (let tile of this) {
|
||||||
if (tile !== actor &&
|
if (tile !== actor &&
|
||||||
@ -148,6 +159,8 @@ export class Cell extends Array {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Cell.prototype.was_powered = false;
|
||||||
|
Cell.prototype.is_powered = false;
|
||||||
|
|
||||||
class GameEnded extends Error {}
|
class GameEnded extends Error {}
|
||||||
|
|
||||||
@ -205,6 +218,9 @@ export class Level {
|
|||||||
|
|
||||||
let n = 0;
|
let n = 0;
|
||||||
let connectables = [];
|
let connectables = [];
|
||||||
|
// Handle CC2 wiring; a contiguous region of wire is all updated as a single unit, so detect
|
||||||
|
// those units ahead of time for simplicity and call them "clusters"
|
||||||
|
this.wire_clusters = [];
|
||||||
// FIXME handle traps correctly:
|
// FIXME handle traps correctly:
|
||||||
// - if an actor is in the cell, set the trap to open and unstick everything in it
|
// - if an actor is in the cell, set the trap to open and unstick everything in it
|
||||||
for (let y = 0; y < this.height; y++) {
|
for (let y = 0; y < this.height; y++) {
|
||||||
@ -398,6 +414,9 @@ export class Level {
|
|||||||
this.step_on_cell(actor, cell);
|
this.step_on_cell(actor, cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now we handle wiring
|
||||||
|
this.update_wiring();
|
||||||
|
|
||||||
// Only reset the player's is_pushing between movement, so it lasts for the whole push
|
// Only reset the player's is_pushing between movement, so it lasts for the whole push
|
||||||
if (this.player.movement_cooldown <= 0) {
|
if (this.player.movement_cooldown <= 0) {
|
||||||
this.player.is_pushing = false;
|
this.player.is_pushing = false;
|
||||||
@ -558,7 +577,7 @@ export class Level {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let direction of direction_preference) {
|
for (let direction of direction_preference) {
|
||||||
let dest_cell = this.cell_with_offset(actor.cell, direction);
|
let dest_cell = this.get_neighboring_cell(actor.cell, direction);
|
||||||
if (! dest_cell)
|
if (! dest_cell)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -600,7 +619,7 @@ export class Level {
|
|||||||
if (actor.type.is_player && dir2 &&
|
if (actor.type.is_player && dir2 &&
|
||||||
! old_cell.blocks_leaving(actor, dir2))
|
! old_cell.blocks_leaving(actor, dir2))
|
||||||
{
|
{
|
||||||
let neighbor = this.cell_with_offset(old_cell, dir2);
|
let neighbor = this.get_neighboring_cell(old_cell, dir2);
|
||||||
if (neighbor) {
|
if (neighbor) {
|
||||||
let could_push = ! neighbor.blocks_entering(actor, dir2, this, true);
|
let could_push = ! neighbor.blocks_entering(actor, dir2, this, true);
|
||||||
for (let tile of Array.from(neighbor)) {
|
for (let tile of Array.from(neighbor)) {
|
||||||
@ -677,7 +696,7 @@ export class Level {
|
|||||||
|
|
||||||
let move = DIRECTIONS[direction].movement;
|
let move = DIRECTIONS[direction].movement;
|
||||||
if (!actor.cell) console.error(actor);
|
if (!actor.cell) console.error(actor);
|
||||||
let goal_cell = this.cell_with_offset(actor.cell, direction);
|
let goal_cell = this.get_neighboring_cell(actor.cell, direction);
|
||||||
|
|
||||||
// TODO this could be a lot simpler if i could early-return! should ice bumping be
|
// TODO this could be a lot simpler if i could early-return! should ice bumping be
|
||||||
// somewhere else?
|
// somewhere else?
|
||||||
@ -903,11 +922,126 @@ export class Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_with_offset(cell, direction) {
|
// Update the state of all wired tiles in the game.
|
||||||
|
// XXX need to be clear on the order of events here. say everything starts out unpowered.
|
||||||
|
// then:
|
||||||
|
// 1. you step on a pink button, which flags itself as going to be powered next frame
|
||||||
|
// 2. this pass happens. every unpowered-but-wired cell is inspected. if a powered one is
|
||||||
|
// found, floodfill from there
|
||||||
|
// FIXME can probably skip this if we know there are no wires at all, like in a CCL, or just an
|
||||||
|
// unwired map
|
||||||
|
// FIXME this feels inefficient. most of the time none of the inputs have changed so none of
|
||||||
|
// this needs to happen at all
|
||||||
|
// FIXME none of this is currently undoable
|
||||||
|
update_wiring() {
|
||||||
|
// Turn off power to every cell
|
||||||
|
// TODO wonder if i need a linear cell list, or even a flat list of all tiles (that sounds
|
||||||
|
// like hell to keep updated though)
|
||||||
|
for (let row of this.cells) {
|
||||||
|
for (let cell of row) {
|
||||||
|
cell.was_powered = cell.is_powered;
|
||||||
|
cell.is_powered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through the grid looking for emitters — tiles that are generating current — and
|
||||||
|
// propagated it via flood-fill through neighboring wires
|
||||||
|
for (let row of this.cells) {
|
||||||
|
for (let cell of row) {
|
||||||
|
// TODO probably this should set a prop on the tile
|
||||||
|
if (! cell.some(tile => tile.type.is_emitting && tile.type.is_emitting(tile, this)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We have an emitter! Flood-fill outwards
|
||||||
|
let neighbors = [cell];
|
||||||
|
for (let neighbor of neighbors) {
|
||||||
|
// Power it even if it's not wired itself, so that e.g. purple tiles work
|
||||||
|
neighbor.is_powered = true;
|
||||||
|
|
||||||
|
let wire = neighbor.get_wired_tile();
|
||||||
|
if (! wire)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Emit along every wire direction, and add any unpowered neighbors to the
|
||||||
|
// pending list to continue the floodfill
|
||||||
|
// TODO but only if wires connect
|
||||||
|
// TODO handle wire tunnels
|
||||||
|
for (let [direction, dirinfo] of Object.entries(DIRECTIONS)) {
|
||||||
|
if (! (wire.wire_directions & dirinfo.bit))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let neighbor2, wire2;
|
||||||
|
let opposite_bit = DIRECTIONS[dirinfo.opposite].bit;
|
||||||
|
if (wire.wire_tunnel_directions & dirinfo.bit) {
|
||||||
|
// Search in the given direction until we find a matching tunnel
|
||||||
|
// FIXME these act like nested parens!
|
||||||
|
let x = neighbor.x;
|
||||||
|
let y = neighbor.y;
|
||||||
|
let nesting = 0;
|
||||||
|
while (true) {
|
||||||
|
x += dirinfo.movement[0];
|
||||||
|
y += dirinfo.movement[1];
|
||||||
|
if (! this.is_point_within_bounds(x, y))
|
||||||
|
break;
|
||||||
|
|
||||||
|
let candidate = this.cells[y][x];
|
||||||
|
wire2 = candidate.get_wired_tile();
|
||||||
|
if (wire2 && (wire2.wire_tunnel_directions ?? 0) & opposite_bit) {
|
||||||
|
neighbor2 = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Otherwise this is easy
|
||||||
|
neighbor2 = this.get_neighboring_cell(neighbor, direction);
|
||||||
|
wire2 = neighbor2.get_wired_tile();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neighbor2 && ! neighbor2.is_powered &&
|
||||||
|
// Unwired tiles are OK; they might be something activated by power.
|
||||||
|
// Wired tiles that do NOT connect to us are ignored.
|
||||||
|
(! wire2 || wire2.wire_directions & opposite_bit))
|
||||||
|
{
|
||||||
|
neighbors.push(neighbor2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inform any affected cells of power changes
|
||||||
|
for (let row of this.cells) {
|
||||||
|
for (let cell of row) {
|
||||||
|
if (cell.was_powered !== cell.is_powered) {
|
||||||
|
let method = cell.is_powered ? 'on_power' : 'on_depower';
|
||||||
|
for (let tile of cell) {
|
||||||
|
if (tile.type[method]) {
|
||||||
|
tile.type[method](tile, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performs a depth-first search for connected wires and wire objects, extending out from the
|
||||||
|
// given starting cell
|
||||||
|
*follow_circuit(cell) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
// Board inspection
|
||||||
|
|
||||||
|
is_point_within_bounds(x, y) {
|
||||||
|
return (x >= 0 && x < this.width && y >= 0 && y < this.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_neighboring_cell(cell, direction) {
|
||||||
let move = DIRECTIONS[direction].movement;
|
let move = DIRECTIONS[direction].movement;
|
||||||
let goal_x = cell.x + move[0];
|
let goal_x = cell.x + move[0];
|
||||||
let goal_y = cell.y + move[1];
|
let goal_y = cell.y + move[1];
|
||||||
if (goal_x >= 0 && goal_x < this.width && goal_y >= 0 && goal_y < this.height) {
|
if (this.is_point_within_bounds(goal_x, goal_y)) {
|
||||||
return this.cells[goal_y][goal_x];
|
return this.cells[goal_y][goal_x];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -200,7 +200,12 @@ export const CC2_TILESET_LAYOUT = {
|
|||||||
popwall2: [8, 10],
|
popwall2: [8, 10],
|
||||||
gravel: [9, 10],
|
gravel: [9, 10],
|
||||||
ball: [[10, 10], [11, 10], [12, 10], [13, 10], [14, 10]],
|
ball: [[10, 10], [11, 10], [12, 10], [13, 10], [14, 10]],
|
||||||
steel: [15, 10],
|
steel: {
|
||||||
|
// Wiring!
|
||||||
|
base: [15, 10],
|
||||||
|
wired: [9, 26],
|
||||||
|
is_wired_optional: true,
|
||||||
|
},
|
||||||
|
|
||||||
// TODO only animates while moving
|
// TODO only animates while moving
|
||||||
teeth: {
|
teeth: {
|
||||||
@ -216,7 +221,7 @@ export const CC2_TILESET_LAYOUT = {
|
|||||||
swivel_ne: [11, 11],
|
swivel_ne: [11, 11],
|
||||||
swivel_se: [12, 11],
|
swivel_se: [12, 11],
|
||||||
swivel_floor: [13, 11],
|
swivel_floor: [13, 11],
|
||||||
// TODO some kinda four-edges thing again
|
'#wire-tunnel': [14, 11],
|
||||||
stopwatch_penalty: [15, 11],
|
stopwatch_penalty: [15, 11],
|
||||||
paramecium: {
|
paramecium: {
|
||||||
north: [[0, 12], [1, 12], [2, 12]],
|
north: [[0, 12], [1, 12], [2, 12]],
|
||||||
@ -666,10 +671,10 @@ export class Tileset {
|
|||||||
coords = drawspec.tile;
|
coords = drawspec.tile;
|
||||||
}
|
}
|
||||||
else if (drawspec.wired) {
|
else if (drawspec.wired) {
|
||||||
if (tile && tile.wire_directions !== undefined && tile.wire_directions !== 0) {
|
if (tile && tile.wire_directions) {
|
||||||
// TODO all four is a different thing entirely
|
// TODO all four is a different thing entirely with two separate parts, ugh
|
||||||
// Draw the appropriate wire underlay
|
// Draw the appropriate wire underlay
|
||||||
this.draw_type('#unpowered', tile, tic, blit);
|
this.draw_type(tile.cell.is_powered ? '#powered' : '#unpowered', tile, tic, blit);
|
||||||
|
|
||||||
// Draw a masked part of the base tile
|
// Draw a masked part of the base tile
|
||||||
let wiredir = tile.wire_directions;
|
let wiredir = tile.wire_directions;
|
||||||
@ -726,7 +731,7 @@ export class Tileset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply custom per-type visual states
|
// Apply custom per-type visual states
|
||||||
if (TILE_TYPES[name].visual_state) {
|
if (TILE_TYPES[name] && TILE_TYPES[name].visual_state) {
|
||||||
// Note that these accept null, too, and return a default
|
// Note that these accept null, too, and return a default
|
||||||
let state = TILE_TYPES[name].visual_state(tile);
|
let state = TILE_TYPES[name].visual_state(tile);
|
||||||
// If it's a string, that's an alias for another state
|
// If it's a string, that's an alias for another state
|
||||||
@ -797,6 +802,30 @@ export class Tileset {
|
|||||||
blit(coords[0], coords[1]);
|
blit(coords[0], coords[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wired tiles may also have tunnels, drawn on top of everything else
|
||||||
|
if (drawspec.wired && tile && tile.wire_tunnel_directions) {
|
||||||
|
let tunnel_coords = this.layout['#wire-tunnel'];
|
||||||
|
let tunnel_width = 6/32;
|
||||||
|
let tunnel_length = 12/32;
|
||||||
|
let tunnel_offset = (1 - tunnel_width) / 2;
|
||||||
|
if (tile.wire_tunnel_directions & DIRECTIONS['north'].bit) {
|
||||||
|
blit(tunnel_coords[0] + tunnel_offset, tunnel_coords[1],
|
||||||
|
tunnel_offset, 0, tunnel_width, tunnel_length);
|
||||||
|
}
|
||||||
|
if (tile.wire_tunnel_directions & DIRECTIONS['south'].bit) {
|
||||||
|
blit(tunnel_coords[0] + tunnel_offset, tunnel_coords[1] + 1 - tunnel_length,
|
||||||
|
tunnel_offset, 1 - tunnel_length, tunnel_width, tunnel_length);
|
||||||
|
}
|
||||||
|
if (tile.wire_tunnel_directions & DIRECTIONS['west'].bit) {
|
||||||
|
blit(tunnel_coords[0], tunnel_coords[1] + tunnel_offset,
|
||||||
|
0, tunnel_offset, tunnel_length, tunnel_width);
|
||||||
|
}
|
||||||
|
if (tile.wire_tunnel_directions & DIRECTIONS['east'].bit) {
|
||||||
|
blit(tunnel_coords[0] + 1 - tunnel_length, tunnel_coords[1] + tunnel_offset,
|
||||||
|
1 - tunnel_length, tunnel_offset, tunnel_length, tunnel_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Special behavior for special objects
|
// Special behavior for special objects
|
||||||
// TODO? hardcode this less?
|
// TODO? hardcode this less?
|
||||||
if (name === 'floor_letter') {
|
if (name === 'floor_letter') {
|
||||||
|
|||||||
@ -588,10 +588,16 @@ const TILE_TYPES = {
|
|||||||
},
|
},
|
||||||
green_floor: {
|
green_floor: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
level.transmute_tile(me, 'green_wall');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
green_wall: {
|
green_wall: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
blocks_all: true,
|
blocks_all: true,
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
level.transmute_tile(me, 'green_floor');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
green_chip: {
|
green_chip: {
|
||||||
draw_layer: LAYER_ITEM,
|
draw_layer: LAYER_ITEM,
|
||||||
@ -605,6 +611,7 @@ const TILE_TYPES = {
|
|||||||
level.remove_tile(me);
|
level.remove_tile(me);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Not affected by gray buttons
|
||||||
},
|
},
|
||||||
green_bomb: {
|
green_bomb: {
|
||||||
draw_layer: LAYER_ITEM,
|
draw_layer: LAYER_ITEM,
|
||||||
@ -619,15 +626,32 @@ const TILE_TYPES = {
|
|||||||
level.transmute_tile(other, 'explosion');
|
level.transmute_tile(other, 'explosion');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Not affected by gray buttons
|
||||||
},
|
},
|
||||||
purple_floor: {
|
purple_floor: {
|
||||||
// TODO wired
|
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
level.transmute_tile(me, 'purple_wall');
|
||||||
|
},
|
||||||
|
on_power(me, level) {
|
||||||
|
me.type.on_gray_button(me, level);
|
||||||
|
},
|
||||||
|
on_depower(me, level) {
|
||||||
|
me.type.on_gray_button(me, level);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
purple_wall: {
|
purple_wall: {
|
||||||
// TODO wired
|
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
blocks_all: true,
|
blocks_all: true,
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
level.transmute_tile(me, 'purple_floor');
|
||||||
|
},
|
||||||
|
on_power(me, level) {
|
||||||
|
me.type.on_gray_button(me, level);
|
||||||
|
},
|
||||||
|
on_depower(me, level) {
|
||||||
|
me.type.on_gray_button(me, level);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
cloner: {
|
cloner: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
@ -658,6 +682,13 @@ const TILE_TYPES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// Also clones on rising pulse or gray button
|
||||||
|
on_power(me, level) {
|
||||||
|
me.type.activate(me, level);
|
||||||
|
},
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
me.type.activate(me, level);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
trap: {
|
trap: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
@ -693,7 +724,7 @@ const TILE_TYPES = {
|
|||||||
level.set_actor_stuck(other, true);
|
level.set_actor_stuck(other, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
add_press(me, level, is_begin) {
|
add_press(me, level) {
|
||||||
level._set_prop(me, 'presses', (me.presses ?? 0) + 1);
|
level._set_prop(me, 'presses', (me.presses ?? 0) + 1);
|
||||||
if (me.presses === 1) {
|
if (me.presses === 1) {
|
||||||
// Free everything on us, if we went from 0 to 1 presses (i.e. closed to open)
|
// Free everything on us, if we went from 0 to 1 presses (i.e. closed to open)
|
||||||
@ -718,6 +749,15 @@ const TILE_TYPES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
on_power(me, level) {
|
||||||
|
// Treat being powered or not as an extra kind of brown button press
|
||||||
|
me.type.add_press(me, level);
|
||||||
|
console.log("powering UP", me.presses);
|
||||||
|
},
|
||||||
|
on_depower(me, level) {
|
||||||
|
me.type.remove_press(me, level);
|
||||||
|
console.log("powering down...", me.presses);
|
||||||
|
},
|
||||||
visual_state(me) {
|
visual_state(me) {
|
||||||
if (me && me.presses) {
|
if (me && me.presses) {
|
||||||
return 'open';
|
return 'open';
|
||||||
@ -793,13 +833,30 @@ const TILE_TYPES = {
|
|||||||
return level.iter_tiles_in_reading_order(me.cell, 'teleport_yellow', true);
|
return level.iter_tiles_in_reading_order(me.cell, 'teleport_yellow', true);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// FIXME do i want these as separate objects? what would they do, turn into each other? or should it be one with state?
|
|
||||||
flame_jet_off: {
|
flame_jet_off: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
|
activate(me, level) {
|
||||||
|
level.transmute_tile(me, 'flame_jet_on');
|
||||||
|
},
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
me.type.activate(me, level);
|
||||||
|
},
|
||||||
|
on_power(me, level) {
|
||||||
|
me.type.activate(me, level);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
flame_jet_on: {
|
flame_jet_on: {
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
// FIXME every tic, kills every actor in the cell
|
// FIXME every tic, kills every actor in the cell
|
||||||
|
activate(me, level) {
|
||||||
|
level.transmute_tile(me, 'flame_jet_off');
|
||||||
|
},
|
||||||
|
on_gray_button(me, level) {
|
||||||
|
me.type.activate(me, level);
|
||||||
|
},
|
||||||
|
on_power(me, level) {
|
||||||
|
me.type.activate(me, level);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
// Buttons
|
// Buttons
|
||||||
button_blue: {
|
button_blue: {
|
||||||
@ -920,8 +977,17 @@ const TILE_TYPES = {
|
|||||||
// FIXME toggles flame jets, connected somehow, ???
|
// FIXME toggles flame jets, connected somehow, ???
|
||||||
},
|
},
|
||||||
button_pink: {
|
button_pink: {
|
||||||
// TODO not implemented
|
|
||||||
draw_layer: LAYER_TERRAIN,
|
draw_layer: LAYER_TERRAIN,
|
||||||
|
is_emitting(me, level) {
|
||||||
|
// We emit current as long as there's an actor on us
|
||||||
|
return me.cell.some(tile => tile.type.is_actor);
|
||||||
|
},
|
||||||
|
on_arrive(me, level, other) {
|
||||||
|
level.sfx.play_once('button-press', me.cell);
|
||||||
|
},
|
||||||
|
on_depart(me, level, other) {
|
||||||
|
level.sfx.play_once('button-release', me.cell);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
button_black: {
|
button_black: {
|
||||||
// TODO not implemented
|
// TODO not implemented
|
||||||
@ -941,11 +1007,8 @@ const TILE_TYPES = {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (let tile of cell) {
|
for (let tile of cell) {
|
||||||
if (tile.type.name === 'green_floor') {
|
if (tile.type.on_gray_button) {
|
||||||
level.transmute_tile(tile, 'green_wall');
|
tile.type.on_gray_button(tile, level);
|
||||||
}
|
|
||||||
else if (tile.type.name === 'green_wall') {
|
|
||||||
level.transmute_tile(tile, 'green_floor');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
tileset-lexy.png
BIN
tileset-lexy.png
Binary file not shown.
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 54 KiB |
Binary file not shown.
Loading…
Reference in New Issue
Block a user