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

1.7.10 Player Detector for a Door OPA Sensor

Started by Tamtam18_2, 15 November 2014 - 08:46 PM
Tamtam18_2 #1
Posted 15 November 2014 - 09:46 PM
ok, i am stumped. This player detector code of mine has been the bane of me for years, and this time around I nearly got it to work perfectly.

Updated:
Player_Detector_2.1
http://pastebin.com/uxEjL0s6

Here is a list of the problems it has

1:
(the most stranious) At one point I could change the code to where it would detect the player and switch between players, but not update their coords. and likewise update one player's coords and not switch between players.

This has been fixed.

2:
The code can't properly detect a player. As the code stands, it will detect me, display coords, etc, but I can't seem to find a way to get it to detect another player and update their coords. for example, if I have a buddy in the room, and if im nearest to the computer/sensor, and I move to past my buddy in relation to said computer. the code will break at line 17: attempt to index ? (a nil value). As username = info[1].name gathers the players username. If i was nearest to the computer first it would assign me to the first person it detected online. hence table value of 1, my buddy is number 2. I assume it doesn't automatically switch between the assigned numbers, or that players don't get reassigned, but I can't see that part of computer craft.

3:
A java programming friend of mine who is helping me with the code off and on suggests that I refresh the information coming in or the peripheral connection. When playing around with the 3 local variables (other than peripheral.wrap) I find that the information lingers and does not want to change. I really did try refreshing these variables within the code, but to no avail, the code breaks or doesn't do what its supposed to do.

I suggest looking through my previous versions of the code before you offer a suggestion. chances are i've done that already here, but post anyways!

Any Ideas?

Previous Versions:
order is from Eldest to Newest

Computercraft 1.5 for 1.6.4:

Player_Detector
http://pastebin.com/x3dYYTZw

Player_Detector_v1.3
http://pastebin.com/3hfBPVip

