====== Getting Player Attributes using scripts ===== ==== What are the player attributes ==== As you may have guessed, Player Attributes, or 'playerattr' for short are really important, because these attributes hold essential values directly asociated with the game character. for example, health points of our character, attack capabilities, speed and defense ((You can find more info about playerattrs here: [[developer_center:developer_editor:script:datatype#player_attributes| Player attribute list]] )). You may think they are the same as private variables, but they are pretty different, altough they both are values directly related to the player, playerattrs are already defined by the game, we can change their value using scripts but we cant create them, whereas private variables are created and defined by us ==== How to use the player attributes ==== After a little bit of theory, you may start to wonder, how to use them? and the answer is the **Player:getAttr(objid: number,attrtype: number)** method, it takes two args. * the id of the player who we want to get the attr (**objid**) * the attribute that we want to get (**attrtype**) this method returns also returns * the **errorcode** ((Learn more about error codes and error handling here [[developer_center:developer_editor:script:miniapi_tutorialerrorhandling|Error codes and error handling]])) * the attribute value as a number === Example === For this example, we want that when the player attacks and it hits an actor or a player, we get the attr of the player who attacked and the attr of the actor that took the damage, we create a function and make it so it takes the parameters that the event returns, as there is already a tutorial for this, i won't go as deep as i did there (The tutorial: [[developer_center:developer_editor:script:miniapi_tutorialevent| Mini world API event usage]]) **The code should look like this:** function PlayerAttackHits(params) end We then add the [[wp>https://en.wikipedia.org/wiki/Event_(computing)#Event_handler| Listener]] function and the code should look like this function PlayerDamageActor(params) end ScriptSupportEvent:registerEvent([=[Player.DamageActor]=], PlayerDamageActor) After that we declare a variable to store the params Code should look like this function PlayerDamageActor(params) local playerid = params.eventobjid local otheractorid = params.toobjid end ScriptSupportEvent:registerEvent([=[Player.DamageActor]=], PlayerDamageActor) And then we must add the logic to check if the actor is a player or a creature, for that, we can use the **Actor:isPlayer(objid: number)** method that checks if the actor is a player, the parameter it takes its the **objid** which is the id of the actor we would like to know if it's a player,if the actor is a player, it returns 0, otherwise (if the actor is not a player) it returns the number 1001, so we add it to our code along with an if statement and an else one function PlayerAttackHits(params) local playerid = params.eventobjid local otheractorid = params.toobjid if Actor:isPlayer(otheractorid) == 0 then else end end ScriptSupportEvent:registerEvent([=[Player.DamageActor]=], PlayerAttackHits) (You may ask, what is local for, it's the scope, more info about scope in the footnote ((in lua Local variables are confined to the specific block or function where they are declared. They have a limited scope and cannot be accessed outside of that block or function. This helps in keeping the code modular and prevents unintended interference with other parts of the program.)) ) if you do not feel comfortable with using functions in the if statement (the more direct way) you can use the functions in variables and the code would look like this function PlayerAttackHits(params) local playerid = params.eventobjid local otheractorid = params.toobjid local result = Actor:isPlayer(otheractorid) if result == 0 then else end end ScriptSupportEvent:registerEvent([=[Player.DamageActor]=], PlayerAttackHits) **Note: Both approaches give the same outcome, but the latter is more recommended if you will use that comparison or function more than one time** After that we declare two variables, the first that holds the result and the second that holds the attr value Just like this: **local result,AttributeValue = Player:getAttr(otheractorid, PLAYERATTR.CUR_HP)** and we can add it to a message, for this we will use the Chat:SendSystemMsg(content: string, targetuin: number) method that lets us send messages to chat from the script You can use **Chat:SendSystemMsg("Your enemy's helth is " + tostring(AttributeValue))** or you can also use the recommended way **Chat:SendSystemMsg("Your enemy's helth is ".. AttributeValue)** both do essentially the same but the latter concatenates the number, it turns it into a string and adds it, to contatenate we use the (..) ((Example: print("Hello".. "world!") -> Hello world! )) **So, the code should look something like this:** function PlayerDamageActor(params) local playerid = params.eventobjid local otheractorid = params.toobjid if Actor:isPlayer(otheractorid) == 0 then local result,AttributeValue = Player:getAttr(otheractorid, PLAYERATTR.CUR_HP) Chat:sendSystemMsg("Your enemy's health is: ".. AttributeValue, playerid) else local result, OtherAttributeValue = Creature:getAttr(otheractorid,CREATUREATTR.CUR_HP) Chat:sendSystemMsg("Your enemy's health is: ".. OtherAttributeValue, playerid) end end ScriptSupportEvent:registerEvent([=[Player.DamageActor]=], PlayerDamageActor) ==== Modifying the player attributes ==== To modify the player attributes, we can use the **Player:setAttr(objid,attrtype,NewVal)** it's simpler, here we will use the same example but we will set the Player or Actor's current Hp to 0, we can do this === Example === local function PlayerDamageActor(params) local playerid = params.eventobjid local otheractorid = params.toobjid if Actor:isPlayer(otheractorid) == 0 then local result,AttributeValue = Player:setAttr(otheractorid, PLAYERATTR.CUR_HP,0) else local result, OtherAttributeValue = Creature:setAttr(otheractorid,CREATUREATTR.CUR_HP,0) end end ScriptSupportEvent:registerEvent([=[Player.DamageActor]=], PlayerDamageActor) Now, whenever a player damages anything the life of the mob or player he attacked will become 0