Lua double if

Hey,

wasn’t sure if I should put it in here or to “Help” but I think and hope it’s right here :stuck_out_tongue:

At the moment I’m trying around with lua (not good at it^^) but atm I stuck at one point.
I made a function which has an if in an if right at the start and I think there’s a problem with the ends.


function X(ply)
	
	-- Check if donator
	if ply:IsUserGroup("1") or ply:IsUserGroup("2") or ply:IsUserGroup("3") or ply:IsUserGroup("4") or ply:IsUserGroup("5") then
		if ply:SteamID("STEAM_0:0") then 
			end -- To say "go on to the next if in this function"
			else			
				ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
				return
				
	end
(function goes on here)

The function shouldn’t end after this. I want following:
If the person who executes the script is not in one of the groups it should print “You are no donator.” and returns (stops the whole function), otherwise it just goes on to the other things in the function.
BUT if the person who executes the script is in one of the groups but has the SteamID I wrote in there (in the script at the moment Steam_0:0) it shouldn’t return, just go on like usual in the script.
Hope you can understand what I mean and help me :smiley:

Thank you in advance.

a few things, and this is purely constructive, so pardon me if i sound dickish

  1. use proper spacing, especially when you want other people to read your code. it makes it a hell of a lot easier to read.

  2. if you’re using an else, you don’t put an end before it. example:



if x then 
	print(x)
else
	print("no x") 
end 


the rest you might be able to figure out on your own

Oh, didn’t see there’s one end too many. Edited it. But still, what did I do wrong? Do I need to put anything else as end into the if?

And to the spacing: I teached lua by myself so just did how I think it’s right^^

Here’s a very helpful post: http://forum.facepunch.com/showthread.php?t=1337945

Also, look for my posts for helpful tutorials, or ask the right questions in the right places and I may respond with a tutorial, or others may respond:

Simple Problems / Quick Questions that don’t need a dedicated thread: http://forum.facepunch.com/showthread.php?t=1348923

DarkRP Help Thread: http://forum.facepunch.com/showthread.php?t=1249475

I’d suggest being consistent; you’ll encounter many coding standards and styles throughout learning. Be sure to stick to one for the very least each project. Here’s mine: https://dl.dropboxusercontent.com/u/26074909/tutoring/_tutorial_quizzes/_coding_standards.lua.html

Read the TOP of that file; it tells you a little bit about the real-world in terms of coding standards. Large companies can demand you use their standard when working for them, project leads may require theirs, or you may be able to use whatever.

In your first post, you have several ifs with the THEN on the next line, kind of like php/C with curly braces. That’s fine, if you want to do that and you don’t get an error ( pretty sure BNF ignores whitespace in certain areas ) then be consistent. You have at least one where the then is on the same line. It confuses people, it makes it harder to read, it makes you think more to determine what each piece of code actually does.

Additionally, you have tabs all over the place, be consistent.

Hopefully this post helps.


if Animal:IsDonkey() then
	if Animal:GetColor() == Color(255, 0, 0 ) then
		print("Animal is a red donkey")
	else
		print("Animal isn't red, but is a donkey!")
	end
else
	print("Animal isn't a donkey")
end

Im no lua guru, so others will have to correct me if im wrong.

[LUA]
function X(ply)
if ply:IsUserGroup(“donator_group_name_here”) or ply:SteamID(“STEAM_0:0”) then --check if donator or correct SteamID
(call other functions or more code)
else ply:PrintMessage( HUD_PRINTTALK, “You are no donator.”)
return end
end
[/LUA]

-snip-

I typically grab the actual text of the user-group, then set it to lower, then compare in a direct-access table. Here are some benchmarking with NW vars, etc:

https://dl.dropboxusercontent.com/u/26074909/tutoring/benchmarking_tips/benchmarking_nw_vars.lua.html

https://dl.dropboxusercontent.com/u/26074909/tutoring/benchmarking_tips/benchmarking_hud_stuff.lua.html

so:[lua]return VIP_GROUPS_TABLE[ string.lower( _p:GetNWString( “UserGroup” ) ) ];[/lua]

