Glitch's Teleporter Program

Discussion in 'ComputerCraft Programming' started by glitch80, 12 April 2013.

  1. glitch80

    glitch80 Active Member

    Joined:
    26 March 2012
    Messages:
    345
    Likes Received:
    232
    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:
    1. Put the teleporter program on a computer.
    2. Name it "startup" or make a program with that name and put this in it: shell.run("teleport")
    3. Place the sensor peripheral next to your computer and put a proximity sensor card in it.
    4. Attach your teleporter to your computer with red alloy wire.
    5. Edit "teleporterSide" variable if needed (default side is down).
    6. 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.
     
  2. Pathaleon

    Pathaleon Forum & Server Administrator
    Staff Member

    Joined:
    3 July 2012
    Messages:
    1.014
    Likes Received:
    670
    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 ;)
     
  3. glitch80

    glitch80 Active Member

    Joined:
    26 March 2012
    Messages:
    345
    Likes Received:
    232
    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.
     
  4. zevos

    zevos icublock

    Joined:
    19 March 2012
    Messages:
    135
    Likes Received:
    43
    or try and murder me with tesla coils...
     
  5. Opticnerve93

    Opticnerve93 Guest

    Glitch did you manage to fix that glitch that causes it to crash?
     
  6. glitch80

    glitch80 Active Member

    Joined:
    26 March 2012
    Messages:
    345
    Likes Received:
    232
    Install version 2.2
     
  7. ghostpotato

    ghostpotato The Crimson King

    Joined:
    27 January 2013
    Messages:
    92
    Likes Received:
    6
    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.
     
  8. glitch80

    glitch80 Active Member

    Joined:
    26 March 2012
    Messages:
    345
    Likes Received:
    232
    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.
     
  9. ghostpotato

    ghostpotato The Crimson King

    Joined:
    27 January 2013
    Messages:
    92
    Likes Received:
    6
    Now thanks for the help, but where/ what do I replace with this?
     
  10. glitch80

    glitch80 Active Member

    Joined:
    26 March 2012
    Messages:
    345
    Likes Received:
    232
    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.
     
    gknova61 likes this.
  11. ghostpotato

    ghostpotato The Crimson King

    Joined:
    27 January 2013
    Messages:
    92
    Likes Received:
    6
    Ok I believe I understand. But now do i still have to set the "teleporter" coords?
     
  12. glitch80

    glitch80 Active Member

    Joined:
    26 March 2012
    Messages:
    345
    Likes Received:
    232
    Read the instructions above, in-game configuration is baked in.
     
  13. ghostpotato

    ghostpotato The Crimson King

    Joined:
    27 January 2013
    Messages:
    92
    Likes Received:
    6
  14. LeiserGeist

    LeiserGeist Gamer, Software Developer

    Joined:
    26 October 2012
    Messages:
    479
    Likes Received:
    116
    I'm late to reply to this, but...
    IPRESIFFPH
     
  15. Siioh

    Siioh If you can read this, you're too far

    Joined:
    29 May 2013
    Messages:
    333
    Likes Received:
    118
    Looks awesome so far, haven't tried it out yet.