Jump to content

Search the Community

Showing results for tags 'trigger'.

  • 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 14 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. Im working on a script wich create flames on the Thrusters of a vehicle (Mammoth Thruster of GTA Online), works well if you are the only that has a Thruster, but if someone also has a Thruster and gets out the vehicle, your Thruster will keep the attached elements and will not destroy the flames if you get out of the vehicle: Here is a video of what is happening: https://www.youtube.com/watch?v=Q3z9fdnBG0w and serverside and clientside scripts that are involved Serverside: (Functions for creating the flames) function LightOn(vehicle, x, y, z) if thePlayer ~= localPlayer then return end light = createMarker ( x , y , z, "corona", 0.5, 255, 160, 0, 170 ) attachElements(light, vehicle, 0, -0.3, -0.8) end addEvent("lighton", true) addEventHandler("lighton", getRootElement(), LightOn) function LightOff() if thePlayer ~= localPlayer then return end if light then destroyElement(light) end end addEvent("lightoff", true) addEventHandler("lightoff", getRootElement(), LightOff) function ThrustersOn(vehicle, x, y, z) if thePlayer ~= localPlayer then return end superhitbox = createObject (3471, x , y , z) setElementAlpha(superhitbox, 0) firethrustl = createObject (2031, x , y , z) firethrustr = createObject (2031, x , y , z) attachElements(superhitbox, vehicle, 0, -10, -1) attachElements(firethrustl, vehicle, 0.47, -0.4, -0.2) attachElements(firethrustr, vehicle, -0.47, -0.4, -0.2) setElementCollisionsEnabled(firethrustl, false) setElementCollisionsEnabled(firethrustr, false) end addEvent("thrusterson", true) addEventHandler("thrusterson", getRootElement(), ThrustersOn) function ThrustersOff() if thePlayer ~= localPlayer then return end if not firethrustl then return end destroyElement(firethrustl) destroyElement(firethrustr) end addEvent("thrustersoff", true) addEventHandler("thrustersoff", getRootElement(), ThrustersOff) Clientside: (Functions that triggers serverside events when you are in the Thruster) Thruster = 465 function SitOnThruster(thePlayer) if thePlayer ~= localPlayer then return end local vehicle = getPedOccupiedVehicle(localPlayer) if ( vehicle and getElementModel (vehicle) == Thruster ) then bindKey("vehicle_fire", "down", shootProjectile) triggerServerEvent ( "onthruster", resourceRoot) local x, y, z = getElementPosition(vehicle) local h, m = getTime() triggerServerEvent("thrusterson", getRootElement(), vehicle, x, y, z) if h > 20 then triggerServerEvent("lighton", getRootElement(), vehicle, x, y, z) else return end end end addEventHandler ( "onClientVehicleEnter", root, SitOnThruster ) function Notsit(thePlayer) if thePlayer ~= localPlayer then return end if Thruster then triggerServerEvent("thrustersoff", getRootElement(), vehicle, x, y, z) triggerServerEvent("lightoff", getRootElement(), vehicle, x, y, z) else return end end addEventHandler ( "onClientVehicleExit", root, Notsit ) function killed() if Thruster then if (isPedInVehicle(localPlayer) and Cars[getElementModel(getPedOccupiedVehicle(localPlayer))]) then if getPedOccupiedVehicleSeat ( localPlayer ) == 1 then return end triggerServerEvent("thrustersoff", getRootElement(), vehicle, x, y, z) triggerServerEvent("lightoff", getRootElement(), vehicle, x, y, z) else return end end end addEventHandler ( "onClientPlayerWasted", localPlayer, killed ) function shootProjectile() if not disparado then local vehicle = getPedOccupiedVehicle(localPlayer) if ( vehicle and getElementModel (vehicle) == Thruster ) then if isVehicleOnGround(vehicle) == false then local x, y, z = getElementPosition(vehicle) projectile = createProjectile(vehicle, 15, x, y+4, z-10) disparado = true setTimer ( function() disparado = false end, 1500, 1 ) else local x, y, z = getElementPosition(vehicle) createProjectile(vehicle, 15, x, y, z-3) disparado = true setTimer ( function() disparado = false end, 1500, 1 ) end end end end I'm very confused, i'm trying to make the script only create element for each player.
  3. Hey guys please help!!! I have been researching and researching for almost 8 hours now. And I am just stuck as to what I am fundamentally getting wrong here. Main goal: I would like when the person gets into a vehicle, read the license plates, send plates to the server, read a table in the DB, then send info from table back to the client to use in other functions. What works: I am OK server side, I am able to read from the database and pass that back to the client, but can only trigger server side with a RegisterCommand. Issue: Client side, when I start using triggers inside of an if statement it stops working, (yes I am sure conditions are met). I am currently only able to trigger the server function with a register command, when I try to send a trigger from the client to the server, it will not launch the server function. Working code: client.Lua RegisterNetEvent("servertest:output_status") --from server.Lua AddEventHandler("servertest:output_status", function(argument) TriggerEvent("chatMessage", "[Success]", {0,255,0}, argument) TriggerEvent("servertest:vehStatus", argument) end) Citizen.CreateThread(function() while true do Citizen.Wait(1000) local playerPed = GetPlayerPed(-1) if IsPedInAnyVehicle(playerPed, false) then AddEventHandler("servertest:vehStatus", function(vehstatus) TriggerEvent("chatMessage", "[LOOP]", {0,255,0}, vehstatus) end) end end end) server.Lua: RegisterCommand("get", function(source, args) --I dont want to trigger this way, I want to trigger from client side MySQL.Async.fetchAll('SELECT * FROM vehicle_data WHERE plate = @plate', { ['@plate'] = "TSTPLATE1" }, function(result) if result[1] then local vehstatus = result[1].status TriggerClientEvent("servertest:output_status", source, vehstatus) cb(true) else cb(false) end end) end) What I want to do: client.Lua: RegisterNetEvent("servertest:output_status") --from server.Lua AddEventHandler("servertest:output_status", function(argument) TriggerEvent("chatMessage", "[Success]", {0,255,0}, argument) --never receive message TriggerEvent("servertest:vehStatus", argument) --not used now, save for later use end) Citizen.CreateThread(function() while true do Citizen.Wait(1000) local playerPed = GetPlayerPed(-1) if IsPedInAnyVehicle(playerPed, false) then local playerVeh = GetVehiclePedIsIn(playerPed, false) local vehPlates = GetVehicleNumberPlateText(playerVeh) TriggerServerEvent("servertest:sendInfo", vehPlates) --this trigger never happens even though criteria is met end end end) server.Lua: RegisterNetEvent("servertest:sendInfo") AddEventHandler("servertest:sendInfo", function(plates) MySQL.Async.fetchAll('SELECT * FROM vehicle_data WHERE plate = @plate', { ['@plate'] = plates }, function(result) if result[1] then local vehstatus = result[1].status TriggerClientEvent("servertest:output_status", source, vehstatus) cb(true) else cb(false) end end) end) I guess maybe what I need to know is just how to trigger something server side from the client side without using a RegisterCommand. I don't know how to structure it in my code, do I need to do it outside the while loop? I've tried but haven't been successful.
  4. Scrolling through the tutorials, I found a script that displays players in the server when joining and quitting. function playerCount ( ) outputChatBox("#ff8800[server]: #ffffffPlayers: #ffffff(" .. getPlayerCount() .. "#ffffff)" , root, 255, 0, 0, true) end addEventHandler ( "onPlayerJoin", getRootElement(), playerCount ) addEventHandler ( "onPlayerQuit", getRootElement(), playerCount ) What would I have to add to trigger it with a command, such as "/players"?
  5. I am done. I've made a function to display text on elements, on server-side, and I wanted to trigger client event, but what? Doesn't triggering. Look: allElems = 0 function dxDrawTextOnElem(element, text, height, distance, r, g, b, alpha, size, font) allElems = allElems + 1 triggerClientEvent("dxDraw", resourceRoot, element, text, height or 0, distance or 20, r or 255, g or 0, b or 0, alpha or 255, size or 1, font or "arial", allElems) end Boom, client-side script: --Ofcourse, I've created all tables + in "onClientRender" I put outputChatBox(), outputs "{}" (because tables are empty) addEvent("dxDraw", true) addEventHandler("dxDraw", resourceRoot, function(element, text, height, distance, r, g, b, alpha, size, font, k) local i = table.find(elements, element) --table.find(pattern, s) if i then elements[i] = element texts[i] = text heights[i] = height distances[i] = distance rs[i] = r gs[i] = g bs[i] = b alphas[i] = alpha sizes[i] = size fonts[i] = font else elements[k] = element texts[k] = text heights[k] = height distances[k] = distance rs[k] = r gs[k] = g bs[k] = b alphas[k] = alpha sizes[k] = size fonts[k] = font end end) addEventHandler("onClientRender", root, function() for i, text in ipairs(texts) do dxDrawTextOnElement(elements[i], text, heights[i], distances[i], rs[i], gs[i], bs[i], alphas[i], sizes[i], fonts[i]) end end) Jesus, I'm done with it. Sorry for asking a similar thing, but it's really difficult for me. For real, I'm like doing it second time, still fails.
  6. Как правильно триггерить на сервер? У меня есть вот такая функция function ClickSclad(botao, state) if botao == "left" and state == "down" then if sklad.visible then if cursorPosition(570, 274, 227, 27) then triggerServerEvent("GiveWeaponeAndArmor", getLocalPlayer(), "Nightstick") elseif cursorPosition(570, 311, 227, 27) then triggerServerEvent("GiveWeaponeAndArmor", getLocalPlayer(), "Deagle") elseif cursorPosition(570, 348, 227, 27) then triggerServerEvent("GiveWeaponeAndArmor", getLocalPlayer(), "Shotgun") elseif cursorPosition(570, 385, 227, 27) then triggerServerEvent("GiveWeaponeAndArmor", getLocalPlayer(), "MP5") elseif cursorPosition(570, 422, 227, 27) then triggerServerEvent("GiveWeaponeAndArmor", getLocalPlayer(), "M4") elseif cursorPosition(570, 459, 227, 27) then triggerServerEvent("GiveWeaponeAndArmor", getLocalPlayer(), "Armor") elseif cursorPosition(707, 508, 85, 23) then showCursor(false) removeEventHandler("onClientRender", root, wnd_sklad) sklad.visible = false end end end end addEventHandler("onClientClick", getRootElement(), ClickSclad) и вот function GiveWeaponeSklad (source, inf) if inf == Deagle then giveWeapon( source, 24 ) setWeaponAmmo( source, 24, 100 ) setPedWeaponSlot ( source, 2 ) elseif inf == Nightstick then giveWeapon( source, 3 ) setPedWeaponSlot ( source, 1 ) elseif inf == Shotgun then giveWeapon( source, 25 ) setWeaponAmmo( source, 25, 100 ) setPedWeaponSlot ( source, 3 ) elseif inf == MP5 then giveWeapon( source, 29 ) setWeaponAmmo( source, 29, 300 ) setPedWeaponSlot ( source, 7 ) elseif inf == M4 then giveWeapon( source, 31 ) setWeaponAmmo( source, 31, 300 ) setPedWeaponSlot ( source, 7 ) elseif inf == Armor then setPedArmor( source, 100 ) end end addEvent("GiveWeaponeAndArmor", true) addEventHandler("GiveWeaponeAndArmor", getRootElement(), GiveWeaponeSklad) И у меня в дебаге пишет, что 1 аргумент, допустим в Armor, got string 'Armor'. То есть у меня не получается правильно триггернуть на сервер. Заранее спасибо, надеюсь объяснил понятно
  7. My question is how to send a data to the server in a personal way with the client, that is, without including all the clients. Client side function AAB (pia) triggerServerEvent ("KnowAmount", getLocalPlayer(), pia ) end --====================================================================== Server Side function KnowAmountFunction (pia) outputChatBox ("AA") -- This show ALL Client, and that's what I want to avoid if (pia == 1) then PasajENP = PasajENP_a1 -- This change for all players, and it should not be like that triggerClientEvent (client, "GotoClient", resourceRoot, PasajENP ) end end addEvent( "KnowAmount", true ) addEventHandler( "KnowAmount", getRootElement(), KnowAmountFunction )
  8. Hi guys,im stuck here... I want when i press on GUIEditor.button[1] it sends that i typed in GUIEditor.edit[1] to selected player.. --client GUIEditor = { edit = {}, button = {}, window = {}, label = {}, gridlist = {} } addEventHandler("onClientResourceStart", resourceRoot, function() local screenW, screenH = guiGetScreenSize() GUIEditor.window[1] = guiCreateWindow((screenW - 528) / 2, (screenH - 183) / 2, 528, 183, "dm panel - gat", false) guiWindowSetSizable(GUIEditor.window[1], false) GUIEditor.gridlist[1] = guiCreateGridList(29, 32, 186, 142, false, GUIEditor.window[1]) local column = guiGridListAddColumn(GUIEditor.gridlist[1], "players", 0.9) GUIEditor.button[1] = guiCreateButton(247, 107, 271, 60, "DM", false, GUIEditor.window[1]) guiSetProperty(GUIEditor.button[1], "NormalTextColour", "FFAAAAAA") GUIEditor.edit[1] = guiCreateEdit(247, 32, 269, 65, "", false, GUIEditor.window[1]) GUIEditor.label[1] = guiCreateLabel(216, 63, 31, 15, "close", false, GUIEditor.window[1]) for id, player in pairs(getElementsByType("player")) do local row = guiGridListAddRow ( GUIEditor.gridlist[1]) guiGridListSetItemText ( GUIEditor.gridlist[1], row, column, getPlayerName ( player ), false, false ) guiSetVisible(GUIEditor.window[1], false ) end end ) function show () if guiGetVisible(GUIEditor.window[1] ) then guiSetVisible(GUIEditor.window[1], false ) showCursor (false) else guiSetVisible(GUIEditor.window[1], true ) showCursor (true) end end addCommandHandler("dm", show) function clickin () if source == GUIEditor.label[1] then guiSetVisible(GUIEditor.window[1], false ) showCursor (false) elseif source == GUIEditor.button[1] then if guiGetText(GUIEditor.edit[1] ) == "" then return end --im stoped here, showCursor (false) guiSetVisible(GUIEditor.window[1], false ) end end addEventHandler("onClientGUIClick", root, clickin)
  9. I made an script that make staffs can open an panel by using /dm then choose a player and type a message then send it... But my problem is i don't know how to trigger this to put this code in server side outputChatBox(msg, selectedplayer, 255, 255, 255, true) I mean to send the message to selected player only... client variables: msg = guiGetText(editbox) selectedplayer = guiGridListGetSelectedItem(gridlist) Help pls
  10. Al momento de dirigir un dato al servidor funciona todo bien, el caso es cuando al modificar ese valor y devolverlo otro con ClientTrigger, no funciona o por alguna razón no se activa. Client Side (NOTA: La function greetingHandler, el outputChatBox no aparece) function greetingCommand ( Parada01_Ramal_a ) if timer then killTimer(timer) timer = nil end if (actualspeed) <= 20 then veh = getPedOccupiedVehicle( localPlayer ) outputChatBox ("Disponibilidad:" ,255,0,0, true); outputChatBox (DispPasajeros ,255,0,0, true) triggerServerEvent ( "onGreeting", resourceRoot, DispPasajeros ) ---La disponibilidad es el valor que modifico en el servidor end end function greetingHandler ( PasajSuben ) ---Pasajeros Suben, es el valor modificado gracias a la disponibilidad (Y que necesito de vuelta en cliente) CantPasajeros = CantPasajeros + PasajSuben --- Sumo al total con ese dato outputChatBox ("CantidadNueva:" ,255,0,0, true); outputChatBox (CantPasajeros ,255,0,0, true) end addEvent( "onGreeting2", true ) addEventHandler( "onGreeting2", localPlayer, greetingHandler ) Server Side (NOTA: La idea era que con el ELSE que verán a continuación ya devuelva el dato, pero no encontraba la forma de hacerlo) ¿habría una forma de integrar el trigger a la func Parada_58_a_1? function Parada_58_a_1 (DispPasajeros) if (PasajENP_a_1 > 0) and (DispPasajeros > 0) then DispPasajeros = DispPasajeros -1 PasajENP_a_1 = PasajENP_a_1 -1 PasajSuben = PasajSuben +1 outputChatBox ("Pasajeros que suben: " .. PasajSuben, client) outputChatBox ("Pasajeros Disponibles: " .. DispPasajeros, client) setTimer ( Parada_58_a_1, 1000, 1, DispPasajeros) else outputChatBox ("Pasajeros Nuevos Disponibles: " .. DispPasajeros, client) timer = setTimer (greetingCommand, 500, 1, PasajSuben) --Pasa a la otra func, para realizar el Trigger Client end end addEvent( "onGreeting", true ) addEventHandler( "onGreeting", resourceRoot, Parada_58_a_1 ) function greetingCommand ( playerSource, commandName ) local playerSource = getPlayerName( playerSource ) triggerClientEvent ( "onGreeting2", playerSource, PasajSuben ) --Aca es el dato que se pasa a Cliente outputChatBox ("Pasajeros que suben: " .. PasajSuben, client) end Gracias!
  11. Eae pessoal. Estou com uma dúvida rápida aqui. Estou fazendo um sistema de level, nesse sistema existe um verificador server-side que verifica todos os jogadores a cada 1 segundo procurando por players AFK para pausar o Up do level. Até então sem problemas, mas estou querendo colocar o tempo do up de cada jogador aparecer na tela deles, qual procedimento a seguir é MAIS LEVE para fazer isso? cria uma variável, salva o tempo nela e triggerClientEvent a cada 1 segundo, para enviar essa variável atualizada ao cliente. setElementData no jogador a cada 1 segundo, então o client irá sempre mostrar essa data na tela dele. setAccountData no jogador a cada 1 segundo. [Já vi que é inviável fazer assim, até porque não há como receber esse valor client-side] fazer o próprio client calcular o tempo de up? A propósito, o timer em si é este: (server-side) No script client, deverá ter um onClientRender que deverá mostrar o playerLapsed ao jogador. (só que no client, irá formatar os milisegundos em minutos/segundos.)
  12. I tried several ways to make the communication between client and server, but I can not get to the shop that I am armed, my idea is to make different curtains for groups, and each has a color, I can not get that when the person chooses the object who wants to buy, everyone can see the curtain that I would buy in a different color ... The other problem is how to keep it, it has me really disconnected, thank you for your attention. -- Client Side addEventHandler("onClientGUIClick", guiRoot, --VENTANA2 = CORTINAS > Completas > Turquesas function (player) local getGui = guiGetVisible(Ventana2) if source == Boton9a then triggerServerEvent("PonerCortina", localPlayer, localPlayer) PrecioCortinasCompletas = 3500 PrecioTotal = PrecioCortinasCompletas guiSetText(BotonTOTAL2, PrecioCortinasCompletas) local paintjobID = 1 end end) function addPaintjob2(paintjobID,player) if paintjobID == 1 then myTexture = dxCreateTexture( "cortinasRojas.png" ) elseif paintjobID == 2 then myTexture = dxCreateTexture( "cortinasAzules.png" ) else if player == getLocalPlayer() then outputChatBox ("There is no such paintjob ID!") return end end engineRemoveShaderFromWorldTexture ( shader_cars, "cortinas", getPedOccupiedVehicle(player) ) shader_cars, tec = dxCreateShader ( "shader.fx" ) engineApplyShaderToWorldTexture ( shader_cars, "cortinas", getPedOccupiedVehicle(player) ) dxSetShaderValue ( shader_cars, "TX0", myTexture ) end addEvent( "setShader", true ) addEventHandler( "setShader", getLocalPlayer(), addPaintjob2 ) Server-Side function Cortina1() local vehicle = getPedOccupiedVehicle( source ) if ( vehicle ) then local pos = {getElementPosition( vehicle )} Cortinapuesta = createObject( 1000, pos[1], pos[2], pos[3] ) attachElements( Cortinapuesta, vehicle, 0, 0, 0, 0, 0, 0 ) triggerClientEvent (players,"setShader",players,cortina) end end addEvent("PonerCortina", true) addEventHandler("PonerCortina", root, Cortina1)
  13. [Alright, first of all: I just joined the Forums, so if i do anything wrong, just tell me.] Ok, so i got a problem, it's about an event i want to trigger on a certain amount of zombie's, or on a certain timer, that's all fine and such.. But, i want to merge some event's into a resource called "zombies", like the 'onZombieWasted' event, but then for a seperated Event, What i mean with that is i want to have a new 'onNemesisWasted' event working together with the 'onZombieWasted', but they need to sync up with the (if possible exported) createZombie function from the "zombies" resource. And i am aiming to make it to a elementData trigger, that i locally created as for example: local Nemesis = export.zombies:createZombie(etc,etc..), So when i check for that element's data on the name 'Nemesis' by existence (as in: if ( isElement ( Nemesis ) ) then) and in combination on the 'onNemesisWasted'- event to check if that export of createZombie (ped works aswel) is dead or not, after all of that if the createZombie (ped) is actually dead, then i wan't it to trigger the reward system together with the other piece's of code. To clear out this idea and problem, i also recorded the ZTown Nemesis Event Script and also post the 2 main scripts that hold me from finishing the Nemesis: The Video of me, quickly explaining what, how, and showing the problem: "youtube" And the 2 script's, there both Server-Side, The Nemesis.lua is changed to test it's functionality and quick testing, but feel free to change the code and re-post it here to function with 'onNemesisWasted' additions!.. the first setTimer(function() is there to prevent complication problems from other zombie resource's and scripts, just delaying it for better run's. Also, the second setTimer(function() is just to delay it's Blip creation and Attaching to prevent the Blip not being attached to the createZombie named nemesis. Nemesis.lua (start/event): function nemesisON() setTimer(function() if ( not isElement ( Nemesis ) ) then local nemesis = exports.zombies:createZombie ( 2343, 57, 26.5, 90, 38, 0, 0, nemesis, 0, "hunting", true ) setPedHeadless(nemesis, true) exports.extrahealth:setElementExtraHealth ( nemesis, 150 ) setElementData ( nemesis, "nemesis", true ) setTimer(function() myBlip = createBlipAttachedTo ( nemesis, 23 ) outputChatBox ('#FFFFFF[#7CFC00ZTown#FFFFFF]: #00BFFF A #00FFFFNemesis #00BFFFHas been spawned inside ZTown! #FFFFFF(#7CFC00Nemesis Boss Event#FFFFFF)', root, 255, 255, 255, true) triggerClientEvent(root, "event", root, "start") end,2500,1) end end,2500,1) end addEventHandler ( "onResourceStart", getRootElement(), nemesisON) monemesi.lua (check/reward): addEvent ( "onNemesisWasted", true ) addEventHandler ( "onNemesisWasted", root, function ( killer ) if ( isElement ( Nemesis ) ) then givePlayerMoney(killer,math.random(5000,25000)) killer = getPlayerName(killer) destroyElement ( myBlip ) outputChatBox ('#FFFFFF[#7CFC00ZTown#FFFFFF]: #00BFFF The #00FFFFNemesis #00BFFFHas been killed! #FFFFFF(#7CFC00Nemesis-Boss Event#FFFFFF)', root, 255, 255, 255, true) triggerClientEvent(root, "event", root, "stop") end end ) I hope sombady could find a way to make this function correctly, because i have try'ed loads of ways, and the way to use slothbot together with zombies resource... nahh, won't work, they wil keep fighting together like d*cks. EDIT: if ( isElement ( Nemesis ) ) = nemesis, i already changed that, but right after i posted it, derp.. Gr.xboxxxxd
  14. BucketBull

    trigger

    hey guys! I want to make a carshop but i have to trigger a server side marker to client side. The problem is the marker is a part of a function. How shall i trigger the marker?
×
×
  • Create New...