Dzsozi (h03) Posted October 18, 2016 Share Posted October 18, 2016 Hello! I would like to create a custom level system for my server, that works something like GTA V's level system, a little bit different maybe. There would be a limit for a level, so for example 5000 XP is 1 level, if you reach 5000 XP then you level up, after you leveled up another 5000 XP is getting added to the limit, so at level 2 you would need 10000 XP, level 3 15000 XP, level 4 20000 XP etc. etc. I would like to make this thing without tables, because I would like it to be unlimited. I started to make it and firstly I wanted to make the basic commands, like giving getting and setting XP for players, but I bumped into some problems that I can't fix. I would like to ask for help for these things: - How can I make an event handler which detects if a player leveled up? So I could make functions like playing a sound on each level up, or showing a screen that shows my new level and stuff, etc., so I would have an "onClientPlayerLevelUp" and an "onPlayerLevelUp" (for client and server) - How can I fix the current issue, which is the following: the script doesn't give me the amount of XP I write in, if I write in wrong parameters it shows me the error messages, but if I write it in correctly it doesn't give me the XP, only shows 0 XP in chat. Could somebody help me with these two things please? I would highly appreciate it! Here's the server side script: local TPLimit = 5000 local playerTP = 0 local playerLevel = 0 --[[addEvent("onPlayerLevelUp", true) addEventHandler("onPlayerLevelUp", root, function(thePlayer) if thePlayer == source then local if playerTP > TPLimit then -- I DONT KNOW WHAT TO PUT HERE OR HOW TO MAKE THIS EVENT end end)]] function givePlayerTP(thePlayer, tp) if (isElement(thePlayer)) then if (tp > 0) then playerTP = playerTP + tp end end end function getPlayerTP(thePlayer) if (isElement(thePlayer)) then return playerTP else return 0 end end function setPlayerTP(thePlayer, tp) if (isElement(thePlayer)) then if (tp > 0) then playerTP = tp end end end function giveTP(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromName(targetPlayer) if not tonumber(tp) or not tostring(target) then outputChatBox("/" .. commandName .. " [player] [xp]", playerSource) else if tonumber(tp) > 0 then givePlayerTP(target, tp) outputChatBox("" .. getPlayerTP(target) .. " XP") else outputChatBox("must be more than 0", playerSource) end end end addCommandHandler("givetp", giveTP) function getTP(playerSource) local points = getPlayerTP(playerSource) outputChatBox("" .. points .. "", playerSource) end addCommandHandler("gettp", getTP) I'm not sure what's wrong and what's not in this script, I created it by myself but I can't figure out how to fix these two things I mentioned. I would like to make it function like I wrote above, and I would also like to save it somehow, I was thinking about element datas and account datas, maybe I will stick to account datas so I can save it with my current save system, which is similar like the community ones (gets all the data that needs to be saved from the player on quit and then sets the account data to it, when you login it gets the saved account data and sets your stats position, etc. to the saved one, hope you know that or understand me). Thank you for your response and help in advance! P.S.: Also, how I could make client and server side exports for giving XP? Because I would like to make it work like if you do missions or stunts or something like that you will get for example 1500 XP for a mission, or is it enough if I make an export for the server side? Should it be only server sided and then trigger it from the server side to client side in the mission scripts? Link to comment
MIKI785 Posted October 19, 2016 Share Posted October 19, 2016 You're missing the very basic thing: actually giving players those XPs. I mean, you have playerTP variable and you just change that in givePlayerTP, it doesn't make sense. It means that all the players will share the same value since it's on serverside. The best way to do this would be to use setElementData, so you can easily change it both server and client side and not worry about syncing it. Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 So instead of playerTP = playerTP + tp I should use setElementData(thePlayer, "playerTP", playerTP + tp)? Link to comment
Tekken Posted October 19, 2016 Share Posted October 19, 2016 (edited) Actually setElementData(player, "playertp", (getElementData(player, "playertp") or 0) + tp); Or you can use tables like this: Replace local playerTP = 0; playerTP = playerTP + tp; with local playerTP = {}; -- Create the table at the very top. playerTP[player] = playerTP[player] + tp; --Add [player] to make sure it's for the right player. Edited October 19, 2016 by Tekken Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 I think I will go with element datas, I think it's easier, thank you, I will try it! And how can I make the event, to detect if a player leveled up and then duplicate the tplimit and give him a higher level? Link to comment
Tekken Posted October 19, 2016 Share Posted October 19, 2016 Just add a check like this: if (getElementData(player, "playertp") + tp >= TPlimit) then --The player has just level up. end You can create an event and trigger it when the player level's up. Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 4 minutes ago, Tekken said: Just add a check like this: if (getElementData(player, "playertp") + tp >= TPlimit) then --The player has just level up.end You can create an event and trigger it when the player level's up. Alright, I will do that, but I am having issues again, not it doesn't output anything, if I write in /gettp I don't get any message, or if I write in /givetp dzsozi 5 then it doesn't output the amount of TP I have, so I guess it also doesn't even give me the TP. local TPLimit = 5000 local playerTP = 0 local playerLevel = 0 --[[addEvent("onPlayerLevelUp", true) addEventHandler("onPlayerLevelUp", root, function(thePlayer) if thePlayer == source then local if playerTP end end)]] function givePlayerTP(thePlayer, tp) if (isElement(thePlayer)) then if (tp > 0) then --playerTP = playerTP + tp setElementData(thePlayer, "playertp", (getElementData(thePlayer, "playertp") or 0) + tp); end end end function getPlayerTP(thePlayer) if (isElement(thePlayer)) then return getElementData(thePlayer, "playertp") --playerTP end end function setPlayerTP(thePlayer, tp) if (isElement(thePlayer)) then if (tp > 0) then playerTP = tp end end end function giveTP(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromName(targetPlayer) if not tonumber(tp) or not tostring(target) then outputChatBox("/" .. commandName .. " [játékos] [pont]", playerSource) else if tonumber(tp) > 0 then givePlayerTP(target, tp) outputChatBox("" .. getPlayerTP(target) .. " TP", target) else outputChatBox("többnek kell lennie mint 0", playerSource) end end end addCommandHandler("givetp", giveTP) function getTP(playerSource) local points = getPlayerTP(playerSource) outputChatBox("" .. points .. "", playerSource) end addCommandHandler("gettp", getTP) What could be the problem? Link to comment
Tekken Posted October 19, 2016 Share Posted October 19, 2016 Try this: local TPLimit = 5000; function getPlayerFromPartialName(name) local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil; if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower(); if name_:find(name, 1, true) then return player; end end end end function givePlayerTP(thePlayer, tp) if (thePlayer) then if (tp > 0) then setElementData(thePlayer, "playertp", (getElementData(thePlayer, "playertp") or 0) + tp); if (getElementData(thePlayer, "playertp") > TPLimit) then --Level up. end end end end function getPlayerTP(thePlayer) if (thePlayer) then return getElementData(thePlayer, "playertp") or 0; end end function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tp > 0) then setElementData(thePlayer, "playertp", tp); if (getElementData(thePlayer, "playertp") > TPLimit) then --Level up. end end end end addCommandHandler("givetp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); -- way better that the built in MTA function! if not tp or not target then outputChatBox("/" .. commandName .. " [játékos] [pont]", playerSource); else if (tonumber(tp) > 0) then givePlayerTP(target, tp); outputChatBox("" .. getPlayerTP(target) .. " TP", target); else outputChatBox("többnek kell lennie mint 0", playerSource); end end end); addCommandHandler("gettp", function(playerSource) local points = getPlayerTP(playerSource); outputChatBox("" .. points .. "", playerSource); end); Also you must save the TP when player quit and load it when join. Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 It works I guess, thank you very much! I will try to continue and save it, thank you again! I will write if I have any problems. Link to comment
Gravestone Posted October 19, 2016 Share Posted October 19, 2016 For the onPlayerLevelUp event, you can use onElementDataChange event to check if the level data changed and then trigger the onPlayerLevelUp event. Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 I am having problems again, now with handling the level up. Could somebody help me please? local TPLimit = 5000; function getPlayerFromPartialName(name) local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil; if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower(); if name_:find(name, 1, true) then return player; end end end end function givePlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) > 0) then setElementData(thePlayer, "playertp", (getElementData(thePlayer, "playertp") or 0) + tp); if (tonumber(getElementData(thePlayer, "playertp")) >= tonumber(TPLimit)) then --Level up. --TPLimit = TPLimit + TPLimit setElementData(thePlayer, "playerlevel", (getElementData(thePlayer, "playerlevel") or 0) + 1); outputChatBox("level up", thePlayer) outputChatBox("" .. getElementData(thePlayer, "playerlevel") .. "", thePlayer) end end end end function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) >= 0) then setElementData(thePlayer, "playertp", tp); if (tonumber(getElementData(thePlayer, "playertp")) >= tonumber(TPLimit)) then --Level up. --TPLimit = TPLimit + TPLimit setElementData(thePlayer, "playerlevel", (getElementData(thePlayer, "playerlevel") or 0) + 1); outputChatBox("level up", thePlayer) outputChatBox("" .. getElementData(thePlayer, "playerlevel") .. "", thePlayer) end end end end function getPlayerTP(thePlayer) if (thePlayer) then return getElementData(thePlayer, "playertp") or 0; end end addCommandHandler("settp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); -- way better that the built in MTA function! if not tonumber(tp) or not target then outputChatBox("/" .. commandName .. " [játékos] [pont]", playerSource); else if (tonumber(tp) >= 0) then setPlayerTP(target, tp); outputChatBox("" .. getPlayerTP(target) .. " TP", target); else outputChatBox("0-nak vagy annál többnek kell lennie", playerSource); end end end); addCommandHandler("givetp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); -- way better that the built in MTA function! if not tonumber(tp) or not target then outputChatBox("/" .. commandName .. " [játékos] [pont]", playerSource); else if (tonumber(tp) > 0) then givePlayerTP(target, tp); outputChatBox("" .. getPlayerTP(target) .. " TP", target); else outputChatBox("többnek kell lennie mint 0", playerSource); end end end); addCommandHandler("gettp", function(playerSource) local points = getPlayerTP(playerSource); outputChatBox("" .. points .. "", playerSource); end); If I reach 5000 XP then I get leveled up, as it would be normal, but if I get for example 1 XP after I reached 5000 I get leveled up again. So if I have more XP than 5000, no matter how much, I get leveled up everytime when I get XP. I would like to make it work like if you level up then the amount of XP needed for the next level will get added again, like I already wrote down, if you are level 1 then you need 5000 XP, if you reach 5000 XP then you will be level 2 and you need 10000 XP for level 3, etc. How can I make it work like this? Do I have to make other functions for giving a level to the player? How can I make it possible? Link to comment
Tekken Posted October 19, 2016 Share Posted October 19, 2016 (edited) Try this, make sure you edit the table to whatever you like local TPLimit = 5000; local tpForLevel = { {5000, 1}, {10000, 2}, {15000, 3}, -- Add as many as you want! }; function getPlayerFromPartialName(name) local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil; if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower(); if name_:find(name, 1, true) then return player; end end end end function givePlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) > 0) then setElementData(thePlayer, "playertp", (getElementData(thePlayer, "playertp") or 0) + tp); for _,v in ipairs(tpForLevel) do if (v[1] >= getElementData(thePlayer, "playertp")) then setElementData(thePlayer, "playerlevel", v[2]); outputChatBox("level up", thePlayer); outputChatBox(getElementData(thePlayer, "playerlevel"), thePlayer); end end end end end function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) >= 0) then setElementData(thePlayer, "playertp", tp); for _,v in ipairs(tpForLevel) do if (v[1] >= getElementData(thePlayer, "playertp")) then setElementData(thePlayer, "playerlevel", v[2]); outputChatBox("level up", thePlayer); outputChatBox(getElementData(thePlayer, "playerlevel"), thePlayer); end end end end end function getPlayerTP(thePlayer) if (thePlayer) then return getElementData(thePlayer, "playertp") or 0; end end addCommandHandler("settp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); if not tonumber(tp) or not target then outputChatBox("/"..commandName.." [játékos] [pont]", playerSource); else if (tonumber(tp) >= 0) then setPlayerTP(target, tp); outputChatBox(getPlayerTP(target).." TP", target); else outputChatBox("0-nak vagy annál többnek kell lennie", playerSource); end end end); addCommandHandler("givetp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); if not tonumber(tp) or not target then outputChatBox("/"..commandName.." [játékos] [pont]", playerSource); else if (tonumber(tp) > 0) then givePlayerTP(target, tp); outputChatBox(getPlayerTP(target).." TP", target); else outputChatBox("többnek kell lennie mint 0", playerSource); end end end); addCommandHandler("gettp", function(playerSource) local points = getPlayerTP(playerSource); outputChatBox(points, playerSource); end); Edited October 19, 2016 by Tekken Done Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 17 minutes ago, Tekken said: Try this, make sure you edit the table to whatever you like local TPLimit = 5000; local tpForLevel = { {5000, 1}, {10000, 2}, {15000, 3}, -- Add as many as you want! }; function getPlayerFromPartialName(name) local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil; if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower(); if name_:find(name, 1, true) then return player; end end end end function givePlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) > 0) then setElementData(thePlayer, "playertp", (getElementData(thePlayer, "playertp") or 0) + tp); for _,v in ipairs(tpForLevel) do if (v[1] >= getElementData(thePlayer, "playertp")) then setElementData(thePlayer, "playerlevel", v[2]); outputChatBox("level up", thePlayer); outputChatBox(getElementData(thePlayer, "playerlevel"), thePlayer); end end end end end function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) >= 0) then setElementData(thePlayer, "playertp", tp); for _,v in ipairs(tpForLevel) do if (v[1] >= getElementData(thePlayer, "playertp")) then setElementData(thePlayer, "playerlevel", v[2]); outputChatBox("level up", thePlayer); outputChatBox(getElementData(thePlayer, "playerlevel"), thePlayer); end end end end end function getPlayerTP(thePlayer) if (thePlayer) then return getElementData(thePlayer, "playertp") or 0; end end addCommandHandler("settp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); if not tonumber(tp) or not target then outputChatBox("/"..commandName.." [játékos] [pont]", playerSource); else if (tonumber(tp) >= 0) then setPlayerTP(target, tp); outputChatBox(getPlayerTP(target).." TP", target); else outputChatBox("0-nak vagy annál többnek kell lennie", playerSource); end end end); addCommandHandler("givetp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); if not tonumber(tp) or not target then outputChatBox("/"..commandName.." [játékos] [pont]", playerSource); else if (tonumber(tp) > 0) then givePlayerTP(target, tp); outputChatBox(getPlayerTP(target).." TP", target); else outputChatBox("többnek kell lennie mint 0", playerSource); end end end); addCommandHandler("gettp", function(playerSource) local points = getPlayerTP(playerSource); outputChatBox(points, playerSource); end); Isn't it possible to make it without tables? Because I want to make it unlimited (I didn't try the script yet). Link to comment
Tekken Posted October 19, 2016 Share Posted October 19, 2016 Sure it is, but I can't do it right now. Link to comment
pa3ck Posted October 19, 2016 Share Posted October 19, 2016 Of course it is possible, use something like this: local tpLimit = 5000 local currTp = 5001 local nextLevel = math.ceil(currTp / tpLimit) -- round up local currLevel = math.floor(currTp / tpLimit) -- round down if(nextLevel == currLevel) then -- just leveled up and it divides into tpLimit evenly nextLevel = nextLevel + 1 end print("Current level: " .. currLevel .. ", next level: " .. nextLevel) Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 Well, while I was waiting for answers I came up with a new idea, that might be easier to make and more simple. I started doing that but I am having issues. Here's the current script: local TPLimit = 5000 function getPlayerFromPartialName(name) local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil; if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower(); if name_:find(name, 1, true) then return player; end end end end function givePlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) > 0) then setElementData(thePlayer, "playertp", (getElementData(thePlayer, "playertp") or 0) + tp); if (getElementData(thePlayer, "playertp") >= TPLimit) then setElementData(thePlayer, "playerlevel", (getElementData(thePlayer, "playerlevel") or 1) + 1); setElementData(thePlayer, "playertp", 0); outputChatBox("level up", thePlayer); outputChatBox(getElementData(thePlayer, "playerlevel"), thePlayer); end end end end function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) >= 0) then setElementData(thePlayer, "playertp", tp); if (getElementData(thePlayer, "playertp") >= TPLimit) then setElementData(thePlayer, "playerlevel", (getElementData(thePlayer, "playerlevel") or 1) + 1); setElementData(thePlayer, "playertp", 0) outputChatBox("level up", thePlayer); outputChatBox(getElementData(thePlayer, "playerlevel"), thePlayer); end end end end function getPlayerTP(thePlayer) if (thePlayer) then return getElementData(thePlayer, "playertp") or 0; end end addCommandHandler("settp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); if not tonumber(tp) or not target then outputChatBox("/"..commandName.." [játékos] [pont]", playerSource); else if (tonumber(tp) >= 0) then setPlayerTP(target, tp); outputChatBox(getPlayerTP(target).." TP", target); else outputChatBox("0-nak vagy annál többnek kell lennie", playerSource); end end end); addCommandHandler("givetp", function(playerSource, commandName, targetPlayer, tp) local target = getPlayerFromPartialName(targetPlayer); if not tonumber(tp) or not target then outputChatBox("/"..commandName.." [játékos] [pont]", playerSource); else if (tonumber(tp) > 0) then givePlayerTP(target, tp); outputChatBox(getPlayerTP(target).." TP", target); else outputChatBox("többnek kell lennie mint 0", playerSource); end end end); addCommandHandler("gettp", function(playerSource) local points = getPlayerTP(playerSource); outputChatBox(points, playerSource); end); I would like to make it work like the following: If I reach 5000 XP then my XP gets reseted to 0 and I will get a new level, so I am at level 1, I get 5000 XP and then I will be level 2, this part works fine. I have 2 problems with maths, one of them is when I get more XP than the limit, for example 5001, then how can I get the plus 1 XP and level 2? The other problem is, if I get for example 27500 XP then I should get +5 levels, so I would be level 6 and I should get 2500 XP. If I divide 27500 with 5000 (so the TPLimit) then I should get 5,5 and I should give myself 5 levels and multiple the amount of XP that I need with 0.5, but I don't know how to "split" this number, or how to do that whole thing, so I will always get mathematically perfect numbers for levels and XP. Could somebody help me please? Link to comment
pa3ck Posted October 19, 2016 Share Posted October 19, 2016 (edited) There are 2 ways doing it in terms of saving the players' stats: 1st. Save the current level and current XP (between 0-5000) and whenever they level up reset the XP to 0. If you are proceeding with this option, you have to calculate the level from the current experience and save that in MySQL or SQLite along with the current experience (between 0 - 5000) 2nd: Only save the XP and not resetting it at level up (I just provided the exact code for calculating the level from XP). So let's say, you have 23000 XP you are able to calculate the current level, next level and also the exp needed to level up. If you are proceeding with this option, you only need to save the current experience, look at this code and try it yourself, you should be able to finish your script with my code: local expLimit = 5000 local currentExpLevel = 20050 local currentExp = currentExpLevel % expLimit -- use modulus to get the current exp local currentLevel = math.floor(currentExpLevel / expLimit ) -- round down the current exp divided by the expLimit, which gets the current level local nextLevel = math.ceil(currentExpLevel / expLimit ) -- round up to get the next level if nextLevel == currentLevel then nextLevel = nextLevel + 1 end -- evenly divides, so next level and current level is the same, fix that by incrementing the next level local neededNextLevel = expLimit - currentExp -- we already know the current exp (between 0-5000), we can subtract that from the exp limit to get the exp needed to level up outputChatBox ( "Current EXP: " .. currentExp ) outputChatBox ( "Current levelL " .. currentLevel ) outputChatBox ( "Your next level: " .. nextLevel ) outputChatBox ( "Needed for next level: " .. neededNextLevel ) Edited October 19, 2016 by pa3ck 1 Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 4 minutes ago, pa3ck said: There are 2 ways doing it in terms of saving the players' stats: 1st. Save the current level and current XP (between 0-5000) and whenever they level up reset the XP to 0. If you are proceeding with this option, you have to calculate the level from the current experience and save that in MySQL or SQLite along with the current experience (between 0 - 5000) 2nd: Only save the XP and not resetting it at level up (I just provided the exact code for calculating the level from XP). So let's say, you have 23000 XP you are able to calculate the current level, next level and also the exp needed to level up. If you are proceeding with this option, you only need to save the current experience, look at this code and try it yourself, you should be able to finish your script with my code: local expLimit = 5000local currentExpLevel = 20050local currentExp = currentExpLevel % expLimit -- use modulus to get the current explocal currentLevel = math.floor(currentExpLevel / expLimit ) -- round down the current exp divided by the expLimit, which gets the current levellocal nextLevel = math.ceil(currentExpLevel / expLimit ) -- round up to get the next levelif nextLevel == currentLevel then nextLevel = nextLevel + 1 end -- evenly divides, so next level and current level is the same, fix that by incrementing the next levellocal neededNextLevel = expLimit - currentExp -- we already know the current exp (between 0-5000), we can subtract that from the exp limit to get the exp needed to level upoutputChatBox ( "Current EXP: " .. currentExp )outputChatBox ( "Current levelL " .. currentLevel )outputChatBox ( "Your next level: " .. nextLevel )outputChatBox ( "Needed for next level: " .. neededNextLevel ) I would like to do it with the 1st option, and I know that I have to save the xp and level as well, but I would like to do it this way. The only problem is that I don't know how, I fail at the math part of it, I don't know how to get the numbers that I wrote before. Quote I have 2 problems with maths, one of them is when I get more XP than the limit, for example 5001, then how can I get the plus 1 XP and level 2? The other problem is, if I get for example 27500 XP then I should get +5 levels, so I would be level 6 and I should get 2500 XP. If I divide 27500 with 5000 (so the TPLimit) then I should get 5,5 and I should give myself 5 levels and multiple the amount of XP that I need with 0.5, but I don't know how to "split" this number, or how to do that whole thing, so I will always get mathematically perfect numbers for levels and XP. Could you help me with this please? Link to comment
pa3ck Posted October 19, 2016 Share Posted October 19, 2016 (edited) Replace your setPlayerTP function with this and see what happens when you do setPlayerTP(playerElement, 5001): function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) >= 0) then local newLevel = math.floor(tp / TPLimit) local newExp = tp % TPLimit setElementData(thePlayer, "playertp", newExp); setElementData(thePlayer, "playerlevel", newLevel); outputChatBox("Megvaltozott a szinted, uj szint: " .. newLevel .. ", uj exp: " .. newExp, thePlayer); end end end Edited October 19, 2016 by pa3ck Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 9 minutes ago, pa3ck said: Replace your setPlayerTP function with this and see what happens when you do setPlayerTP(playerElement, 5001): function setPlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) >= 0) then local newLevel = math.floor(tp / TPLimit) local newExp = tp % TPLimit setElementData(thePlayer, "playertp", newExp); setElementData(thePlayer, "playerlevel", newLevel); outputChatBox("Megvaltozott a szinted, uj szint: " .. newLevel .. ", uj exp: " .. newExp, thePlayer); end endend The setPlayerTP command works perfectly with this. How can I make it with givePlayerTP? Link to comment
pa3ck Posted October 19, 2016 Share Posted October 19, 2016 This should work: function givePlayerTP(thePlayer, tp) if (thePlayer) then if (tonumber(tp) > 0) then local currExp = getElementData(thePlayer, "playertp") or 0 local currLvl = getElementData(thePlayer, "playerlevel") or 0 local newTempExp = currExp + tp local newTempLevel = math.floor(newTempExp / TPLimit) local newExp = newTempExp - newTempLevel * TPLimit local newLevel = currLvl + newTempLevel setElementData(thePlayer, "playerlevel", newLevel); setElementData(thePlayer, "playertp", newExp); if (newLevel > currLvl) then outputChatBox("level up", thePlayer); end end end end Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 Oh my god, I can't believe, thank you very much!!!!!! <3 It works perfectly!! I would like to ask just 1 more question, sorry for bothering you, but how can I make the event I was talking about, for checking if a player leveled up? So therefore I could add notifications from other scripts and things like that. Link to comment
pa3ck Posted October 19, 2016 Share Posted October 19, 2016 You're welcome. Try this client-side: addEventHandler("onClientElementDataChange", root, function(data, oldLevel) if source == localPlayer and oldLevel and data == "playerlevel" then local currLevel = getElementData(localPlayer, "playerlevel") if currLevel > oldLevel then outputChatBox("szintet leptel") end end end) Link to comment
Dzsozi (h03) Posted October 19, 2016 Author Share Posted October 19, 2016 It works client-side, but can I make a custom event? For example onPlayerLevelUp and onClientPlayerLevelUp? Or how do these custom events work? Link to comment
pa3ck Posted October 19, 2016 Share Posted October 19, 2016 (edited) Yes, you can do it with onClientElementDataChange or just trigger client and serverside whenever a users gets experience and is leveled up, but if you want to go with the element date change: addEventHandler("onClientElementDataChange", root, function(data, oldLevel) if source == localPlayer and oldLevel and data == "playerlevel" then local currLevel = getElementData(localPlayer, "playerlevel") if currLevel > oldLevel then triggerEvent("onClientLevelUp", localPlayer) -- this one triggers client side event, player element will be the source triggerServerEvent("onLevelUp", localPlayer) -- this one is server side, player element will be the variable 'client' end end end) Edited October 19, 2016 by pa3ck 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