Bilal135 Posted December 15, 2019 Share Posted December 15, 2019 I'm trying to find the difference between two tables. For e.g, if I have two tables, one with all players online in the server, and the other who are currently typing (have their chat box input active). I want to return a new table that would contain all players except the players who are typing. The code below should output the names of those players who are NOT typing at the moment, but it outputs names of even those players who are typing. I have already got the players who are typing, in a table, called 'my_player_list'. function difference(a, b) local aa = {} for k,v in pairs(a) do aa[v]=true end for k,v in pairs(b) do aa[v]=nil end local ret = {} local n = 0 for k,v in pairs(a) do if aa[v] then n=n+1 ret[n]=v end end return ret end addEventHandler("onClientRender", root, function() -- using onClientRender here because I'm going to use dxDraw functions here local playerTable = getElementsByType("player") rTable = difference(playerTable, my_player_list) -- my_player_list is a table which contains players who are typing for i, v in pairs(rTable) do if (v) then outputChatBox(""..getPlayerName(v).."") end end end) Thanks. Link to comment
Platin Posted December 15, 2019 Share Posted December 15, 2019 (edited) Just do something like this, it should work just fine: function difference(a,b) -- This should put everything that is on table A and it isn't on table B into a new indexed table local ret = {} for k,v in pairs(a) do local insert = true for k2,v2 in pairs(b) do if v == v2 then insert = false break; end end if insert then table.insert(ret, v) end end return ret end If you want to go the way you code went then you should do something like this: function difference(a,b) local aa = {} for k,v in pairs(a) do aa[v]=true end for k,v in pairs(b) do aa[v]=nil end local ret = {} for k,v in pairs(aa) do table.insert(ret, v) end return ret end However I don't think you should use this (if it even works) because you just run too much stuff without it being really needed to be, and it's kinda pointless. Edited December 15, 2019 by Platin - xNikoXD I forgot the return, and I added something else Link to comment
Bilal135 Posted December 15, 2019 Author Share Posted December 15, 2019 (edited) addEventHandler("onClientRender", root, function() local playerTable = getElementsByType("player") rTable = difference(playerTable, my_player_list) for i, v in pairs(rTable) do if (v) then outputChatBox(""..getPlayerName(v).."") local px, py, pz, tx, ty, tz, dist px, py, pz = getCameraMatrix( ) tx, ty, tz = getElementPosition( v ) dist = math.sqrt( ( px - tx ) ^ 2 + ( py - ty ) ^ 2 + ( pz - tz ) ^ 2 ) if dist < 60.0 then if isLineOfSightClear( px, py, pz, tx, ty, tz, true, false, false, true, false, false, false,localPlayer ) then local sx, sy, sz = getPedBonePosition( v, 6 ) local x,y = getScreenFromWorldPosition( sx, sy, sz + 0.2 ) local playerR, playerG, playerB = getPlayerNametagColor ( v ) if x then dxDrawBorderedText( string.gsub ( getPlayerName ( v ), "#%x%x%x%x%x%x", "" ).."", x, y, x, y, tocolor(playerR, playerG, playerB), 1.1, "default-bold", "center", "center" ) end else return end end end end end) How else would you approach this then? element datas maybe? Edited December 15, 2019 by Lynch Link to comment
Platin Posted December 15, 2019 Share Posted December 15, 2019 (edited) Never, really never never never element datas if you will edit them every frame, you will just lag the client (and if synced) the entire server. The above code is ok, but I would personally make this changes: addEventHandler("onClientRender", root, function() -- Using getElementsByType("player", root, true) instead of getElementsByType("player") will give us only the users that the client is streaming in local rTable = difference(getElementsByType("player", root, true), my_player_list) -- This would be the same for the entirety of the frame, you don't need to update it for every player, so just let it seat outside local px, py, pz = getCameraMatrix( ) -- We should use ipairs, because our table is indexed properly, this should decrease usage of... cpu? ig for i, v in ipairs(rTable) do -- i don't know why you have this check here, but if you want to check if V is an element, use this: if isElement(v) then local tx, ty, tz = getElementPosition( v ) local dist = math.sqrt( ( px - tx ) ^ 2 + ( py - ty ) ^ 2 + ( pz - tz ) ^ 2 ) if dist < 60.0 then if isLineOfSightClear( px, py, pz, tx, ty, tz, true, false, false, true, false, false, false, localPlayer) then local sx, sy, sz = getPedBonePosition( v, 6 ) local x,y = getScreenFromWorldPosition( sx, sy, sz + 0.2 ) -- You shouldn't store variables if they won't vary, if possible ofc if x then dxDrawBorderedText( string.gsub ( getPlayerName ( v ), "#%x%x%x%x%x%x", "" ).."", x, y, x, y, tocolor(getPlayerNametagColor(v)), 1.1, "default-bold", "center", "center" ) end -- If you return here, you won't be drawing anyone else if the check fails end end end end end ) Edited December 15, 2019 by Platin - xNikoXD minor update Link to comment
Bilal135 Posted December 15, 2019 Author Share Posted December 15, 2019 (edited) Tried it. It does not work as expected. When typing, nametag does not disappear. One thing to be noted is that when doing this, for i, v in pairs(my_player_list) do 'i' returns player element and not 'v'. Makes any difference in how the 'difference' function should operate? EDIT: Solved. Thank you @Platin - xNikoXD. Edited December 15, 2019 by Lynch Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now