Advertisement
osmarks

Thing doing software

Feb 22nd, 2022 (edited)
683
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.12 KB | None | 0 0
  1. local username = "gollark"
  2. local ni = peripheral.wrap "back"
  3. local w, h = ni.canvas().getSize()
  4. if _G.thing_group then
  5.     pcall(_G.thing_group.remove)
  6. end
  7. local group
  8. local function initialize_group_thing()
  9.     if group then pcall(group.remove) end
  10.     group = ni.canvas().addGroup({ w - 70, 10 })
  11.     _G.thing_group = group
  12. end
  13. initialize_group_thing()
  14.  
  15. local targets = {}
  16.  
  17. local function is_target(name)
  18.     for target, type in pairs(targets) do
  19.         if name:lower():match(target) then return type end
  20.     end
  21. end
  22.  
  23. local function vector_sqlength(self)
  24.     return self.x * self.x + self.y * self.y + self.z * self.z
  25. end
  26.  
  27. local function project(line_start, line_dir, point)
  28.     local t = (point - line_start):dot(line_dir) / vector_sqlength(line_dir)
  29.     return line_start + line_dir * t, t
  30. end
  31.  
  32. local function calc_yaw_pitch(v)
  33.     local x, y, z = v.x, v.y, v.z
  34.     local pitch = -math.atan2(y, math.sqrt(x * x + z * z))
  35.     local yaw = math.atan2(-x, z)
  36.     return math.deg(yaw), math.deg(pitch)
  37. end
  38.  
  39. local counterattack = false
  40. local addressed_lasers = {}
  41. local timers = {}
  42. local function bool_to_yn(b)
  43.     if b == true then return "y"
  44.     elseif b == false then return "n"
  45.     else return "?" end
  46. end
  47. local laser_power = 5
  48.  
  49. local status_lines = {}
  50. local notices = {}
  51. local function push_notice(t)
  52.     table.insert(notices, { t, os.epoch "utc" })
  53. end
  54.  
  55. local function lase(entity)
  56.     local target_location = entity.s
  57.     for i = 1, 5 do
  58.         target_location = entity.s + entity.v * (target_location:length() / 1.5)
  59.     end
  60.     local y, p = calc_yaw_pitch(target_location)
  61.     ni.fire(y, p, laser_power)
  62. end
  63.  
  64. local user_meta
  65. local fast_mode_reqs = {}
  66.  
  67. local function scan_entities()
  68.     while true do
  69.         fast_mode_reqs.laser = false
  70.         fast_mode_reqs.acting = false
  71.         local entities = ni.sense()
  72.         local maybe_players = {}
  73.         local things = {}
  74.         local notices = {}
  75.         local lasers = {}
  76.         user_meta = ni.getMetaByName(username)
  77.         user_meta.motionY = user_meta.motionY + 0.07840001
  78.         local v = vector.new(user_meta.motionX, user_meta.motionY, user_meta.motionZ)
  79.  
  80.         status_lines.vel = ("Vel: %.2f/%.2f"):format(v:length(), user_meta.motionY)
  81.  
  82.         for _, entity in pairs(entities) do
  83.             entity.s = vector.new(entity.x, entity.y, entity.z)
  84.             entity.v = vector.new(entity.motionX, entity.motionY, entity.motionZ)
  85.             if entity.displayName ~= username then
  86.                 things[entity.displayName] = (things[entity.displayName] or 0) + 1
  87.             end
  88.             if entity.displayName ~= username and entity.displayName == entity.name and (math.floor(entity.yaw) ~= entity.yaw and math.floor(entity.pitch) ~= entity.pitch) then -- player, quite possibly
  89.                 entity.v = entity.v + vector.new(0, 0.0784, 0)
  90.                 table.insert(maybe_players, entity)
  91.             end
  92.             if entity.name == "plethora:laser" and not addressed_lasers[entity.id] then
  93.                 local closest_approach, param = project(entity.s, entity.v - v, vector.new(0, 0, 0))
  94.                 if param > 0 and vector_sqlength(closest_approach) < 5 then
  95.                     push_notice "Laser detected"
  96.                     fast_mode_reqs.laser = true
  97.                     local time_to_impact = (entity.s:length() / (entity.v - v):length()) / 20
  98.                     print("got inbound laser", time_to_impact, vector_sqlength(closest_approach), param)
  99.                     addressed_lasers[entity.id] = true
  100.                     timers[os.startTimer(math.max(0, time_to_impact / 2 - 0.1))] = { "dodge", entity }
  101.                     timers[os.startTimer(15)] = { "clear", entity.id }
  102.                     table.insert(lasers, entity)
  103.                 end
  104.             end
  105.         end
  106.         for _, laser in pairs(lasers) do
  107.             for _, player in pairs(maybe_players) do
  108.                 local closest_approach, param = project(laser.s, laser.v, player.s)
  109.                 print(player.displayName, closest_approach, param)
  110.                 if param < 0 and vector_sqlength(closest_approach - player.s) < 8 and counterattack then
  111.                     print("execute counterattack", player.displayName)
  112.                     push_notice(("Counterattack %s"):format(player.displayName))
  113.                     --lase(player, 5)
  114.                     targets[player.displayName:lower()] = "laser"
  115.                 end
  116.             end
  117.         end
  118.        
  119.         status_lines.counterattacks = "Counter: " .. bool_to_yn(counterattack)
  120.  
  121.         local i = 0
  122.         local ok, err = pcall(group.clear)
  123.         if not ok then
  124.             initialize_group_thing()
  125.         end
  126.         local time = os.epoch "utc"
  127.         for _, text
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement