local Wire = { NORTH = 1, EAST = 2, SOUTH = 4, WEST = 8, } Wire.directions = { {bit = Wire.NORTH, opposite = Wire.SOUTH, x = 0, y = -1}, {bit = Wire.EAST, opposite = Wire.WEST, x = 1, y = 0}, {bit = Wire.SOUTH, opposite = Wire.NORTH, x = 0, y = 1}, {bit = Wire.WEST, opposite = Wire.EAST, x = -1, y = 0}, } function Wire.has(mask, bit) return math.floor((mask or 0) / bit) % 2 == 1 end function Wire.add(mask, bit) mask = mask or 0 return Wire.has(mask, bit) and mask or mask + bit end function Wire.remove(mask, bit) mask = mask or 0 return Wire.has(mask, bit) and mask - bit or mask end function Wire.directionBetween(a, b) local dx, dy = b.x - a.x, b.y - a.y for _, direction in ipairs(Wire.directions) do if direction.x == dx and direction.y == dy then return direction end end end -- Circuit colours are deliberately independent from the RGB gameplay layers. -- A stable hash makes a route keep the same editor colour after save/load. local palette = { {1.00, 0.78, 0.20}, {0.20, 0.92, 0.92}, {1.00, 0.42, 0.72}, {0.62, 1.00, 0.32}, {0.72, 0.55, 1.00}, {1.00, 0.55, 0.22}, } function Wire.color(circuitId) local hash = 0 for index = 1, #(circuitId or "") do hash = (hash * 33 + circuitId:byte(index)) % 65521 end return palette[hash % #palette + 1] end return Wire