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(); this.foreign_object.remove();
} }
} }
class FillOperation extends MouseOperation { class FillOperation extends DrawOperation {
start() { start() {
// Filling is a single-click thing, and all the work was done by the preview! // Filling is a single-click thing, and all the work was done by the preview!
let preview = this.editor.mouse_hover_op; let preview = this.editor.mouse_hover_op;
@ -1005,7 +1005,7 @@ class SelectOperation extends MouseOperation {
} }
} }
class ForceFloorOperation extends DrawOperation { class ForceFloorOperation extends MouseOperation {
start() { start() {
// Begin by placing an all-way force floor under the mouse // 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}); 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? // 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 // 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? // the directions the mouse is moving? or is FF tool too different?
class TrackOperation extends DrawOperation { class TrackOperation extends MouseOperation {
start() { start() {
// Do nothing to start; we only lay track when the mouse leaves a cell // Do nothing to start; we only lay track when the mouse leaves a cell
this.entry_direction = null; this.entry_direction = null;
@ -1165,7 +1165,7 @@ class TrackOperation extends DrawOperation {
} }
} }
class WireOperation extends DrawOperation { class WireOperation extends MouseOperation {
start() { start() {
if (this.modifier === 'ctrl') { if (this.modifier === 'ctrl') {
// Place or remove wire tunnels // Place or remove wire tunnels
@ -1312,7 +1312,7 @@ class WireOperation extends DrawOperation {
// TODO probably a better way to do this // TODO probably a better way to do this
if (! tile) if (! tile)
continue; 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; continue;
tile = {...tile}; tile = {...tile};
@ -4165,7 +4165,27 @@ export class Editor extends PrimaryView {
return; 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) { erase_tile(cell, tile = null) {

View File

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