Make a table like:

[lua]VIP_GROUPS_TABLE = {
member = true;
donator = true;
admin = true;
superadmin = true;
}[/lua]

Minteh Fresh: I did it exactly like you with “my things” and between the last else and the last end I had more code but it says there’s an end missing next to the last else…

Zapha: I want to do it the other way around. In one of these groups=no except if steam id = XX, else no. And I think your code says to donators they’re no donators :stuck_out_tongue:

Ace: Thanks for the links, will read through them but for some reason I don’t think this will help much.

And I don’t want to change much, I just want to do it in the same way I already did it. I just want to know what I did wrong^^
If the person is in the group say no, except his name is A. If the person isn’t in one of these groups say yes. That’s the short form of what I want :stuck_out_tongue:

Edit:
Minteh: I know, I changed it how I needed it but it says next to else needs to be an end but I did the end at the end of the function. Right over the end of it.

Animal and IsDonkey() aren’t real things, that’s probably why…

Not sure if I understood that. Are you trying to say that you dont have a usergroup for donators?

Zapha, I have but I have special groups for them, too^^ And instead of adding a new donator group it’s much easier to do it the other way round. And writing a donator group addon is much more complicated.
Ace: That’s near the same I did with the few “or”. So that’s the same problem, donator but in a group which isn’t usually allowed to use this.

My only problem with the code at the start:
It doesn’t know when the end is in the if and when the end closes the if. How can I fix that?

If you are using an admin addon like ulx or evolve, making usergroups are not hard at all. Its easier to make usergroup and making scripts refer to them than having to write every script to check for steamID’s.

Acecool: thanks for pinning that misstake you dick xD

Zapha, like I told you: I know, and I didn’t say it’s hard. But I already said I have special ranks for them, too (donator=own rank). And I already said I need the SteamID check for people who donated but are in groups which aren’t usually allowed to use this (trusted for example).

I’m really happy and thankful so many people answer so quick but please, I don’t want any suggestions to make it easier for me, just answer me this little question:
It doesn’t know when the end is in the if and when the end closes the if. How can I fix that?

Snipped it, sorry.

[editline]8th May 2014[/editline]

They’re useful for showing how much time using a table search can really cost you, and why direct-access is so useful and efficient. Also, I’m not sure how IsUserGroup operates, however if it looks up the NW var EACH TIME, that is EXPENSIVE. Look at the cost of just looking up NW vars, it is pricey… Cache it / call the var once for the check and compare like I did with direct access. Its much quicker, you don’t need to change much except get rid of all the if boolean statements, make the table with your group names set to true for is vip, and return the value… simple!

[editline]8th May 2014[/editline]

I don’t understand this.

When you type if if if if end end end end, the first if doesn’t use the first end, it uses the last. The inner most if uses the inner most end, they’re paired like that. If you tab code properly you can easily see how this works, look at this: https://dl.dropboxusercontent.com/u/26074909/tutoring/_tutorial_quizzes/_coding_standards.lua.html

More specifically:
[lua] function x( _blah )
// …
if ( _blah ) then
// …
for k, v in pairs( _blah ) do
// …
end
else
// …
print( “Blah !set” );
end
end[/lua]

If you print it out, and draw a line STRAIGHT DOWN from the F to the E you’ll see which matches which. Likewise, the inner if the else and the end match up in a straight line. The for and end match up.

Another example using this code from OP:

[lua]function X(ply)

-- Check if donator
if ply:IsUserGroup("1") or ply:IsUserGroup("2") or ply:IsUserGroup("3") or ply:IsUserGroup("4") or ply:IsUserGroup("5") then
	if ply:SteamID("STEAM_0:0") then 
		end -- To say "go on to the next if in this function"
		else			
			ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
			return
	[/lua]

Lets rewrite it…
[lua]function X(ply)

-- Check if donator
[if1] ply:IsUserGroup("1") or ply:IsUserGroup("2") or ply:IsUserGroup("3") or ply:IsUserGroup("4") or ply:IsUserGroup("5") then
	[if2] ply:SteamID("STEAM_0:0") then 
		[end2] -- To say "go on to the next if in this function"
		[else1]			
			ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
			return
	[/lua]

