Jump to content

IIYAMA

Moderators
  • Posts

    6,097
  • Joined

  • Last visited

  • Days Won

    218

Everything posted by IIYAMA

  1. You can also use the onClientRender event to load the textures one by one. To keep up the frame- rate, you can use getTickCount() function to delay the process even further. https://wiki.multitheftauto.com/wiki/OnClientRender https://wiki.multitheftauto.com/wiki/GetTickCount Have you ever considered using a map file? Loading map files is damn xxxxxxx fast in compare to create every single element with createObject. Take it or leave it. (of course this means that you will lose the ability to send specific maps to each client) local file = xmlCreateFile("saved.map", "map") if file then local mapRoot = createElement("map") setElementParent(createObject([[...]]), mapRoot) -- all your objects saveMapData ( file, mapRoot) xmlSaveFile ( file ) xmlUnloadFile ( file ) end https://wiki.multitheftauto.com/wiki/SaveMapData
  2. That would me sense. But the way you are using it now is very heavy work. Searching through all elements in the whole server. Would this not make more sense? (limiting to the resource only) for i, race in ipairs(getElementsByType('race', resourceRoot)) do -- do stuff here end This is even faster and has a better structure: -- server local raceContainer = createElement("raceContainer", "raceContainer") for i=1, 10 do setElementParent(createElement("race"), raceContainer) end (find one and access the rest) -- client local raceContainer = getElementByID("raceContainer") local raceElements = getElementsByType("race", raceContainer) -- search also through sub-elements -- or local raceElements = getElementChildren(raceContainer, "race") -- just the direct children (faster) for i, race in ipairs(raceElements) do -- do stuff here end Why bother making a race element? - You can let sub-elements hang on it. They will be deleted when you delete the parent. - Attach addEventHandlers to the parents of sub-elements. (which limits the event scope) - Limit the scope of element queries. (like: getElementsByType) - The benefit of having access to scoped propagation / inherits. -- server local raceContainer = createElement("raceContainer", "raceContainer") for i=1, 10 do setElementParent(createElement("race"), raceContainer) end setElementDimension(raceContainer, 50) (propagation / inherits is by default enabled: https://wiki.multitheftauto.com/wiki/SetElementCallPropagationEnabled)
  3. I am only using elementdata to share information globally or between resources(with sync disabled). If I want to get the title for within the resource, then I will get it from a variable. If I want to set the title within the resource, then I will save it in a variable. + If I want to show the title of the map on a client his screen, yes I will use elementdata as second method.
  4. -- server Race = {} Race.__index = Race addEventHandler("onResourceStart", resourceRoot, function () attachRaceClasses(Race) -- initial end) addEvent("testRaceClasses", true) addEventHandler("testRaceClasses", resourceRoot, function (raceElement) attachRaceClasses(raceElement) outputChatBox(raceElement:getTitle()) end, false) -- client Race = {} Race.__index = Race addEventHandler("onClientResourceStart", resourceRoot, function () attachRaceClasses(Race) -- initial local raceElement = Race.new() raceElement:setTitle("Sorata_Kanda") triggerServerEvent("testRaceClasses", resourceRoot, raceElement) end) -- shared function attachRaceClasses (race) function race.new() local self = setmetatable({}, race) self.title = 'Great 8-Track' self.laps = 10 self.element = Element('race', 'Race 1') self.checkpoint = Marker(...) self.checkpoint:setParent(self.element) self.element:setData('sourceobj', self) return self end function race:setTitle(string) self.title = string end function race:getTitle() return self.title end function race:getCheckpoint() return self.checkpoint end end Like this. Nothing special.
  5. IIYAMA

    coroutine

    A coroutine is a function block which can be frozen with: coroutine.yield() This function has to be called during the execution of the block. It doesn't have to be in the same block, but within the code that is executed in the block. The resume function can be called from where ever you want. It can be used to start the executing the coroutine function. But also to resume a frozen(yield) coroutine function. coroutine.resume(co) When a coroutine function has been executed till the end, the status of the coroutine function is considered dead. It can't be resumed any more.
  6. IIYAMA

    coroutine

    local co co = coroutine.create(function () *
  7. IIYAMA

    coroutine

    You can do that, but the coroutine has to be placed around this: -- couroutine function local id = querydb("SOME DB FUNCS") local result = getQueryResult(id) -- function something () local co = coroutine.create(function () local id = querydb(co, "query") local result = querydb(co, "query") end) coroutine.resume(co) -- start the coroutine end function querydb (co, query) -- ... local callBackFunction = function () coroutine.resume(co) -- resume! end -- execute the query here! coroutine.yield() -- freeze! return results end Something like that.
  8. IIYAMA

    coroutine

    This is not how you use coroutines. Databases and coroutines are two very different things. But for what kind of reason do you want to use a coroutines? dbQuery is already providing you with a callback option. https://wiki.multitheftauto.com/wiki/DbQuery Optional Arguments callbackFunction: An optional function to be called when a result is ready. The function will only be called if the result has not already been read with dbPoll. The function is called with the query handle as the first argument. (Notice: Do not use a function with a local prefix) If you want to improve your database performance, then write better queries with limiters.
  9. Nope, not 100%, a new instance of the table is already happening behind the scenes. A new instance will be created when: (there might be more) When the table leaves the resource (export or event system) When the table gets transferred from clientside <> serverside (event system) When a table is send as parameter with timer (< not many people are aware of this one, but for timers there isn't a feature that is suppose to keep the table out of the garbage collector. So they let the timer make a deep-copy of the table.) It might contain the same content, but it is not the same table. Creating the instance is done already, but re-attaching the classes to give it the full functionality back is the remaining work.
  10. Not being able to send functions is more than logic. Functions are bound to the blocks around it. But you could try to create a shared file with all classes in it. When sending a table over to the otherside the only thing left to do is putting the classes back in to the table.
  11. probably. But can't you just make exports? function Race:setTitle(string) self.title = string end -- export function function raceSetTitle (string) return Race:setTitle(string) end
  12. We are doing more or less the same. The main difference is that I am building a higher object tree. Technically tables in tables. The one of the race resource is just one layer. Example. clown = { animation = { sleep = function () end, dance = function () end }, movement = { run = function () end, walk = function () end, fly = function () end }, title = { set = function () end, get = function () end, remove = function () end } } A clown can do animations, movements and have a title. This example is used for single clown, without using the hidden variable self.
  13. Nope, I write it a bit different. I am still experimenting with it to be honest and I haven't found my style yet. See the client file of this resource: It is looks like JavaScripts with a few Immediate Function Invocation hacks...
  14. Yes that would indeed happen. There is no predefined variable, because each loaded map in a single resource has it's own mapRoot. See image: (there are two maps on one resourceRoot) Function to get it: https://wiki.multitheftauto.com/wiki/GetResourceMapRootElement You might also be able to get it with: https://wiki.multitheftauto.com/wiki/GetElementChildren Which only takes the direct children of an element. This will give you the root of all elements created by scripting: (No pre-defined variable for some unknown reason) https://wiki.multitheftauto.com/wiki/GetResourceDynamicElementRoot
  15. Yes it is indeed different and limited to an extend. I am using OOP for my code, but I am NOT using the MTA OOP classes which you might think is strange. The reason behind that is that I structure my code with OOP. The MTA OOP classes have nothing to do with with structuring the position of the code.
  16. yes, Unless: There is a wrapper in between. do local setElementData_ = setElementData function setElementData (...) -- hell happens here... setElementData_(...) end end Or this event is used: https://wiki.multitheftauto.com/wiki/OnElementDataChange Which is a async.
  17. You could also use the setElementDimension function on the map root element. Propagation calls down the element tree should be enabled for that element. https://wiki.multitheftauto.com/wiki/SetElementDimension https://wiki.multitheftauto.com/wiki/Element_tree
  18. setElementData on the race element, wouldn't change line 6, which sets a table value under the key "title". self.title = 'Great 8-Track' Is that not your issue?
  19. Download this resource and you will be able to find the texture names. https://wiki.multitheftauto.com/wiki/Shader_examples#Texture_names
  20. move line 1, in the healthshake function. The value of the variable `hp` doesn't change by itself. It has to be done every 500ms.
  21. I am very sure that you do not want to make a infinity loop. It is a very bad thing after all. This is an infinity loop: while true do end Never ending execution of code, which at the end gets abort because the game starts to freeze. And this is what you probably want: setTimer(function () end, 1000, 0) Executing the function once per second.
  22. IIYAMA

    Help DxText

    function getProgress( addtick, tick ) local tick = getTickCount() local tableMessages = {texto, r, g, b, tick} getProgress(5000, v[5]) By Attaching the tick data to the message.
  23. @JeViCo The syntax: bool fetchRemote ( string URL[, string queueName = "default" ][, int connectionAttempts = 10, int connectTimeout = 10000 ], function callbackFunction, [ string postData = "", bool postIsBinary = false, [ arguments... ] ] ) Problem 1 Always be called The callback function will always be called, even if there is an error. function myCallback( responseData, errno ) if errno == 0 then Problem 2 Execution order: Line: 1 local variable Line: 2 fetchRemote("http_stuff", Making a network request. Line: 6 Line: 7 print(variable) -- nil ------------------------------------------------------------------------------------------------- ---------- Waiting for the network request to be finished ---------- ------------------------------------------------------------------------------------------------- Line: 2 function(resp) Callback function will be called after a delay. The delay can be long or short, depending on the response. If not response, it will be called eventually with an error. connectTimeout: Number of milliseconds each connection attempt will take before timing out https://wiki.multitheftauto.com/wiki/FetchRemote Line: 3 variable = resp Line: 4 print(variable) -- OK Line: 5 end) Callback functions in combination with the network are always async. The code doesn't wait for these callback functions.
  24. @Sorata_Kanda The value [function] is a part of a class. Functions can't leave their resource environment. So it is impossible to export them while they are loaded. But you can send them over as unloaded code: local exportedFunctionValue = "Airplane = {} function Airplane:fly () end" loadstring(exportedFunctionValue)()
  25. I am also not using the MTA account system for players. As I want my database to be 100% complete + portable. If you are going to switch server, you need to move 2 databases. So I decided not do that. There were some unhappy staff players about it, as they had to login double... even so it felt like a valid decision. If you want to make use of the MTA's account system, the username is most of the time used as the primary key for both databases. Do you need the account system and ACL? The account system is useful for registering staff. The ACL is useful for setting the rights of for staff. The account system is making use of the ACL. Yes, unless you want to build up a whole `staff rights system` by yourself. Do you need it for players? No, unless you want players to use the /login and /register commands.
×
×
  • Create New...