This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Bandus's profile picture

[Question][Lua][CCSensors] Proximity Door, Player Only

Started by Bandus, 02 April 2013 - 04:34 PM
Bandus #1
Posted 02 April 2013 - 06:34 PM
For context, I have read over this link: http://www.computercraft.info/wiki/index.php?title=OpenCCSensors

Which gave me the basics and I understand what the "example" code is doing and how this can be used to create a door that opens when players get within a certain distance of the door. However, this doesn't get me all the way to where I need to be for what I am attempting to accomplish. Specifically, I would like the door to open when players and only players get close enough. So, for example, if NPCs (cows, sheep, etc.) get close I do not want the door to open.

I have a feeling the answer to this lies somewhere in getTargets() and then taking the information in the table and making it useable to determine if whatever is close is a player character or not. I even considered using some type of FS API access list as part of the answer. The fact is though, this is pushing the limits of what I know how to do with LUA at this point and was hoping someone could help me out here.

Thank you!
LordIkol #2
Posted 02 April 2013 - 10:31 PM
Hi bandus,

Here is some code i wrote that maybe works but im not sure cause i did not sleep tonight and im sitting in the train at the moment :D/>
Will check Tomorrow again but maybe it helps you to get the clue


os.loadAPI("ocs/apis/sensor")
s = sensor.wrap("right")
local signal = false
-- the location of the door
local offset = {
  X = 1,
  Y = 1,
  Z = 0
}
-- how close a player has to be to activate the lamp
local radius = 5
-- find the distance from the player position to the offset
function distance(pos)
  local xd = pos.X - offset.X
  local yd = pos.Y - offset.Y
  local zd = pos.Z - offset.Z
  return math.sqrt(xd*xd + yd*yd + zd*zd)
end

local function Opendoor()
t = s.getTargets()
for name, basicDetails in pairs(t) do
  if name == "YourCharName" then  -- change to your account name
print("Master Found: "..name)
-- get more details
local Master = s.getTargetDetails(name)
if distance(Master.Position) < radius then
	  signal = true
   end
  end
  end
end

while true do
if signal == false then
Opendoor()
else
rs.setOutput("top", signal)
sleep(3) -- let the door open for 3 seconds
signal = false
end
end
Bandus #3
Posted 03 April 2013 - 10:50 AM
Thank you for the assistance! I attempted to use your code and this is what I currently have:

os.loadAPI("ocs/apis/sensor")
local proximity = sensor.wrap("top")
local signal = false

local offset = {
X = 1.36,
Y = 1,
Z = -4
}

local radius = 4

function distance(pos)
local xd = pos.X - offset.X
local yd = pos.Y - offset.Y
local zd = pos.Z - offset.Z
return math.sqrt(xd*xd + yd*yd + zd*zd)
end

local function opendoor()
t = proximity.getTargets()
for name, basicDetails in pairs(t) do
  if name =="Bandus" then
  print("Master Found: "..name)
local master = proximity.getTargetDetails(name)
   if distance(master.position) < radius then
	signal = true
   end
  end
end
end

while true do
if signal == false then
opendoor()
else
rs.setOutput("back", signal)
sleep(3)
signal = false
end
end

When I attempt to run the program, however, it prints the "Master Found" part on line 29, however, then it gives the following error: "proximitydoortest:19: attempt to index ? (a nil value)"

Line 19 refers to an item in the distance function obviously, however, that was working properly previously so I'm not clear on what the problem might be.

Again, I appreciate your help!
PixelToast #4
Posted 03 April 2013 - 03:53 PM
the problem isnt the distance function (though you sould be using math.abs instead of sqrt)

if distance(master.position) < radius then
for some reason master.position is nil
but im not sure because that wasnt the full code
Bandus #5
Posted 03 April 2013 - 06:05 PM
@PixelToast - I'm not sure what you mean. What I posted above is all the code I have so far for this program. It is entirely possible I haven't put something in that should be there.
LordIkol #6
Posted 03 April 2013 - 11:20 PM
just change

if distance(master.position) < radius then
to
if distance(master.Position) < radius then
Position has to be Capital like its in my code

and the distance Function is correct. Math.abs would just give you the absolute value of the calculation. lets say your relative coordinates to the door are xd = 3 zd = -1 and yd= 0
math.abs would return 10
math.sqrt returns 3.16 which is the correct value

greets
Loki
Molinko #7
Posted 15 April 2013 - 06:34 PM

if distance(master.position) < radius and master.Name == "player" then
		signal = true
end

I think getTargets() returns the keys "Name" = entity type(i.e "Creeper" or "Player"); "Position" = (you've got this key); "RawName" = (youre player IGN here)
hope that helps…

You can actually test this by using a for loop and printing the keys to see what's available on that "level" or "depth" of the table so…


for k,v in pairs(players) do
    print(k..": ".. tostring(v))
end
matmatspeed #8
Posted 29 May 2013 - 02:24 PM
Hi I've copied this code and made correction from users above and get This Error:

bios:338: [string "door"]:37: `=` expected

The Code I used:


os.loadAPI("ocs/apis/sensor")
local proximity = sensor.wrap("top")
local signal = false


local offset = {
X = 1,
Y = 1,
Z = 0
}


local radius = 4


function distance(pos)
local xd = pos.X - offset.X
local yd = pos.Y - offset.Y
local zd = pos.Z - offset.Z
return math.abs(xd*xd + yd*yd + zd*zd)
end


local function opendoor()
t = proximty.getTargets()
for name, basicDetails in pairs(t) do
  if name =="SPEEDY7890" then
  print("Master Found: "..name)
local master = proximity.getTargetDetails(name)
   if distance(master.position) < radius and master.Name == "SPEEDY7890" then
		signal = true

   end
end
end
end


while true do
if signal == false then
opendoor()
esle
rs.setOutput("back", signal)	  [b]-- This is line 37--[/b]
sleep(3)
signal = false
end
end				

Thanks
Molinko #9
Posted 29 May 2013 - 03:24 PM
1.) try not to necro old threads… and two, you need to capitalize Position… as in 'if master.Position < radius then'
matmatspeed #10
Posted 29 May 2013 - 03:54 PM
1.) try not to necro old threads… and two, you need to capitalize Position… as in 'if master.Position < radius then'

hi

sorry I've done that and I still receive the error

thanks
Lyqyd #11
Posted 29 May 2013 - 04:52 PM
It should be else, not esle.

Molinko, you can also use the sensorview program (ocs/programs/sensorview) to see what the details table for a given target contains. And don't backseat moderate. It's not your job to call people out on bumping old topics. Just report the post next time.
matmatspeed #12
Posted 29 May 2013 - 05:29 PM
It should be else, not esle.

Molinko, you can also use the sensorview program (ocs/programs/sensorview) to see what the details table for a given target contains. And don't backseat moderate. It's not your job to call people out on bumping old topics. Just report the post next time.

Thanks and again sorry I couldn't find another program. Stupid spelling error but I Now recive an error on line 35 'opendoor' I cant see what its spouse to do. Error: door:35: attempt to call nil
Molinko #13
Posted 30 May 2013 - 11:03 AM
@Lyquid, didnt mean to. just informing others on forum edicate
Bomb Bloke #14
Posted 30 May 2013 - 07:59 PM
Thanks and again sorry I couldn't find another program. Stupid spelling error but I Now recive an error on line 35 'opendoor' I cant see what its spouse to do. Error: door:35: attempt to call nil
The line that reads "opendoor()"? Do you still have a function defined by that exact name above that line?