pd (I don't remember what this one was for, probbably testing)
http://pastebin.com/vLSPvH3M

Computercraft 1.6 for 1.7.10 pastebins:
(More recent)

sensor
http://pastebin.com/2R70VBbg

prank
http://pastebin.com/4YvLke07

Door (working code/testing horror)
http://pastebin.com/E8U73dWR
Edited on 17 November 2014 - 12:51 AM
Tamtam18_2 #2
Posted 15 November 2014 - 10:56 PM
Update

Checking for Info ~= nil does not work. I'll need something else instead. "If info then" does not work either
Bomb Bloke #3
Posted 16 November 2014 - 12:14 AM
It sounds like p.getPlayers() returns an empty table if there are no players in range (as opposed to just nil). This means that even if "info" isn't nil, "info[1]" might still be nil - best way to check for this is to see if #info > 0.

I'd guess that info[1] will be whichever player is closest to the sensor. At least, that's how the OpenPeripheral sensor I played with once worked.

I'm afraid your functions are a bit of a mess. You don't really need to be defining functions at all - better to stick your data-gathering code into the main loop, in this case.

Here's a bit of a re-hash of what you've got. Assuming it runs at all (I've not tested it), it should continue tracking whichever player was closest first, until that player moves out of range:

local p, i, username, playerData = peripheral.wrap("right"), 1

redstone.setOutput("left", true)

while true do
	print("Iteration: "..i)
	i = i + 1

	-- If we have a "username" stored:
	if username then
		playerData = p.getPlayerByName(username)
	end
	
	-- If the above didn't work (because we didn't already have
	-- a username stored, or the user moved out of range for eg):
	if not (playerData or username) then
		local info = p.getPlayers()
		
		if #info > 0 then
			username = info[1].name
			playerData = p.getPlayerByName(username)
		else
			username = nil
		end
	end
	
	term.clear()
	term.setCursorPos(1,1)
	
	if username then
		print(username)
	
		if playerData then
			for A, E in pairs(playerData.position) do
				print(A..": "..E)
			end
		end
	else
		print("No users in range!")
	end
	
	sleep(10)
end
Tamtam18_2 #4
Posted 16 November 2014 - 12:33 AM
Further update

Upon looking at my codes posted here, I tried some of the earlier methods out and using "if #p.getPlayers() ~= 0 then" works wonders. I've been able to finish the code and will post it soonish.

Oh, I didn't see your post until just now, I've been able to figure it out on my own it seems. Yes my code turned into a mess, usually I don't do that to a piece of code.

Edit: using variables in place of their assigned functions doesn't seem to work when trying to actually use them, not sure if others are having the same problem

It sounds like p.getPlayers() returns an empty table if there are no players in range (as opposed to just nil). This means that even if "info" isn't nil, "info[1]" might still be nil - best way to check for this is to see if #info > 0.

I'd guess that info[1] will be whichever player is closest to the sensor. At least, that's how the OpenPeripheral sensor I played with once worked.

I'm afraid your functions are a bit of a mess. You don't really need to be defining functions at all - better to stick your data-gathering code into the main loop, in this case.

Here's a bit of a re-hash of what you've got. Assuming it runs at all (I've not tested it), it should continue tracking whichever player was closest first, until that player moves out of range:

local p, i, username, playerData = peripheral.wrap("right"), 1

redstone.setOutput("left", true)

while true do
	print("Iteration: "..i)
	i = i + 1

	-- If we have a "username" stored:
	if username then
		playerData = p.getPlayerByName(username)
	end
	
	-- If the above didn't work (because we didn't already have
	-- a username stored, or the user moved out of range for eg):
	if not (playerData or username) then
		local info = p.getPlayers()
		
		if #info > 0 then
			username = info[1].name
			playerData = p.getPlayerByName(username)
		else
			username = nil
		end
	end
	
	term.clear()
	term.setCursorPos(1,1)
	
	if username then
		print(username)
	
		if playerData then
			for A, E in pairs(playerData.position) do
				print(A..": "..E)
			end
		end
	else
		print("No users in range!")
	end
	
	sleep(10)
end
Edited on 16 November 2014 - 01:24 AM
Bomb Bloke #5
Posted 16 November 2014 - 12:51 AM
Upon looking at my codes posted here, I tried some of the earlier methods out and using "if #p.getPlayers() ~= 0 then" works wonders.

That won't be 100% reliable - calling p.getPlayers() twice (once to check if it returns anything and once to see what was actually returned) may result in two different sets of results (one which indicates a player is in range, and one which doesn't contain any players at all).

Call it once, store the result, then check the length of that stored result.

Edit: using variables in place of their assigned functions doesn't seem to work when trying to actually use them, not sure if others are having the same problem

Exactly how are you attempting to do this?
Tamtam18_2 #6
Posted 16 November 2014 - 01:05 AM
Upon looking at my codes posted here, I tried some of the earlier methods out and using "if #p.getPlayers() ~= 0 then" works wonders.

That won't be 100% reliable - calling p.getPlayers() twice (once to check if it returns anything and once to see what was actually returned) may result in two different sets of results (one which indicates a player is in range, and one which doesn't contain any players at all).

Call it once, store the result, then check the length of that stored result.

Edit: using variables in place of their assigned functions doesn't seem to work when trying to actually use them, not sure if others are having the same problem

Exactly how are you attempting to do this?

im fixing up my code as we speak, i'll post it and show you when I can get the links. The variable bit, using it like "p.getPlayerbyName(username).position" is just fine, but I tried using just the name, without anything else in the line, of the variable before and it didn't work.
Edited on 16 November 2014 - 12:06 AM
Tamtam18_2 #7
Posted 16 November 2014 - 01:31 AM
Theres my code

http://www.computercraft.info/forums2/index.php?/topic/20997-player-detector-v20/
Tamtam18_2 #8
Posted 16 November 2014 - 02:25 AM

ok, it still breaks. on "info[1].name"

http://pastebin.com/C7jchGfd
Edited on 16 November 2014 - 01:29 AM
Dragon53535 #9
Posted 16 November 2014 - 03:29 AM

