Jump to content

Citizen

Moderators
  • Posts

    1,803
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by Citizen

  1. It wasn't about the the resolution of his problem, it's about to let you guys know relative values doesn't need to be translated in absolute ones when using gui functions. It just add code that is already written in the original functions ... (And it's not because your solution is working that it's a good solution ...) How do you know where 0.4, 0.8 etc etc. will be on the screen? It's really simple but maybe hard to get it at the begining. So here is what you have to know: on the horizontal axis: 0 (0%) is the left side of your screen (of every screens) and 1(100%) is the right side of your screen (of every screens too). on the vertical axis: 0 (0%) is the top side of your screen (of every screens) and 1 (100%) is the bottom side of your screen (of every screens too). So instead of using pixels to place and size your gui elements (which will not be rendered the same on every resolutions) then you use percentages of the screen. The gui elements are placed using the top left corner of that gui element. So if you place it at 1, 1 (100%, 100%) then your gui element will be rendered out of the screen. So to place it correctly at the bottom right corner, you have to use: 100 - , 100 - So as another example, if you wan to create a window pefectly centered on every screens: guiCreateWindow(50% - 30%/2, 50% - 40%/2, 30%, 40%, "My window", true) --just for comprehension -- so: guiCreateWindow(0.5 - 0.15, 0.5 - 0.2, 0.3, 0.4, "My window", true) -- will work guiCreateWindow(0.5 - 0.15, 0.5 - 0.2, 0.3, 0.4, "My window", true) -- will work too Note: 0.5 = 50% 0.15 is half of 0.3 0.2 is half of 0.4
  2. It wasn't about the the resolution of his problem, it's about to let you guys know relative values doesn't need to be translated in absolute ones when using gui functions. It just add code that is already written in the original functions ... (And it's not because your solution is working that it's a good solution ...)
  3. And the most easiest way to do this is using values between 0 and 1 AND not translating it in absolute values: testWindow = guiCreateWindow ( 0.4, 0.3, 0.2, 0.35, "test window", true) (And no need to use ; too)
  4. Pas de soucis, non pas la peine de poster le nouveau code. Bon codage !
  5. Ok I stopped trying to make it without testing it myself (didn't know I would get problems I had). I made it work, but there is something strange that should be reported to the bugtracker: the executeCommandHandler doesn't execute the comands on the other side (only tested from server-side to client side commands, but I'm pretty sure the other way doesn't work too). I mean that if I use executeCommandHandler("fr", player) on the server-side, then it will not execute this commands on the client-side of that player, only addCommandHandler for "fr" on the server-side only will work. So if you understood right, I had to make a triggerClientEvent to then run the executeCommandHandler on the client-side (as the freeroam resource added this command on the client-side). server: function bindF1( param ) if param then for k, i in ipairs(getElementsByType("player")) do bindKey(i, "f1", "down", openF1) end else bindKey(source, "f1", "down", openF1) end end addEventHandler("onResourceStart", resourceRoot, bindF1) addEventHandler("onPlayerJoin", root, bindF1) local randomSecret = "secret_" .. math.random(10000) --kind of bypass prevention function openF1( player, cmd, preventLoop ) if preventLoop ~= randomSecret and getElementData(player, "isInForbiddenArea") then triggerClientEvent("forcePressF1", player, randomSecret) end end addCommandHandler("fr", openF1) client: addEvent("forcePressF1", true) addEventHandler("forcePressF1", root, function ( secret ) executeCommandHandler("fr", secret) end) I have tested it and it works, but if you spam the F1 key, then you will just see it blicking, but you still can't use it
  6. On est dans la section française ici, pas la peine d'écrire en anglais ... Et Rouche, ça ne vient pas forcément du gta_sa.exe, ça peut venir de n'importe quel fichier que charge gta_sa.exe au moment du lancement. Si un fichier de voiture ou un truc du genre est corrompu, pas au bon format, le chargement va merder et va provoquer son crash. Donc assure toi d'avoir un crack NO-CD en v1.0 (1.01 ne marchera pas non plus). Assure toi aussi que le jeu solo marche normalement, si c'est pas le cas, c'est que t'as modifié quelque chose qu'il ne fallait pas ou que tu as téléchargé une version du jeu bugué. Ce que tu nous ne dit pas non plus c'est: Est-ce que ton jeu marchait avant, car apparemment ce n'est pas aujourd'hui que tu rejoins MTA. Faut vraiment que les gens comprennent qu'il faut donner le plus de détails possible pour qu'on puisse plus rapidement trouver le problème et le résoudre. Là on ne sait rien, a part que ça crash chez toi (super !).
  7. Please explain better (give a lot of details) what you are trying to achieve. Do you want to prevent others to steal your client script code ? Yes, but im unsure if loadstring will let a function go on perfectly, if i load like this, will it work? myString = "function Cheetah() dxDrawText('Test', 400,200, 100,100,tocolor(255,255,255,255),3) end addEventHandler('onClientRender', getRootElement(), Cheetah)" loadstring(myString) Yes it will work but only if you don't forget to execute that loaded string: loadstring(myString)() --the extra parenthesis will execute the string loaded returned by the loadstring function Also note that you can't wrote a string in multiple lines like u did from line 2 to 5 but I got the main idea you were trying to explain. There is a usefull topic for what you want to achieve: https://forum.multitheftauto.com/viewtopic.php?f ... 90#p337791 This script is sending only one file to the clientside but you can easilly modify it to provide a list of file to send (for example using a xml file like the meta but only listing the client files you want to send using this way). It's loading that script as a string, then send it to the client that will receive and then use the loadstring as you did to make this work. Note that the event "onClientResourceStart" won't be triggered for your resource in your resource because it would be triggered before your script has done loading your script from the server.
  8. Replace + with .. for the randomSecret
  9. Please explain better (give a lot of details) what you are trying to achieve. Do you want to prevent others to steal your client script code ?
  10. Yes (why didn't you try yourself ?!) This won't work even if you used the tostring function because you would get a lua function pointer instead of the instructions. As far I know, you can't If you want to call a function with its name, you can do something like this: function callMyFunction( funcName ) _G[funcName]() end --and then function myFunction() outputChatBox("Hi") end callMyFunction("myFunction") But if your function is on the server side, you can't call it from the client side and vice-versa. Btw, I just got an idea. It would be possible actually. You can do this by making a function which will take a function name as argument. It will then open all lua files look for the function using the name provided. Once it found it, then it will read the instruction and append each line of it into a string. When the end keyword of that function is found, then it will stop everything and send the string to the client side wich will receive the string, use the loadstring function and then call that function. That should definitly work if you can make a well coded function to parse the files and get the functions properly.
  11. ça ne l'aidera absolument pas parce qu'il a bien donner les bons arguments ... Le seul problème c'est qu'il a appelé addEventHandler avant la déclaration de la fonction à appeler: addEventHandler ( "onColShapeHit", bombshopCol, bombshopEnter ) function bombshopEnter ( element, dim ) -- blablabla end Lors du chargement du script, les instructions sont exécutés dans l'ordre donc lorsqu'il passe sur cette ligne: addEventHandler ( "onColShapeHit", bombshopCol, bombshopEnter ) La fonction n'existe pas encore car elle est déclarée juste après. Il faut donc placer le addEventHandler après la déclaration de la fonction comme ceci: function bombshopEnter ( element, dim ) -- blablabla end addEventHandler ( "onColShapeHit", bombshopCol, bombshopEnter ) Dans ce cas, la fonction est bien chargée avant l'execution du addEventHandler qui l'utilise. Mais alors pourquoi le script était comme ça Et bah ce script n'était surement pas comme ça, car il devait surement utiliser des fonctions anonymes qu'il déclarait en même temps que le addEventHandler comme ceci: addEventHandler ( "onColShapeHit", bombshopCol, function ( element, dim ) -- blablabla end) --fermeture de la parenthèse du [b]addEventHandler[/b]
  12. Ah my bad, just replace lines 29 to 34 with this: local randomSecret = "secret_" + math.random(10000) --kind of bypass prevention function openF1( player, cmd, preventLoop ) if preventLoop ~= randomSecret and getElementData(player, "isInForbiddenArea") then executeCommandHandler("fr", player, randomSecret) end end addCommandHandler("fr", openF1) I added a random generated string to be used instead of "true" (as a string) because everyone would be able to bypass it by doing /fr true
  13. Tell me the errors then EDIT: Try again with this: local forbiddenAreas = { --x, y, width, height {0, 0, 50, 50}, --example1 (needs a ',' because it's not the last) {-500, -1613, 50, 50} --example2 (no need a ',' because it's the last) } addEventHandler("onResourceStart", resourceRoot, function() for k, i in ipairs(forbiddenAreas) do local col = createColRectangle(i[1], i[2], i[3], i[4]) addEventHandler("onColShapeHit", col, function ( hitElement ) if getElementType(hitElement) ~= "player" then return end setElementData(hitElement, "isInForbiddenArea", true) outputChatBox("You entered in the forbidden area !", hitElement) end) addEventHandler("onColShapeLeave" col, function( leaveElement ) if getElementType(leaveElement) ~= "player" then return end setElementData(leaveElement, "isInForbiddenArea", false) outputChatBox("You left the forbidden area !", leaveElement) end) end end) addeEventHandler("onPlayerJoin", root, function() bindKey(source, "f1", "down" openF1) end) function openF1( player, preventLoop ) if preventLoop ~= true and getElementData(player, "isInForbiddenArea") then executeCommandHandler("fr", player, true) end end addCommandHandler("fr", openF1) I used root instead of col for the colshape events and replaced preventLoop == false with preventLoop ~= true. I also added 2 outputs to let you be sure you really are in a forbidden area.
  14. And you can't trigger built-in events.
  15. Did you go in the shop with other cars before trying with jester ? I mean, if you restart the resource and then try directly with the jester, does it show the exact same list ? If yes, then it's a bug coming from the getVehicleCompatibleUpgrades function. If not, then it's just that you have to clear the gridlist before executing the loop that fill the list (guiGridListClear).
  16. Probably because a vehicle upgrade can be available for more than one car ?
  17. Oui grâce à un accès ssh qui te sera fournit
  18. Haha yeah, too much Java and C# these days sorry about that mistake
  19. Oh, je connaissais pas celui là ! Très intéressant, c'est (je pense) le meilleur serveur par rapport à son prix. En plus y a assez pour héberger un server teamspeak/mumble et web.
  20. Ca ne veut rien dire, un serveur dédié est un serveur classique dont tous les composants te sont entièrement destinés. tu as les serveurs mutualisés, c'est un serveur sur lequel il y a plusieurs personnes. au niveau manipulations, c'est exactement pareil, sauf que le processeur, la ram, la bande passante etc sont utilisisé par plusieurs personnes. Imaginons que y ai une ou deux personnes qui sont sur le même serveur que toi qui se mettent à télecharger des gros fichiers, ta connexion va devenir très mauvaise.
  21. An error in my code ? If yes, then I would like to know what it was please
  22. Citizen

    Save System

    Why would you drop a table ?
  23. Yeah, get the 1.4 server and client that are still in development: https://nightly.multitheftauto.com/
  24. Ok, I just made a standalone script that will hide the panel immediatly if a player opens it in a forbidden area. You have to put this in your gamemode that must runs with the freeroam/play resource: local forbiddenAreas = { --x, y, width, height {0, 0, 50, 50}, --example1 (needs a ',' because it's not the last) {-500, -1613, 50, 50} --example2 (no need a ',' because it's the last) } addEventHandler("onResourceStart", resourceRoot, function() for k, i in ipairs(forbiddenAreas) do local col = createColRectangle(i[1], i[2], i[3], i[4]) addEventHandler("onColShapeHit", root, function ( hitElement ) if getElementType(hitElement) ~= "player" then return end setElementData(hitElement, "isInForbiddenArea", true) end) addEventHandler("onColShapeLeave" root, function( leaveElement ) if getElementType(leaveElement) ~= "player" then return end setElementData(leaveElement, "isInForbiddenArea", false) end) end end) addeEventHandler("onPlayerJoin", root, function() bindKey(source, "f1", "down" openF1) end) function openF1( player, preventLoop ) if preventLoop == false and getElementData(player, "isInForbiddenArea") then executeCommandHandler("fr", player, true) end end addCommandHandler("fr", openF1) (I didn't test the code, quote the errors if any.)
  25. Please paste the code between [­­­code=lua][/code] tags next time, because I had to rewrite it, so you are wasting the time of guys who want to help you. That being said, here is the code you were looking for, please take time to read and understand the comments: bodymodstab = guiCreateTab("Body Mods", tabpan) bodygrid = guiCreateGridList(11, 15, 422, 213, false, bodymodstab) local bname = guiGridListAddColumn(bodygrid, "Body Mod Name", 0.5) local bprice = guiGridListAddColumn(bodygrid, "Price", 0.4) local vCompUpgrades = getVehicleCompatibleUpgrades(element) for key, value in ipairs(vCompUpgrades) do -- for all compatibles upgrades ... local upgradeDetails = getVehcileUpgradeDetails(value) -- get the upgrade details if upgradeDetails then --if we got the the name (if we didn't get false or nil) local row = guiGridListAddRow(bodygrid) guiGridListSetItemText(bodygrid, row, bname, upgradeDetails[1], false, false) guiGridListSetItemText(bodygrid, row, bname, upgradeDetails[2], false, true) --true for the ability to sort the grid per price else --Problem that should never happen if the vehicleuprades is complete, but if it's not, we will see it in the client logs. outputDebugString("[ERROR] Couldn't get a vehicle upgrade name (" + tostring(value) + ")", 1) end end --add this function somewhere in your script file function getVehcileUpgradeDetails( upgradeId ) for k, i in ipairs(vehicleuprades) do --iterate over the vehicleuprades table if i[3] == upgradeId then --if the id (3rd column) in the current row is equal to upgradeId then return i --return the entire row of that upgrade (so the name, the price and the id) end end -- go to the next row or go to the line below if it was the last row. return nil --If the code goes here, it means he didn't found, so we return nil end (I'm in a good day, but I almost put a screenshot instead to let you see how it can be annoying to rewrite code instead of a simple copy paste )
×
×
  • Create New...