• Content Count

  • Joined

  • Last visited

Everything posted by Awang

  1. Yeah, actually you are right... I overlooked the fact... I think sorting the table every time when a new layer filled with data can lose the data of the layer index. I think, it's can be a good solution, if we specify a maximum number for the layer, like 100. Now with this information we can do like this: local imgTable = {} function drawImages() for i=1,100 do if imgTable[i] then dxDrawImage(posX,posY,sizeX,sizeY,imgTable[i].path) end end end function addImgToTable(cmd,index,imgPath) imgTable[tonumber(index)] = {path = imgPath, active = true} end addCommandHandler("addimg",addImgToTable)
  2. Because there is difference beetween pairs and ipairs. And yes, you are find out the problem, what is it. When you use pairs the sequence will be not the sequence of the ordered number keys. Use the ipairs, and you might have what you want to earn.
  3. I think the reason is, that the first table has the index 1, but theres no need to show it by the iprint, beacuse it is trivial. Now the reason is, that the 2. and the 8. indexes has the printed key, that it is want to show, that beetwen the 2 key there are unused keys. I if you loop over the table by ipairs, you will get a key argument also for the first table.
  4. What you want to earn called texture projection. I never did it before in MTA, but I guess you could make it. Here is a good description with codes: In my understanding, by getting the world coordinates and your camera direction, you can project a texture into the world. You can get these matrices from the mtasa-helper.fx, you can get it from the wiki: Sometime I see, that scripters earn this effect by drawing a picture into the 3D world and place it with the element coordinates, combined with the ground level. I know its not showing good on uneven ground, but more easier to implement. dxDrawMaterialLine3D() getGroundPosition()
  5. I suggest you to make shaders for every player or you can optimalize the method by create shaders for players who are in streamed in and destroy for who are exiting from the streaming range. Because MTA only can use 1 core of your CPU in client side, its a good tactic to depend more on memory instead on CPU by making texture moving in the render function before every player. local streamed_players = {} function render() for player in pairs(streamed_players) do -- Do what you want with the shader and renderTarget end end addEventHandler( "onClientElementStreamIn",root,function() if getElementType(source) == "player" then streamed_players[source] = {shader = dxCreateShader(shaderFile), renderTarget = dxCreateRenderTarget(arg1, arg2, true)} end end) addEventHandler( "onClientElementStreamOut",root,function() if getElementType(source) == "player" then streamed_players[source] = nil end end) About RenderTargets, some videocard not really like them, so I suggest you, if you want to just put some material together and after you not want to really change them, than you can read the texture from the target and save out into a simple texture. local target = dxCreateRenderTarget(arg1, arg2, true) dxSetRenderTarget(target) dxDrawImage(...) dxDrawText(...) dxSetRenderTarget() local texture = dxCreateTexture(dxGetTexturePixels(target)) target = nil Basically, you burn together the textures and after you save out, but you cant change it after all.
  6. # operator gives you back the size of the following table. In the example what @IIYAMA write to you means, that the forloop loops over all of the players one by one and if its found the value what you seach for just simple stop the looping. And yes, math.random(#players) give you back a random index from the range of the players table. With the index you can get the player element from the players table and give an element data for it.
  7. Do not use dbPoll with -1 query time, its will couse server side freeze if one of the query comeback with timeout. You can use the dbQuery's callback function with zero timeout instead of, like this: function LoadMessages() local query = dbQuery(function(qh) result = dbPoll(qh,0) end,connection, "SELECT * FROM messages WHERE characterID = 1") for x, ad in ipairs( result ) do local res = result[x]['message'] end end addEvent("LoadMsg", true) addEventHandler("LoadMsg", resourceRoot, LoadMessages) You can read more about there:
  8. I reccomend to use this resource to monitor the usages of your scripts: But basicly, I dont believe, that your precalculate will decrease the usage. Multiply two number is not a hard task for the CPU, even in every frame.
  9. Awang

    MTA Classes

    You need to understand first of all the MTA's element tree. Object's, vehicle's, player's, ped's objects are inherited from Element class. If you want to override the setData for all of these classes, you should override in the Element class. Element._setData = setElementData function Element:setData(name,data) self:_setData(name,data) outputDebugString("Element Data `""` changed to `"..tostring(data).."` for the element: "..tostring(self)) end Self element will be the element, what you called before the function. Important thing, that you need to call with ':', like: localPlayer:setData("source.inheritance",localPlayer) These classes, which are in the element tree are automaticly declaired by MTA, so you do not need to declair them. But if you want for example an other specific override for just players, you can do it: Player._setData = setElementData -- Unfortunatelly, if you want it to replace it to the parent class, for a real inheritance, it will cause stack owerflow... function Player:setData(name,data) self:_setData(name,data) -- this will be the original setData function, not the function of the parent class... outputDebugString("Element Data `""` changed to `"..tostring(data).."` for the player: " end
  10. Awang

    Multi Language

    Due to the fact, that each of the scripts are running over an own virtual machine you need to avoid from call export functions often, like in a render loops for a better performance. I suggest to get the language text on the resourceStart and store them in each scripts. It will be costs more ram, but you will save CPU as @IIYAMA said. My experiences that we need to save more CPU usage rather than RAM for a better performance. ~o~ Arra a tényre alapozva, hogy a scriptjeid mindegyike egy külön Lua virtuális gépen futnak, a közöttük lévő kommunikáció viszonylag lassabb, ezért nem ajánlom az export funkciókat sokszor hívni, mint például egy onClientRender-rel megfuttatott funkcióban. Azt ajánlom, hogy kérd ki a szükséges szövegeket a resource indulásakor és tárold őket lokálisan. A tapasztalatom azt mutatja, hogy jobb teljesítményt lehet elérni akkor, ha inkább RAM-ot használsz mint CPU erőforrást.
  11. Its not about speed, its about the permission of read/write/change... Like in Linux, you can doit in Windows...
  12. Yes, but if somebody just simple do a trick with the writing/reading/deleting acces of the folder then can allow to create the font, but after the script has no right for delete it... Thats why I prefer raw data like in shaders, models other lower sized files, send to cliens with LatentEvents...
  13. Hey Community! I wonder, if its possible to make dxCreateFont function to load font files from raw data in the future updates? Could be a good way to secure my paid fonts.
  14. Yous can use the marker's elementData for it. Like, when player z enter to marker x, the player set the marker with setElementData(theMarker,"marker.player",localPlayer) Now, whenever other player hit the marker, you can look for the elemenet data. If it is a player, you do nothing, otherwise you set the ElementData. When player z leave the marker, then you set the ElementData to nil, so now other player can acces it. But you should think about, what if the player quit from the server, while it is the "root" of the marker, or there is a teleport by other player... Maybe you can check it double, like with getElementColShape() and isElementWithinColShape() or getElementsWithinColShape()
  15. local Timer = 12300 function timer() setTimer(function() if Timer <= 0 then Timer = Timer-2300 outputChatBox("Time is:".. Timer) timer() end end, 2300,1) end Thats what you can do with setTimer()
  16. You should use setTimer(), set 5 minute to execute and make a recursive algorithm with an outside counter. If the counter reach the 12 value, it means you reach the 1 hour... And you can decrease your variable in each loop and write out into the chat...
  17. You may want like @Ren_712's object viewer can do... You should check the resource:
  18. Awang

    Unlimited oxygen.

    I think it's a better way to cancel this damage, than use a client render for it... function stopDrown ( attacker, damage_type) if ( damage_type == 53 ) then -- if the damage type is drowning, check the wiki for more id cancelEvent() --cancel the event end end addEventHandler ( "onClientPlayerDamage", getLocalPlayer(), stopDrown ) Always think about the client's cpu, when you use ClientRender...
  19. An other example for this: In a race server is a quite big problem the different fps... Like who have more fps will be faster than the others, thats why we fix the limit. I usually use 45-50...
  20. Instead of using Luac, you could delete the file, when it's starting to run from the harddrive, because it's already loaded into the memory... I say this, because there are some guy, who can encrypt your luac file...
  21. local dx_healt = getElementHealth(localPlayer) local healt = getElementHealth(localPlayer) function setHealth(_type,_value) if _value >= 5 then if _type == "add" then dx_healt = dx_healt + 5 else dx_healt = dx_healt - 5 end setTimer(function() setHealth(_type,_value-5) end,500,1) elseif _value > 0 then if _type == "add" then dx_healt = dx_healt + _value else dx_healt = dx_healt - _value end end end function healthChecker() if getElementHealth(localPlayer) < healt then setHealth("add",healt-getElementHealth(localPlayer)) elseif getElementHealth(localPlayer) > healt then setHealth("loss",getElementHealth(localPlayer)-healt) end setTimer(function() healthChecker() end,500,1) end addEventHandler("onClientResourceStart",resourceRoot,function() healthChecker() end) Now you can use dx_health variable to draw the animated health for your bar... I used recursive timer instead of "onClientPlayerDamege" because you can detect if the player get an HP and animate the bar filling up... you can change the animation speed and rate by change the Timer milisecond value and the "dx_healt = dx_healt + 5" or "dx_healt = dx_healt - 5" number parameter... Otherway, you should think about what if the player get other damage, while the animation still in progress... Code not tested, maybe you need to correct it...
  22. You can split the string with the basic Lua function, call string.sub(). If I were you, I store the colored name in an elementData, and if the localPlayer set able to see the colors, I used the strings from the elementData, otherway the strings from getPlayerName() function. And if there is a colorcoded nickname, you can use this: function removeHex( s ) return s:gsub( '#%x%x%x%x%x%x', '' ) or s end
  23. I see... Then you need to split the characters which you want to be colored and go ahead with hexameter colors. For the nametag, you should do a trick with the getScreenFromWorldPosition() wich can help you to calculate screen position from World postion and make a feel that is in the 3D world, but actually, its not....
  24. You can use Hexameter colorcodes in the string, for example: dxDrawBorderedText("#F44242@#FFFFFF"..getPlayerName(player), x - w / 2 + 35, y - h + 6, w, h, tocolor(255,255,255,255), scale, font, "left", "top", false, false, false, true, false) For the automatically change you can use a string variable to store the actually color code for the changing part: local colorcode = "#F44242" dxDrawBorderedText(colorcode.."@#FFFFFF"..getPlayerName(player), x - w / 2 + 35, y - h + 6, w, h, tocolor(255,255,255,255), scale, font, "left", "top", false, false, false, true, false) And by change the value of 'colorcode' variable, you can do, want you want...
  25. With these instructions, I think, if you calculate in client side, you should only calculate peds, which are in the streamed zone. Use an if branching with isElementStreamedIn(), or if you really want to reduce the peds table, you should use "onClientElementStreamedIn" and "onClientElementStreamedOut" events and a table, where you push and remove the peds. Good to know, that if you restart the resource while you have peds already in the srteamed zone, they will not trigger this event, so you need to loop peds table with getElementsByType("ped",root,true), where the last param choose you only the streamed peds, then you can add to the table. Anyway, making AIs in Mta is very interesting, have a good luck with this!