Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --utils
- local function output(line,str,_m)
- _m = _m or term
- _m.setCursorPos(1,line)
- _m.clearLine()
- _m.write(str)
- end
- local _floor = math.floor
- local function strTime(sec)
- local str,d,h,m,s = "", _floor(sec/86400),_floor(sec/3600)%24,_floor(sec/60)%60,_floor(sec%60)
- if d>0 then str = d>1 and d.." days " or "1 day " end
- if h>0 then str = str..h.."h" end
- if m>0 then str = str..(m>9 and m or "0"..m) end
- if h==0 then str = m>0 and str..":"..(s>9 and s or "0"..s) or s.."s" end
- return str
- end
- --init
- local iniFile = "/.settings/ZombieSelector"
- if fs.exists(iniFile) then
- settings.load(iniFile)
- end
- settings.set("shell.allow_disk_startup",false)
- settings.save(iniFile)
- --init redstone
- rs.setOutput("top",false) sleep(.05)
- if rs.getInput("top") then
- term.setCursorPos(1,1)
- term.clear()
- error("Redstone input on top should be OFF",0)
- return
- end
- --init Cells positions
- if not fs.exists("/cell") then
- local fh = fs.open("/cell","w")
- fh.write([[-- <Peripheral name> = { x = <Num>, y = <Num>, z = <Num> }
- -- <Peripheral name> Correspond au nom du coputer qui contrôle la cellule
- -- x,y,z Correspondent à la position de la cellule
- -- s Le signal redstone de 1 à 15 (confirmation)
- computer_0 = { x = 0, y = 0, z = 0, s=0 }
- ]])
- fh.close()
- end
- os.loadAPI("/cell")
- if not os.loadAPI("/cell") or type(cell.computer_0) ~= "nil" then
- term.setCursorPos(1,1)
- term.clear()
- print("Required: Edit coords in file /cell")
- print("Press Y/N")
- local confirm = false
- while not confirm do
- local e,k = os.pullEvent("key")
- if e=="key" and (k==keys.y or k==keys.n) then
- confirm = true
- if k==keys.n then
- sleep(.2)
- error("Terminated",0)
- return
- else
- shell.run("edit /cell")
- sleep(1)
- end
- end
- end
- end
- --init Career wanted list
- if not fs.exists("/wanted") then
- local fh = fs.open("/wanted","w")
- fh.write([[--Career wanted list
- -- true: wanted
- -- false: unwanted
- career = {
- ["Brown Robe (Farmer)"] = true,
- ["Farmer"] = true,
- ["Fisherman"] = true,
- ["Shepherd"] = true,
- ["Fletcher"] = true,
- ["White Robe (Librarian)"] = true,
- ["Librarian"] = true,
- ["Purple Robe (Priest)"] = true,
- ["Cleric"] = true,
- ["Black Apron (Blacksmith)"] = true,
- ["Armorer"] = true,
- ["Weapon Smith"] = true,
- ["Tool Smith"] = true,
- ["White Apron (butcher)"] = true,
- ["Butcher"] = true,
- ["Leatherworker"] = true,
- ["Green Robe (Nitwit 1.11)"] = true,
- ["Nitwit (1.11)"] = true,
- }]])
- fh.close()
- end
- os.loadAPI("/wanted")
- --init Peripherals
- ed = peripheral.find("EntityDetector")
- if not ed then
- term.setCursorPos(1,1)
- term.clear()
- error("Network require Entity Detector (peripheral not found)",0)
- return
- end
- local _getEntityList = ed.getEntityList
- wi = peripheral.find("WorldInterface")
- if not wi then
- term.setCursorPos(1,1)
- term.clear()
- error("Network require World Interface (peripheral not found",0)
- return
- end
- local _getBlockInfos = wi.getBlockInfos
- local drive = peripheral.find("drive")
- if not drive then
- term.setCursorPos(1,1)
- term.clear()
- error("Network require a disk drive (peripheral not found)",0)
- return
- end
- if not drive.isDiskPresent() or not drive.hasData() then
- term.setCursorPos(1,1)
- term.clear()
- error("Disk drive require Floppy Disk",0)
- return
- end
- local path = "/"..drive.getMountPath().."/startup"
- if drive.getDiskLabel()~="ZombieSelector_RS_Pulse" then
- term.setCursorPos(1,1)
- term.clear()
- print("Overwrite Disk ?")
- print("Press Y/N")
- local confirm = false
- while not confirm do
- local e,k = os.pullEvent("key")
- if e=="key" and (k==keys.y or k==keys.n) then
- confirm = true
- if k==keys.n then
- sleep(.2)
- error("Terminated",0)
- return
- else
- if fs.exists(path) then
- fs.delete(path)
- end
- drive.setDiskLabel("ZombieSelector_RS_Pulse")
- end
- end
- end
- end
- if not fs.exists(path) then
- sleep(.2)
- term.clear()
- term.setCursorPos(1,1)
- print("Input master computer coords :\nX:\nY:\nZ:")
- term.setCursorPos(3,2)
- local _x = read()
- term.setCursorPos(3,3)
- local _y = read()
- term.setCursorPos(3,4)
- local _z = read()
- if not (tonumber(_x) and tonumber(_y) and tonumber(_z)) then
- term.setCursorPos(1,5)
- error("Invalid coords values",0)
- return
- end
- _x,_y,_z = tonumber(_x), tonumber(_y), tonumber(_z)
- local master = _getBlockInfos(_x,_y,_z)
- if not (master
- and master.blockName == "computercraft:CC-Computer"
- and master.datatags.label
- and master.datatags.label == os.getComputerLabel()
- ) then
- term.setCursorPos(1,5)
- error(string.format("Master computer is not on this coords (%s)",master.blockName),0)
- return
- end
- local fh = fs.open("/disk/startup","w")
- fh.write(string.format([[local wi = peripheral.find("WorldInterface")
- --Coords: Redstone lamp on top of master computer
- local lamp = _getBlockInfos(%d,%d,%d)
- if lamp.blockName=="minecraft:lit_redstone_lamp"
- and lamp.isPowered then
- shell.run("rs pulse top 1 1.6")
- end
- os.shutdown()
- ]],_x, _y+1 ,_z))
- fh.close()
- end
- --functions
- --Villager helper
- -- profession[e.datatags.Profession][e.datatags.Career]
- local profession = {
- [0] = {
- [0] = "Brown Robe (Farmer)",
- [1] = "Farmer",
- [2] = "Fisherman",
- [3] = "Shepherd",
- [4] = "Fletcher",
- },
- [1] = {
- [0] = "White Robe (Librarian)",
- [1] = "Librarian",
- },
- [2] = {
- [0] = "Purple Robe (Priest)",
- [1] = "Cleric",
- },
- [3] = {
- [0] = "Black Apron (Blacksmith)",
- [1] = "Armorer",
- [2] = "Weapon Smith",
- [3] = "Tool Smith",
- },
- [4] = {
- [0] = "White Apron (butcher)",
- [1] = "Butcher",
- [2] = "Leatherworker",
- },
- [5] = {
- [0] = "Green Robe (Nitwit 1.11)",
- [5] = "Nitwit (1.11)",
- },
- }
- local function getVillagerCareer(e)
- if e and e.type=="EntityVillager" then
- return profession[e.datatags.Profession][e.datatags.Career]
- else
- return false
- end
- end
- local function getCellInfos(pos,raw)
- raw = raw or false
- local t = _getEntityList(1.5,pos.x+.5,pos.y,pos.z+.5)
- if raw then return #t>=1 and t[1] or false end
- if not t or #t==0 then
- return false
- else
- local hasZombie = false
- local hasZombieVillager = false
- local hasVillager = false
- local count,_,mob = 0
- for _,mob in pairs(t) do
- mob.x,mob.z = tonumber(mob.x),tonumber(mob.z)
- if mob.x and mob.z
- and mob.x >= pos.x-.1 and mob.x <= pos.x +1.1
- and mob.z >= pos.z-.1 and mob.z <= pos.z +1.1
- then
- if mob.type=="EntityZombie" then
- count = count+1
- hasZombie = true
- if mob.datatags.IsVillager then
- hasZombieVillager = mob.datatags.IsVillager
- end
- elseif mob.type=="EntityVillager" then
- count = count+1
- hasVillager = true
- end
- end
- end
- if hasZombie then
- return count, "EntityZombie", hasZombieVillager
- elseif hasVillager then
- return count, "EntityVillager"
- end
- end
- return false
- end
- local function isDoorOpen(pos)
- --y+5
- local data = _getBlockInfos(pos.x,pos.y+5,pos.z)
- if data.blockName == "minecraft:fence_gate"
- or data.blockName == "minecraft:spruce_fence_gate"
- or data.blockName == "minecraft:birch_fence_gate"
- or data.blockName == "minecraft:jungle_fence_gate"
- or data.blockName == "minecraft:dark_oak_fence_gate"
- or data.blockName == "minecraft:acacia_fence_gate" then
- return data.isPowered
- else
- --Structure error
- error(string.format([[Block on coords [%d,%d,%d] should be "minecraft:fence_gate". "%s" found]],
- pos.x, pos.y+5, pos.z, data.blockName),0)
- exit()
- end
- end
- local function resetCell(com,pos)
- rs.setAnalogOutput("top",pos.s)
- local c = peripheral.wrap(com)
- sleep(.1)
- if c.isOn() then c.shutdown() end
- c.turnOn()
- while c.isOn() do
- sleep(.1)
- end
- repeat
- sleep(.1)
- until not c.isOn()
- rs.setOutput("top",false)
- sleep(.1)
- end
- local function select()
- local i,com,pos=0
- for com,pos in pairs(cell) do
- local y = 4+(i*3)
- local dump = false
- output(y,string.format("%s[x:%d, y:%d, z:%d]",com,pos.x,pos.y,pos.z))
- local _entity,_type,_isVillager = getCellInfos(pos)
- if not _entity then
- output(y+1,"Empty cell")
- --Check if need reset
- dump = not isDoorOpen(pos)
- elseif _entity>1 then
- output(y+1,"Too many mobs (".._entity..")")
- dump = true
- elseif _type=="EntityVillager" then
- local _e = getCellInfos(pos,true)
- local career = getVillagerCareer(_e)
- if career then
- dump = not wanted.career[career]
- output(y+1,string.format("%sVillager (%s) : %s",
- (_e.datatags.Career==0 and "New " or ""),
- career,
- dump and "unwanted" or "wanted")
- )
- end
- elseif _type=="EntityZombie" then
- output(y+1,"Zombie, "..( _isVillager and "villager" or "not villager"))
- dump = not _isVillager
- elseif _type=="EntityPlayerMP" then
- output(y+1,"Player")
- dump = false
- else
- output(y+1,_type)
- dump = true
- end
- output(y+2,string.rep("-",20))
- i=i+1
- if dump then
- resetCell(com,pos)
- end
- end
- end
- --main
- term.clear()
- local tick = os.startTimer(.1)
- while true do
- local e,p,x,y = os.pullEvent()
- local ts = os.clock()
- if e=="timer" and p==tick then
- --header
- output(1,string.format("#%d - %s",
- os.getComputerID(),
- os.getComputerLabel()))
- output(2,"Running: "..strTime(ts))
- output(3,string.rep("-",20))
- if math.floor(ts)%2==0 then
- select()
- end
- tick = os.startTimer(1)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement