Jump to content

arezu

Members
  • Posts

    446
  • Joined

  • Last visited

Everything posted by arezu

  1. arezu

    index problem

    score[v] doesn't have a value yet, that's why that happens. The common solution is to do score[v] = (score[v] or 0) + 4. Since you are checking if the table only contains one value, you might as well do: local alivePlayers = getAlivePlayers() if(#alivePlayers == 1)then local player = alivePlayers[1] score[player] = (score[player] or 0) + 4 end
  2. Cancel https://wiki.multitheftauto.com/wiki/OnClientExplosion
  3. arezu

    OOP

    Just make the function part of the class, like this: function Player:isCool() return true end localPlayer:isCool() Alternatively use the following method, which also works with custom elements: local element = createElement("myElementType", "yolo") local myElementTypeClass = getmetatable(element).__class function myElementTypeClass:testFunc() outputChatBox("my Element type id: "..getElementID(self)) end element:testFunc() If you however dont have an element to use for getmetatable to get the class metatable, like if you are doing it server side then relying on getRandomPlayer() would be stupid, so in that case you can do this: local registry = debug.getregistry() local playerMetatable = registry.mt.Player local playerClass = playerMetatable.__class function playerClass:isCool() return true end If you want to store values for elements, and then also get/set them by doing element.key = value and value = element.key, then you can do the following: local registry = debug.getregistry() local playerMetatable = registry.mt.Player local playerData = {} local setFunc = playerMetatable.__set local getFunc = playerMetatable.__get function setFunc:cool(value) if(not playerData[self])then playerData[self] = {} end playerData[self].cool = value end function getFunc:cool() if(not playerData[self])then return nil end return playerData[self].cool end localPlayer.cool = true function Player:isCool() return self.cool end outputChatBox("localPlayer is cool: "..tostring(localPlayer:isCool())) Note: The functions you add to classes will only be available in the resource in which they were defined in.
  4. It doesn't work while you stand on the ground, you get stuck. You have to first jump and then use it (alternatively set your position above the ground and then use it, or setElementVelocity upwards and then timer and setElementVelocity forwards, lol).
  5. But i need remove the string. Like Mr.Aleks said, use testTable[test] That will give you the table which holds "test1" and "test2". testTable[test] is the same as testTable.pers if test is a string that is equal to "pers", just like testTable["pers"] is the same as testTable.pers
  6. In other words, you check if the first character of the code has value 0x1B (use string.byte to convert from string to byte value), and then if the three next values are "Lua". However if the code has also been encrypted, then you need to check for the encrypted byte values instead. The best way is to just check what 4 byte values are placed at the start of code compiled with luac.multitheftauto.com, and then also check the values when using encryption option. You can see the byte values if you open the script file with sublime text or just string.byte the value in mta to output it and use those values.
  7. Some client-side functions sync with server, because they set values that are always synced with the server after intervals; like position, rotation and velocity. Changing localPlayer skin wont change how you look for others. Changing a players money client-side wont change it server-side as noted on wiki for the function: If you check for a players money server-side (like you should with most things where security is an issue), you wont have to worry.
  8. myElementType = createElement("myElementType", "yolo") local myElementTypeClass = getmetatable(myElementType).__class function myElementTypeClass:testFunc() outputChatBox("my Element type id: "..getElementID(self)) end getElementsByType("myElementType")[1]:testFunc()
  9. You may need to use this instead: https://wiki.multitheftauto.com/wiki/OnClientSoundChangedMeta or https://wiki.multitheftauto.com/wiki/OnClientSoundStream
  10. It depends on how your gui looks like. Sometimes it's better to scale things depending on screen height only for a linear scaling in both axes, or even make a different layout design for lower screen resolutions.
  11. I think you have to make your own colshapes for that, to check for shortest distance from a colshape to a cuboid.
  12. Everytime a player got hunter, you added onClientPreRender and you didn't remove the old ones, so they are all drawn on top of each other.
  13. It was a bug in 1.4, it was fixed though. Download latest nightly. https://nightly.multitheftauto.com/
  14. arezu

    Event

    Check for the weapon id and check if the player is in a vehicle? Maybe checking the weapon id is enough.
  15. The messages are received in order. You can use triggerLatent(Client/Server)Event if you don't care about order and if you want the message to be sent/received in another thread so that if you send a big message, it wont cause network trouble.
  16. arezu

    Graphic

    That can happen if you draw text with a bad scale or if you draw text at a non integer position on the screen (try math.floor for x and y position), but that shouldn't happen if you draw text with 'subPixelPositioning' set to false.
  17. arezu

    New logo MTA :D

    It looks very nice, but that guy is from GTA:III
  18. https://wiki.multitheftauto.com/wiki/OnClientPlayerStuntStart
  19. Yes, that is the right way to do it. You could alternatively animate the render target by changing position in the dxDrawImage, but it depends on how you are going to use the render target.
  20. Both are wrong, but second one is closest to right. Render targets are textures and they can be created outside onClientRender. They should be created once, and when you want to update it you should use dxSetRenderTarget(gTarget) just like you are doing (this can be called in onClientRender or outside) and then draw stuff on it just like you are doing right now and then call dxSetRenderTarget() which you are doing right. But since dxCreateRenderTarget creates a texture like dxCreateTexture does and is a dx function, you have to draw it each frame (in onClientRender), so dxDrawImage with gTarget has to be done always in onClientRender if you want it to be visible. Important notes: when the mta loses focus (alt-tab is used, etc) then render targets are cleared so they are empty, and you have to redraw everything in the render target. onClientRestore is called when mta is back in focus again and you can draw on the render target again there. onClientRestore has a parameter "didClearRenderTargets" but dont check if it's true, instead always redraw to render target when onClientRestore is called. Text may have bad quality in render targets, so you should experiment with dxSetBlendMode (look it up on mta wiki for example) for better visual quality. Another important thing to remember is that when you are drawing in render targets you cant enable postGUI (for example in dxDrawText) since then the text wont be visible in the render target, but you can draw the render target with postGUI enabled. Here is an example using your example as base: sWidth, sHeight = guiGetScreenSize() sW, sH = 105, 32 cFont = dxCreateFont("files/fonts/SegoeWPN_0.ttf", 32, false) gTarget = dxCreateRenderTarget(sW, sH, true) function updateRenderTarget() -- Set second argument to true to clear the render target -- before drawing on it. dxSetRenderTarget(gTarget, true) -- Clipping the text here using same width and height -- as the render target is not necessary, since the render target does that automatically. dxDrawText("CWS:Home", 0, 0, sW, sH, tocolor(0, 0, 255), 0.5, cFont, "center", "center") dxSetRenderTarget() end updateRenderTarget() addEventHandler("onClientRestore", root, updateRenderTarget) function testRender() dxDrawImage((sWidth/2)-(sW/2), (sHeight/2)-(sH/2), sW, sH, gTarget) end addEventHandler("onClientRender", getRootElement(), testRender)
  21. These tricks you have may work on newbies, but the following is if you want to make it more secure; or if you are interested in how you can make it more secure: The example you provided can be easily bypassed by using onClientElementDataChange, and even if you dont use setElementData; the functions that you use to make the check if the script can be loaded can also be overriden to return expected result, or by returning a table with metamethod for comparison operator, so you can check what the result is expected to be. The first suggestion I have is to send the encrypted client-side script file content using triggerClientEvent when somebody joins your server and then have one client-side script that is downloaded normally, and the script should simply use loadstring on the received code from triggerClientEvent. The reason this will be more secure is because triggerClientEvent encrypts data before sending (encryption is enabled by default in mtaserver.conf) and the script content is also encrypted, so it's a double layer of encryption. With this option you should not save the file on the players harddrive when received so it's only used in RAM, which on the other hand means the client-side script files will have to be sent everytime to a player when they join the server (script files are small so it wont matter much). The second suggestion is harder, but the idea is to do the same as the suggestion above but instead use luac.multitheftauto.com together with your own encrypter, so when you can send the script content using triggerClientEvent as suggested above, but this time you can then save the script content into a file so you dont have to send script each time the player joins the server. But you should send the decryption key each time the player joins the server so the script can be decrypted and loaded using the loadstring function. The decryption key will be encrypted in triggerClientEvent so it can be sent safely. For this you will have to write a RSA decryption function in lua, so the first suggestion is highly recommended over this suggestion.
  22. triggerEvent creates a copy of provided tables since triggerEvent is meant to be used to trigger remote resources, or mta team has chosen this behavior when triggering inside the same resource to make behavior consistent. Since a copy of table is used, and triggerEvent is mostly used for remote resource, function pointers would no longer be valid as they point to a function that doesn't exist in the other resource; and therefore they are set to nil (removed from the table). There is an undocumented mta function to get an unique number that represents tables which you could pass along in triggerEvent, but I think it only works for global tables. A better solution is to have a table where you add each instance of your classes and store them under the tostring value of the table, like: instances[tostring(Public)] = public and you can then pass that string with the triggerEvent, and in the event you could have a function that loops instances table to get the class instance from string (you can override triggerEvent and addEventHandler to do it automatically). Btw, your class system will create new functions for each instance of the class you create with the system like that, you should look up "metatables" on some lua tutorial on how to make a "proper" class system.
  23. You can use server-side functions during download, so you can spectate another player while downloading by using setCameraTarget server-side in onPlayerJoin event.
  24. You replied to the person that wrote the correct code though and said his code didn't work, and you never said any of the code from replies worked, even though the solution was one of the first replies?
×
×
  • Create New...