UPDATE: Version 2.2 fixes a crashing bug caused when players moved out of range before the program collected their detailed information. It will work with existing config files. Several players have asked me how my teleporters work (sneek/crouch to teleport), so I thought I would share. The teleporter program uses openccsensor's proximity sensor to see if a player is sneaking at a specific set of coordinates, and activates a teleporter if they are. Installation: Put the teleporter program on a computer. Name it "startup" or make a program with that name and put this in it: shell.run("teleport") Place the sensor peripheral next to your computer and put a proximity sensor card in it. Attach your teleporter to your computer with red alloy wire. Edit "teleporterSide" variable if needed (default side is down). Reboot (ctrl-r) or run teleporter program. When the program first runs it creates three config files. teleport.admins - list of players (on first start all players in range are added to this list) teleport.access - list of players (empty by default. Any player can teleport if blank) teleport.coords - the x,y,z coordinates of the teleporter Administrators can set the teleporter location and add players to the access list using a wooden sword. They simply hold a wooden sword, and block to set the teleporter location, or sneak on the teleporter to add all players in range to the access list. Code: os.loadAPI("ocs/apis/sensor") local teleporterSide = "bottom" local sensorSide = nil for n,side in ipairs(rs.getSides()) do if(peripheral.getType(side) == "sensor") then sensorSide = side break end end if sensorSide == nil then print("No sensor attached") return end local sensor = sensor.wrap(sensorSide) local version = "2.2" local updateAccess = false local noConfigFiles = true local admins = {} local access = {} local coords = {} function readConfig(name, filename, kvFormat) local file = io.open(filename, "r"); local i = 0 local list = {} if file then noConfigFiles = false for line in file:lines() do -- config's in key/value format deliniated with a colon if kvFormat then for k, v in string.gmatch(line, "(%w+):(%-*%w+)") do if name == "coords" then list[k] = tonumber(v) else list[k] = v end end -- configs with line seperated lists else i = i + 1 table.insert (list, line); end end file:close() else file = io.open(filename, "w"); file:write("") file:close() end return list end function writeConfig(name, file, data, kvFormat) local file = io.open(file, "w"); if kvFormat then for k, v in pairs(data) do file:write(k..":"..v.."\n") end else for i, v in ipairs(data) do file:write(v.."\n") end end file:close() end function validate(name, table) local valid = false if next(table) ~= nil then for index,value in ipairs(table) do if name == value then valid = true end end return valid else return true end end function round(number) if ( number >= 0 ) then number = math.floor(number + 0.5); else number = math.ceil(number - 0.5); end return number; end function roundCoords(coords) coords.X = round(coords.X) coords.Y = round(coords.Y) coords.Z = round(coords.Z) return coords end function positioned(pos) pos = roundCoords(pos) if (pos.X == coords.X and pos.Y == coords.Y and pos.Z == coords.Z) then return true else return false end end function setPosition(pos) pos = roundCoords(pos) writeConfig("coords", "teleport.coords", pos, true) coords.X = pos.X coords.Y = pos.Y coords.Z = pos.Z sleep(1) end rs.setOutput(teleporterSide, false) print ("Teleporter version "..version) print("") admins = readConfig("admins", "teleport.admins", false) access = readConfig("access", "teleport.access", false) coords = readConfig("coords", "teleport.coords", true) sleep(1.5) while true do sleep(0.5) local signal = false local valid = false local admin = false local basicDetails = {} local moreDetails = {} local adminMode = false for name,basicDetails in pairs(sensor.getTargets()) do valid = validate(name, access) admin = validate(name, admins) if noConfigFiles then table.insert(admins, name) elseif updateAccess then if (not valid) and (not admin) then table.insert(access, name) end elseif (valid or admin) then moreDetails = sensor.getTargetDetails(name) if moreDetails ~= nil then if admin and moreDetails.HeldItem.Name == "Wooden Sword" then adminMode = true end if (adminMode and moreDetails.IsBlocking) then setPosition(basicDetails.Position) elseif positioned(basicDetails.Position) then moreDetails = sensor.getTargetDetails(name) if (adminMode and moreDetails.IsSneaking ) then updateAccess = true elseif moreDetails.IsSneaking then signal = true end end end end end if noConfigFiles then writeConfig("admins", "teleport.admins", admins, false) noConfigFiles = false end if updateAccess then writeConfig("access", "teleport.access", access, false) updateAccess = false end if signal then rs.setOutput(teleporterSide, true) sleep(0.2) rs.setOutput(teleporterSide, false) sleep(0.8) end end Development code (with comments and debug messages) here.
That sounds incredible glitch. I will have to give it a try soon! Loving the recent surge of computer craft use in the server, although I know you have always done stuff. Good luck with your further projects, fellow gangbanger
Have fun with it Path. OpenCCSensors is amazing, it can tell you all kinds of things like the direction and pitch of a player's head, the contents of their inventories, and much more.
If anyone can help me, I am trying to make a program the same as this accept for a door. The only real diff is that instead of triggering when players were on the teleporter It would trigger when players sneaked within five or so blocks of the door.
To accomplish that edit the positioned function. Its purpose is simple; Return true if a player is at the set coordinates. This modification (untested) should work for you. Code: function positioned(pos) pos = roundCoords(pos) range = 5 pos_upper.X = pos.X + range pos_upper.Y = pos.Y + range pos_upper.Z = pos.Z + range pos_lower.X = pos.X - range pos_lower.Y = pos.Y - range pos_lower.Z = pos.Z - range if ( coords.X <= pos_upper.X and coords.X >= pos_lower.X and coords.Y <= pos_upper.Y and coords.Y>= pos_lower.Y and coords.Z <= pos_upper.Z and coords.Z >= pos_lower.Z) then return true else return false end end There's probably a cleaner way to do this, but all we're doing is setting a 5 block range (radius) and checking to see if the set coordinates fall within it.
The positioned function. It's untested though, so probably will not work without some tweaking. It sounds like you need to read some of the lua manual. It's not a complicated language, so an hour of reading will get you going, especially if you have any experience with other scripting/programming languages.