Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/02/19 in all areas

  1. Events tutorial The reason why I created this topic, is that a lot of people are struckeling with them. In this tutorial I will only discus the very basic of them. If you want more, then there is a list of links at the end with more information. If I made any mistakes in the code, please let me know because I am not going to test every part. What are events? (basic description) Events are something custom added by MTA to make it easier to bring scripting(Lua) closer to our game. If we do not have events, then the only thing we can do is give instructions to our game. But our code will never detect changes in our game. The same question again: "So what are the events?" Events are a way to communicate changes in our game to our scripts (or from our scripts). So for example my little ped(cat) gets ran over by a car. Then I really want to know about that, don't I? When an event activates, I describe this as: triggered (from the word trigger) Full wiki information can be found here: Event_system Before we can use events, what do we need to know? There are two things we need to know: The reason why it is triggered. <What happens?/when something happens?> In MTA this is the eventName of the event. (Example: you <ran over> my ped) Who is the one using the event? The event system in MTA is using elements as base (baseElement). This makes it easier to combine the what/when happens? with the one who is related to it. In MTA this is the source of the event. (Example: you ran over my <ped>) Trigger an event A scripting example: (this is not an official event) local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped triggerEvent("onPedRanOver", ped) In this example, a custom event gets triggered to tell you that my new created ped has been ranOver. The eventName is "onPedRanOver" and the baseElement is ped. local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) In this SERVERSIDE example, I am also adding an extra argument drunkDriver to use the player that ran over the ped. This is not required, but it makes it more complete. See syntax. Syntax bool triggerEvent ( string eventName, element baseElement, [ var argument1, ... ] ) TriggerEvent Receiving triggers Receiving triggers is a bit more complicated, because there are a lot of options for it. You can receive events by listening to them. It is like: You know that something is going to happen but you do not know when. The first step that you have to take is related to this question: "Do I want to receive a custom or not custom event?" Custom events are self created events. They only exist when a scripter makes them. Two lists of NOT CUSTOM EVENTS but default MTA events, serverside and clientside: Server_Scripting_Events Client_Scripting_Events Do I want to receive a CUSTOM event? In case of a custom event, you have to register/enable it first. If you do not enable it and trigger it, you will receive a warning/error about that in your debug console. Syntax bool addEvent ( string eventName [, bool allowRemoteTrigger = false ] ) AddEvent The example below, shows you how to enable a custom event only for trigger events within the same server/client side. addEvent("eventName") -- Is the same as: addEvent("eventName", false) If you put the second argument to false or not fill it in, this means that you can't communicate from the other server/client-side. This option is most likely used for security reasons. Some events shouldn't be able to trigger by the other side For example, worst case scenario: (remote events enabled for a default MTA event) Serverside code: addEvent("onPlayerWasted", true) Clientside code: triggerServerEvent("onPlayerWasted", player, 0, localPlayer, 0, 9, false) OnPlayerWasted If this event is enabled for remote trigger events, then it might be possible to cheating kills/deaths score. Of course, it is not likely that players can run their own clientside code, but it is not impossible in case of not trust able community resources. Enable a custom event for trigger events that crossing sides (From clientside to serverside. From serverside to clientside). addEvent("eventName", true) This event can now be used by remote trigger event functions. See list: Client to server TriggerClientEvent TriggerLatentClientEvent Server to client TriggerServerEvent TriggerLatentServerEvent Enable the event from our previous example: addEvent("onPedRanOver", false) local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) If you do not use cross triggering, then I recommend to use the addEvent function in the same resource as where you are going to trigger from. This makes sure that the event is already added and that you will never receive this kind of error/warning "Event isn't added". If you put it in another resource which hasn't started yet, then after triggering you would still receive that error/warning. Start listening The next step is to add the addEventHandler. This function is used to listen to events. When an event is triggered, this handler(addEventHandler) will call the function you have attached to it, in MTA this function is called the handlerFunction. Syntax bool addEventHandler ( string eventName, element attachedTo, function handlerFunction [, bool getPropagated = true, string priority = "normal" ] ) AddEventHandler Resource 1 addEvent("onPedRanOver", false) local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) Resource 2 function handlerFunction () end addEventHandler("onPedRanOver", root, handlerFunction) The first 3 arguments, the require ones: eventName attachedTo handlerFunction Making sure that the addEventHandler options are correct set-up. Resource 1 addEvent("onPedRanOver", false) local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) Resource 2 function handlerFunction () end addEventHandler("onPedRanOver", root, handlerFunction) There are two conditions for an eventHandler to call the handlerFunction. 1. The event has to be exactly the same. In this case the event "onPedRanOver" is the same in both resources. 2. In both functions, triggerEvent and addEventHandler is an element being used. This element has to be exactly the same. (from where you trigger as well as where you receive) <OR> The triggered element from resource 1, has to be a CHILD of the element in resource 2. The root element is the very top layer of the MTA element structure. It will accept all elements you want to use for your events. See the element tree: If you do not understand the element tree please read this page: Element_tree Source variable The source of an event is the element that triggers the event. This variable isn't passed as an parameter, but it is predefined. This means that it is already created before hand. Some predefined variables do only exist under special conditions. The source variable is one of those, it is a hidden and local variable which is only available when a function is called by an event. List of predefined variables. addEvent("onPedRanOver", false) -- local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) function handlerFunction (drunkDriver) iprint(source) -- ped element end addEventHandler("onPedRanOver", resourceRoot, handlerFunction) In this example the ped is the source. See how those two code blocks are connected: addEvent("onPedRanOver", false) -- local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) function handlerFunction (drunkDriver) iprint(source) -- ped element end addEventHandler("onPedRanOver", resourceRoot , handlerFunction) resourceRoot In some examples, you see people use the resourceRoot instead of the root element for their addEventHandlers. The resourceRoot is an element created by a resource. This element holds all elements of that resource as (in)direct children. In the example above, the resourceRoot as baseElement will not work, because there are two resources. Each resource has it's own resourceRoot element. The resourceRoot is accessible with the same keyword: resourceRoot, but if you were to inspect the element in multiple resources, then the user data (element identifier) value is not the same. outputChatBox(inspect(resourceRoot)) If we were to put everything in one resource, then it would work: ? addEvent("onPedRanOver", false) -- function handlerFunction () end addEventHandler("onPedRanOver", resourceRoot, handlerFunction) -- local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) In case of remote triggering, the resourceRoot in serverside and clientside is considered the same.(As long as they are part of the same resource) Why/when would we use resourceRoot? 1. Limit eventHandlers to the resource elements If you have 1000 markers in your server. One of the resources is for example a trucker mission, where you can get money by hitting markers. The resourceRoot element will make sure that the onMarkerHit event will only trigger for markers created by that resource. addEventHandler("onMarkerHit", resourceRoot, function () -- source element is the marker end) OnMarkerHit 2. Another benefit is that you are able to re-use the same eventNames. Resource 1 addEvent("onPedRanOver", false) function handlerFunction () end addEventHandler("onPedRanOver", resourceRoot, handlerFunction) -- local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) Resource 2 addEvent("onPedRanOver", false) function handlerFunction () end addEventHandler("onPedRanOver", resourceRoot, handlerFunction) -- local ped = createPed( 120, 5540.6654, 1020.55122, 1240.545 ) -- my ped local drunkDriver = getRandomPlayer() triggerEvent("onPedRanOver", ped, drunkDriver) These two resources do use the same event, but will not trigger each other their addEventHandlers. Warning: If root was used, then they will!!!! ;@ Lets cross triggering with resourceRoot! Clientside triggerServerEvent("example", resourceRoot) Serverside addEvent("example", true) -- second argument is true! cross triggering enabled! addEventHandler("example", resourceRoot, function () end) getPropagated In this bigger example we will be talking about the option getPropagated. If this option is disabled, it will not detect children any more. Keep reading! After that start code scanning from A, to B and then to C. Syntax addEventHandler bool addEventHandler ( string eventName, element attachedTo, function handlerFunction [, bool getPropagated = true, string priority = "normal" ] ) Example: Clientside -- A triggerServerEvent("onClientPlayerLoaded", resourceRoot) -- trigger an event to serverside --------------------------------------- -- C addEvent("onResponseServer", true) -- first listener addEventHandler("onResponseServer", resourceRoot, function () outputChatBox("getPropagated enabled") end, true) -- getPropagated true by default. -- second listener addEventHandler("onResponseServer", resourceRoot, function () outputChatBox("getPropagated disabled") end, false) -- getPropagated is false. Serverside -- B addEvent("onClientPlayerLoaded", true) -- second argument is true! cross triggering enabled! addEventHandler("onClientPlayerLoaded", resourceRoot, function () --[[ client is a predefined variable, which represents the client/player that communicates with the server More information about predefined variables: https://forum.multitheftauto.com/topic/33407-list-of-predefined-variables/ ]] triggerClientEvent(client, "onResponseServer", resourceRoot) -- first trigger event local element = createElement("randomElement") -- making a randomElement triggerClientEvent(client, "onResponseServer", element) -- second trigger event end) How does this this code works? A. When a client his code has been started, it will execute a triggerServerEvent. (It doesn't wait for any other clientside files to be loaded) B. The server receives the event. And sends two triggerClientEvents back: The first one is using the resourceRoot as baseElement. The second one is using a randomElement as baseElement. Both are using the event "onResponseServer" C. There are two addEventHandlers listening to the event: "onResponseServer" The first one is using getPropagated and the second one is not using getPropagated. The randomElement that is created, is by default an indirect child of the resourceRoot of the same resource. What will happen? When firing the first trigger event, both listeners will call their handlerFunction. But when firing the second trigger event, only the first listener will call it's handlerFunction. The randomElement is an indirect child of resourceRoot, but because getPropagated is disabled it will not call it's handlerFunction. Other tutorials related to this one: See also this tutorial about deeper limiting event ranges within your resource and reducing addEventHandlers https://forum.multitheftauto.com/topic/100069-tut-addeventhandler-on-a-group-of-elements-small-tutorial/ More information Full wiki information: Event_system A list of more information about triggering events: (Client to client / server to server) TriggerEvent Client to server TriggerClientEvent TriggerLatentClientEvent Server to client TriggerServerEvent TriggerLatentServerEvent A list of more information about receiving events: AddEvent AddEventHandler RemoveEventHandler Two lists of MTA events, serverside and clientside: (warning: not custom events) Server_Scripting_Events Client_Scripting_Events Cancel events CancelEvent WasEventCancelled (warning: custom events ONLY) GetCancelReason (Server only) Cancel latent events and their status GetLatentEventHandles CancelLatentEvent GetLatentEventStatus
    4 points
  2. Presented By (Previously J Series) With more than 3 years of work I decided to publicly release my map conversions, I had dropped my previous listings due to some "Issues" however, they're back. ---------------------------------------------------------------------------------------------- Download Streaming Quality - 8/10 Get's the job done, awesome all around, but some places are better than others ---------------------------------------------------------------------------------------------- Download Streaming Quality 7/10 Beats VC in other places, very poor in others; as well as a huge FPS drop in the first island (Issues are rockstars fault) ---------------------------------------------------------------------------------------------- Download Streaming Quality 9/10 Beats both VC and LC ---------------------------------------------------------------------------------------------- Vehicle testing gridmap Download Streaming Quality 10/10 Perfecto ---------------------------------------------------------------------------------------------- Download Streaming Quality 7/10 Decent all around Might be a tad laggy due to the high poly and Russian nature of this map Extremely detailed for a user created map ------------------------------------------------- Download (Coming soon) streaming quality 10/10 Very light weight ------------------------------------------------- MTA-Stream MTA-Stream a new lightweight streamer promising near instant load times and better streaming Post any bugs here Or here Questions or discussions can be either posted in this topic or here --- If you would like to support my work, please donate encourages me to make good updates. https://www.paypal.me/BlueJayL
    1 point
  3. Hey, after a long time I am releasing a newer version of this Multigamemode. You can find it on Github. Some Features: - Create as many arenas as you like by just calling a simple function providing a name and other properties. - Allow players to create their own arenas, in which they are automatically added as an admin for their arena. These custom arenas are destroyed the moment everyone has left them. - Use the Training button to train every map available on the server. - Common features like respawn, rewind, cp/tp etc. to help practising maps. - Custom ACL system: Each arena has their own acl file, yet you still can define global admins in the usual server acl. - A few maps have been included to make it easier to test and show the way how maps have to be organized. A little screenshot of the Lobby: More Screenshots can be found on Github for now. In order to use this Multigamemode, you will have to follow a quick instruction: Some of you might have seen this Multigamemode on the DDC server. This is a slightly different version from what we use on DDC. It excludes a few resource such as Userpanel or Stats, as they rely on our MySQL database and therefore cannot be shared so easy. Also, you will have to change the way Login works, if you want to login using an account of the mta server or remotely by using a website. Right now you can only login with an account on the ddc forum, as most people are gonna change the login to what they need anyway. Not everything is done in the best way and I would probably do some things differently now, but it works quite good and might be a good base for people to start their own project. If you want to contribute, you can create a pull request on Github. Bonsai
    1 point
  4. سلام عليكم ورحمة الله تعالى وبركاته كيفكم ياحلوين من زمان عنكم والله حبيت أخبر كل شخص يحبني .. إني راجع للبرمجة وراح انزل كل مود حصري بسويه بـ يدي ونقول ولكم باك يـ فخامة ؟؟
    1 point
  5. صحيح , السطر رقم 4 في الكود الثاني من ردي , خطأ مطبعي شكراً لك
    1 point
  6. thx! Lots of after editing ? pfff pfff fff Will add some missing content later.
    1 point
  7. A wonderful explanation as usual
    1 point
  8. It always returns false server-side. Bug report here.
    1 point
  9. Valeu pela explicação, @MaligNos. Realmente era necessário aumentar o valor do iBands, também fiz uma modificação que não entendi muito bem o porquê que isso fez dar certo. Removi a função matemática 'math.sqrt', deixei apenas o fft[ 1 ] * largura_máxima_da_imagem. Agora o código tá dessa forma: -- // rodapé - ícone do auto-falante if ( theSound ) then local fft = getSoundFFTData( theSound, 2048, 512 ); if ( fft ) then rot = rot + 8; local h = fft[ 1 ] * 20; if ( h > 0 ) then dxDrawImage( sX + 180 - ( h / 2 ), sY + panel_size[ 2 ] - 65 - ( h / 2 ), 12 + ( h ), 12 + ( h ), "images/speaker.png", rot ); end end end Nem mesmo uma voz ou ruído faz a imagem do auto-falante aumentar, apenas quando há batida. Esses negócios são loucos, mas pelo menos consegui entender de certa forma. @EDIT: Usei essa mesma linha de raciocínio em um shader no veículo, pra deixar a opacidade da cor mais forte e deu super certo. Quando dá uma batida, a cor fica mais forte, ao contrário fica com menos opacidade. Também consegui realizar alguns algoritmos para os DVOs.
    1 point
  10. Mas a questão não vai ser > Como saber quais frequências vai ser necessário remover para chegar ao som ideal? Ou seja, apenas batidas. Eu sou um leigo nesse assunto também, posso estar dando informação errada, mas acho que pra isso, você vai precisar pegar todas essas frequências e fazer uma análise para julgar aquelas que não fazem parte da batida. E isso não se resume em frequências altas e baixas - cada frequência reproduz certo som (foi o que entendi lendo um pouco sobre o assunto). Acho que fazer isso de uma forma 100% efetiva pra todos sons é quase impossível, se for para ajustar alguns sons/músicas especificas pode ser mais fácil pra quem não é expert no assunto. Embora tudo isso possa ser mais fácil do que eu imagino, já que hoje em dia encontra-se de tudo na internet xd
    1 point
  11. Thank you, i'll try it out soon.
    1 point
  12. Dei uma lida na wiki e vi que ele já ordena por frequência: da mais baixa, para a mais alta (de determinado quadro em execução do som): “A fast fourier transform generates a table of all the frequencies of the current audio frame which starts at the bass end of the spectrum to mids to highs in that order“ - by Wiki Possivelmente se você fizer isso: local tbl = getSoundFFTData ( som, 512 ) --retorna o total de samples/2 = 512/2 => 256 print(tbl[256]) Ele retornará o valor mais alto dessa amostra de 512 “faixas”. Agora, quando a gente define o iBands, se você usar um valor baixo, ex: 2, ele “junta” essas 512 faixas em apenas duas, e por isso dá essa “mistura” da batida com a voz, pois foram colocadas em um mesmo conjunto (possivelmente metade com frequência mais baixa, e outra com a mais alta). Se eu fosse você, eu tentaria aumentar o número de iBands e utilizaria esse valor definido para trabalhar apenas com as frequências mais altas. p.s. Existe a função getSoundWaveData que talvez dê também para usar.
    1 point
  13. Não creio que seja possível fazer isso. Pelo menos não por métodos comuns. Programadores experientes já tentaram fazer isso pra sincronizar luzes do cinema com o áudio do vídeo mas não conseguiram. Vc está tentando algo que somente gênios poderiam conseguir. -------------------------- Fui procurar na Wiki e encontrei isto: https://wiki.multitheftauto.com/wiki/GetSoundBPM Batidas por minuto, é isso que vc queria?
    1 point
  14. Isso não é minha área, não sei nem o que é iSamples ou iBands . Mas creio que com essas funções não tem essa separação de batida e voz, provavelmente seja por frequência/amplitude, ou seja, em diferentes sons tais valores serão alterados, não tendo um padrão específico para conseguir diferenciar a voz de uma batida. Imagino que para conseguir fazer o que quer, seja necessário estudar muito sobre acústica, além de deter conhecimento para conseguir implementar algum algoritmo bem complexo que faça essa identificação (ou encontrar algum).
    1 point
  15. I made this custom command for you as an example of what I'm saying: local anchoPantalla, largoPantalla = guiGetScreenSize() function obtenerPosicionVentana(ancho, largo) local x = anchoPantalla / 2 - ancho / 2 local y = largoPantalla / 2 - largo / 2 return x, y, ancho, largo end local tableItems = { 'item1', 'item2', 'item3' } local itemRow = 1 function createTable() local x, y, ancho, largo = obtenerPosicionVentana(400, 400) local windowItems = guiCreateWindow(x, y, ancho, largo, 'Example', false) local listItems = guiCreateGridList(0.04, 0.1, 0.4, 0.78, true, windowItems) local columnItems = guiGridListAddColumn(listItems, 'Items', 0.75) if (columnItems) then for _, item in pairs(tableItems) do local row = guiGridListAddRow(listItems, item) guiGridListSetItemText(listItems, row, columnItems, item, false, true) end end local btn = guiCreateButton(0.55, 0.1, 0.2, 0.1, 'Delete', true, windowItems) showCursor(true) itemRow = itemRow - 1 if #tableItems == 1 then itemRow = 0 end if itemRow == #tableItems then itemRow = itemRow - 1 end guiGridListSetSelectedItem(listItems, itemRow, 1, true) addEventHandler('onClientGUIClick', btn, function (boton, estado) if boton == 'left' and estado == 'up' then itemRow = guiGridListGetSelectedItem (listItems) itemRow = itemRow + 1 table.remove(tableItems, itemRow) local timer = setTimer(createTable, 100, 1) destroyElement(windowItems) end end, false) end addCommandHandler('items', createTable) THIS IS NOT A SOLUTION, JUST AN EXAMPLE.
    1 point
  16. ولكككم نوورت
    1 point
  17. If it is not looped or streamed, then it will destroy itself when it ends.
    1 point
  18. Eu também optaria por utilizar o formato JSON como mencionado pelo @DNL291 Mas segue um modo que talvez funcione da maneira que deseja: local vecPos = Vector3(unpack(split(datas[1]["Coordenadas"],", "))) spawnPlayer(player, vecPos:getX(), vecPos:getY(), vecPos:getZ())
    1 point
  19. Eu usaria from/toJSON para converter as coordenadas de uma tabela > string e vice-versa. Um exemplo no seu código: function loadUsuarios(player, acc) local accName = getAccountName(getPlayerAccount(player)) local datas = db:query("SELECT * FROM Usuarios WHERE Usuario=? LIMIT 1", accName) if (datas and type(datas) == "table" and #datas > 0) then -- @Datas local coordsTable = fromJSON( datas[1]["Coordenadas"] ) or { 0,0,0 } setElementData(player, "CRP:Skin", tonumber(datas[1]["Skin"])) setElementData(player, "CRP:Dinheiro", tonumber(datas[1]["Dinheiro"])) setElementData(player, "CRP:Coordenadas", datas[1]["Coordenadas"]) setElementData(player, "CRP:Interior", tonumber(datas[1]["Interior"])) setElementData(player, "CRP:Dimensao", tonumber(datas[1]["Dimensao"])) setElementData(player, "CRP:Procurado", tonumber(datas[1]["Procurado"])) iprint(datas[1]["Coordenadas"]) -- @Funções setCameraTarget(player, player) fadeCamera(player, true, 2.0) spawnPlayer(player, unpack( coordsTable ) ) setElementPosition(player, unpack( coordsTable )) setElementModel(player, tonumber(datas[1]["Skin"])) setPlayerMoney(player, tonumber(datas[1]["Dinheiro"])) setElementInterior(player, tonumber(datas[1]["Interior"])) setElementDimension(player, tonumber(datas[1]["Dimensao"])) setPlayerWantedLevel(player, tonumber(datas[1]["Procurado"])) else setCameraTarget(player, player) fadeCamera(player, true, 2.0) spawnPlayer(player, x2, y2, z2) setElementPosition(player, x2, y2, z2) local x, y, z = getElementPosition(player) local pos = toJSON( { x, y, z + 0.7 } ) db:exec("INSERT INTO Usuarios VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", getPlayerName(player):gsub("#%x%x%x%x%x%x", ""), accName, getPlayerSerial(player), getElementModel(player), getPlayerMoney(player), pos, getElementInterior(player), getElementDimension(player), getPlayerWantedLevel(player)) end end
    1 point
  20. 1 point
  21. Hallo, da ich ein angefangenes Zombie Apocalypse Script habe und es verkaufe möchte, dachte ich mir, ich biete es hier zum Verkauf an, da ich mit MTA nichtsmehr zutun habe. Das Script ist 100% Selfmade. Testserver: mtasa://54.38.22.45:22003 Das Script Beinhaltet: - Autokauf system - Tanksystem - Inventarsystem - Adminsystem - Register/login System - Kills/Tode System - Autorespawnsystem - VIP System - GUNshopsystem - Skinshopsystem - Logsystem - Downloadmanager - Achievmentsystem - Safezonsystem - Damagesystem - Hitmarkersystem - Levelsystem - Spielstundensystem Preis: 60€ PSC/Paypal
    0 points
×
×
  • Create New...