Fix some minor wire bugs: NOT/counter/pink button power drawing, circuit block motion, nested wire tunnels
This commit is contained in:
parent
3790e0f07e
commit
62eb1a86e4
26
js/game.js
26
js/game.js
@ -151,7 +151,7 @@ export class Cell extends Array {
|
|||||||
get_wired_tile() {
|
get_wired_tile() {
|
||||||
let ret = null;
|
let ret = null;
|
||||||
for (let tile of this) {
|
for (let tile of this) {
|
||||||
if (tile.wire_directions || tile.wire_tunnel_directions) {
|
if ((tile.wire_directions || tile.wire_tunnel_directions) && ! tile.movement_cooldown) {
|
||||||
ret = tile;
|
ret = tile;
|
||||||
// Don't break; we want the topmost tile!
|
// Don't break; we want the topmost tile!
|
||||||
}
|
}
|
||||||
@ -1430,7 +1430,6 @@ export class Level {
|
|||||||
// - make this undoable :(
|
// - make this undoable :(
|
||||||
// - blue tele, red tele, and pink button have different connections
|
// - blue tele, red tele, and pink button have different connections
|
||||||
// - would like to reuse the walk for blue teles
|
// - would like to reuse the walk for blue teles
|
||||||
// - currently doesn't notice when circuit block moves sometimes
|
|
||||||
|
|
||||||
// Gather every tile that's emitting power. Along the way, check whether any of them have
|
// Gather every tile that's emitting power. Along the way, check whether any of them have
|
||||||
// changed since last tic, so we can skip this work entirely if none did
|
// changed since last tic, so we can skip this work entirely if none did
|
||||||
@ -1453,11 +1452,11 @@ export class Level {
|
|||||||
if (! actor.cell)
|
if (! actor.cell)
|
||||||
continue;
|
continue;
|
||||||
// Only count when they're on a floor tile AND not in transit!
|
// Only count when they're on a floor tile AND not in transit!
|
||||||
let emitting = 0;
|
let emitting = null;
|
||||||
if (actor.movement_cooldown === 0 && actor.has_item('lightning_bolt')) {
|
if (actor.movement_cooldown === 0 && actor.has_item('lightning_bolt')) {
|
||||||
let wired_tile = actor.cell.get_wired_tile();
|
let wired_tile = actor.cell.get_wired_tile();
|
||||||
if (wired_tile && wired_tile.type.name === 'floor') {
|
if (wired_tile && (wired_tile === actor || wired_tile.type.name === 'floor')) {
|
||||||
emitting = true;
|
emitting = wired_tile.wire_directions;
|
||||||
neighbors.push([actor.cell, wired_tile.wire_directions]);
|
neighbors.push([actor.cell, wired_tile.wire_directions]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1531,7 +1530,6 @@ export class Level {
|
|||||||
let opposite_bit = DIRECTIONS[dirinfo.opposite].bit;
|
let opposite_bit = DIRECTIONS[dirinfo.opposite].bit;
|
||||||
if (wire && (wire.wire_tunnel_directions & dirinfo.bit)) {
|
if (wire && (wire.wire_tunnel_directions & dirinfo.bit)) {
|
||||||
// Search in the given direction until we find a matching tunnel
|
// Search in the given direction until we find a matching tunnel
|
||||||
// FIXME these act like nested parens!
|
|
||||||
let x = cell.x;
|
let x = cell.x;
|
||||||
let y = cell.y;
|
let y = cell.y;
|
||||||
let nesting = 0;
|
let nesting = 0;
|
||||||
@ -1543,9 +1541,19 @@ export class Level {
|
|||||||
|
|
||||||
let candidate = this.cells[y][x];
|
let candidate = this.cells[y][x];
|
||||||
neighbor_wire = candidate.get_wired_tile();
|
neighbor_wire = candidate.get_wired_tile();
|
||||||
if (neighbor_wire && ((neighbor_wire.wire_tunnel_directions ?? 0) & opposite_bit)) {
|
if (neighbor_wire) {
|
||||||
neighbor = candidate;
|
if ((neighbor_wire.wire_tunnel_directions ?? 0) & opposite_bit) {
|
||||||
break;
|
if (nesting === 0) {
|
||||||
|
neighbor = candidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nesting -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((neighbor_wire.wire_tunnel_directions ?? 0) & dirinfo.bit) {
|
||||||
|
nesting += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
110
js/tileset.js
110
js/tileset.js
@ -982,20 +982,25 @@ export class Tileset {
|
|||||||
// What goes on top varies a bit...
|
// What goes on top varies a bit...
|
||||||
// FIXME implement for NOT and counter!
|
// FIXME implement for NOT and counter!
|
||||||
let r = this.layout['#wire-width'] / 2;
|
let r = this.layout['#wire-width'] / 2;
|
||||||
if (tile.cell.powered_edges & DIRECTIONS[tile.direction].bit) {
|
if (tile.gate_type === 'not' || tile.gate_type === 'counter') {
|
||||||
// Output (on top)
|
this._draw_fourway_tile_power(tile, 0x0f, blit);
|
||||||
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0, 0.5 + r, 0.5);
|
|
||||||
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
|
||||||
}
|
}
|
||||||
if (tile.cell.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].right].bit) {
|
else {
|
||||||
// Right input, which includes the middle
|
if (tile.cell.powered_edges & DIRECTIONS[tile.direction].bit) {
|
||||||
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0.5 - r, 1, 1);
|
// Output (on top)
|
||||||
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0, 0.5 + r, 0.5);
|
||||||
}
|
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
if (tile.cell.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].left].bit) {
|
}
|
||||||
// Left input, which does not include the middle
|
if (tile.cell.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].right].bit) {
|
||||||
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0, 0.5 - r, 0.5 - r, 1);
|
// Right input, which includes the middle
|
||||||
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0.5 - r, 0.5 - r, 1, 1);
|
||||||
|
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
|
}
|
||||||
|
if (tile.cell.powered_edges & DIRECTIONS[DIRECTIONS[tile.direction].left].bit) {
|
||||||
|
// Left input, which does not include the middle
|
||||||
|
let [x0, y0, x1, y1] = this._rotate(tile.direction, 0, 0.5 - r, 0.5 - r, 1);
|
||||||
|
blit(powered_coords[0], powered_coords[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,6 +1013,42 @@ export class Tileset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_draw_fourway_tile_power(tile, wires, blit) {
|
||||||
|
// Draw the unpowered tile underneath, if any edge is unpowered (and in fact if /none/ of it
|
||||||
|
// is powered then we're done here)
|
||||||
|
let powered = (tile.cell ? tile.cell.powered_edges : 0) & wires;
|
||||||
|
if (! tile.cell || powered !== tile.wire_directions) {
|
||||||
|
this._draw_fourway_power_underlay(this.layout['#unpowered'], wires, blit);
|
||||||
|
if (! tile.cell || powered === 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._draw_fourway_power_underlay(this.layout['#powered'], powered, blit);
|
||||||
|
}
|
||||||
|
|
||||||
|
_draw_fourway_power_underlay(drawspec, bits, blit) {
|
||||||
|
// Draw the part as a single rectangle, initially just a small dot in the center, but
|
||||||
|
// extending out to any edge that has a bit present
|
||||||
|
let wire_radius = this.layout['#wire-width'] / 2;
|
||||||
|
let x0 = 0.5 - wire_radius;
|
||||||
|
let x1 = 0.5 + wire_radius;
|
||||||
|
let y0 = 0.5 - wire_radius;
|
||||||
|
let y1 = 0.5 + wire_radius;
|
||||||
|
if (bits & DIRECTIONS['north'].bit) {
|
||||||
|
y0 = 0;
|
||||||
|
}
|
||||||
|
if (bits & DIRECTIONS['east'].bit) {
|
||||||
|
x1 = 1;
|
||||||
|
}
|
||||||
|
if (bits & DIRECTIONS['south'].bit) {
|
||||||
|
y1 = 1;
|
||||||
|
}
|
||||||
|
if (bits & DIRECTIONS['west'].bit) {
|
||||||
|
x0 = 0;
|
||||||
|
}
|
||||||
|
blit(drawspec[0], drawspec[1], x0, y0, x1 - x0, y1 - y0);
|
||||||
|
}
|
||||||
|
|
||||||
_draw_railroad(drawspec, tile, tic, blit) {
|
_draw_railroad(drawspec, tile, tic, blit) {
|
||||||
// All railroads have regular gravel underneath
|
// All railroads have regular gravel underneath
|
||||||
// TODO would be nice to disambiguate since it's possible to have nothing visible
|
// TODO would be nice to disambiguate since it's possible to have nothing visible
|
||||||
@ -1107,48 +1148,13 @@ export class Tileset {
|
|||||||
else if (drawspec.wired) {
|
else if (drawspec.wired) {
|
||||||
// This /should/ match CC2's draw order exactly, based on experimentation
|
// This /should/ match CC2's draw order exactly, based on experimentation
|
||||||
let wire_radius = this.layout['#wire-width'] / 2;
|
let wire_radius = this.layout['#wire-width'] / 2;
|
||||||
if (tile && tile.wire_directions === 0x0f) {
|
// TODO circuit block with a lightning bolt is always powered
|
||||||
// This is a wired tile with crossing wires, which acts a little differently
|
// TODO circuit block in motion doesn't inherit cell's power
|
||||||
|
if (tile && tile.wire_directions) {
|
||||||
// Draw the base tile
|
// Draw the base tile
|
||||||
blit(drawspec.base[0], drawspec.base[1]);
|
blit(drawspec.base[0], drawspec.base[1]);
|
||||||
|
|
||||||
// Draw the two wires as separate rectangles, NS then EW
|
this._draw_fourway_tile_power(tile, tile.wire_directions, blit);
|
||||||
let wire_inset = 0.5 - wire_radius;
|
|
||||||
let wire_coords_ns = this.layout[
|
|
||||||
tile.cell && tile.cell.powered_edges & DIRECTIONS['north'].bit ? '#powered' : '#unpowered'];
|
|
||||||
let wire_coords_ew = this.layout[
|
|
||||||
tile.cell && tile.cell.powered_edges & DIRECTIONS['east'].bit ? '#powered' : '#unpowered'];
|
|
||||||
blit(wire_coords_ns[0], wire_coords_ns[1], wire_inset, 0, wire_radius * 2, 1);
|
|
||||||
blit(wire_coords_ew[0], wire_coords_ew[1], 0, wire_inset, 1, wire_radius * 2);
|
|
||||||
|
|
||||||
// Draw the cross tile on top
|
|
||||||
coords = drawspec.wired_cross ?? drawspec.wired;
|
|
||||||
}
|
|
||||||
else if (tile && tile.wire_directions) {
|
|
||||||
// Draw the base tile
|
|
||||||
blit(drawspec.base[0], drawspec.base[1]);
|
|
||||||
|
|
||||||
// FIXME some tiles don't have active wiring on all sides...
|
|
||||||
// Draw the wire part as a single rectangle, initially just a small dot in the
|
|
||||||
// center, but extending out to any edge that has a wire present
|
|
||||||
let x0 = 0.5 - wire_radius;
|
|
||||||
let x1 = 0.5 + wire_radius;
|
|
||||||
let y0 = 0.5 - wire_radius;
|
|
||||||
let y1 = 0.5 + wire_radius;
|
|
||||||
if (tile.wire_directions & DIRECTIONS['north'].bit) {
|
|
||||||
y0 = 0;
|
|
||||||
}
|
|
||||||
if (tile.wire_directions & DIRECTIONS['east'].bit) {
|
|
||||||
x1 = 1;
|
|
||||||
}
|
|
||||||
if (tile.wire_directions & DIRECTIONS['south'].bit) {
|
|
||||||
y1 = 1;
|
|
||||||
}
|
|
||||||
if (tile.wire_directions & DIRECTIONS['west'].bit) {
|
|
||||||
x0 = 0;
|
|
||||||
}
|
|
||||||
let wire_coords = this.layout[tile.cell && tile.cell.powered_edges ? '#powered' : '#unpowered'];
|
|
||||||
blit(wire_coords[0], wire_coords[1], x0, y0, x1 - x0, y1 - y0);
|
|
||||||
|
|
||||||
// Then draw the wired tile on top of it all
|
// Then draw the wired tile on top of it all
|
||||||
coords = drawspec.wired;
|
coords = drawspec.wired;
|
||||||
|
|||||||
@ -1528,7 +1528,6 @@ const TILE_TYPES = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
button_black: {
|
button_black: {
|
||||||
// TODO not implemented
|
|
||||||
draw_layer: DRAW_LAYERS.terrain,
|
draw_layer: DRAW_LAYERS.terrain,
|
||||||
is_power_source: true,
|
is_power_source: true,
|
||||||
get_emitting_edges(me, level) {
|
get_emitting_edges(me, level) {
|
||||||
@ -1540,6 +1539,12 @@ const TILE_TYPES = {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
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_gray: {
|
button_gray: {
|
||||||
// TODO only partially implemented
|
// TODO only partially implemented
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user