View difference between Paste ID: 42ukkniu and Tzrk2rHg
SHOW: | | - or go back to the newest paste.
1-
-- Combined Shield Control & Monitor (“ztc+”)
1+
-- Combined Shield Control & Monitor with Rednet “Toggle” control (“ztc+”)
2
3
-- 1) Configuration
4
local OffsetValue = 3
5
local safedist    = 15
6-
local lever       = "front"
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-
-- 4) Compute the offset point and distance
18+
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-
print("Control System Online, Toggle Redstone To Toggle Shields, Press C to Configure")
44+
45-
trySpeak("Control System Online")
45+
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-
-- 9) State‐monitor coroutine: watch for shield enable/disable changes
57+
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-
        print("Shield state changed → ENABLED")
64+
65-
        trySpeak("Shield enabled")
65+
66
      prevEnabled = enabled
67
    end
68-
        print("Shield state changed → DISABLED")
68+
69-
        trySpeak("Shield disabled")
69+
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-
-- 10) Rednet‐listener coroutine: respond to "check" queries
78+
79
80
        rednet.broadcast("StatON", "SMiner")
81
      else
82
83
        rednet.broadcast("StatOFF", "SMiner")
84
      end
85-
        print("Received check → Shield currently ENABLED")
85+
86-
        trySpeak("Shield is enabled")
86+
87
end
88
89-
        print("Received check → Shield currently DISABLED")
89+
-- 11) Main control coroutine
90-
        trySpeak("Shield is disabled")
90+
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-
-- 11) Main control coroutine: handle incoming target coords, redstone, config
97+
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-
      -- unpack broadcast as p1=sender, p2=table{x,y,z}, p3=protocol
103+
104
      local ty = (t1y - fy) / Size
105
      local tz = (t1z - fz) / Size
106
107
      local rd   = math.floor(distance + 0.5)
108
109-
      -- normalize for shield.translation
109+
110
        print("Target too close → disabling shield")
111
        trySpeak("Target too close, shield disabled")
112
        shield.enable(false)
113
      else
114-
      -- rounded for speech
114+
115
        trySpeak("Distance " .. rd)
116-
      local rt1x = math.floor(t1x     + 0.5)
116+
117-
      local rt1y = math.floor(t1y     + 0.5)
117+
118-
      local rt1z = math.floor(t1z     + 0.5)
118+
    elseif event == "rednet_message" 
119
       and p3 == "SMiner" 
120
       and p2 == "Toggle" then
121-
        print("Target is too Close! Shield Disabled!")
121+
      -- **only flip the shield**; let stateMonitor announce it
122-
        trySpeak("Target is too close! Shield disabled!")
122+
      toggledOn = not toggledOn
123
      local fx, fy, fz = shield.getLocalPosition()
124-
        trySpeak("Target distance " .. rd)
124+
125-
        trySpeak(("Offset coords x=%d, y=%d, z=%d"):format(rt1x,rt1y,rt1z))
125+
126-
        trySpeak(("Target coords x=%d, y=%d, z=%d"):format(lastX,lastY,lastZ))
126+
      if toggledOn and distance > safedist then
127
        shield.enable(true)
128
      else
129-
        trySpeak("Target distance " .. rd)
129+
130-
        trySpeak(("Offset coords x=%d, y=%d, z=%d"):format(rt1x,rt1y,rt1z))
130+
131-
        trySpeak(("Target coords x=%d, y=%d, z=%d"):format(lastX,lastY,lastZ))
131+
132
    elseif event == "key" and p1 == keys.c then
133
      print("C key pressed → running 'conf'")
134-
    elseif event == "redstone" then
134+
135-
      -- front lever toggles shield (with safedist guard)
135+
136
  end
137
end
138-
      local on = redstone.getAnalogInput(lever)
138+
139
-- 12) Run all three loops in parallel
140-
      if on > 6 and distance > safedist then
140+
141