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 | + | local lever = "front" -- redstone side to check |
| 7 | ||
| 8 | -- 2) Wrap peripherals | |
| 9 | local shield = peripheral.find("warpdriveForceFieldProjector")
| |
| 10 | local speaker = peripheral.find("warpdriveSpeaker")
| |
| 11 | assert(shield, "ForceFieldProjector not found!") | |
| 12 | ||
| 13 | - | -- 3) Speak helper (no-op if no speaker) |
| 13 | + | -- 3) Speak helper (only if speaker exists AND redstone input is active) |
| 14 | local function trySpeak(msg) | |
| 15 | - | if speaker then speaker.speak(msg) end |
| 15 | + | if speaker and redstone.getInput(lever) then |
| 16 | speaker.speak(msg) | |
| 17 | end | |
| 18 | - | -- 4) Compute the offset point and distance |
| 18 | + | |
| 19 | ||
| 20 | -- 4) Compute offset point and distance | |
| 21 | local function shieldOffset(lx, ly, lz, fx, fy, fz) | |
| 22 | local dx, dy, dz = lx - fx, ly - fy, lz - fz | |
| 23 | local distance = math.sqrt(dx*dx + dy*dy + dz*dz) | |
| 24 | dx, dy, dz = dx/distance, dy/distance, dz/distance | |
| 25 | return | |
| 26 | lx + dx * OffsetValue, | |
| 27 | ly + dy * OffsetValue, | |
| 28 | lz + dz * OffsetValue, | |
| 29 | distance | |
| 30 | end | |
| 31 | ||
| 32 | -- 5) Ensure config script exists | |
| 33 | if not fs.exists("conf") then
| |
| 34 | shell.run("pastebin get 38M5cNbZ conf")
| |
| 35 | term.clear() | |
| 36 | end | |
| 37 | ||
| 38 | -- 6) Open all modems for Rednet | |
| 39 | for _, side in ipairs(peripheral.getNames()) do | |
| 40 | if peripheral.getType(side) == "modem" then | |
| 41 | rednet.open(side) | |
| 42 | end | |
| 43 | - | -- 7) Announce readiness |
| 43 | + | |
| 44 | - | print("Control System Online, Toggle Redstone To Toggle Shields, Press C to Configure")
|
| 44 | + | |
| 45 | - | trySpeak("Control System Online")
|
| 45 | + | -- 7) One–time disable on boot |
| 46 | shield.enable(false) | |
| 47 | - | -- 8) Determine shield range multiplier |
| 47 | + | |
| 48 | -- 8) Announce readiness | |
| 49 | print("Control System Online, Toggle via Rednet → Press C to Configure")
| |
| 50 | ||
| 51 | -- 9) Determine shield range multiplier | |
| 52 | local _, upgrades = shield.getUpgrades() | |
| 53 | local Size = ({
| |
| 54 | ["1/4 x Range"] = 16, | |
| 55 | ["2/4 x Range"] = 32, | |
| 56 | ["3/4 x Range"] = 48, | |
| 57 | - | -- 9) State‐monitor coroutine: watch for shield enable/disable changes |
| 57 | + | |
| 58 | ["0/4 x Range"] = 0, | |
| 59 | })[upgrades:match("(%d/4 x Range)")] or 32
| |
| 60 | ||
| 61 | -- 10) State-monitor coroutine: announce on enable/disable | |
| 62 | local function stateMonitor() | |
| 63 | local prevEnabled = shield.enable() | |
| 64 | - | print("Shield state changed → ENABLED")
|
| 64 | + | |
| 65 | - | trySpeak("Shield enabled")
|
| 65 | + | |
| 66 | if enabled ~= prevEnabled then | |
| 67 | if enabled then | |
| 68 | - | print("Shield state changed → DISABLED")
|
| 68 | + | |
| 69 | - | trySpeak("Shield disabled")
|
| 69 | + | |
| 70 | rednet.broadcast("StatOFF", "SMiner")
| |
| 71 | end | |
| 72 | prevEnabled = enabled | |
| 73 | end | |
| 74 | os.sleep(0.5) | |
| 75 | end | |
| 76 | end | |
| 77 | ||
| 78 | - | -- 10) Rednet‐listener coroutine: respond to "check" queries |
| 78 | + | -- 11) Rednet-listener coroutine: reply to “check” |
| 79 | local function rednetListener() | |
| 80 | while true do | |
| 81 | local _, message = rednet.receive("SMiner")
| |
| 82 | if message == "check" then | |
| 83 | local enabled = shield.enable() | |
| 84 | if enabled then | |
| 85 | - | print("Received check → Shield currently ENABLED")
|
| 85 | + | |
| 86 | - | trySpeak("Shield is enabled")
|
| 86 | + | |
| 87 | rednet.broadcast("StatOFF", "SMiner")
| |
| 88 | end | |
| 89 | - | print("Received check → Shield currently DISABLED")
|
| 89 | + | |
| 90 | - | trySpeak("Shield is disabled")
|
| 90 | + | |
| 91 | end | |
| 92 | ||
| 93 | -- 12) Main control coroutine | |
| 94 | local function mainControl() | |
| 95 | local lastX, lastY, lastZ = 0,0,0 | |
| 96 | local toggledOn = false | |
| 97 | - | -- 11) Main control coroutine: handle incoming target coords, redstone, config |
| 97 | + | |
| 98 | while true do | |
| 99 | local event, p1, p2, p3 = os.pullEventRaw() | |
| 100 | ||
| 101 | if event == "rednet_message" and p3 == "SMineBroadcast" then | |
| 102 | -- unpack broadcast | |
| 103 | - | -- unpack broadcast as p1=sender, p2=table{x,y,z}, p3=protocol
|
| 103 | + | |
| 104 | ||
| 105 | local fx, fy, fz = shield.getLocalPosition() | |
| 106 | local t1x, t1y, t1z, distance = shieldOffset(lastX, lastY, lastZ, fx, fy, fz) | |
| 107 | ||
| 108 | local tx = (t1x - fx) / Size | |
| 109 | - | -- normalize for shield.translation |
| 109 | + | |
| 110 | local tz = (t1z - fz) / Size | |
| 111 | ||
| 112 | local rd = math.floor(distance + 0.5) | |
| 113 | ||
| 114 | - | -- rounded for speech |
| 114 | + | |
| 115 | - | local rd = math.floor(distance + 0.5) |
| 115 | + | print("Target too close → disabling shield")
|
| 116 | - | local rt1x = math.floor(t1x + 0.5) |
| 116 | + | trySpeak("Target too close, shield disabled")
|
| 117 | - | local rt1y = math.floor(t1y + 0.5) |
| 117 | + | |
| 118 | - | local rt1z = math.floor(t1z + 0.5) |
| 118 | + | |
| 119 | shield.translation(tx, ty, tz) | |
| 120 | trySpeak("Distance " .. rd)
| |
| 121 | - | print("Target is too Close! Shield Disabled!")
|
| 121 | + | |
| 122 | - | trySpeak("Target is too close! Shield disabled!")
|
| 122 | + | |
| 123 | elseif event == "rednet_message" | |
| 124 | - | trySpeak("Target distance " .. rd)
|
| 124 | + | and p3 == "SMiner" |
| 125 | - | trySpeak(("Offset coords x=%d, y=%d, z=%d"):format(rt1x,rt1y,rt1z))
|
| 125 | + | and p2 == "Toggle" then |
| 126 | - | trySpeak(("Target coords x=%d, y=%d, z=%d"):format(lastX,lastY,lastZ))
|
| 126 | + | -- flip the shield on/off; stateMonitor will announce |
| 127 | toggledOn = not toggledOn | |
| 128 | local fx, fy, fz = shield.getLocalPosition() | |
| 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 | + | if toggledOn and distance > safedist then |
| 132 | shield.enable(true) | |
| 133 | else | |
| 134 | - | elseif event == "redstone" then |
| 134 | + | |
| 135 | - | -- front lever toggles shield (with safedist guard) |
| 135 | + | |
| 136 | ||
| 137 | elseif event == "key" and p1 == keys.c then | |
| 138 | - | local on = redstone.getAnalogInput(lever) |
| 138 | + | print("C key pressed → running 'conf'")
|
| 139 | shell.run("conf")
| |
| 140 | - | if on > 6 and distance > safedist then |
| 140 | + | |
| 141 | end | |
| 142 | - | elseif on > 6 then |
| 142 | + | |
| 143 | - | print("Target is too Close! Shield Disabled!")
|
| 143 | + | |
| 144 | - | trySpeak("Target is too close! Shield disabled!")
|
| 144 | + | -- 13) Run all three loops in parallel |
| 145 | parallel.waitForAny(stateMonitor, rednetListener, mainControl) | |
| 146 |