is how it sees things.

It’d be better and easier to read like this:

[lua][function] X(ply)
– Check if donator
[if1] ply:IsUserGroup(“1”) or ply:IsUserGroup(“2”) or ply:IsUserGroup(“3”) or ply:IsUserGroup(“4”) or ply:IsUserGroup(“5”) then
[if2] ply:SteamID(“STEAM_0:0”) then

	[end2] -- To say "go on to the next if in this function"
[else1]			
	ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
	return;
[end1]

[endfunction]
[/lua]

That’s what I wanted, thx^^ Problem: It’s the other way round. If the one who uses it is in these groups it works, if the one isn’t it doesn’t. So your else1 should be else2.

If in one of these groups:no, return
If in one of these groups but steam id=XX:yes, go on in script
If not in one of these groups:yes, go on in script

I don’t quite follow. Are you saying the groups above do NOT have vip access?

You can either inverse the logic ( change ||s to &&s, and use !s ), or move your content into the other thing. I still recommend writing it like this to save on efficiency; if you run it every frame or really often this can help:

[lua]// true = vip; strings can be written directly, numbers must use , odd strings ( start with number, etc ) must use [""]
local VIP_GROUPS_TABLE = {
admin = true;
superadmin = true;
developer = true;
[ 1 ] = false;
[ 2 ] = false;
[ 3 ] = false;
[ 4 ] = false;
[ 5 ] = false;
};

local META_PLAYER = FindMetaTable( “Player” );
function META_PLAYER:IsVIP( )
// Basic cache system, if cache hasn’t been set, or the cache has expired ( 3 seconds ) then set it, and reset the group so that it can be reset from networked var
if ( !self.__group_cache || CurTime( ) - self.__group_cache >= 3 ) then
self.__group_cache = CurTime( );
self.__group = nil;
end

// If the group isn't set, possibly from cache reset, set it -- in case the value is nil, set a default failsafe as guest
if ( !self.__group ) then
	self.__group = string.lower( ply:GetNWString( "UserGroup" ) ) || "guest";
end

// Return the true/false value if they're VIP. Also return the group just in case you need it.
// used like this: local _bIsVIP, _group = Player:IsVIP( ); -- _vIsVIP is the boolean value to test, _group is the group name, all lowercase. This function will work as is in if ( Player:IsVIP( ) ) then... statements...
return VIP_GROUPS_TABLE[ self.__group ], self.__group;

end
[/lua]

That’s exactly what I (tried to say) said a few times^^

So Ace, like I said, this code:


[function] X(ply)
	-- Check if donator
	[if1] ply:IsUserGroup("1") or ply:IsUserGroup("2") or ply:IsUserGroup("3") or ply:IsUserGroup("4") or ply:IsUserGroup("5") then
		[if2] ply:SteamID("STEAM_0:0") then 

		[end2] -- To say "go on to the next if in this function"
	[else1]			
		ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
		return;
	[end1]
[endfunction]

is close to the one I wanted. Else1 just needs to be else2. How can I do it?


[function] X(ply)
	-- Check if donator
	[if1] ply:IsUserGroup("1") or ply:IsUserGroup("2") or ply:IsUserGroup("3") or ply:IsUserGroup("4") or ply:IsUserGroup("5") then
		[if2] ply:SteamID( ) == "STEAM_0:0" then 
			// ...
		[else2]
			// ...
		[end2] -- To say "go on to the next if in this function"
	[else1]
		ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
		return;
	[end1]
[endfunction]

or


function X(ply)
	-- Check if donator
	if ply:IsUserGroup("1") or ply:IsUserGroup("2") or ply:IsUserGroup("3") or ply:IsUserGroup("4") or ply:IsUserGroup("5") then

		// So if they are NOT donators; you want a steam clause for someone in particular - it needs to be compared using ==, it accepts no arguments, much like PLAYER:Health( ) and PLAYER:Armor( ), etc...?
		if ( ply:SteamID( ) == "STEAM_0:0" ) then 
			// Steam Clause for whoever, even if not in official vip group...
			// ...

			// You may want to return so they aren't said no to...
			return true;
		else
			// So they aren't VIP, and they aren't a special SteamID claused person, what next?
			// ...

			// This else really isn't needed; because it could just fall through to the NO text
		end

		// No clause...
		ply:PrintMessage( HUD_PRINTTALK, "You are no donator.")
		return false;

	else

		// They ARE vip?
		return true;

	end
