Jump to content

IIYAMA

Moderators
  • Posts

    5,843
  • Joined

  • Last visited

  • Days Won

    160

Everything posted by IIYAMA

  1. See useful function getPedGender for getting the gender. https://wiki.multitheftauto.com/wiki/GetPedGender (getPedGender and getSkinGender) As for the skins table: local maleSkins = skins[1] -- returns a table print(maleSkins[1]) -- first male skin local femaleSkins = skins[2] -- returns a table print(femaleSkins[1]) -- first female skin
  2. Requiring a loop and a table. function generateRandomNumbers (count, maxSize) local randomNumbers = {} for i=1, count do randomNumbers[#randomNumbers + 1] = math.random(maxSize) end return randomNumbers end local randomNumbers = generateRandomNumbers(30, 10) -- Generate 30 random numbers. With a max value of 10 print(1, randomNumbers[1]) -- 1 <random number> print(5, randomNumbers[5]) -- 5 <random number> print(10, randomNumbers[10]) -- 10 <random number> print(30, randomNumbers[30]) -- 30 <random number>
  3. It is a bit tricky, but not impossible. And if the rotation is inverted, then invert the rotation. But yes, changing the engine is not possible, there will always be some limitations.
  4. Not sure, but this is how you can get the camera rotation: local cameraElement = getCamera() -- local x, y, z = getElementRotation(cameraElement) --
  5. onClientElementDataChange, that is if you do not mis use elementdata. For example setting element data every frame. If the event onClientElementDataChange is triggered more than ~5x each second (9 func calls x 1s vs ~2 func calls each update, 9 / 2 = ~5). The timer will be more optimised than the event. (9x with different element data key) But in general the timer has a slower update timing, which should also taken in consideration.
  6. I agree with XaskeL, clusters are the most efficient way of doing this. @Hydra Feel free to use this cluster library, which I am using for the airplane resource. Or find another library if the cells are too large, there should be more available. (this is size 31x31) local sourceMap = Cluster:new() --[[ SET ]] local cell = sourceMap:getCellFromWorldMap( x, y ) if cell then cell:setData( "key", "<mixing>" ) end --[[ GET using position ]] local centerCell = sourceMap:getCellFromWorldMap( x, y ) local cellCollection = sourceMap:getCellsBetweenCells( sourceMap:getCellFromSourceMap( centerCell.x - 1, centerCell.y - 1 ), sourceMap:getCellFromSourceMap( centerCell.x + 1, centerCell.y + 1 ) ) -- 9 cells returned (but can be less) -- LOOP: cellCollection cell:getData( "key" ) --
  7. For the resource servertimesync, I am using this method to solve that problem. 1. I am using the function getServerTime to get the time, if available. local timeNow = exports.servertimesync:getServerTime() 2. If it not available, then I am also listening to the event "onServerTimeInitialized", which is triggered when the data is available. addEventHandler( "onServerTimeInitialized", root, function() end )
  8. setElementDoubleSided(obj, true) https://wiki.multitheftauto.com/wiki/SetElementDoubleSided If the object is successful created, you can use this function to make the object doublesided.
  9. You can reduce this code btw, by disable caseSensitive. bool addCommandHandler ( string commandName, function handlerFunction [, bool caseSensitive = true ] ) addCommandHandler("buy", detectPanel, false) As for your initial question. local zones_CScns = {["Jefferson"] = true} local zones_GTcns = {["Rodeo"] = true} --- ... if zones_CScns[gps] then CScns() elseif zones_GTcns[gps] then GTcns() end or -- !Order matters local zones --- ... local theFunc = zones[gps] if theFunc then theFunc() else -- do something else... end -- ... functions CScns and GTcns here zones = {["Jefferson"] = CScns, ["Rodeo"] = GTcns}
  10. Like this. When adding a subscriber, the data will be automatic synced. Here you have a test resource to see the behaviour of all stages. Very recommended to test it out, so that you do not add too much code.
  11. Step 1: Find ALL existing slots This method does not do that unfortunately. So you will have to create a new one. local carrySlots = self:findExistingItemSlots(itemID) Step 2: Fill those up. Step 3: Create new slots for the remaining items. Repeat until is fine. repeat local slotX, slotY = self:findFreeSlotForItem(itemID) if slotX then local countInsert = math.min(count, itemDetails.stacklimit) -- ... local newItem = { ["itemID"] = itemID, ["count"] = countInsert, ["slot"] = {x = slotX, y = slotY}, } count = count - countInsert -- ... end until count == 0 or not slotX Step 4: Return the items that do not fit, so that you can decide what to do with those. local remainingItems = object:giveItem(1, 8) if #remainingItems > 0 then iprint("items do not fit", #remainingItems) end
  12. You are not finished in the slightest + a lot of edge cases to look at. The most significant optimisation will be applied when working with subscriber mode. This will stop sending element data to other players and only the ones that need it. On vehicle enter: addElementDataSubscriber(veh, "Fuel", thePlayer ) On vehicle exit: removeElementDataSubscriber(veh, "Fuel", thePlayer ) https://wiki.multitheftauto.com/wiki/AddElementDataSubscriber setElementData( veh, "Fuel", fuelVeh, "subscribe" ) https://wiki.multitheftauto.com/wiki/SetElementData
  13. Clientside Doing a live check: if isPedInVehicle(localPlayer) then Serverside Add some more local's etc. local veh = getPedOccupiedVehicle(source) local stateG = getVehicleEngineState(veh) And make use of arguments for the vehMove() function. vehMove(veh, fuelVeh, x, y, z) -- in > arguments ------------- function vehMove(veh, fuelVeh, x, y, z) -- out > parameters That way you make sure that the data stays within the functions. Adding a fallback for new vehicles (until there is data available from a database): local fuelVeh = getElementData(veh, "Fuel") or 0 -- or set to max This doesn't looks like a logic line, there is no value change so there is no need to set it: setElementData(veh, "Fuel", fuelVeh) ------if the fuel it's above 0 then the fuel recieved it's saved (this is because of the next function)
  14. local duration = 10000 function cinematic1() smoothMoveCamera(2444.0747070312, -1656.7917480469, 28.93049621582, 2526.1335449219, -1710.7858886719, 10.195858001709, 2489.0947265625, -1636.412109375, 30.221374511719, 2499.2856445312, -1728.2391357422, -8.0401239395142, 10000) setTimer(cinematic2, duration , 1) end function cinematic2() smoothMoveCamera(1726.8065185547, -1484.8432617188, 143.54656982422, 1670.5084228516, -1413.7943115234, 185.7670135498, 1535.7916259766, -1267.5806884766, 272.14398193359, 1474.7834472656, -1199.0876464844, 311.97747802734, 10000) setTimer(cinematic3, duration , 1) end function cinematic3() smoothMoveCamera(1338.3666992188, -1257.4116210938, 95.983924865723, 1352.1002197266, -1257.2800292969, -3.0684490203857, 1340.6787109375, -1498.6977539062, 95.983924865723, 1354.4122314453, -1498.5661621094, -3.0684490203857, 10000) setTimer(cinematic1, duration , 1) end setPlayerHudComponentVisible("all", false) cinematic1() -- start Try this.
  15. Clientside is located on the player their pc. When the game is not running, you are able to modify your downloaded files. Files which are defined by the server meta.xml are protected and will be validated (+reset if incorrect). But files created by Lua scripts are not. As long as it is not setElementData, it is fine. Building the fuel system fuel-value-management clientside is OK, but not great.
  16. Saving the data on the client is possible (cookie). The downside is of course that the player could modify or delete it. XML file: https://wiki.multitheftauto.com/wiki/Client_Scripting_Functions#XML_functions Regular file: https://wiki.multitheftauto.com/wiki/Client_Scripting_Functions#File_functions + any format or the usage of JSON Note: If something is decreasing in a linear way, the server can nearly precise compute what the value will be in the future. It just needs to know: The start time. The start value. How much it decrease every <time interval> When the player quits: -- local startTime = getTickCount() -- 1. local startValue = 50 -- 2. local usageEachSecond = 1 -- 3. -- -- time passes here... -- on quit local timeNow = getTickCount() local timePassed = timeNow - startTime local used = (timePassed / 1000) * usageEachSecond local endValue = startValue - used if endValue < 0 then endValue = 0 end
  17. In most cases not. (with an important exception: on clientside setElementData used on an element which is created by serverside)
  18. Then do the selection 100% clientside, that way you eliminate the connection delay and also not wasting network for other players. In your code I do not see serverside btw.
  19. Here is a useful function to add a rate limit (to user input): https://wiki.multitheftauto.com/wiki/CheckPassiveTimer
  20. The way the items are stacked depends on the inventory system. Basic formule: -- generate some fake data local item = {name = "apple", quantity = 36} -- do the stacking local stackSize = 10 local itemCount = item.quantity -- 36 local stacksRawCount = itemCount / stackSize local stacksMaxCount = math.ceil(stacksRawCount) -- 4 local stacksMinCount = math.floor(stacksRawCount) -- 3 local remainingItems = itemCount % stackSize -- 6
  21. It is unwanted network information. > > > setElementData. (getElementData doesn't use network) Every layer of information, means that you have less data to spare for future resources that also use the network. The servertimesync resource uses getTickCount(which Mkl explains) to synchronize time between the client and the server. Now all you have to do is send future time to the client, which will sets it's counter to the right time. Untested example, feel free to optimise it even more. Server -- set when a new round starts (NOT every second) local timeNow = exports.servertimesync:getServerTime() if timeNow then setElementData(resourceRoot,"lobbyEndTime", timeNow + 60000) end Client local timeNow = exports.servertimesync:getServerTime() if timeNow then local lobbyEndTime = getElementData(resourceRoot,"lobbyEndTime") if lobbyEndTime then local remainingTime = (lobbyEndTime - timeNow) / 1000 if remainingTime < 0 then remainingTime = 0 end dxDrawText("Time : " ..math.floor(remainingTime), 300, 300 ) end end
  22. When the player leaves. But the downside is of that is the chance of data loss. (when the server crashes) Yet, that part should be considered more as a feature than a must in my opinion. The most logic timing is when the player leaves. For some data it is not an option to make use of the onPlayerQuit event timing, for example the data that is only stored at the client their PC shouldn't/couldn't be send over to the server when a player quits.
  23. @Rendet_ I have moved your topic to here: https://forum.mtasa.com/forum/149-looking-for-staff/ Please read the rules and formatting of this section:
  24. Yes, everytime getElementsByType is called, a new table with the current players is created.
  25. The player-list is dynamic, it does not seems to be a worth option for your user-case. It is only an option when the list is static, so no new players. -- function ( playerSource, commandName ) local playerList = getElementsByType ("player") for index, player in pairs(playerList) do if player ~= playerSource then end end -- end
×
×
  • Create New...