Posted 14 May 2014 - 02:10 PM
EDIT: I resolved this myself between posting this and the moderator approving it. I just needed to use the textutils.unserialize() function.
This is my new final working code:
Hello everyone. Hoping I can get a little help with what I'm trying to do here that doesn't seem to be working. First off a little about my setup. I'm playing on a server running The Crack Pack from ATLauncher.com It has computercraft 1.58 and OpenPeripherals (among many other mods) atm. I am working on my first computercraft script and ran into a little bit of a problem. I know of another way I could potentially handle it,b but would rather not do it that way (will get to that part below). Also just want to mention, I've been a developer for 14 years, so I'm not a complete noob when it comes to programming, but I am a noob when it comes to CC programming :)/>
Now then, what I'm trying to do. So in my base I've got lots of doors, and I like to use double doors to make a wider space to walk through. So I've been going around trying to combine computercraft, with an openperipherals sensor, a few logic gates from BC and some structure pipes in order to make an automatic opening door when players are near. Right now I'm just doing this based on any player being near. The sensor has getPlayerNames() and getPlayerData(username) functions that allow me to do this, with getPlayerData returning a position relative to the sensor. What I'm working on is one door_control program for all of my doors instead of having to go in and change hard coded values every time I need to place a new one for another door. Also though, being that my base has multiple levels and such, I'm wanting to restrict the XYZ that opens each said door to make it more likely that the door is in fact going to be used and not opening when someone is underneath it. The route I went to accomplish this initially is after seeing the tables and such in CC, I figured I could just pass one in as an argument so that I could define only the variables I wanted to change from default at the start, however that does not seem to work. Here is my code:
And this is an example of how I would call it for the first door I was trying to set up (this would be in the startup file so that if the computer restarts it auto restarts with the correct parameters).
Like I said, this isn't working, it treats the entire argument as a single string instead of as a table. Makes sense I guess, but I'm wondering if there is a way around this so that I can do what I'm trying to do and pass in a variable number of arguments.
The alternative I know I could do that I mentioned above would be to have the initial run of the program check for a file for saved settings and if it doesn't exist ask for the settings initially and then save them to the file so that it doesn't have to ask next time it starts up. I may still end up going that route, but for now I want o figure out if there is a way to achieve the above method. It's also partially because of the way I edit the programs. The terminal in game is unbearable to use for any real editing. I choose to instead use VIM and edit the files directly on my server, so it'd be nice to simply be able to copy my door_control program, set a startup script for the computer and then power on the computer and be done rather than have to mess with the in game terminal at all. Although I just had yet another idea, perhaps I can just edit that save file on VIM as well so that it's already there ….. hmm definite possibility, but I'm still interested in finding out if there is a way to do what I initially tried to do above.
Thanks for any help!
This is my new final working code:
args = {...}
sensorPosition="top"
xMin=-5
xMax=5
yMin=-5
yMax=5
zMin=-5
zMax=5
outputDirections={front=false}
directions={"front","back","left","right","top","bottom"}
if args[1] ~= nil then
args[1]=textutils.unserialize(args[1])
if args[1].xMin ~= nil then xMin=args[1].xMin end
if args[1].xMax ~= nil then xMax=args[1].xMax end
if args[1].yMin ~= nil then yMin=args[1].yMin end
if args[1].yMax ~= nil then yMax=args[1].yMax end
if args[1].zMin ~= nil then zMin=args[1].zMin end
if args[1].zMax ~= nil then zMax=args[1].zMax end
if args[1].output ~= nil then
outputDirections={}
n = 1
while args[1].output[n] ~= nil do
thisInvert=false
if args[1].output[n]=="table" then
if args[1].output[n].invert ~= nil then thisInvert=args[1].output[n].invert else thisInvert=false end
outputDirections[args[1].output[n].dir]=thisInvert
else
outputDirections[args[1].output[n]]=thisInvert
end
n=n+1
end
end
if args[1].sensor ~= nil then sensorPosition=args[1].sensor end
else
print("No arguments specified")
end
p=peripheral.wrap(sensorPosition)
function setOutputs(toState)
local out=1
while directions[out] ~= nil do
dir=directions[out]
if outputDirections[dir] ~= nil and outputDirections[dir] == true then
if toState==false then
redstone.setOutput(dir,true)
else
redstone.setOutput(dir,false)
end
elseif outputDirections[dir]~=nil then
redstone.setOutput(dir,toState)
else
redstone.setOutput(dir,false)
end
out=out+1
end
end
function anyKeyExit()
local runScript=true
while runScript==true do
local event,param1,param2,param3=os.pullEvent()
if event=="key" then runScript=false break end
end
end
function main()
while true do
if (p.getPlayerNames()[1] ~= nil) then
players=p.getPlayerNames()
playerFound=false
n=1
while players[n] ~=nil do
playerd=p.getPlayerData(players[n])
if playerd.position.y>=yMin and playerd.position.y<=yMax and playerd.position.x>=xMin and playerd.position.x<=xMax and playerd.position.z>=zMin and playerd.position.z<=zMax then
playerFound=true
else
--print(playerd.position.x,",",playerd.position.y,",",playerd.position.z)
end
n=n+1
end
setOutputs(playerFound)
else
setOutputs(false)
end
end
end
setOutputs(false)
parallel.waitForAny(main,anyKeyExit)
setOutputs(false)
Hello everyone. Hoping I can get a little help with what I'm trying to do here that doesn't seem to be working. First off a little about my setup. I'm playing on a server running The Crack Pack from ATLauncher.com It has computercraft 1.58 and OpenPeripherals (among many other mods) atm. I am working on my first computercraft script and ran into a little bit of a problem. I know of another way I could potentially handle it,b but would rather not do it that way (will get to that part below). Also just want to mention, I've been a developer for 14 years, so I'm not a complete noob when it comes to programming, but I am a noob when it comes to CC programming :)/>
Now then, what I'm trying to do. So in my base I've got lots of doors, and I like to use double doors to make a wider space to walk through. So I've been going around trying to combine computercraft, with an openperipherals sensor, a few logic gates from BC and some structure pipes in order to make an automatic opening door when players are near. Right now I'm just doing this based on any player being near. The sensor has getPlayerNames() and getPlayerData(username) functions that allow me to do this, with getPlayerData returning a position relative to the sensor. What I'm working on is one door_control program for all of my doors instead of having to go in and change hard coded values every time I need to place a new one for another door. Also though, being that my base has multiple levels and such, I'm wanting to restrict the XYZ that opens each said door to make it more likely that the door is in fact going to be used and not opening when someone is underneath it. The route I went to accomplish this initially is after seeing the tables and such in CC, I figured I could just pass one in as an argument so that I could define only the variables I wanted to change from default at the start, however that does not seem to work. Here is my code:
args = {...}
sensorPosition="top"
xMin=-5
xMax=5
yMin=-5
yMax=5
zMin=-5
zMax=5
outputDirections={front=false}
if args[1] ~= nil then
--This isn't working... the arg isn't being passed in as a table
if args[1].xMin ~= nil then xMin=args[1].xMin end
if args[1].xMax ~= nil then xMax=args[1].xMax end
if args[1].yMin ~= nil then yMin=args[1].yMin end
if args[1].yMax ~= nil then yMax=args[1].yMax end
if args[1].zMin ~= nil then zMin=args[1].zMin end
if args[1].zMax ~= nil then zMax=args[1].zMax end
if args[1].output ~= nil then
outputDirections={}
n = 1
while args[1].output[n] ~= nil do
thisInvert=false
if args[1].output[n]=="table" then
if args[1].output[n].invert ~= nil then thisInvert=args[1].output[n].invert else thisInvert=false end
outputDirections[args[1].output[n].dir]=thisInvert
else
outputDirections[args[1].ouptut[n]]=thisInvert
end
n=n+1
end
end
if args[1].sensor ~= nil then sensorPositions=args[1].sensor end
else
print("No arguments specified")
end
directions={"front","back","left","right","top","bottom"}
p=peripheral.wrap(sensorPosition)
function setOutputs(toState)
local out=1
while directions[out] ~= nil do
dir=directions[out]
if outputDirections[dir] ~= nil and outputDirections[dir] == true then
if toState==false then
redstone.setOutput(dir,true)
else
redstone.setOutput(dir,false)
end
else
redstone.setOutput(dir,toState)
end
out=out+1
end
end
function anyKeyExit()
local runScript=true
while runScript==true do
local event,param1,param2,param3=os.pullEvent()
if event=="key" then runScript=false break end
end
end
function main()
while true do
if (p.getPlayerNames()[1] ~= nil) then
players=p.getPlayerNames()
playerFound=false
n=1
while players[n] ~=nil do
playerd=p.getPlayerData(players[n])
if playerd.position.y>=yMin and playerd.position.y<=yMax and playerd.position.x>=xMin and playerd.position.x<=xMax and playerd.position.z>=zMin and playerd.position.z<=zMax then
playerFound=true
else
--print(playerd.position.x,",",playerd.position.y,",",playerd.position.z)
end
n=n+1
end
setOutputs(playerFound)
else
setOutputs(false)
end
end
end
setOutputs(false)
parallel.waitForAny(main,anyKeyExit)
setOutputs(false)
And this is an example of how I would call it for the first door I was trying to set up (this would be in the startup file so that if the computer restarts it auto restarts with the correct parameters).
shell.run("door_control {yMin=-2,yMax=1,zMin=-3.5,zMax=-1.5,output={'back'}}")
Like I said, this isn't working, it treats the entire argument as a single string instead of as a table. Makes sense I guess, but I'm wondering if there is a way around this so that I can do what I'm trying to do and pass in a variable number of arguments.
The alternative I know I could do that I mentioned above would be to have the initial run of the program check for a file for saved settings and if it doesn't exist ask for the settings initially and then save them to the file so that it doesn't have to ask next time it starts up. I may still end up going that route, but for now I want o figure out if there is a way to achieve the above method. It's also partially because of the way I edit the programs. The terminal in game is unbearable to use for any real editing. I choose to instead use VIM and edit the files directly on my server, so it'd be nice to simply be able to copy my door_control program, set a startup script for the computer and then power on the computer and be done rather than have to mess with the in game terminal at all. Although I just had yet another idea, perhaps I can just edit that save file on VIM as well so that it's already there ….. hmm definite possibility, but I'm still interested in finding out if there is a way to do what I initially tried to do above.
Thanks for any help!
Edited on 14 May 2014 - 01:49 PM