Jump to content

Player Specific Data In Arrays


Frequency

Recommended Posts

Hi, may I ask what about what the standard way to con a player data array ? For instance, the following will declare an array and make it grow, I've set it to go to the maximum player count.

  
-- The player array variable. 
plrArray = {} 
  
-- Make the array grow according to the maximum amount of players on the server. 
for i=1, getMaxPlayers() do 
    plrArray[i] = 0 
end 
  

But, I have got into the prediciment where I don't know how I'd be able to get a playerid. Does playerid exist in MTA, or is it just source? If it's just source, how would I implement it as to getting player specific data? I'd rather it not require an account system. Thanks in advance. :)

Link to comment

Players are Elements in MTA. You could see it as an unique ID (Identification), but it's not a simple number, but rather some more obscure data, like an object. When a player joins, an player object is created and passed on to the onPlayerJoin event, which you can use to greet the player on join or something. When a player leaves, the object is destroyed.

I'm not sure what you are trying to do exactly, but if you want to get all players on the server, you can just use getElementsByType (see the example).

Link to comment

Thanks for your reply driver2.

I am not trying to fill an array with a list of players as such, rather fill an array with a boolean value for each possible player. The boolean value will determine whether the player could perform a specific task, such as using a bind. Is there an example or alternative method out there?

Link to comment

You can use the ACL for this. For example, in the everyone group, add this to prevent anyone from accessing the "fix" command:

  
   ... 
   <acl name="Default"> 
      [b]<right name="command.fix" access="false" />[/b] 
  
      <right name="general.ModifyOtherObjects" access="false"/> 
      <right name="general.http" access="false"/> 
      ... 
  

Then you can give moderators access to it for example by adding:

  
   ... 
   <acl name="Moderator"> 
      [b]<right name="command.fix" access="true"/>[/b] 
      <right name="general.ModifyOtherObjects" access="false"/> 
      ... 
  

If you're looking for a way to store player specific data in a list, I'd use a table/array for things you don't want the client to change, for example score, kills, deaths etc... and the values that the client can change using setElementData and getElementData.

Here is a set of functions I wrote to get/set different scores for players. But the same system can be used to store a boolean for every player for example:

  
-- Joined players. Don't use elementdata for security reasons. Clients 
-- can change it. 
scorePlayers = {} 
  
  
-- Increment a score of a player 
function addPlayerScore ( thePlayer, entry, amount ) 
  
    -- Get the table entry of this player. If it doesn't 
    -- exist, add it. 
    local playerTableEntry = scorePlayers [ thePlayer ] 
    if ( not playerTableEntry ) then 
        playerTableEntry = {} 
        scorePlayers [thePlayer] = playerTableEntry 
    end 
     
    -- Grab the score entry and increment it with the amount 
    local previousAmount = playerTableEntry [entry]  
    if ( not previousAmount ) then previousAmount = 0 end 
    playerTableEntry [entry] = previousAmount + amount 
     
    -- Also set his score entry in his elementdata 
    setElementData ( thePlayer, "lms.score." .. entry, previousAmount + amount ) 
  
end 
  
  
-- Get a score of a player 
function getPlayerScore ( thePlayer, entry ) 
  
    -- Get the table entry of this player. If it doesn't 
    -- exist, add it. 
    local playerTableEntry = scorePlayers [ thePlayer ] 
    if ( not playerTableEntry ) then 
        return false 
    end 
     
    -- Grab the score entry and increment it with the amount 
    local ret = playerTableEntry [entry] 
    if ( not ret ) then 
        return 0 
    else 
        return ret 
    end 
end 
  
  
-- Set a score of a player 
function setPlayerScore ( thePlayer, entry, score ) 
  
    -- Get the table entry of this player. If it doesn't 
    -- exist, add it. 
    local playerTableEntry = scorePlayers [ thePlayer ] 
    if ( not playerTableEntry ) then 
        playerTableEntry = {} 
        scorePlayers [thePlayer] = playerTableEntry 
    end 
     
    -- Grab the score entry and increment it with the amount 
    playerTableEntry [entry] = score 
     
    -- Also set his score entry in his elementdata so clients can read it 
    setElementData ( thePlayer, "lms.score." .. entry, amount ) 
  
end 
  
  
-- Resets the score of a player. Also call this when he exists 
-- to erase him from the list 
function resetPlayerScore ( thePlayer ) 
  
    -- Remove him from our table 
    table.remove ( scorePlayers, thePlayer ) 
  
end 
  
  
-- Resets the score of all players. 
function resetPlayerScores () 
  
    -- Clear the table 
    scorePlayers = {} 
  
end 
  

Example usage:

  
function onPlayerJoinHandler () 
    setPlayerScore ( source, "somenumber", 50 ) 
    setPlayerScore ( source, "somebool", true ) 
    setPlayerScore ( source, "sometable", { 30, 50, 60, 100 } ) 
end 
  
function onPlayerQuitHandler () 
    local somenumber = getPlayerScore ( source, "somenumber" ) 
    local somebool = getPlayerScore ( source, "somebool" ) 
    local sometable = getPlayerScore ( source, "sometable" ) 
  
    -- Iterate the table etc.. 
end 
  
addEventHandler ( "onPlayerJoin", getRootElement (), onPlayerJoinHandler ) 
addEventHandler ( "onPlayerQuit", getRootElement (), onPlayerQuitHandler ) 
  

In LUA, anything can be used to index arrays, not just numbers. You can use numbers, strings, elements, tables even functions to index them. Here I take advantage of using the player element to index the array so I don't have to mess with indexes and looping and screwing with that. Much neater :).

I named my functions score because I specifically use them to keep track of my score, but it's no problem to use it for other data except you can't use addPlayerScore for other data. Hope this helps :).

Link to comment
In LUA, anything can be used to index arrays, not just numbers.

Ah, thank you for clearing that up. I will assume that I will need to clean up the element in the array in which I would want to be using? If I were to do this, would I set it's value to nil, or give it a value of zero? I understand the array can't have any more than 999 elements (1-1000), and if the script was getting different clients on and off, it could possibly exceed this limit if the values weren't cleaned up. Thanks in advance. :)

Link to comment
Let me just emphasize that you should not have to create an array for player data, use setElementData and getElementData instead.

Until we have server-only element data, element-data should not be used for scores and similar because clients can change them in theory.

Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...