From 55c12f48284cb3f59981581d14cfe6489fe22cf3 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Sun, 7 Aug 2022 21:20:22 -0600 Subject: [PATCH] Update state of circuit graph --- src/game.zig | 20 ++++++++--- src/world.zig | 92 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/game.zig b/src/game.zig index 2c6a4f2..f87b180 100644 --- a/src/game.zig +++ b/src/game.zig @@ -10,6 +10,7 @@ const State = @import("main.zig").State; // const Disk = @import("disk.zig"); const extract = @import("extract.zig"); const world = @import("world.zig"); +const Coord = world.Coordinate; const world_data = @embedFile(@import("world_data").path); const Vec2 = util.Vec2; @@ -253,6 +254,15 @@ fn loadLevel(lvl: usize) !void { } } + { + var i: usize = 0; + while (level.getJoin(i)) |join| : (i += 1) { + const globalc = Coord.fromWorld(level.world_x, level.world_y).addC(join); + if (db.isEnergized(globalc)) { + circuit.addSource(.{join.val[0], join.val[1]}); + } + } + } try coins.resize(0); // if (!try Disk.load()) { @@ -268,7 +278,6 @@ fn loadLevel(lvl: usize) !void { // } try updateCircuit(); - } fn moveLevel(direction: enum { L, R, U, D }) !void { @@ -625,6 +634,10 @@ fn manipulationProcess(pos: *Pos, control: *Control) !void { control.grabbing = .{ .id = wire.id, .which = wire.which }; wires.slice()[wire.id].nodes.slice()[wire.which].pos = pos.pos + Vec2f{ 0, -4 }; wires.slice()[wire.id].nodes.slice()[wire.which].pinned = false; + const local32 = vec2ftovec2(wires.slice()[wire.id].nodes.slice()[wire.which].pos / @splat(2, @as(f32, 8))); + const x = level.world_x * 20 + @intCast(i16, local32[0]); + const y = level.world_y * 20 + @intCast(i16, local32[1]); + db.disconnectPlug(Coord.init(.{ x, y })); try updateCircuit(); }, .plug => |plug| { @@ -654,8 +667,7 @@ fn updateCircuit() !void { circuit.bridge(.{ cellBegin, cellEnd }, wireID); - const Coord = world.Coordinate; - const topleft = Coord.fromWorld( level.world_x, level.world_y ); + const topleft = Coord.fromWorld(level.world_x, level.world_y); const p1 = Coord.init(.{ @intCast(i16, cellBegin[0]), @intCast(i16, cellBegin[1]), @@ -695,7 +707,7 @@ fn updateCircuit() !void { try map.set_cell(door, world.Tiles.Empty); } - + db.updateCircuit(); } fn wirePhysicsProcess(dt: f32, wire: *Wire) !void { diff --git a/src/world.zig b/src/world.zig index 09dc7a5..a7d71da 100644 --- a/src/world.zig +++ b/src/world.zig @@ -307,6 +307,26 @@ pub const Level = struct { return tiles[i]; } + pub fn getJoin(level: Level, which: usize) ?Coordinate { + const tiles = level.tiles orelse return null; + var joinCount: usize = 0; + for (tiles) |tile, i| { + switch (tile) { + .flags => |flag| { + if (flag.circuit == .Join) { + if (joinCount == which) { + const x = @intCast(i16, @mod(i, 20)); + const y = @intCast(i16, @divFloor(i, 20)); + return Coord.init(.{ x, y }); + } + } + }, + else => continue, + } + } + return null; + } + pub fn getWire(level: *Level, num: usize) ?[2]Entity { std.debug.assert(level.entities != null); var node_begin: ?Entity = null; @@ -622,15 +642,71 @@ pub const Database = struct { if (!p1.eq(node.coord) or !p2.eq(node.coord)) continue; if (p1.eq(node.coord)) opt1 = i else opt2 = i; } - var w1 = db.circuit_info[opt1 orelse return]; - var w2 = db.circuit_info[opt2 orelse return]; + var plug1 = db.circuit_info[opt1 orelse return]; + var plug2 = db.circuit_info[opt2 orelse return]; - if (w1.energized and !w2.energized) { - w2.energized = true; - w2.kind.Plug = @intCast(NodeID, opt1.?); - } else if (w2.energized and !w1.energized) { - w1.energized = true; - w1.kind.Plug = @intCast(NodeID, opt2.?); + if (plug1.energized and !plug2.energized) { + plug2.energized = true; + plug2.kind.Plug = @intCast(NodeID, opt1.?); + } else if (plug2.energized and !plug1.energized) { + plug1.energized = true; + plug1.kind.Plug = @intCast(NodeID, opt2.?); + } + } + + pub fn disconnectPlug(db: *Database, plug: Coord) void { + for (db.circuit_info) |node, i| { + if (!plug.eq(node.coord)) continue; + db.circuit_info[i].energized = false; + } + } + + pub fn isEnergized(db: *Database, coord: Coord) bool { + for (db.circuit_info) |node, i| { + if (!coord.eq(node.coord)) continue; + return db.circuit_info[i].energized; + } + return false; + } + + pub fn updateCircuit(db: *Database) void { + for (db.circuit_info) |node, i| { + switch (node.kind) { + .And => |And| { + const input1 = db.circuit_info[And[0]].energized; + const input2 = db.circuit_info[And[1]].energized; + db.circuit_info[i].energized = (input1 and input2); + }, + .Xor => |Xor| { + const input1 = db.circuit_info[Xor[0]].energized; + const input2 = db.circuit_info[Xor[1]].energized; + db.circuit_info[i].energized = (input1 and !input2) or (input2 and !input1); + }, + .Source => db.circuit_info[i].energized = true, + .Conduit => |Conduit| { + const input1 = db.circuit_info[Conduit[0]].energized; + const input2 = db.circuit_info[Conduit[1]].energized; + db.circuit_info[i].energized = (input1 or input2); + }, + .Plug => |plug_opt| { + if (plug_opt) |input| { + db.circuit_info[i].energized = db.circuit_info[input].energized; + } else { + db.circuit_info[i].energized = false; + } + }, + .Switch => |state| { + // TODO Rework switch to make sense + db.circuit_info[i].energized = false; + _ = state; + }, + .Join => |Join| { + db.circuit_info[i].energized = db.circuit_info[Join].energized; + }, + .Outlet => |Outlet| { + db.circuit_info[i].energized = db.circuit_info[Outlet].energized; + }, + } } } };