mirror of
https://github.com/osmarks/random-stuff
synced 2024-12-28 19:10:35 +00:00
143 lines
3.7 KiB
Lua
143 lines
3.7 KiB
Lua
local other_monitor
|
|
repeat
|
|
other_monitor = peripheral.wrap "monitor_5213"
|
|
until other_monitor
|
|
local integrators = {}
|
|
for i = 937, 942 do
|
|
table.insert(integrators, peripheral.wrap("redstone_integrator_" .. i))
|
|
end
|
|
local big_screen = peripheral.wrap "left"
|
|
local sensor = peripheral.wrap "right"
|
|
local screen_center = vector.new(1, 0, 0.5)
|
|
|
|
local trusted = {
|
|
gollark = true,
|
|
heav_ = true,
|
|
["6_4"] = true
|
|
}
|
|
local targets = {}
|
|
|
|
local function center(text)
|
|
local w, h = term.getSize()
|
|
local x, y = term.getCursorPos()
|
|
local start = (w-#text)/2
|
|
term.setCursorPos(start, y)
|
|
term.write(text)
|
|
end
|
|
|
|
local function redraw()
|
|
big_screen.setTextScale(0.5)
|
|
local orig = term.redirect(big_screen)
|
|
term.setCursorPos(1, 4)
|
|
term.setTextColor(colors.white)
|
|
term.setBackgroundColor(colors.black)
|
|
term.clear()
|
|
center "Initiative Sigma Conference Room"
|
|
term.setCursorPos(1, 5)
|
|
center "Restricted Area"
|
|
term.setCursorPos(1, 6)
|
|
center "Retina Scan Required"
|
|
term.setCursorPos(1, 1)
|
|
term.redirect(orig)
|
|
end
|
|
|
|
redraw()
|
|
|
|
local function set_state(state)
|
|
for _, i in pairs(integrators) do
|
|
i.setOutput("west", state)
|
|
i.setOutput("east", state)
|
|
end
|
|
end
|
|
|
|
local function scan()
|
|
local nearby = sensor.sense()
|
|
local ret = {}
|
|
for k, v in pairs(nearby) do
|
|
v.s = vector.new(v.x, v.y, v.z)
|
|
v.v = vector.new(v.motionX, v.motionY, v.motionZ)
|
|
v.distance = v.s:length()
|
|
if v.displayName == v.name then ret[v.name] = v end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local function angles_to_axis(yaw, pitch)
|
|
return vector.new(
|
|
-math.sin(math.rad(yaw)) * math.cos(math.rad(pitch)),
|
|
-math.sin(math.rad(pitch)),
|
|
math.cos(math.rad(yaw)) * math.cos(math.rad(pitch))
|
|
)
|
|
end
|
|
|
|
local function vector_sqlength(self)
|
|
return self.x * self.x + self.y * self.y + self.z * self.z
|
|
end
|
|
|
|
local function project(line_start, line_dir, point)
|
|
local t = (point - line_start):dot(line_dir) / vector_sqlength(line_dir)
|
|
return line_start + line_dir * t, t
|
|
end
|
|
|
|
set_state(false)
|
|
|
|
local function display_animation()
|
|
local orig = term.redirect(big_screen)
|
|
for y = 1, select(2, term.getSize()) do
|
|
term.setBackgroundColor(colors.black)
|
|
term.clear()
|
|
term.setCursorPos(1, y)
|
|
term.setBackgroundColor(colors.red)
|
|
term.clearLine()
|
|
sleep(0.1)
|
|
end
|
|
term.redirect(orig)
|
|
end
|
|
|
|
local function is_looking_at_screen(p)
|
|
local closest_point, t = project(p.s, angles_to_axis(p.yaw, p.pitch), screen_center)
|
|
local dist = (closest_point - screen_center):length()
|
|
return p.distance < 5 and dist < 0.6
|
|
end
|
|
|
|
local function retina_scan()
|
|
while true do
|
|
local nearby = scan()
|
|
for _, p in pairs(nearby) do
|
|
if is_looking_at_screen(p) then
|
|
display_animation()
|
|
print(p.name)
|
|
local new_scan = scan()
|
|
if trusted[p.name] and new_scan[p.name] and is_looking_at_screen(new_scan[p.name]) then
|
|
print "opening"
|
|
set_state(true)
|
|
end
|
|
redraw()
|
|
sleep(2)
|
|
set_state(false)
|
|
end
|
|
end
|
|
sleep(0.1)
|
|
end
|
|
end
|
|
|
|
local function inner_door()
|
|
local orig = term.redirect(other_monitor)
|
|
term.setTextColor(colors.white)
|
|
term.setBackgroundColor(colors.black)
|
|
term.clear()
|
|
term.setCursorPos(1, 3)
|
|
center " Press to exit"
|
|
term.redirect(orig)
|
|
while true do
|
|
local ev, side = os.pullEvent "monitor_touch"
|
|
if side == peripheral.getName(other_monitor) then
|
|
print "opening from inside"
|
|
set_state(true)
|
|
sleep(2)
|
|
set_state(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
parallel.waitForAll(inner_door, retina_scan) |