-- v1.3.0 local observer = {} local redstone = require("redstone") local npcManager = require("npcManager") local floor = math.floor observer.name = "observer" observer.id = NPC_ID observer.order = 1 observer.onRedPower = function() return true end observer.config = npcManager.setNpcSettings({ id = observer.id, width = 32, height = 32, gfxwidth = 32, gfxheight = 32, gfxoffsetx = 0, gfxoffsety = 0, frames = 1, framespeed = 8, framestyle = 0, invisible = false, width = 32, height = 32, nogravity = true, jumphurt = true, noblockcollision = true, notcointransformable = true, nohurt = true, noyoshi = true, blocknpc = true, playerblock = true, playerblocktop = true, npcblock = true, disabledespawn = false, poweronmove = true -- When the observer gets moved by a piston, activate the observer }) local function scanBox(n, dir) if dir == 0 or dir == 2 then return Colliders.Box(0, 0, n.width*0.5, n.height*0.9) else return Colliders.Box(0, 0, n.width*0.9, n.height*0.5) end end local function updateScanBox(n, dir) if dir == 0 then n.data.observbox.x, n.data.observbox.y = n.x - n.width*0.5, n.y + n.height*0.05 elseif dir == 1 then n.data.observbox.x, n.data.observbox.y = n.x + n.width*0.05, n.y - n.height*0.5 elseif dir == 2 then n.data.observbox.x, n.data.observbox.y = n.x + n.width, n.y + n.height*0.05 else n.data.observbox.x, n.data.observbox.y = n.x + n.width*0.05, n.y + n.height end end function observer.prime(n) local data = n.data data.animFrame = data.animFrame or 0 data.animTimer = data.animTimer or 0 data.frameX = data._settings.dir or 0 data.frameY = data.frameY or 0 data.powerTimer = data.powerTimer or 0 data.isOn = data.isOn or false data.observNotice = data.observNotice or false data.prevX = data.prevX or floor(n.x) data.prevY = data.prevY or floor(n.y) data.observbox = scanBox(n, data.frameX) data.redhitbox = redstone.basicDirectionalRedHitBox(n, (data.frameX + 2)%4) end function observer.onRedTick(n) local data = n.data data.observ = false if data.isOn then redstone.updateDirectionalRedHitBox(n, (data.frameX + 2)%4) redstone.passDirectionEnergy{source = n, power = data.power, hitbox = data.redhitbox} data.powerTimer = data.powerTimer + 1 if data.powerTimer == 4 then data.observ = true elseif data.powerTimer >= 5 and not data.observNotice then data.powerTimer = 0 data.isOn = false end end if data.isOn then data.frameY = 1 else data.frameY = 0 end data.observNotice = false end local filter = function(n) return n.data.observ end function observer.onRedTickObserver(n) local data = n.data updateScanBox(n, data.frameX) for _, v in ipairs(Colliders.getColliding{a = data.observbox, b = NPC.ALL, btype = Colliders.NPC, filter = filter}) do data.isOn = true data.power = v.data.observpower data.observNotice = true break end if observer.config.poweronmove then n.x = floor(n.x) n.y = floor(n.y) if data.prevX ~= n.x or data.prevY ~= n.y then data.isOn = true data.power = 15 data.observNotice = true end data.prevX = n.x data.prevY = n.y end end function observer.onRedDraw(n) redstone.drawNPC(n) end redstone.register(observer) return observer