end

Tried your first one but still have the same problem. Too many ends in the if so it closes the function. Will try the 2nd one later.

Okay, thanks for your trying and fast responding but I think I just do it with more if and just set a variable. At the end it checks the variable and either says yes or no.

The second one is the cleaned version. So, that is the complete function; if you have more to add to the function, the LAST end is for the FUNCTION. Put the rest in between the last 2 ends…

Honestly, using the code with the meta-table would be the easiest and best bet. All you’d need to do is:

[lua]if ( ply:IsVIP( ) ) then
ply:PrintMessage( HUD_PRINTTALK, “You are a donator.”)
else
ply:PrintMessage( HUD_PRINTTALK, “You are not a donator.”)
end[/lua]

or

// Although this one does what could be done inside of the IsVIP function; check the STEAM IDS inside of that too
[lua]function VIPFunctionality( ply )
if ( ply:IsVIP( ) ) then
ply:PrintMessage( HUD_PRINTTALK, “You are a donator.” );
return true;
else
// Second chance:
if ( ply:SteamID( ) == “STEAM_0:0:1234” ) then
ply:PrintMessage( HUD_PRINTTALK, “You are saved by the bell…” );
return true;
end
end

ply:PrintMessage( HUD_PRINTTALK, "You are not a donator." );
return false;

end[/lua]

[lua]// true = vip; strings can be written directly, numbers must use , odd strings ( start with number, etc ) must use [""]
local VIP_GROUPS_TABLE = {
// String group names
admin = true;
superadmin = true;
developer = true;

// Number group names - false doesn't even need to be inserted
[ 1 ] 				= false;
[ 2 ] 				= false;
[ 3 ] 				= false;
[ 4 ] 				= false;
[ 5 ] 				= false;

// Odd strings
["1steamgroup"] 	= true;
["123testers"] 		= true;

};

// Define table
local VIP_STEAMIDS_TABLE = { };

// Add stuff to it
VIP_STEAMIDS_TABLE[ “STEAM_0:0:1234” ] = true;
VIP_STEAMIDS_TABLE[ “STEAM_0:1:1234” ] = true;

local META_PLAYER = FindMetaTable( “Player” );
function META_PLAYER:IsVIP( )
// Basic cache system, if cache hasn’t been set, or the cache has expired ( 3 seconds ) then set it, and reset the group so that it can be reset from networked var
if ( !self.__group_cache || CurTime( ) - self.__group_cache >= 3 ) then
self.__group_cache = CurTime( );
self.__group = nil;
end

// If the group isn't set, possibly from cache reset, set it -- in case the value is nil, set a default failsafe as guest
if ( !self.__group ) then
	self.__group = string.lower( ply:GetNWString( "UserGroup" ) ) || "guest";
end

// Return the true/false value if they're VIP. Also return the group just in case you need it.
// used like this: local _bIsVIP, _group = Player:IsVIP( ); -- _vIsVIP is the boolean value to test, _group is the group name, all lowercase. This function will work as is in if ( Player:IsVIP( ) ) then... statements...

// Updated, now the logic reads IF STEAMID is false or nil, check VIP GROUPS table, if that is false or nil return false, and the current group...
return ( VIP_STEAMIDS_TABLE[ self:SteamID( ) ] || VIP_GROUPS_TABLE[ self.__group ] ), self.__group;

end[/lua]

Which brings that code, back to this:
[lua]if ( ply:IsVIP( ) ) then
ply:PrintMessage( HUD_PRINTTALK, “You are a donator.”)
else
ply:PrintMessage( HUD_PRINTTALK, “You are not a donator.”)
end[/lua]