Indicate active wires

master
Louis Pearson 2022-01-20 14:15:56 -07:00
parent 18dae1722d
commit 7931f03738
2 changed files with 46 additions and 28 deletions

View File

@ -132,16 +132,17 @@ fn cell2index(c: Cell) ?usize {
const CellState = struct { enabled: bool = false, tile: u8 }; const CellState = struct { enabled: bool = false, tile: u8 };
const MAXCELLS = 400; const MAXCELLS = 400;
const CellMap = [MAXCELLS]CellState; const CellMap = [MAXCELLS]CellState;
const BridgeState = struct { cells: [2]Cell, id: usize, enabled: bool };
offset: Cell, offset: Cell,
cells: CellMap, cells: CellMap,
bridges: std.BoundedArray([2]Cell, 10), bridges: std.BoundedArray(BridgeState, 10),
pub fn init() @This() { pub fn init() @This() {
var this = @This(){ var this = @This(){
.offset = Cell{ 0, 0 }, .offset = Cell{ 0, 0 },
.cells = undefined, .cells = undefined,
.bridges = std.BoundedArray([2]Cell, 10).init(0) catch unreachable, .bridges = std.BoundedArray(BridgeState, 10).init(0) catch unreachable,
}; };
return this; return this;
} }
@ -169,14 +170,22 @@ pub fn enable(this: *@This(), cell: Cell) void {
} }
} }
pub fn bridge(this: *@This(), cells: [2]Cell) void { pub fn bridge(this: *@This(), cells: [2]Cell, bridgeID: usize) void {
if (this.indexOf(cells[0])) |_| { if (this.indexOf(cells[0])) |_| {
if (this.indexOf(cells[1])) |_| { if (this.indexOf(cells[1])) |_| {
this.bridges.append(cells) catch unreachable; this.bridges.append(.{ .cells = cells, .id = bridgeID, .enabled = false }) catch unreachable;
} }
} }
} }
pub fn enabledBridges(this: @This()) std.BoundedArray(usize, 10) {
var items = std.BoundedArray(usize, 10).init(0) catch unreachable;
for (this.bridges.constSlice()) |b| {
if (b.enabled) items.append(b.id) catch unreachable;
}
return items;
}
pub fn isEnabled(this: @This(), cell: Cell) bool { pub fn isEnabled(this: @This(), cell: Cell) bool {
if (this.indexOf(cell)) |c| { if (this.indexOf(cell)) |c| {
return this.cells[c].enabled; return this.cells[c].enabled;
@ -227,11 +236,13 @@ pub fn fill(this: *@This(), rootRaw: Cell) void {
q.insert(cell + delta); q.insert(cell + delta);
} }
if (is_plug(tile)) { if (is_plug(tile)) {
for (this.bridges.constSlice()) |b| { for (this.bridges.slice()) |*b| {
if (@reduce(.And, b[0] == cell)) { if (@reduce(.And, b.cells[0] == cell)) {
q.insert(b[1]); q.insert(b.cells[1]);
} else if (@reduce(.And, b[1] == cell)) { b.enabled = true;
q.insert(b[0]); } else if (@reduce(.And, b.cells[1] == cell)) {
q.insert(b.cells[0]);
b.enabled = true;
} }
} }
} }

View File

@ -51,7 +51,7 @@ const Kinematic = struct {
return this.isFalling() and !approxEqAbs(f32, this.lastCol[0], 0, 0.01); return this.isFalling() and !approxEqAbs(f32, this.lastCol[0], 0, 0.01);
} }
}; };
const Wire = struct { nodes: std.BoundedArray(Pos, 32) }; const Wire = struct { nodes: std.BoundedArray(Pos, 32), enabled: bool = false };
const Physics = struct { gravity: Vec2f, friction: Vec2f }; const Physics = struct { gravity: Vec2f, friction: Vec2f };
const Component = struct { const Component = struct {
pos: Pos, pos: Pos,
@ -141,24 +141,13 @@ export fn start() void {
} }
} }
var indicator: ?struct { pos: Vec2, t: enum { wire, plug, lever } } = null; var indicator: ?struct { pos: Vec2, t: enum { wire, plug, lever }, active: bool = false } = null;
var time: usize = 0; var time: usize = 0;
export fn update() void { export fn update() void {
w4.DRAW_COLORS.* = 0x0004; w4.DRAW_COLORS.* = 0x0004;
w4.rect(.{ 0, 0 }, .{ 160, 160 }); w4.rect(.{ 0, 0 }, .{ 160, 160 });
world.process(1, &.{.pos}, velocityProcess);
world.process(1, &.{ .pos, .physics }, physicsProcess);
world.process(1, &.{ .pos, .control }, wireManipulationProcess);
world.process(1, &.{ .pos, .control }, circuitManipulationProcess);
world.process(1, &.{.wire}, wirePhysicsProcess);
world.process(1, &.{ .pos, .control, .physics, .kinematic }, controlProcess);
world.process(1, &.{ .pos, .kinematic }, kinematicProcess);
world.process(1, &.{ .sprite, .staticAnim }, staticAnimProcess);
world.process(1, &.{ .sprite, .controlAnim, .control }, controlAnimProcess);
world.process(1, &.{ .pos, .sprite }, drawProcess);
{ {
circuit.clear(); circuit.clear();
const q = World.Query.require(&.{.wire}); const q = World.Query.require(&.{.wire});
@ -169,13 +158,29 @@ export fn update() void {
const cellBegin = util.world2cell(nodes[0].pos); const cellBegin = util.world2cell(nodes[0].pos);
const cellEnd = util.world2cell(nodes[nodes.len - 1].pos); const cellEnd = util.world2cell(nodes[nodes.len - 1].pos);
circuit.bridge(.{ cellBegin, cellEnd }); circuit.bridge(.{ cellBegin, cellEnd }, wireID);
} }
for (assets.sources) |source| { for (assets.sources) |source| {
circuit.fill(source); circuit.fill(source);
} }
var wireComponents = world.components.items(.wire);
var enabledWires = circuit.enabledBridges();
for (enabledWires.slice()) |wireID| {
wireComponents[wireID].?.enabled = true;
}
} }
world.process(1, &.{.pos}, velocityProcess);
world.process(1, &.{ .pos, .physics }, physicsProcess);
world.process(1, &.{ .pos, .control }, wireManipulationProcess);
world.process(1, &.{ .pos, .control }, circuitManipulationProcess);
world.process(1, &.{.wire}, wirePhysicsProcess);
world.process(1, &.{ .pos, .control, .physics, .kinematic }, controlProcess);
world.process(1, &.{ .pos, .kinematic }, kinematicProcess);
world.process(1, &.{ .sprite, .staticAnim }, staticAnimProcess);
world.process(1, &.{ .sprite, .controlAnim, .control }, controlAnimProcess);
world.process(1, &.{ .pos, .sprite }, drawProcess);
map.draw(); map.draw();
for (circuit.cells) |cell, i| { for (circuit.cells) |cell, i| {
@ -199,7 +204,7 @@ export fn update() void {
else => size = Vec2{ 8, 8 }, else => size = Vec2{ 8, 8 },
} }
if (circuit.isEnabled(util.vec2cell(pos))) { if (details.active) {
w4.tone(.{ .start = 60, .end = 1 }, .{ .release = 30, .sustain = 0 }, 10, .{ .channel = .triangle }); w4.tone(.{ .start = 60, .end = 1 }, .{ .release = 30, .sustain = 0 }, 10, .{ .channel = .triangle });
w4.DRAW_COLORS.* = 0x0020; w4.DRAW_COLORS.* = 0x0020;
} else { } else {
@ -268,7 +273,8 @@ fn wireManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
} }
if (Circuit.is_plug(circuit.get_cell(mapPos) orelse 0)) { if (Circuit.is_plug(circuit.get_cell(mapPos) orelse 0)) {
indicator = .{ .t = .plug, .pos = mapPos * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 } }; const active = circuit.isEnabled(mapPos);
indicator = .{ .t = .plug, .pos = mapPos * @splat(2, @as(i32, 8)) + Vec2{ 4, 4 }, .active = active };
if (input.btnp(.one, .two)) { if (input.btnp(.one, .two)) {
nodes[details.which].pinned = true; nodes[details.which].pinned = true;
nodes[details.which].pos = vec2tovec2f(indicator.?.pos); nodes[details.which].pos = vec2tovec2f(indicator.?.pos);
@ -296,14 +302,14 @@ fn wireManipulationProcess(_: f32, pos: *Pos, control: *Control) void {
var dist = util.distancef(begin, offsetPos); var dist = util.distancef(begin, offsetPos);
if (dist < minDistance) { if (dist < minDistance) {
minDistance = dist; minDistance = dist;
indicator = .{ .t = .wire, .pos = vec2ftovec2(begin) }; indicator = .{ .t = .wire, .pos = vec2ftovec2(begin), .active = wire.enabled };
interactWireID = entityID; interactWireID = entityID;
which = 0; which = 0;
} }
dist = util.distancef(end, offsetPos); dist = util.distancef(end, offsetPos);
if (dist < minDistance) { if (dist < minDistance) {
minDistance = dist; minDistance = dist;
indicator = .{ .t = .wire, .pos = vec2ftovec2(end) }; indicator = .{ .t = .wire, .pos = vec2ftovec2(end), .active = wire.enabled };
interactWireID = entityID; interactWireID = entityID;
which = wire.nodes.len - 1; which = wire.nodes.len - 1;
} }
@ -391,11 +397,12 @@ fn wireDrawProcess(_: f32, wire: *Wire) void {
var nodes = wire.nodes.slice(); var nodes = wire.nodes.slice();
if (nodes.len == 0) return; if (nodes.len == 0) return;
w4.DRAW_COLORS.* = 0x0002; w4.DRAW_COLORS.* = if (wire.enabled) 0x0002 else 0x0003;
for (nodes) |node, i| { for (nodes) |node, i| {
if (i == 0) continue; if (i == 0) continue;
w4.line(vec2ftovec2(nodes[i - 1].pos), vec2ftovec2(node.pos)); w4.line(vec2ftovec2(nodes[i - 1].pos), vec2ftovec2(node.pos));
} }
wire.enabled = false;
} }
fn vec2tovec2f(vec2: w4.Vec2) Vec2f { fn vec2tovec2f(vec2: w4.Vec2) Vec2f {