Preserve wires when drawing a wireable tile in the editor; light switches don't propagate

This commit is contained in:
Eevee (Evelyn Woods) 2021-03-10 23:20:00 -07:00
parent 3020e3b038
commit 0b957cfeb1
2 changed files with 64 additions and 6 deletions

View File

@ -895,7 +895,7 @@ class FillPreview extends OperationPreview {
this.foreign_object.remove();
}
}
class FillOperation extends MouseOperation {
class FillOperation extends DrawOperation {
start() {
// Filling is a single-click thing, and all the work was done by the preview!
let preview = this.editor.mouse_hover_op;
@ -1005,7 +1005,7 @@ class SelectOperation extends MouseOperation {
}
}
class ForceFloorOperation extends DrawOperation {
class ForceFloorOperation extends MouseOperation {
start() {
// Begin by placing an all-way force floor under the mouse
this.editor.place_in_cell(this.cell(this.gx0, this.gy0), {type: TILE_TYPES.force_floor_all});
@ -1077,7 +1077,7 @@ class ForceFloorOperation extends DrawOperation {
// fix it if it wasn't there?
// TODO gonna need an ice tool too, so maybe i can merge all three with some base thing that tracks
// the directions the mouse is moving? or is FF tool too different?
class TrackOperation extends DrawOperation {
class TrackOperation extends MouseOperation {
start() {
// Do nothing to start; we only lay track when the mouse leaves a cell
this.entry_direction = null;
@ -1165,7 +1165,7 @@ class TrackOperation extends DrawOperation {
}
}
class WireOperation extends DrawOperation {
class WireOperation extends MouseOperation {
start() {
if (this.modifier === 'ctrl') {
// Place or remove wire tunnels
@ -1312,7 +1312,7 @@ class WireOperation extends DrawOperation {
// TODO probably a better way to do this
if (! tile)
continue;
if (['floor', 'steel', 'button_pink', 'button_black', 'teleport_blue', 'teleport_red', 'light_switch_on', 'light_switch_off', 'circuit_block', 'teleport_blue_exit', 'turntable_cw', 'turntable_ccw'].indexOf(tile.type.name) < 0)
if (! tile.type.contains_wire)
continue;
tile = {...tile};
@ -4165,7 +4165,27 @@ export class Editor extends PrimaryView {
return;
}
this._assign_tile(cell, layer, {...tile}, existing_tile);
let new_tile = {...tile};
// Special case: preserve wires when replacing one wired tile with another
if (new_tile.type.contains_wire &&
// FIXME this is hacky garbage
tile === this.palette_selection && this.palette_selection_from_palette)
{
if (existing_tile.type.contains_wire) {
new_tile.wire_directions = existing_tile.wire_directions;
}
else if (existing_tile.type.name === 'logic_gate') {
// Extract the wires from logic gates
new_tile.wire_directions = 0;
for (let dir of existing_tile.type.get_wires(existing_tile)) {
if (dir) {
new_tile.wire_directions |= DIRECTIONS[dir].bit;
}
}
}
}
this._assign_tile(cell, layer, new_tile, existing_tile);
}
erase_tile(cell, tile = null) {

View File

@ -252,6 +252,7 @@ const TILE_TYPES = {
// Floors and walls
floor: {
layer: LAYERS.terrain,
contains_wire: true,
on_approach(me, level, other) {
if (other.type.name === 'blob' || other.type.name === 'boulder') {
// Blobs spread slime onto floor
@ -451,6 +452,7 @@ const TILE_TYPES = {
steel: {
layer: LAYERS.terrain,
blocks_collision: COLLISION.all,
contains_wire: true,
},
canopy: {
layer: LAYERS.canopy,
@ -721,6 +723,7 @@ const TILE_TYPES = {
},
turntable_cw: {
layer: LAYERS.terrain,
contains_wire: true,
wire_propagation_mode: 'all',
on_arrive(me, level, other) {
level.set_actor_direction(other, DIRECTIONS[other.direction].right);
@ -737,6 +740,7 @@ const TILE_TYPES = {
},
turntable_ccw: {
layer: LAYERS.terrain,
contains_wire: true,
wire_propagation_mode: 'all',
on_arrive(me, level, other) {
level.set_actor_direction(other, DIRECTIONS[other.direction].left);
@ -1710,6 +1714,7 @@ const TILE_TYPES = {
teleport_blue: {
layer: LAYERS.terrain,
slide_mode: 'teleport',
contains_wire: true,
wire_propagation_mode: 'all',
*teleport_dest_order(me, level, other) {
let exit_direction = other.direction;
@ -1790,11 +1795,13 @@ const TILE_TYPES = {
},
teleport_blue_exit: {
layer: LAYERS.terrain,
contains_wire: true,
wire_propagation_mode: 'all',
},
teleport_red: {
layer: LAYERS.terrain,
slide_mode: 'teleport',
contains_wire: true,
wire_propagation_mode: 'none',
teleport_allow_override: true,
on_begin(me, level) {
@ -2117,6 +2124,7 @@ const TILE_TYPES = {
},
button_pink: {
layer: LAYERS.terrain,
contains_wire: true,
is_power_source: true,
wire_propagation_mode: 'none',
get_emitting_edges(me, level) {
@ -2139,6 +2147,7 @@ const TILE_TYPES = {
},
button_black: {
layer: LAYERS.terrain,
contains_wire: true,
is_power_source: true,
wire_propagation_mode: 'cross',
get_emitting_edges(me, level) {
@ -2225,6 +2234,30 @@ const TILE_TYPES = {
me.direction = 'north';
}
},
// Returns [in0, in1, out0, out1] as directions
get_wires(me) {
let gate_def = me.type._gate_types[me.gate_type];
let dir = me.direction;
let ret = [null, null, null, null];
for (let i = 0; i < 4; i++) {
let cxn = gate_def[i];
let dirinfo = DIRECTIONS[dir];
if (cxn === 'in0') {
ret[0] = dir;
}
else if (cxn === 'in1') {
ret[1] = dir;
}
else if (cxn === 'out0') {
ret[2] = dir;
}
else if (cxn === 'out1') {
ret[3] = dir;
}
dir = dirinfo.right;
}
return ret;
},
get_emitting_edges(me, level) {
// Collect which of our edges are powered, in clockwise order starting from our
// direction, matching _gate_types
@ -2317,7 +2350,9 @@ const TILE_TYPES = {
// Light switches, kinda like the pink/black buttons but persistent
light_switch_off: {
layer: LAYERS.terrain,
contains_wire: true,
is_power_source: true,
wire_propagation_mode: 'none',
get_emitting_edges(me, level) {
// TODO weird and inconsistent with pink buttons, but cc2 has a single-frame delay here!
if (me.is_first_frame) {
@ -2335,7 +2370,9 @@ const TILE_TYPES = {
},
light_switch_on: {
layer: LAYERS.terrain,
contains_wire: true,
is_power_source: true,
wire_propagation_mode: 'none',
get_emitting_edges(me, level) {
// TODO weird and inconsistent with pink buttons, but cc2 has a single-frame delay here!
if (me.is_first_frame) {
@ -2358,6 +2395,7 @@ const TILE_TYPES = {
item_pickup_priority: PICKUP_PRIORITIES.never,
is_actor: true,
is_block: true,
contains_wire: true,
can_reverse_on_railroad: true,
movement_speed: 4,
on_clone(me, original) {