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

Nil value check

Started by Carden, 02 May 2013 - 07:55 AM
Carden #1
Posted 02 May 2013 - 09:55 AM
Title: Nil value check

Using openccsensors and a turtle to detect a player and open a door.


os.loadAPI("ocs/apis/sensor")
while true do
local prox = sensor.wrap("right")
local targets = prox.getTargets()
if targets == "" then
  redstone.setOutput("bottom", false)
else
  for k,v in pairs(prox.getTargets()) do
	local ptest = prox.getTargetDetails(k)
	if ptest.Name ~= "Player" then
	 redstone.setOutput("bottom", false)
	else
	 redstone.setOutput("bottom", true)
	end
	
  end
end
end

Detection works correctly however walking away and back into range leads to the following error code.

test2:10: attempt to index ? (a nil value) Which should be this line if ptest.Name ~= "Player" then

I'm banging my head against the wall as to how to skip line 10 if there is no Player nearby.
Jarle212 #2
Posted 02 May 2013 - 10:47 AM

if ptest.Name ~= nil then
   if ptest.Name ~= "Player" then
      --DO STUFF
   end
end
remiX #3
Posted 02 May 2013 - 11:16 AM
just do
if ptest.Name and ptest.Name ~= "Player" then
Carden #4
Posted 03 May 2013 - 12:00 AM
Unfortunately it seems that in both cases a nil value is being indexed as ptest.Name is still being accessed without any valid targets. Is there a way to inject a dummy entry into the table that would not effect the search for players but still allow for a entry to exist?
Jarle212 #5
Posted 03 May 2013 - 09:12 AM
Unfortunately it seems that in both cases a nil value is being indexed as ptest.Name is still being accessed without any valid targets. Is there a way to inject a dummy entry into the table that would not effect the search for players but still allow for a entry to exist?
May be:


if ptest and ptest.Name and ptest.Name ~= "Player" then
theoriginalbit #6
Posted 03 May 2013 - 09:14 AM
just try something for us… after this line
local ptest = prox.getTargetDetails(k)
add this in
print(type(ptest))
and tell us what it says. btw it should say 'table'
KaoS #7
Posted 03 May 2013 - 10:54 AM

os.loadAPI("ocs/apis/sensor")
while true do
  local prox = sensor.wrap("right")
  local targets = prox.getTargets()
  if targets == "" then
	redstone.setOutput("bottom", false)
  else
	for k,v in pairs(prox.getTargets()) do
	  local ptest = prox.getTargetDetails(k)
	  if type(ptest)=="table" and ptest.Name ~= "Player" then
		redstone.setOutput("bottom", false)
	  else
		redstone.setOutput("bottom", true)
	  end
	end
  end
end

is the corrected code

EDIT: HOWEVER it will not work either, if the targets table contains a player and a mob it will go through the table and set the output to true when it finds the player, then set it to false again when it finds the mob…


os.loadAPI("ocs/apis/sensor")
while true do
  local prox = sensor.wrap("right")
  local targets = prox.getTargets()
  redstone.setOutput("bottom", false) --default to off, set to on if player is found
  if type(targets)=="table" then
	for k,v in pairs(targets) do --no need to execute the command again, you already have it in a var
	  local ptest = prox.getTargetDetails(k)
	  if type(ptest)=="table" and ptest.Name == "Player" then
		redstone.setOutput("bottom", true)
		break --makes the code execute faster as it doesn\'t waste time with other mobs once a player is detected
	  end
	end
  end
  sleep(0.5) --small delay, no need to hog processing time
end
Edited on 03 May 2013 - 08:59 AM
Carden #8
Posted 04 May 2013 - 11:02 AM

if type(targets)=="table" then
    &
if type(ptest)=="table" and ptest.Name == "Player" then

These 2 solved it perfectly,
Thank you
KaoS #9
Posted 05 May 2013 - 05:30 AM
Glad to help :)/>

PLEASE read the edit though or your prog won't work in all situations, use the second code