diff --git a/js/main-editor.js b/js/main-editor.js index c0be38b..a74d16c 100644 --- a/js/main-editor.js +++ b/js/main-editor.js @@ -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) { diff --git a/js/tiletypes.js b/js/tiletypes.js index fe41bbb..307ab6b 100644 --- a/js/tiletypes.js +++ b/js/tiletypes.js @@ -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) {