Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Citizen

  1. Moved to Scripting
  2. Hello @Wananazo, Your topic is not a tutorial so it has been moved to the Scripting Section. Tutorials section is only meant for tutorials. Make sure to post your next topic to this section when asking for help with scripts. Also make sure to paste code in code blocks (I edited your post to fix that) Best regards,
  3. @Mr.Hugin sendDiscordMessage doesn't exist (rename the function at line 3 from msg to sendDiscordMessage)
  4. Hello, I moved your topic to the Scripting section. The Tutorials section is only for Scripting Tutorials, for scripting questions, use the Scripting section instead. Make sure to use this section for your next scripting questions. I also edited your code to hide your discord webhook id and secret, never share it or someone else can send message to the targeted discord channel.
  5. @Shady1Il n'est pas en train de demander de l'aide pour créer un système spécifique, il cherche à monter une équipe pour créer un serveur roleplay et il recherche donc des personnes pour scripter et mapper son serveur. @Kratos_26000Bienvenue sur le forum et bonne chance pour ta recherche. Pour être transparent, il n'y a pas beaucoup de personnes dans la section FR du forum/discord, et en général ces personnes sont déjà prises sur d'autres projets ou n'ont plus le temps suffisant pour se lancer dans de nouveaux. Mais il y aura toujours des personnes pour te décoincer si tu as des soucis de code ou d'installation de ton serveur (ici ou sur le discord officiel MTA).
  6. Hello @VortDyn, I moved your topic to the Scripting section. The Tutorials section is only for Scripting Tutorials, for scripting questions, use the Scripting section instead. Make sure to use this section for your next scripting questions.
  7. Are you sure you are showing the code where it actually happens ? Because there is no way you can reach the arithmetic operation (+1 or -1) unless ID = true, but table.find can't return true, it can only return false so if ID then should stop the code there. Can you show the exact command you type in chat, and the exact error message please ? (and which line the error occurs at)
  8. - You use getElementData "Map" but where do you setElementData "Map" ? The element data doesn't exist when it is called and you get false instead of the map's name. - Don't escape strings yourself with gsub, use "?" placeholders instead. It will prevents bad things like SQL Injections for you. Example: local playerName = getPlayerName(source) executeSQLQuery("SELECT * FROM players WHERE name=?", playerName) - At line 144 I see you use getElementData "country" and "Country" are you sure about the names ? Why do you have 2 versions of the country data ? Looks like bad practice and looks confusing - [perf] Why do you need to trigger onServerSendRanking AND onServerSendRanking2 ?? They are the exact same calls, just use onServerSendRanking on both client handlers triggerClientEvent(source,"onServerSendRanking",source,ranking) triggerClientEvent(source,"onServerSendRanking2",source,ranking) - [perf] Don't use getElementData for the same data twice where you can call it once: if getElementData(v,"state") and getElementData(v,"state") == "alive" then Do this instead: local state = getElementData(v, "state") if state and state == "alive" then - [bug] Should be `< 10` here on both lines because you want that "8" or "9" turns into "08" or "09" respectively - Don't use reserved keywords for your variable names. Here table is a reserved keyword:
  9. I think you removed a lot of the actual code but your loop should work if you fix the typo here (everything you did is case sensitive already): for _, p in pairs(getElementsByType("player")) do -- "player" not "Player" If that's not the issue in your code, then there has to be an error in the logs ? (playerLogged is the server event called from the login GUI form right ?)
  10. Then this should work : triggerServerEvent("kilLDayZPlayer", hitElement, source) For onClientPlayerWeaponFire, source is the player element who fired the weapon, so adding it as the attacker attacker for the kilLDayZPlayer event should do the trick.
  11. Where did you put that code ? can you show more of the script so we can see the context ? if you have the attacker available as a variable, you have to add it in your triggerServerEvent: triggerServerEvent("kilLDayZPlayer", hitElement, attacker) -- assuming attacker is the variable that holds the player element who attacked
  12. I don't really understand, do you have a problem with the dxDrawText ? Can you take a screenshot and show us what the problem is please ? I just want to point out that it looks like you want to make a password field. For this, you should use guiCreateEdit instead (there is also a method for edit to not show the password when writing in it: guiEditSetMasked). Memo are for multiline texts. But anyway, it won't fix your problem. Your problem is that you are giving a relative size (width and height) that is too small for it to work on small screen: 0.10 and 0.03 - on a 1920x1080 screen: it means 0.10 x 1920 = 192 pixels(px) of width (that's okay) and 0.03 x 1080 = 32.4px of height which is okay too, but - on a 1280×720 screen: it means 0.10 x 1280 = 128px width but 0.03 x 720 = 21.6px of height which is not okay because it's too small. Memo or Edit have some inner margin that you can't override so the text doesn't have enough space to show. To fix that one quick solution you can try is to make sure the height doesn't go under a minimum height by using math.max : guiCreateMemo(0.45*screenW, 0.42*screenH, 0.10*screenW, math.max(0.03*screenH, 30), "", false) -- back to false (absolute) I put 30 px as minimum but you can change it a bit (I don't know what the real minimum is for the text to show properly). NOTE: If it is part of a window (guiCreateWindow) then you have to instead to make it relative to the window (and not the entire screen) by setting the gui window as its parent: local window = guiCreateWindow(0.36, 0.27, 0.35, 0.34,"GUI Window", true) guiCreateMemo(0.45, 0.42, 0.10, 0.03, "", true, window) -- you have to rework the values here For more understanding, please consider reading this guide: https://wiki.multitheftauto.com/wiki/Introduction_to_Scripting_the_GUI
  13. You have to verify if there are some sort of errors in you logs because maybe it tries to play an animation but there can be a problem somewhere and so it doesn't work ? Check your code to make sure there is no attempt of playing one when doing the actions. If there is nothing related to animation in the code, then add it yourself by calling setPedAnimation at the same place where it starts/triggers the usage of food/tent/medic etc. By default you have access to a lot of built-in animations from the game.
  14. Did you consider using setVehicleHandling instead ? For me, all you are doing can be done using that function. It will be easier and will prevent stressing the player's CPU as well.
  15. Is that the entire message ? can you screenshot the error maybe ? Make sure you have the "msgbox" resource and that it is running (start msgbox) before calling exported functions.
  16. No, it's just that Useful functions are functions made by the community and that are not built-in into MTA. To use them, you have to copy the function code first. And then you can call it (the function source code is lower on the wiki page: https://wiki.multitheftauto.com/wiki/DxDrawTextOnElement local randomPed = createPed(285, 2476.91406, -1665.31799, 13.32435) addEventHandler("onClientRender", getRootElement(), function() dxDrawTextOnElement(randomPed, "SWATTEAM Officer", 1, 20, 0, 0, 255, 255, 1, "pricedown") end) -- Function source copied from wiki https://wiki.multitheftauto.com/wiki/DxDrawTextOnElement function dxDrawTextOnElement(TheElement,text,height,distance,R,G,B,alpha,size,font,...) local x, y, z = getElementPosition(TheElement) local x2, y2, z2 = getCameraMatrix() local distance = distance or 20 local height = height or 1 if (isLineOfSightClear(x, y, z+2, x2, y2, z2, ...)) then local sx, sy = getScreenFromWorldPosition(x, y, z+height) if(sx) and (sy) then local distanceBetweenPoints = getDistanceBetweenPoints3D(x, y, z, x2, y2, z2) if(distanceBetweenPoints < distance) then dxDrawText(text, sx+2, sy+2, sx, sy, tocolor(R or 255, G or 255, B or 255, alpha or 255), (size or 1)-(distanceBetweenPoints / distance), font or "arial", "center", "center") end end end end ^ Like this, your script will work
  17. No, SQL is not meant to replace element data, it is way slower than element data. What should replace element data is custom lua table using element as indices. SQL is meant to persist data so that (for example) one player can load back his data. Like on an RP server, when someone leaves the server, his position, health, money weapons etc are saved into SQL tables, and when he joins back the next day (or even a month later) you load back his data so he can start from where he left. Element data are only in RAM and are destroyed when the element is destroyed (for player elements, when they leave the server). Element data are hated because by default, they are synced with all clients and the server so if a data is modified, even if only 1 player should care about that modification which is a waste of resources and bandwidth. One should replace them with lua tables and syncing them when needed using triggerServer/ClientEvent so you have control over what is synced and what isn't and its better for performance. Imo if they are used correctly, they are perfect to store data regarding an element on said element using elementData . For example, if I had to implement a trunk system, I'll defintely use elementData to store what is inside the trunk. EDIT: Want to point out again that SQL queries are expensive, for the cell phone example, I would use SQL when the player logs in so I can load all his account data (and so the doIHaveCellphone value) and will call setElementData(player, "doIHaveCellphone", sqlrow['doIHaveCellphone'] or false) and then will only use setElementData to modify it (if needed) during his entire game session. Once the player leaves (or crash, or anything that makes the player disconnect => onPlayerQuit) I'll make the needed SQL queries to save all his data into SQL tables from the elementData. You can't affort to make SQL queries for every data you need to get. Per player it will adds up and you will end making 100+ SQL queries per second with only 25 players and your server will cry. SQL queries are way more expensive than element data.
  18. If I understand you want an AI that is capable of driving or flying alone. This is huge and a very advanced system to script. I'm pretty sure no one will do it for you. You can have a look at these resources by CrystalMV : https://github.com/jlillis/crystalmv-resources/tree/master/npc_hlc https://github.com/jlillis/crystalmv-resources/tree/master/npc_tseq https://github.com/jlillis/crystalmv-resources/tree/master/npchlc_traffic https://github.com/jlillis/crystalmv-resources/tree/master/npchlc_traffic_editor
  19. With both codes, if you have "John Doe" and "John Wick" on your server and you try to locate "John Wick" then it will only look for "John" and will return the 1st one it finds in the player list. If you are lucky you will get "John Wick" but there are chances it will return "John Doe" too.
  20. Can you attach the .ttf file here please ? Can you also give us a screenshot of the folder where you have put your .ttf file ?
  21. Where are money1 and money2 defined ? Can you print the values ? Also, 2 things to note: https://wiki.multitheftauto.com/wiki/GivePlayerMoney On the client side, it only takes 1 argument (your error looks like a server side error, so I don't think it is related to the givePlayerMoney you are showing us in your code). Don't add money on the client side, wiki says: So just like the XP, make a triggerServerEvent to then add the money on the server side. (For optimisation, make only 1 triggerServerEvent to add XP and money on the server side)
  22. 2. And even 1 more info if you check the wiki https://wiki.multitheftauto.com/wiki/OnVehicleEnter. It also can give you the player that you are kicking out of the vehicle to take its place (if there was a player already in ofc) as 3rd argument of your event handler. 3. and 4. okay perfect 5. Yes you can totally do that, even though the place this data takes on the server is very tiny. Even if you multiply that by 5,000+ potential vehicles. But yes, it's better and you are right. if isTimer(timerF) then killTimer(timerF) end -------Don't know if this is neccesary if I set the timer as you said ('setElementData(source,"fuelTimer", timerF') Yes you still have to kill it. removeElementData will only remove the timer from element (kind of unlinking) but the timer will still run in background. Note: My setElementData for the fuelTimer had a 4th argument which was false (it's true by default if you omit it) and it's important to prevent it to be automatically sent to all clients connected to the server (if you have 500 players, this only call will make 500 calls to triggerClientEvent (well, not exactly but almost like if) which is a waste of CPU and bandwidth as we only need it on the server side). Also, make sure you get your timerF using getElementData(source, "fuelTimer") 6. perfect You are doing good by the way (understanding and implementing the suggestions), keep it up
  23. Both. function setFuelCar(thePlayer) local source = getPedOccupiedVehicle(thePlayer) -- (1) if getPedOccupiedVehicleSeat(thePlayer)==0 then -- (2) if getVehicleEngineState(source)==true then ---------if the engine it's on I start the timer -- (3) local x,y,z = getElementPosition(source) local fx,fy,fz = x+0.05, y+0.05,z+0.05 -- (4) local fuelConsumption = 0.900 local fuelVeh = getElementData(source, "Fuel") or 0 if (fuelVeh <= 0) then setVehicleEngineState(source, false) else timerF = setTimer( function () -- (5) local enginePlus = 0.200 local distance = getDistanceBetweenPoints3D(x,y,z,fx,fy,fz) -- (6) local newFuel = tonumber((fuelVeh - (fuelConsumption*(distance+enginePlus)))) setElementData(source, "Fuel", newFuel) end, 20000, 0) end end end end addEventHandler("onVehicleEnter", root, setFuelCar) You don't need to overwrite the source variable. It already exists thanks to the onVehicleEnter event. Have a look at: https://forum.multitheftauto.com/topic/33407-list-of-predefined-variables/#comment-337231 onVehicleEnter already gives you the seat number, you have to "grab" it too : function setFuelCar(thePlayer, seat) if seat == 0 then Here in your code, this check is only done once, when entering the vehicle. You have to change it so that you create the fuel timer anyway when entering the vehicle at seat 0 but inside the timer function, the 1st thing you do is to check the engine state. If it's ON, do the newFuel calculation thing. And if fuel is <= 0 then set it to OFF. (Why the +0.05 to each components ? seems totaly useless) You can't use a global variable on the server side or else if another player enters another vehicle, it will start his vehicle fuel timer and override the value in timerF so you have no way to kill the timer of your vehicle later. Must be local and "link it" with your vehicle element: setElementData(source, "fuelTimer", timerF, false) (false because there is no need to sync this value with all connected clients, only the server needs to know and manipulate it). You have to update the value of fx,fy,fz with the current x, y, z at the end to calculate the new distance traveled between point B and point C (20 secs later). Again, use element data to store that position for the next fuel consumption calculations (you can't use global variables).
  24. if player == localPlayer then return end UPS ! My bad, I meant ~= there if player ~= localPlayer then return end (replace in both) Okay yeah, here is your problem: You are creating 1 new timer per frame (x30 per sec at 30fps) so after 20 seconds of calmness you are calling triggerServerEvent every frame. Does that make sense ? What I would do is: -- on server side: listen to onVehicleEnter and when someone enters it, create the 20sec timer to update the fuel. Remember the timer (a table or a "not synced" element data and using the vehicle element as index/key to retreive it later) To update the fuel: make the necessary checks (engine state = ON etc) and use element data (element data get so much hate and I don't agree with all that hate, its perfect to sync an element data between server and clients when used correctly) local currentFuel = getElementData(vehicle, "fuel") or 0 setElementData(vehicle, "fuel", currentFuel - 5) -- updating the fuel on server Listen to onVehicleExit and get back the timer you created (and that you stored) and kill that timer -- on client side: Listen to onVehicleEnter and onVehicleExit to show or hide the speedometer (= add or remove the onClientRender) Yes you can use "onClientElementDataChange" to listen and update the fuel value updates for drawing local currentVeh = nil local currentFuel = 0 function checkDataFuel(dataName, oldValue, newValue) if dataName ~= "fuel" or source ~= currentVeh then return end -- cancel if it's not "fuel" update or if it's not for our vehicle currentFuel = newValue end addEventHandler("onClientElementDataChange", root, checkDataFuel) function enterVehicle(player, seat) if player ~= localPlayer then return end if seat == 0 or seat == 1 then currentVeh = source currentFuel = getElementData(source, "fuel") -- making sure we show the right value at 1st frame addEventHandler("onClientRender", root, drawSpeedo) -- show speedo isSpeedoVisible = true end end addEventHandler("onClientVehicleEnter", root, enterVehicle) function exitVehicle(player) if player ~= localPlayer then return end currentVeh = nil if isSpeedoVisible then removeEventHandler("onClientRender", root, drawSpeedo) -- hide speedo isSpeedoVisible = false end end addEventHandler("onClientVehicleStartExit", root, exitVehicle) function drawSpeedo() if not currentVeh then return end -- should never happen, just in case --[[ draw vehicle speed and fuel here. You have access to these variables to draw: currentVeh currentFuel ]] end I gave you a lot of client code to show you how it should look like with the new logic (your latest version was going a bit wild) For the server part, I let you try with the instructions I gave you. Note: After all that, the last optimization would be to not call getVehicleEngineState at every frame (in your getCarStateColor function) but it's a minor optimization, the biggest gain is to not spam the triggerServerEvent by implementing the new logic I'm suggesting.
  25. If you want to do that, I'd suggest you create another table that will store all players connection dates. Check this DB fiddle I made for you that does exactly what you want (pure SQL with the help of triggers) https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=a9ffcada462d8d1dff443bc0a1cf874d Ask any question.
  • Create New...