if p.getPlayers() ~= 0 then
getInfo()
getUsername()
--#Is basically
if p.getPlayers() ~= 0 then
getInfo()
getInfo()
username = info[1].name
--#Which is
if p.getPlayers() ~= 0 then
info = p.getPlayers()
info = p.getPlayers()
username = info[1].name
Perhaps that may be a problem? Otherwise what actual error are you receiving?

You do notice that you're calling p.getPlayers() 3 times in a row though, at one point you're going to have a problem if one of the last 2 doesn't return a player.
Edited on 16 November 2014 - 02:33 AM
Bomb Bloke #10
Posted 16 November 2014 - 07:40 AM
Come to think of it, does p.getPlayers() ever return a table filled with tables? If so, then what's the point of p.getPlayerByName()? I've got a sneaking suspicion the former only returns a table of strings - may be worth double checking that.

That is to say, what does this print?:

p = peripheral.wrap("right")
for key, value in pairs(p.getPlayers()) do
  print(key..": "..value)
end
Tamtam18_2 #11
Posted 17 November 2014 - 01:07 AM
Come to think of it, does p.getPlayers() ever return a table filled with tables? If so, then what's the point of p.getPlayerByName()? I've got a sneaking suspicion the former only returns a table of strings - may be worth double checking that.

That is to say, what does this print?:

p = peripheral.wrap("right")
for key, value in pairs(p.getPlayers()) do
  print(key..": "..value)
end

getPlayers() returns the uuid and username of the closest player, put it in a loop somehow to get multiple players at once.
getPlayerByName("Insert Player Name Here") needs getPlayers() to return a username to function and give out the player's position as well as their uuid, username and id, for whatever that last one is for.

With cc 1.6 the lua interpreter now prints tables from functions such as getPlayerByNames().
Tamtam18_2 #12
Posted 17 November 2014 - 01:58 AM

if p.getPlayers() ~= 0 then
getInfo()
getUsername()
--#Is basically
if p.getPlayers() ~= 0 then
getInfo()
getInfo()
username = info[1].name
--#Which is
if p.getPlayers() ~= 0 then
info = p.getPlayers()
info = p.getPlayers()
username = info[1].name
Perhaps that may be a problem? Otherwise what actual error are you receiving?

You do notice that you're calling p.getPlayers() 3 times in a row though, at one point you're going to have a problem if one of the last 2 doesn't return a player.

I've updated this post with a more developed and clean version of the code. what I posted earlier was a paper wad crumpled up, thrown into a bin, and then re-purposed. v2.1 still has some of the problems that door has, and it still has entity not found errors at lines 13 and 14 when I move 2 chunks away. I also added the line "p.getPlayers()" after line 11 and no luck.
Bomb Bloke #13
Posted 17 November 2014 - 03:58 AM
Specifics, please. Exactly what does p.getPlayers() return when you're nearby, and exactly what does it return when no one is nearby? If you get errors, exactly what do they say?
mrodin #14
Posted 12 April 2015 - 07:14 PM
Come to think of it, does p.getPlayers() ever return a table filled with tables? If so, then what's the point of p.getPlayerByName()? I've got a sneaking suspicion the former only returns a table of strings - may be worth double checking that.

That is to say, what does this print?:

p = peripheral.wrap("right")
for key, value in pairs(p.getPlayers()) do
  print(key..": "..value)
end

getPlayers() returns the uuid and username of the closest player, put it in a loop somehow to get multiple players at once.
getPlayerByName("Insert Player Name Here") needs getPlayers() to return a username to function and give out the player's position as well as their uuid, username and id, for whatever that last one is for.

With cc 1.6 the lua interpreter now prints tables from functions such as getPlayerByNames().

When I test this I get the following error

test:2: attempt to call nil
Bomb Bloke #15
Posted 12 April 2015 - 11:08 PM
That would suggest that whatever peripheral you have to the right of your system doesn't have a "getPlayers" function available through it. Odds are it isn't a sensor of the type Tamtam18_2 was using.