I don't know what's wrong with this code

I made an RTV extension to Wiox’s mapvote addon, based on Flow Bhop rtv.
Now this command works fine:


function RTV:Check( ply )
	RTV.Required = math.ceil( #player.GetHumans() * ( 3 / 5 ) )
	RTV.VotesLeft = RTV.Required - RTV.MapVotes
	ULib.tsayColor( ply, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.White, "There are " .. RTV.VotesLeft .. " votes needed to change map" )
end

hook.Add( "PlayerSay", "RTV_Check", function( ply, text, public )
	if string.sub( text, 1, 10 ) == "!rtv check" or string.sub( text, 1, 9 ) == "!rtv left" then
		RTV:Check( ply )
		return( "" )
	end
end )


But this one does not:



function RTV:Who( ply )
	local Voted = {}
	local NotVoted = {}
	
	for _, ply in pairs( player.GetHumans() ) do
		if ply.Rocked then
			table.insert( Voted, ply:Nick() )
		else
			table.insert( NotVoted, ply:Nick() )
		end
	end
	
	RTV.Required = math.ceil( #player.GetHumans() * ( 3 / 5 ) )
	
	ULib.tsayColor( ply, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.White, RTV.Required .. "vote(s) needed to change maps.
", "Voted(" .. #Voted .. "):" .. string.Implode( ", ", Voted ) .. "
", "Haven't Voted (" .. #NotVoted .. "):" .. string.Implode( ", ", NotVoted ) )
end

hook.Add( "PlayerSay", "RTV_Who", function( ply, text, public )
	if string.sub( text, 1, 8 ) == "!rtv who" or string.sub( text, 1, 9 ) == "!rtv list" then
		RTV:Who( ply )
		return( "" )
	end
end )

There command isn’t even being called (Tested it).
It’s probably retarded but I honestly have no clue wtf is going on…

Also, I have this line of code:


ULib.tsayError( ply, "'" .. Invalid_RTV_Subcommand[2] .. "' is not a valid subcommand of the rtv command.
Valid: " .. string.Implode( ", ", SubCommands ) )

But for some reason the "
" is only called at the end of the line, causing a weird double-row space between the 1st & 2nd line

Are you sure the file your code is in is being run?

Definitely.
As I said one command works, and the other one doesn’t (They’re both in the same file).
Full code:


--Tables for easier sorting
RTV = {}
QPS = {}

RTV.VoteInProgress = false
RTV.VoteShouldTakePlace = false
RTV.MapInit = CurTime()
RTV.MapEnd = 0
RTV.MapVotes = 0
RTV.VotesLeft = 0
RTV.Initialized = 0

--Presets
QPS.White 	= Color( 255, 255, 255 )
QPS.Notify 	= Color( 231, 76, 60 )
QPS.Ply 	= Color( 82, 82, 82 )

SubCommands = {
	"who",
	"check",
	"list",
	"left",
	"revoke",
}

function RTV:Vote( ply )
	if ply.RTVLimit and CurTime() - ply.RTVLimit < 60 then --If the player already voted and it hasn't been 60 seconds..
		return ULib.tsayError( ply, "You have to wait for another " .. math.ceil( 60 - (CurTime() - ply.RTVLimit) ) .. " seconds before using RTV again", true ) --Deny the vote
	elseif ply.Rocked then --If the player rocked the vote and hasn't revoked..
		return ULib.tsayError( ply, "You have already rocked the vote", true ) --Deny the vote
	elseif RTV.VoteInProgress then --If there's a vote in progress..
		return ULib.tsayError( ply, "There is already a vote in process", true ) --Deny the vote
	end
	
	ply.RTVLimit = CurTime()
	ply.Rocked = true
	
	RTV.MapVotes = RTV.MapVotes + 1
	RTV.Required = math.ceil( #player.GetHumans() * ( 3 / 5 ) )
	RTV.VotesLeft = RTV.Required - RTV.MapVotes
	ULib.tsayColor( nil, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.Ply, ply:Nick() .. " ", QPS.White, "has rocked the vote! ", Color( 255, 255, 255 ), "(" .. RTV.VotesLeft .. " votes left)" )
	
	if RTV.MapVotes >= RTV.Required then
		RTV:StartVote()
	end
end

hook.Add( "PlayerSay", "RTV_Vote", function( ply, text, public )
	if string.sub( text, 1, 4 ) == "!rtv" then
		RTV:Vote( ply )
		return( "" )
	end
end )

function RTV:Revoke( ply )
	if RTV.VoteInProgress then
		return ULib.tsayError( ply, "A map vote is in progress. You cannot vote right now", true )
	end

	if ply.Rocked then
		ply.Rocked = false
		
		RTV.MapVotes = RTV.MapVotes - 1
		RTV.Required = math.ceil( #player.GetHumans() * ( 3 / 5 ) )
		RTV.VotesLeft = RTV.Required - RTV.MapVotes
		ULib.tsayColor( nil, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.Ply, ply:Nick() .. " ", QPS.White, "has revoked his vote! ", Color( 255, 255, 255 ), "(" .. RTV.VotesLeft .. " votes left)" )
	else
		ULib.tsayError( ply, "You cannot revoke your vote because you haven't voted yet.", true )
	end
end

hook.Add( "PlayerSay", "RTV_Revoke", function( ply, text, public )
	if string.sub( text, 1, 7 ) == "!revoke" or string.sub( text, 1, 11 ) == "!rtv revoke" then
		RTV:Revoke( ply )
		return( "" )
	end
end )

function RTV:Check( ply )
	RTV.Required = math.ceil( #player.GetHumans() * ( 3 / 5 ) )
	RTV.VotesLeft = RTV.Required - RTV.MapVotes
	ULib.tsayColor( ply, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.White, "There are " .. RTV.VotesLeft .. " votes needed to change map" )
end

hook.Add( "PlayerSay", "RTV_Check", function( ply, text, public )
	if string.sub( text, 1, 10 ) == "!rtv check" or string.sub( text, 1, 9 ) == "!rtv left" then
		RTV:Check( ply )
		return( "" )
	end
end )

function RTV:Who( ply )
	local Voted = {}
	local NotVoted = {}
	
	for _, ply in pairs( player.GetHumans() ) do
		if ply.Rocked then
			table.insert( Voted, ply:Nick() )
		else
			table.insert( NotVoted, ply:Nick() )
		end
	end
	
	RTV.Required = math.ceil( #player.GetHumans() * ( 3 / 5 ) )
	
	ULib.tsayColor( ply, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.White, RTV.Required .. "vote(s) needed to change maps.
", "Voted(" .. #Voted .. "):" .. string.Implode( ", ", Voted ) .. "
", "Haven't Voted (" .. #NotVoted .. "):" .. string.Implode( ", ", NotVoted ) )
end

hook.Add( "PlayerSay", "RTV_Who", function( ply, text, public )
	if string.sub( text, 1, 8 ) == "!rtv who" or string.sub( text, 1, 9 ) == "!rtv list" then
		RTV:Who( ply )
		return( "" )
	end
end )

function RTV:StartVote()
	if RTV.VoteInProgress then return end
	
	if #player.GetHumans() == 1 then
		LANG.Msg("limit_vote")
		timer.Stop( "end2prep" )
		return MapVote.Start( MapvoteSettings.Length, MapvoteSettings.AllowCurrent, MapvoteSettings.Limit, MapvoteSettings.Prefix )
	end
		
	RTV.VoteInProgress = true
	RTV.VoteShouldTakePlace = true
	if RTV.VoteShouldTakePlace then
		ULib.tsayColor( nil, true, QPS.White, "[", QPS.Notify, "RTV", QPS.White, "] ", QPS.White, "A vote will take place at the end of this round" )
	end
end

hook.Add( "PlayerSay", "RTV_Invalid_Subcommand", function( ply, text, public )
	if string.sub( text, 1, 5 ) == "!rtv " then
		Invalid_RTV_Subcommand = string.Split( text, " " )
		if Invalid_RTV_Subcommand[2] and !table.HasValue( SubCommands, Invalid_RTV_Subcommand[2] ) then
			ULib.tsayError( ply, "'" .. Invalid_RTV_Subcommand[2] .. "' is not a valid subcommand of the rtv command. Valid: " .. string.Implode( ", ", SubCommands ) )
		end
		return( "" )
	end
end )

hook.Add( "TTTEndRound", "RTV_Vote_End_Round", function()
	if RTV.VoteShouldTakePlace then
		LANG.Msg("limit_vote")
		
		timer.Stop( "end2prep" )
		timer.Simple( 3, function()
			MapVote.Start( MapvoteSettings.Length, MapvoteSettings.AllowCurrent, MapvoteSettings.Limit, MapvoteSettings.Prefix )
		end )
	end
end )

-snipping bc i didnt read carefully enough-

My recommendation for you would really be to just study actual mapvote plugins before trying to extract one from a gamemode that has it integrated inside, though.

By that logic, using any of the rtv commands would not work, which they do.
RTV:Who is the only one that doesn’t.
Also I’m doing return( “” ) AFTER calling the function…

I don’t use the ULib.tSayColor function myself (read: i have never used it), but it looks like you have an extra comma in that function after the "
" to separate voted/not voted.
Again, I have never used the function, so I’m purely speculating.

Edit: you’re not getting ANY errors in console?

The commas are fine, I’ve used it in other codes.
The problem is the function is never even called.
I tried replacing everything inside RTV:Who with a simple ply:ChatPrint and print, they never showed up

Your hooks are all the exact same thing, with the unique ID being different. There’s no reason that RTV:Who shouldn’t execute.
You could try concatenating the functions and use if/elseif statements to switch between them and store the commands in a table. Use the PlayerSay hook to check for the use of !rtv and go into the function from that. If the function doesn’t run, the problem lies with your hook.

So you could just do this for your hook


hook.Add( "PlayerSay", "RTV", function( ply, text )
    if string.sub( text, 1, 4 ) == "!rtv" then
        RTV:Commands( ply, text )
    end
end

And then use if/elseif in an RTV:Commands function.

I’m tossing you ideas now. All I know for sure is the hook used to call RTV:Who is either not executing or the code inside is being skipped.