Jump to content

Search the Community

Showing results for tags 'table'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Multi Theft Auto: San Andreas 1.x
    • Support for MTA:SA 1.x
    • User Guides
    • Open Source Contributors
    • Suggestions
    • Ban appeals
  • General MTA
    • News
    • Media
    • Site/Forum/Discord/Mantis/Wiki related
    • MTA Chat
    • Other languages
  • MTA Community
    • Scripting
    • Maps
    • Resources
    • Other Creations & GTA modding
    • Competitive gameplay
    • Servers
  • Other
    • General
    • Multi Theft Auto 0.5r2
    • Third party GTA mods
  • Archive
    • Archived Items
    • Trash

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


About Me


Member Title


Gang


Location


Occupation


Interests

Found 24 results

  1. Hey. After two years of scripting i've decided to shared a bit of my knowledge with community, which i've learnt - special thanks goes to @IIYAMA for teaching me trigger and tables related stuff. Therefore i present you: Custom element data It is data system based on Lua tables and trigger(Server)(Client)Event, which was created and released back in 2020, over few months received a significant updates which introduced useful client-side features and not-so complex logic to fully control data flow through server-side. I do plan to actively develop it, mainly in improving performance which is already great, but also introducing new features. But before going forward... Let's do some comparision to element data. Color of divbox explains whether is a pro, con, or neutral difference. Tables are resource dependent, that means you cannot get table and it's contents in other resource without special steps (using exports), while Element data is resource independent, it's possible to get data from any resource. Restarting resource causes table to lost stored data, while Element data keeps it, until element gets destroyed. Tables are considerably faster, while Element data is slower. After acknowledging differences you might say that advantage is taken by element data system because of resource independency, but in later part of tutorial i will point out and describe two scripted features in this data system (they aren't implemented in element data) which are important during sending anything to players, afromentioned features are heavily affecting both client and server performance. Source code Latest version is available on GitHub. Syntax Client: mixed getCustomData(mixed pElement, string pKey, string pType) mixed getElementsByKey(string pKey, mixed pValue, string pType, bool pMultipleResults) bool setCustomData(mixed pElement, string pKey, mixed pValue, string pType, mixed pEvent, mixed pSyncer) bool addDataHandler(mixed pElementTypes, mixed pTypes, mixed pKeys, function pFunction, mixed pEvent) Server: mixed getCustomData(mixed pElement, string pKey, string pType, mixed pRequester) mixed getElementsByKey(string pKey, mixed pValue, string pType, mixed pRequester, bool pMultipleResults) bool setCustomData(mixed pElement, string pKey, mixed pValue, string pType, mixed pReceivers, mixed pSyncer, mixed pEvent, mixed pBuffer, int pTimeout) bool forceBatchDataSync(mixed pQueue, mixed pType) Function acceptable types of data, returns and behaviours: Client: mixed getCustomData(mixed pElement, mixed pKey, string pType) pElement: element or a string which holds data pack pKey: string which holds data under certain name or nil pType: string which defines data type, can be "local", "synced" or "private" nil: on failure, or when certain key it's not existing table: with all data, on success, when pKey is equal to nil anything else: on success, this can be a string, number, table, bool This function is used for retrieving data stored under element, you can retrieve certain key or whole data. mixed getElementsByKey(string pKey, mixed pValue, string pType, bool pMultipleResults) pKey: string, which defines a key used by element pValue: string, bool, number, userdata in case if you want filter by certain value, or false/nil if you don't need value to be matching pType: string, which defines data types, can be "local", "synced" or "private" pMultipleResults: bool, which decides if you want get more than one element using certain data, true for multiple elements, false for single element false: on failure table: empty on failure, and containing element(s) on success - only if pMultipleResults is enabled element: on success This function allows you to get a element(s) which contains certain data key, if required you can enable matching key to specified value. bool setCustomData(mixed pElement, string pKey, mixed pValue, string pType, mixed pEvent, mixed pSyncer) pElement: element or string, which you wish to set data pKey: string, which defines a key used by element pValue: string, boolean, number, userdata or table which will be set as key value pType: string, which defines type of data, can be "local", "synced" or "private" pEvent: string or false/nil, defining which server event caused data to change pSyncer: element or false/nil, responsible for data syncing false: on failure true: on success This function allows you to set a data for element, with certain key, value and data type on client-side with some extras. It doesn't force sync due of security reasons. Server: mixed getCustomData(mixed pElement, string pKey, string pType, element pRequester) pElement: element or a string which holds data pack pKey: string which holds data under certain name or nil pType: string which defines data type, can be "local", "synced" or "private" pRequester: player or nil/false, which requests data - ignored when pType isn't equal to "private" nil: on failure, or when certain key it's not existing table: with all data, on success, when pKey is equal to nil anything else: on success, this can be a string, number, table, bool This function is used for retrieving data stored under element, you can retrieve certain key or whole data. mixed getElementsByKey(string pKey, mixed pValue, string pType, mixed pRequester, bool pMultipleResults) pKey: string, which defines a key used by element pValue: string, bool, number, userdata in case if you want filter by certain value, or false/nil if you don't need value to be matching pType: string, which defines data types, can be "local", "synced" or "private" pRequester: player or nil/false, which requests data - ignored when pType isn't equal to "private" pMultipleResults: bool, which decides if you want get more than one element using certain data, true for multiple elements, false for single element false: on failure table: on success/failure, when pMultipleResults is enabled element: on success, when pMultipleResults is disabled This function allows you to get a element(s) which contains certain data key, if required you can enable matching key to specified value. bool setCustomData(mixed pElement, string pKey, mixed pValue, string pType, mixed pReceivers, mixed pSyncer, mixed pEvent, mixed pBuffer, int pTimeout) pElement: element or string, which you wish to set data pKey: string, which defines a key used by element pValue: string, boolean, number, userdata or table which will be set as key value pType: string, which defines type of data, can be "local", "synced" or "private" pReceivers: player or table with players or nil/false, specifies which players will receive data, ignored if pType isn't equal to "private" pSyncer: element or false/nil, responsible for data syncing pEvent: string or false/nil, defining which server event caused data to change pBuffer: string or false/nil, if string passed it will enable batch or buffer functionality (see below for explanation) pTimeout: integer or false/nil, if it's == -1 then server will use batch, if it's >= 0 server will use buffer, ignored if pBuffer isn't enabled true: on success false: on failure This function allows you to set a data for element, with certain key, value and data type with some extras on server-side. bool forceBatchDataSync(mixed pQueue, mixed pType) pQueue: string/false/nil, when string is passed server will search for specified queue to sync, otherwise it will select all queues, not dependent on it's name pType: string/false/nil, when string is passed server will search for certain type of queue, can be "synced" or "private", otherwise it will select all queues, not dependent on type true: on success false: on failure This function allows you to optimise data flow by collecting pack of data and sending it with merged trigger, further explanations available in later part of tutorial. After reading detailed syntax, it's time to move on next topic and understand server-side data validation. Often skipped by majority of scripters, even though it's a very important thing. Server-side data validation It's a process when server validates data sent from client, if you aren't familiar with it, it might sound difficult, but in reality it isn't. Validation is made in server event function handler, via simple if conditions, it ensures that client sent valid data which later will be used by server. While MTA:SA anticheat is one of strongest ones and you can rely on it in most cases, it is scripter task to make sure that server-side logic is also scripted well, to completely eliminate possibility of harming your server by client sending fake (malicious variant), or incorrect data (default variant). Yes, even default client could be harmful, even unintentionally - let's take for a example ping as a main factor, due of delay between certain player and server, data for player A might have different value than for player B. What to do in that case? Answer is simple, get data value from server. Instead of: Client -> Request data change with player value -> Server -> Process it Do: Client -> Request data change -> Server -> Check for client variable -> Get value from server -> Process it But, what if (MTA) function isn't available server-side? Then you need use client for returning it and sending to server, e.g collision checks. While this might feels insecure you can (and should) always check whether type of data passed is valid. Special Lua function will be irreplaceable here. local clientData = {} local typeOfData = type(clientData) print(typeOfData) -- "table" You might wonder what is client variable? Shortly, it's a special global variable which is used in server events. This wiki article explains that when we want to receive a player who called the event, we should use client instead of source. Why? Because: Any player with access to runcode/Lua injector can pass another player which might have admin permissions. This will result in executing server code even though it shouldn't happen by default. Aforementioned source might be not an actual player, because you can pass pretty much every element e.g root, resourceRoot. Perhaps you already know that nothing is 100% safe? That is accurate sentence, but when it comes to scripted server-side data validation - you can't bypass it, if it's correctly written. Well, probably you could do that, but you'd need to access server itself, however if it'd happen then it's game over. Example of validation is available here, since i do not pass any data from player side, if client then condition with parent check is sufficient. Is there anything else you can do to protect your server more? Actually yes. Since trigger(Client)ServerEvent is a function which calls a counter-side functions (and pass data to it) it's affecting traffic and CPU. It should be well maintained (element data isn't exception). If you do not understand events then feel free to check IIYAMA's events tutorial, while he explains basics i will be expanding this by showing how you can reduce calls and optimise passing data between sides, because triggers are main component of my data system. We'll be moving step by step from easier to a bit harder topics, here comes our first step. Client-side delays As i mentioned before that triggers should be well maintained, we should add some delay for client-side, which will be a obstacle for someone, who'd try to spam server with triggerServerEvent calls. It's easily achievable with getTickCount function. --[[ /*************************************************** Client ***************************************************\ ]] local dataToPass = "string" -- data we want pass to server local lastTriggerCall = getTickCount() -- store last trigger call local delayValue = 500 -- ms function triggerEventByCommand() if getTickCount() - lastTriggerCall >= delayValue then -- if delay has passed triggerServerEvent("onServerEvent", localPlayer, dataToPass) -- trigger server event lastTriggerCall = getTickCount() -- update last trigger call end end addCommandHandler("trigger", triggerEventByCommand) --[[ /*************************************************** Server ***************************************************\ ]] function onServerEvent(pData) if client then -- check whether client exists (just for sake) local isString = type(pData) == "string" -- make sure that is string if isString then -- if so local validLength = #pData <= 4 -- check whether is less or equal to 4 chars if validLength then -- if so print("The checks have passed... Processing code.") end end end end addEvent("onServerEvent", true) addEventHandler("onServerEvent", root, onServerEvent) You can also implement same delay checks on server-side, but i believe that client-side should be sufficient. Selecting lowest possible source element for trigger Probably many of you (including myself), have passed root or resourceRoot as a 2-nd/3-rd argument in function: triggerServerEvent ( string event, element theElement, [arguments...] ) triggerClientEvent ( [ table/element sendTo = getRootElement(), ] string name, element sourceElement [, arguments... ] ) That shouldn't be done, unless you know what you are doing. Because of CPU impact which wiki states on client and server variation. Most of people (once again, including myself) misunderstood this note. Which is not about attaching custom events to root, but about passing it to trigger itself. While resourceRoot is lower than root in element tree, you should use localPlayer instead - on client-side. When it comes to server-side you can also use same player which triggered certain event, as for example this is handled similarly in server-side part of custom data. But i do also check if sourceElement (pSyncer) is actual element to avoid warnings. We could say that attachedTo is some kind of filter which checks if sourceElement which triggered certain event is allowed (depending on it's position in element tree) to process the function. But you've should already know that if you read events tutorial. addEventHandler ( string eventName, element attachedTo, function handlerFunction [, bool propagate = true, string priority = "normal" ] ) Optimising data flow First and foremost my favourite way - batching. What is it, why and when you should use it? Batching is a process when you place data in certain queue, this data however isn't synced instantly, it's stored at server-side in additional table, till force sync will be called (forceBatchDataSync). This is different scenario when we compare it to element data, while custom data with batching enabled sends pack of data in 1 trigger (1 queue = 1 trigger), element data sends each (!) data separately. In other words, you can do x100 setCustomData and they will be sent with 1 trigger, while x100 setElementData waste a lot of traffic and CPU by doing that separately. Generally you should use it always when you set more than one data. Practical example, setting data upon spawning vehicle: local dataTable = {{"Data 1", "Value 1"}, {"Data 2", "Value 2"}} function spawnInfernus(pPlayer) local playerType = getElementType(pPlayer) == "player" -- check if it's player if playerType then -- if so local playerX, playerY, playerZ = getElementPosition(pPlayer) -- get player position local infernusElement = createVehicle(411, playerX + 5, playerY, playerZ) -- create vehicle for dataID = 1, #dataTable do -- loop through data table local dataPack = dataTable[dataID] -- get data at certain index local dataName = dataPack[1] -- get data name local dataValue = dataPack[2] -- get data value setCustomData(infernusElement, dataName, dataValue, "synced", false, pPlayer, "spawn_infernus", "queue_spawn_infernus", -1) -- set data for vehicle, with specified name and value, with type "synced", receivers false, pPlayer as syncer, "spawn_infernus" as event name and queue "queue_spawn_infernus" with timeout -1 (batch) end forceBatchDataSync("queue_spawn_infernus", "synced") -- force "queue_spawn_infernus" to sync from "synced" type end end addCommandHandler("spawninfernus", spawnInfernus) Second way is using buffer, the difference between previous technique is that instead awaiting synchronization we create a timer which collects pack of data with given delay. Using it also results in data reduction, because calls are reduced. You can apply it to data which is being changed by multiple players, or in different scenario where you'd want to collect various data and sync them in same queue, i'll also include handy code by @IIYAMA which would help you adjust your delay. local sendingDelay = 100 -- ms local fps = 60 local timeSlice = 1000/fps local dataReduction = sendingDelay/timeSlice print("~"..(dataReduction - 1).." x times LESS per "..sendingDelay.." ms.") An simple buffer example: function bufferExample(pPlayer) local playerType = getElementType(pPlayer) == "player" -- check if it's player if playerType then -- if so local bufferChanges = getCustomData(pPlayer, "Buffer changes", "private", pPlayer) or 0 -- get changes for this data setCustomData(pPlayer, "Buffer changes", bufferChanges + 1, "private", pPlayer, pPlayer, "buffer_change", "queue_buffer_change", 3000) bufferChanges = getCustomData(pPlayer, "Buffer changes", "private", pPlayer) -- get once again changes for this data outputChatBox("Data has changed for player: "..getPlayerName(pPlayer).." -> Buffer changes: "..bufferChanges) end end addCommandHandler("buffertest", bufferExample) Data handlers - awesome addition Meet data handlers, equivalent of onClientElementDataChange, those are your own custom functions which could be attached to certain element, data type, key, and event. Once the function is triggered, it provides set of useful parameters which could be used inside function scope, this is another feature which makes this data system powerful. For examples, we'll refer to previously set data with batch and buffer. function onClientInternusDataChange(pElement, pKey, pType, pOldValue, pNewValue, pEvent, pSyncer) if pSyncer == localPlayer then print("I am syncer of this data! At event: "..tostring(pEvent)) end print("Key: "..pKey.." ("..pType..") has changed: "..tostring(pOldValue).." -> "..tostring(pNewValue)) end addDataHandler("vehicle", {}, {}, onClientInternusDataChange, "spawn_infernus") -- requirements to trigger function: element needs to be vehicle, any data type and key name can trigger this, event needs to be equal to "spawn_infernus" --[[ /*************************************************** ***************************************************\ ]] function onClientBufferChange(pElement, pKey, pType, pOldValue, pNewValue, pEvent, pSyncer) if pSyncer == localPlayer then print("I am syncer of this data! At event: "..tostring(pEvent)) end print("Key: "..pKey.." ("..pType..") has changed: "..tostring(pOldValue).." -> "..tostring(pNewValue)) end addDataHandler("player", "private", "Buffer changes", onClientBufferChange, "buffer_change") -- requirements to trigger function: element needs to be player, data type == "private" and key name == "Buffer changes" can trigger this, event needs to be equal to "buffer_change" How to use it? Download latest version, and add it directly to your gamemode, to use functions directly or leave it as a separate resource to use functions with exports. First option gives best performance, and allows you to use data handlers. Make sure that player parent isn't changed, in order for server-side to work correctly. Efficiency test Element data & Custom data in 100000 iterations (client-side, sync off) Set local data: ED: 31 ms < CD: 17 ms Get local data by key: ED: 19 ms < CD: 9 ms Get all local data: ED: n/a < CD: 10 ms
  2. table = {} function table.contains(table, element) for _, value in pairs(table) do if value == element then return true end end return false end function tablefind(tab,el) for index, value in pairs(tab) do if value == el then return index end end end function OnClientGuiButton() if not table.contains(BedwarsEQ, "P1") then table.insert(table, "P1") -- Insert to a table string "P1" (Player1) end if tablefind(table, "P1")==1 then -- check index, if is Item in index(1) then == true AdxItem1 = 255 -- dxDrawImage, drawing image to effect SLOT1 = SLOT1 + 1 -- type how many items is in P1 end if tablefind(table, "P1")==2 then -- if is Item in index(1) then check "if is Item in Index(2)" == true BdxItem1 = 255 --second dxDrawImage, drawing image to effect SLOT2 = SLOT2 + 1 --type how many items is in P1 end end addEvenetHandler("onClientGUIClick", button, OnClientGuiButton I will explain the problem. The problem is that when I press the button that gives me to the table "P1", it checks in which index it is. There is a problem that if I click on another button that gives me "P2", it doesn't prove that "P2" is in the table. Debugscript writes to me that the wrong first argument is given in the tableFind function, and that's strange because I checked twice and gave the right one. What's wrong with that?
  3. redditing

    Table

    I wanted to ask if there is a way to check what index the value in the table is for example, t = {} table.insert(t,"Hello") table.insert(t,"HELLO") table.insert(t,"HI") if index==1 and value=="HI" then -- false --do something elseif index==0 and value=="HELLO" then --false --do something elseif index==2 and value=="HI" then --true --do something else --etc. --do something end --If someone does not distinguish the index from the value then the index is for example [0,1,2,3 ...] and the value is an element for example print(t[1]) -------------> 'HELLO'
  4. I have this: -- 2 points on each city. local spawnCoords = { {1125, -2036, 69.89, -90}, {2504, -1686, 13.55, 45}, {-1972, 643, 46.57, -45}, {-2720, -317, 7.85, 45}, {2023, 1008, 10.83, -90}, {1298, 2084, 12.83, -90}, } -- all skins. local validSkins = {0, 1, 2, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312} function spawnPoints (player) local x,y,z,r = unpack(spawnCoords[math.random(1,#spawnCoords)]) spawnPlayer(source, x, y, z, r, validSkins[math.random(1,#validSkins)]) fadeCamera(source, true) setCameraTarget(source, source) end addEventHandler("onPlayerJoin", getRootElement(), spawnPoints) Althought it works, after giving it several tests, I realized the spawn locations where always in the same order, as well as the skins. Coincidentally, I've reached the tables subject in the MTA's tutorial, and I learned about <for key, value in pairs(table) do>. Contrary to "ipairs", "pairs" is supposed to give you a random reading throughout the table everytime the script is ran. I used 'broph.Lua' as a way to understand the process, and to make sure that if I do the same, it'll work. My small knowledge told me that, by adding <for key, value in pairs(spawnCoords) do> right after the beginning of the function, I would get the random effect of the table reading. However, the result is far from what I expected: it destroys the function, and the player doesn't spawn at all (black screen). I'm continuing the tutorial, but 'in pairs' is the last thing NanoBob mentions about the tables. This time, I'd like a bit of a challenge, so if you could give me the hints and point me in the right direction, I would appreciate that.
  5. Iae rapaziada, seguinte fiz um code simples só para aprender melhor tabela, até agora estava tudo normal criando as markers, a mensagem na tela e tudo mais.... porém agora estou com o seguinte problema: São 3 markers cada uma tem uma cadeira do lado. O que tenho em mente é que quando o player hitar uma das markers binde a tecla E, ao pressiona-la ele é colocado sobre a cadeira em que ele esta próximo. Mas no sistema atual o problema é que ele não reconhece qual cadeira é! Quero saber como eu posso fazer uma verificação para saber se a marker é da cadeira [1], [2] ou [3]. Code: local posChairs = { [1] = {1579.4000244141,-1675.8000488281 ,15.199999809265}, -- cadeira interrogado (suspeito) 1 [2] = {1580, -1677.5, 15.199999809265}, -- cadeira interrogado (suspeito) 2 [3] = {1582.0999755859, -1676.3000488281, 15.199999809265}, -- -- cadeira interrogador (policial) } local chairTable = {} function resStart() for i, chair in ipairs(posChairs) do chairTable[i] = createMarker(chair[1], chair[2], chair[3], "cylinder", 1.2, 255,0, 0, 100) outputChatBox(tostring(chairTable[i])) addEventHandler("onMarkerHit", chairTable[i], hittingMk) addEventHandler("onMarkerLeave", chairTable[i], leavingMk) end end addEventHandler("onResourceStart", getResourceRootElement(getThisResource()), resStart) function resStopCircle() if chairTable[i] then destroyElement(chairTable[i]) chairTable[i] = nil outputChatBox(tostring(chairTable[i])) end end addEventHandler("onResourceStop", getResourceRootElement(getThisResource()), resStopCircle) function hittingMk (element, md) if (md) then if getElementType(element) == "player" then outputChatBox("hitou") exports.inMarkerMsg:create(element, "pressione E para sentar") end end end function leavingMk (element, md) if (md) then if getElementType(element) == "player" then outputChatBox("saiu") exports.inMarkerMsg:delete(element) end end end Obs: estou ciente que se eu criar 3 variáveis e 3 eventos uma para cada cadeira dará certo (já testei e consegui!), porém irei criar mais cadeiras além de utilizar esse sistema em outras coisas! fazendo um for com a tabela (chairTable), percebi que há uma edentação um "prefixo" e um "valor": for k,v in pairs(chairTable) do outputChatBox("chairTable "..tostring(k)..", "..tostring(v)) end Retorna: chairTable 1, userdata: 0x7289 chairTable 2, userdata: 0x728c chairTable 3, userdata: 0x728f Tentei fazer uma verificação com if dessa forma (porém sem exito) : if chairTable[1] then outputChatBox("hitou1") elseif chairTable[2] then outputChatBox("hitou2") elseif chairTable[3] then outputChatBox("hitou3") end Será que tem como eu especificar a cadeira sem ter que criar para cada cadeira(marker), um evento e uma variável?
  6. local table = { {"1", "2", "3", "4"}, } function asdasdsdasdd() table.insert(table,"5","6","7","8") end What wrong? No errors and warnings in debugscript 3...
  7. Boa noite rapaziada, bom eu to fazendo um painel login e adicionei 3 musicas que tocam aleatoriamente em uma tabela nomeada (Tab_Musicas), no entanto ao player entrar na tela de login eu gostaria que aparecesse o nome da musica a qual esta tocando! E é ai que entra minha duvida. Como eu poderia estar especificando em um dxDrawText qual musica esta tocando no momento? Linhas de código abaixo: Tabela: local Tab_Musicas = {"musicas/musica1.mp3", "musicas/musica2.mp3", "musicas/musica3.mp3"} Momento em que a musica se inicia: function onClientResourceStart() fadeCamera(true, 5) setCameraMatrix(1468.8785400391, -919.25317382813, 100.153465271, 1468.388671875, -918.42474365234, 99.881813049316) sound = playSound(Tab_Musicas[math.random(1, #Tab_Musicas)], false) ... Print do P/Login, no estado atual (a musica se encontra no canto superior direito):
  8. I created a scoreboard system, but when i make a team, the team does not show in scoreboard.. how can i add this after playerlist?
  9. client: local Admins = {} addEvent("updateAdmins",true) addEventHandler("updateAdmins",root, function(t) Admins = t end) function isPlayerAdmin(player) if(Admins[player]) then return true end return false end function asdi() for k,v in ipairs(Admins) do outputChatBox(k) end end addCommandHandler("asd",asdi) server: local Admins = {} function isPlayerAdmin(player) if(Admins[player]) then return true end return false end addEventHandler("onPlayerLogin",root, function() if isObjectInACLGroup ( "user." .. getAccountName ( getPlayerAccount ( source ) ), aclGetGroup ( "Admin" ))then if not(Admins[source])then Admins[source]= source triggerClientEvent("updateAdmins",source,Admins) end end end) addEventHandler("onPlayerQuit",root, function() if(Admins[source])then Admins[source]= nil triggerClientEvent("updateAdmins",source,Admins) end end) No errors, no warnings... What wrong?
  10. if i create a table, and i insert datas with table.insert, the datas are deleted when i reconnect.. why? how to save datas? sorry for my terrible english :ss
  11. local vehicles = {} addEventHandler("cmdHandler",getRootElement(), function(thePlayer, command) if(command == "/dveh") then for i, v in ipairs (vehicles) do local player, veh = unpack(v) if (player == thePlayer) then destroyElement (veh) table.remove (vehicles, i) return end end end end ) Hi, I want the script to delete all vehicles and rows, but it only deletes the last one, why ?
  12. Why the table disappears after the cycle? Never this was not. shel = {} local shelPlaces = { [1] = { [1] = {x=0,y=0,z=0}, [2] = {x=0,y=0,z=0}, [3] = {x=0,y=0,z=0}, }, } function createShelters(gameId, players) local gameId = tonumber(gameId) shel[gameId] = {} for i=1,#shelPlaces do --outputDebugString("table "..shel[gameId]) shel[gameId][i] = { ["places"] = { [1] = {x=shelPlaces[i][1].x,y=shelPlaces[i][1].y,z=shelPlaces[i][1].z,["object"]="craftTable"}, }, } outputChatBox(shel[1][1]["places"][1]["object"]) -- WORKING for pI=2,#shelPlaces[i] do shel[gameId][i]["places"] = { [pI] = {x=shelPlaces[i][pI].x,y=shelPlaces[i][pI].y,z=shelPlaces[i][pI].z,["object"]=false}, } end end createCraftsTable(gameId) end addEventHandler("onGameStarted", root, createShelters) function createCraftsTable() --for i=1,10 do --for name,object in pairs(shel[gameId][i]) end function tempSpawn() spawnPlayer(source, 0,0,5) setCameraTarget(source, source) end addEventHandler("onPlayerLogin", root, tempSpawn) function startTest(pSource, command, gameId) triggerEvent("onGameStarted", root, gameId) end addCommandHandler("gameTest", startTest) function getGameInfo() outputChatBox(shel[1][1]["places"][1]["object"]) -- NOT WORKING end addCommandHandler("gInfo", getGameInfo)
  13. Hello, I am scripting a new chat and the stuff I scripted is working. But now I have a problem. In my chat I am printing the first 13 messages in dxDraw. But now I want all indexes to +1, so if there come a 14th message it gets visible. local offset = 14 function drawChat() for i, v in ipairs (chatbox) do if (i < offset) then exports.login:dxDrawBorderedText(v, 36, (210 - ((offset-i)*15)), 411, 210, tocolor(255, 255, 255, 255), 1.00, "default-bold", "left", "top", false, false, false, false, false) elseif (i == 14) then --what to add ? I want all index to +1, so the new message will get the first index end end end addEventHandler ("onClientRender", root, drawChat)
  14. Hello, I have been writing gamemode for a long time, everything that is important (information about the vehicle, player, object) is stored on the server side in the table. My question is: what is safer and more optimal? Variables saved on the server side in the table and called to the client by events or elementData?
  15. I want create a script, which create a marker with random position, from a table. How to make this?
  16. Hello. As you can see, in my script i attached 2 weapons to a vehicle. I set a bind for shooting one of the gun. My problem is that when i start the function called "fire_gun_c" then both of the weapons will be fired. So my question is how can i only shoot the weapon "gun1" by using getAttachedElements? client function attach() local gun1 = createWeapon(31, 0,0,0) local gun2 = createWeapon(31, 0,0,0) attachElements ( gun1, veh, 0, 1, 0) attachElements ( gun1, veh, 0, -1, 0) end function fire_gun_c(veh) local attachedElements = getAttachedElements(veh) for ElementKey, ElementValue in ipairs ( attachedElements ) do fireWeapon ( ElementValue ) -- it fires both of the guns because it gets all the data with getAttachedElements end end addEvent("fire_gun_c", true) addEventHandler ( "fire_gun_c", resourceRoot, fire_gun_c)
  17. Hey, I have a problem this code working player in server. But no working when player quit. exitLobby = function(self) local previousLobby = getElementData(localPlayer, "player:selectedLobby") if previousLobby then if self.lobbies[previousLobby] then for k,v in ipairs(self.lobbies[previousLobby].players) do if v == localPlayer then table.remove(self.lobbies[previousLobby].players, k) end end end end setElementData(resourceRoot, "root:lobbies", self.lobbies) setElementData(localPlayer, "player:selectedLobby", false) exports["br_notifications"]:addNotification(localization:getText(localPlayer, "lobby-leftInRoom"), "success") end
  18. Hello everyone! I am beginner in all of this. I am a hobby scripter, because I have interest in scripting. BUT I have problem. I want to make a skill system(like you shoot a leg you get 1points for that), and I found a free resource that varies your skill up to 999 in server side and I found another one that do this client side.(also I won't use it like my scripts in a server) OK I have problems with client AND server side too. I can't connect and update the variable. I created a table for the UZI skill (uzi_skill) to try it, but I can't get working. Original source: https://community.multitheftauto.com/index.php?p=resources&s=details&id=11129 This is just the Uzi skill section. The skill is tied to the character-system. (db: character-system -> table: uzi_skill [tinyint(4)] ) function uzi ( attacker, attackerweapon, bodypart, loss ) local statz = getPedStat(attacker, 75) local healthh = getElementHealth(source) local setstat = statz + (100.0 - healthh) * 0.05 local cteam = getPlayerTeam(attacker) local pteam = getPlayerTeam(source) --exports['skill']:changeProtectedElementDataEx(source, "uzi_skill", tonumber(setstat)) <--- I tried with this. Complete FAIL(I know why) if getTeamName(cteam) == getTeamName(pteam) then return false elseif attacker and getElementType(attacker) == "player" and (attackerweapon == 28 or attackerweapon == 32) and (statz < 999) then setPedStat(attacker, 75, setstat) end if (statz > 980) then setPedStat(attacker, 75, 999) end end addEventHandler("onPlayerDamage", getRootElement(), uzi) I want a bit help, just one example how to do this with this. (Please don't ask in fragments. Also I don't know where to put that script fragment). I'd be happy if someone could help me
  19. Hello, I am creating a PIN system on my server and wanted to ask you for help in my code. When I send the client to the server a trigger wanted to validate if the pin sent from the client to the server is an element of my table if yes setElementData will work and the Pin used will be unable to use again but in my script when it uses a pin all The others are disabled, can you help me? Note: I'm Brazilian, I'm sorry for English. local pins15k = {"UAIFKAJDKEFC15K", "KYJFKAJDEFKC15K", "BESFKSLLKEFC15K"} function PinEdit(Pin) if validatePin(Pin) then if getElementData(source, "Diamond") then setElementData(source, "Diamond", getElementData(source, "Diamond")+10000) else setElementData(source, "Diamond", 10000) end for k, v in ipairs(pins15k) do outputChatBox("["..k.."] = "..v) end else outputChatBox("Pin invalido", source) outputChatBox(tostring(pins15k)) end end addEvent("PinEdit", true) addEventHandler("PinEdit", getRootElement(), PinEdit) function validatePin(pin) local result = false for k, v in ipairs(pins15k) do if (pin == v) then pins15k[k] = nil result = true break end end return result end
  20. Hello again. I have problem with table.insert. I have vehicle shop that saves data to tables and tables to element data. Always when you buy new vehicle, it should add sub-table to main-table and fill sub-table with data that i want to save. I also have panel where you can control your vehicles. Instead of showing data, the gridlist shows only number 1 in first column. Part of my code: [Server] local data = getElementData(client, "wangcars.data") if not data then setElementData(client, "wangcars.data", {}) end local data = getElementData(client, "wangcars.data") local ids = #data + 1 local x, y, z = getElementPosition(wangvehicle[client]) local rx, ry, rz = getElementRotation(wangvehicle[client]) local t = {} table.insert(t, getVehicleName(wangvehicle[client])) table.insert(t, tonumber(id)) table.insert(t, tonumber(ids)) table.insert(t, tonumber(price)) table.insert(t, c1 .. ", " .. c2 .. ", " .. c3 .. ", " .. c4 .. ", " .. c5 .. ", " .. c6) table.insert(t, x .. ", " .. y .. ", " .. z .. ", " .. rx .. ", " .. ry .. ", " .. rz) table.insert(t, "indrive") table.insert(data, t) setElementData(client, "wangcars.data", data) [Client] function refreshlist() guiGridListClear(vlist) guiGridListAddColumn(vlist, "Vehicle name", 0.3) guiGridListAddColumn(vlist, "Sell price", 0.3) guiGridListAddColumn(vlist, "ID", 0.3) local table = getElementData(localPlayer, "wangcars.data") if not table then setElementData(localPlayer, "wangcars.data", {}) end for i=1, #table do local row = guiGridListAddRow(vlist) guiGridListSetItemText(vlist, row, 1, table[i][1], false, false) guiGridListSetItemText(vlist, row, 1, table[i][4], false, false) guiGridListSetItemText(vlist, row, 1, table[i][3], false, false) end end The values are tested and they're working fine. No errors in debugscript.
  21. --[[ -- Resource Name: Information. -- Author: Om (RipeMangoes69) -- Date: 4/12/2016 -- File: client.lua ]]-- -- GUI GUIEditor = { window = {}, label = {}, memo = {} } function createInfoObjects() local markers = { {area = "Los Santos Airport", x = 1582.45, y = -2286.32, z = 12}, {area = "Las Vegas Airport", x = 1674.30859375, y = 1444.9501953125, z = 9.2} } for _, m in ipairs(markers) do local marker = createMarker(m.x, m.y, m.z, "cylinder", 1, 255, 255, 255, 100) GUIEditor.window[1] = guiCreateWindow(645, 250, 266, 378, "Information: " .. m.area, false) guiWindowSetSizable(GUIEditor.window[1], false) guiSetVisible(GUIEditor.window[1], false) GUIEditor.label[1] = guiCreateLabel(5, 353, 190, 15, "* Click anywhere on GUI Window to close it.", false, GUIEditor.window[1]) guiSetFont(GUIEditor.label[1], "default-small") GUIEditor.memo[1] = guiCreateMemo(9, 24, 247, 324, "", false, GUIEditor.window[1]) guiMemoSetReadOnly(GUIEditor.memo[1], true) end end addEventHandler("onClientResourceStart", getRootElement(), createInfoObjects) function openGUI( hitElement, matchingDimension ) if getElementType( hitElement ) == "player" then if isPedInVehicle(hitElement) then outputChatBox("You cannot access GUI from vehicle!", 255, 0, 0) guiSetVisible(GUIEditor.window[1], false) showCursor(false) else guiSetVisible(GUIEditor.window[1], true) showCursor(true) end end end addEventHandler("onClientMarkerHit", resourceRoot, openGUI) function closeGUI() guiSetVisible(GUIEditor.window[1], false) showCursor(false) end addEventHandler("onClientGUIClick", resourceRoot, closeGUI) How am i suppose to "change" the GUI Title ? (area in the table). thanks.
  22. Buenas, estoy creando un sistema de nametags cliente y estoy usando tablas, para que así cuando se loguee/desloguee, se muestre o no el texto en cuestión (el nametag). Todo va correcto, el problema que tengo es a la hora de usar table.insert, que sigue renderizando el nombre local nametags = { } local font = dxCreateFont( "fuente.ttf" ) addEvent( "nmtgs:onPlayerLogin", true ) addEvent( "nmtgs:onPlayerQuit", true ) addEventHandler( "onClientRender", root, function( ) if #nametags > 0 then for i=1, #nametags do local player = nametags[i] local px, py, pz = getElementPosition( player ) local x, y, z = getElementPosition( getLocalPlayer( ) ) local name = getPlayerNametagText( nametags[i] ):gsub("_"," ") end end end ) function addPlayerToTable( player ) if player then table.insert( nametags, player ) end end addEventHandler( "nmtgs:onPlayerLogin", getRootElement( ), addPlayerToTable ) function removePlayerFromTable( player ) if player and nametags[ player ] then table.remove( nametags, player ) end end addEventHandler( "nmtgs:onPlayerQuit", getRootElement( ), removePlayerFromTable ) ¿Alguna idea? Gracias de antemano.
  23. Hello everyone I currently have this function that develops, and some time and I wanted to make a change most do not know it as good is simple. local positions = { { 371, -2040, 8 }, { 2274, -1036, 52 }, { -2245, -1723, 482 }, { -155, -2889, 428 }, } function DisappearPlayer (NamePlayer, Admin) local azar = math.random ( #positions ) local veh = getPedOccupiedVehicle(NamePlayer) if (veh) then setElementPosition(veh, unpack ( positions [ azar ] ) ) else setElementPosition(NamePlayer, unpack ( positions [ azar ] ) ) end end addEvent("random",true) addEventHandler("random",getRootElement(),DisappearPlayer) This teleports the player into a random position map using a table of coordinates. Ok everything works perfectly. But I wanted it stores up the item from the table that has already been used and not used again until the last was used or the successor. Ex local positions = { { 1 }, { 2 }, { 3 }, { 4 }, } function DisappearPlayer (NamePlayer, Admin) local azar = math.random ( #positions ) local veh = getPedOccupiedVehicle(NamePlayer) if (veh) then setElementPosition(veh, unpack ( positions [ azar ] ) ) else setElementPosition(NamePlayer, unpack ( positions [ azar ] ) ) end end addEvent("random",true) addEventHandler("random",getRootElement(),DisappearPlayer) so that happens. 3,3,2,1,3,4,4 way I wanted it occurs. 3.1.2.4 or 3.2.3.1.3 in a way that the same n repeita then! Anyone know how to do?
  24. Good'm creating a tuning shop for my RPG server. most did not want to use files files to decrease the MB script ... so I had the idea of creating music using random using playSound3D URL .. but I have two errors. ERROR 1 = Table does not work. ERROR 2 = He is not changing the interior or the size of the element. can anyone point me a correct direction or point out the error in my script? Client Sid local URLMusics = { {'https://albireo1.sscdn.co/palcomp3/2/a/b/9/equipeinsanos-tribo-da-periferia-mussoumano-convida-6ec60699.mp3'}, {'https://japeto.sscdn.co/palcomp3/a/5/4/a/equipeinsanos-tribodaperiferia-carro-velho-ec4211d7-e7b4a010.mp3'} } function ShowDxMenuStartTuning() addEventHandler("onClientRender", root, DXMenuPrincipal) showCursor(true) PainelMenuPrincipal = true MusicTuning() end addEvent("ShowPainelMenuStartTuning", true) addEventHandler("ShowPainelMenuStartTuning", getRootElement(), ShowDxMenuStartTuning) function MusicTuning() local randomize = math.random ( #URLMusics ) local TuningSound = playSound3D('URLMusics[randomize]',1383,-22,1001,true) setSoundMaxDistance(TuningSound,50) triggerServerEvent("StartSond", root, TuningSound) end Server Sid DIMS___ = 1 function DimensionSond(TuningSound) setElementDimension(TuningSound,DIMS___) setElementInterior(TuningSound,1) setElementPosition(TuningSound,1383,-22,1001) DIMS___ = DIMS___ + 1 end addEvent("StartSond", true) addEventHandler("StartSond", getRootElement(), DimensionSond)
×
×
  • Create New...