Advertisement
jaklsfjlsak

4-25-25水平采矿 广播 状态监控 红网控制

Apr 26th, 2025 (edited)
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Combined Shield Control & Monitor with Rednet “Toggle” control (“ztc+”)
  2.  
  3. -- 1) Configuration
  4. local OffsetValue = 3
  5. local safedist    = 15
  6.  
  7. -- 2) Wrap peripherals
  8. local shield  = peripheral.find("warpdriveForceFieldProjector")
  9. local speaker = peripheral.find("warpdriveSpeaker")
  10. assert(shield, "ForceFieldProjector not found!")
  11.  
  12. -- 3) Speak helper (no-op if no speaker)
  13. local function trySpeak(msg)
  14.   if speaker then speaker.speak(msg) end
  15. end
  16.  
  17. -- 4) Compute offset point and distance
  18. local function shieldOffset(lx, ly, lz, fx, fy, fz)
  19.   local dx, dy, dz = lx - fx, ly - fy, lz - fz
  20.   local distance = math.sqrt(dx*dx + dy*dy + dz*dz)
  21.   dx, dy, dz = dx/distance, dy/distance, dz/distance
  22.   return
  23.     lx + dx * OffsetValue,
  24.     ly + dy * OffsetValue,
  25.     lz + dz * OffsetValue,
  26.     distance
  27. end
  28.  
  29. -- 5) Ensure config script exists
  30. if not fs.exists("conf") then
  31.   shell.run("pastebin get 38M5cNbZ conf")
  32.   term.clear()
  33. end
  34.  
  35. -- 6) Open all modems for Rednet
  36. for _, side in ipairs(peripheral.getNames()) do
  37.   if peripheral.getType(side) == "modem" then
  38.     rednet.open(side)
  39.   end
  40. end
  41.  
  42. -- 7) Announce readiness
  43. print("Control System Online, Toggle via Rednet → Press C to Configure")
  44.  
  45. -- 8) Determine shield range multiplier
  46. local _, upgrades = shield.getUpgrades()
  47. local Size = ({
  48.   ["1/4 x Range"] = 16,
  49.   ["2/4 x Range"] = 32,
  50.   ["3/4 x Range"] = 48,
  51.   ["4/4 x Range"] = 64,
  52.   ["0/4 x Range"] = 0,
  53. })[upgrades:match("(%d/4 x Range)")] or 32
  54.  
  55. -- 9) State-monitor coroutine: announce on enable/disable
  56. local function stateMonitor()
  57.   local prevEnabled = shield.enable()
  58.   while true do
  59.     local enabled = shield.enable()
  60.     if enabled ~= prevEnabled then
  61.       if enabled then
  62.         rednet.broadcast("StatON", "SMiner")
  63.       else
  64.         rednet.broadcast("StatOFF", "SMiner")
  65.       end
  66.       prevEnabled = enabled
  67.     end
  68.     os.sleep(0.5)
  69.   end
  70. end
  71.  
  72. -- 10) Rednet-listener coroutine: reply to “check”
  73. local function rednetListener()
  74.   while true do
  75.     local _, message = rednet.receive("SMiner")
  76.     if message == "check" then
  77.       local enabled = shield.enable()
  78.       if enabled then
  79.  
  80.         rednet.broadcast("StatON", "SMiner")
  81.       else
  82.  
  83.         rednet.broadcast("StatOFF", "SMiner")
  84.       end
  85.     end
  86.   end
  87. end
  88.  
  89. -- 11) Main control coroutine
  90. local function mainControl()
  91.   local lastX, lastY, lastZ = 0,0,0
  92.   local toggledOn = false
  93.  
  94.   while true do
  95.     local event, p1, p2, p3 = os.pullEventRaw()
  96.  
  97.     if event == "rednet_message" and p3 == "SMineBroadcast" then
  98.       lastX, lastY, lastZ = p2.x, p2.y, p2.z
  99.  
  100.       local fx, fy, fz = shield.getLocalPosition()
  101.       local t1x, t1y, t1z, distance = shieldOffset(lastX, lastY, lastZ, fx, fy, fz)
  102.  
  103.       local tx = (t1x - fx) / Size
  104.       local ty = (t1y - fy) / Size
  105.       local tz = (t1z - fz) / Size
  106.  
  107.       local rd   = math.floor(distance + 0.5)
  108.  
  109.       if distance < safedist then
  110.         print("Target too close → disabling shield")
  111.         trySpeak("Target too close, shield disabled")
  112.         shield.enable(false)
  113.       else
  114.         shield.translation(tx, ty, tz)
  115.         trySpeak("Distance " .. rd)
  116.       end
  117.  
  118.     elseif event == "rednet_message"
  119.        and p3 == "SMiner"
  120.        and p2 == "Toggle" then
  121.       -- **only flip the shield**; let stateMonitor announce it
  122.       toggledOn = not toggledOn
  123.       local fx, fy, fz = shield.getLocalPosition()
  124.       local _,_,_,distance = shieldOffset(lastX, lastY, lastZ, fx, fy, fz)
  125.  
  126.       if toggledOn and distance > safedist then
  127.         shield.enable(true)
  128.       else
  129.         shield.enable(false)
  130.       end
  131.  
  132.     elseif event == "key" and p1 == keys.c then
  133.       print("C key pressed → running 'conf'")
  134.       shell.run("conf")
  135.     end
  136.   end
  137. end
  138.  
  139. -- 12) Run all three loops in parallel
  140. parallel.waitForAny(stateMonitor, rednetListener, mainControl)
  141.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement