-
Posts
1,060 -
Joined
-
Last visited
-
Days Won
9
Everything posted by Addlibs
-
local zones = { -- whatever content there would be } function saveZones() if fileExists("zones.json") then fileDelete("zones.json") -- if the file exists, delete it to clear it end local f = fileCreate("zones.json") if not f then outputDebugString("failed to create zones.json") return end fileWrite(f, toJSON(zones)) -- JSONify the zones table and write it to f (file handle for zones.json) fileClose(f) -- make sure to close the file so there's no memory leaks end function loadZones() if not fileExists("zones.json") then return end -- no save file, abort here local f = fileOpen("zones.json", true) if not f then outputDebugString("failed to open zones.json for reading") return end local content = fileRead(f, fileGetSize(f)) zones = fromJSON(content) -- assign the zones table to the de-JSONified content of the zones.json file fileClose(f) -- make sure to close the file so there's no memory leaks end I haven't actually tested this but it should work unless I misspelled some function or forgot an argument somewhere. Also worth noting, toJSON does not work with elements and userdata - you cannot place a player element there but you could place the player name.
-
You could simply use table.insert to add the new zone into the table, however that would only last until the server or client (depending whether the script file is server side or client side) is restarted. If you want it to be permanent, you would have to either: 1) have the script edit itself and write into new lines in the source file, or 2) implement a saving system so you can save and load the table from a different file that's easier to edit The second option could be easily accomplished by simply writing the toJSON notation of the zones table into a file and then load it by assigning the zones table to the result of fromJSON of the save file's contents.
-
local screenSize = Vector2(guiGetScreenSize()) local cursorPos = Vector2(getCursorPosition()) local mapMin, mapMax -- Transform the relative cursor position to absolute position cursorPos.x, cursorPos.y = cursorPos.x * screenSize.x, cursorPos.y * screenSize.y -- Calculate our map points vectors inside a block to delete intermediate variables automatically do local mx, my, Mx, My = getPlayerMapBoundingBox() mapMin = Vector2(mx, my) mapMax = Vector2(Mx, My) end -- If the cursor is inside the map rectangle if cursorPos.x >= mapMin.x and cursorPos.y >= mapMin.y and cursorPos.x <= mapMax.x and cursorPos.y <= mapMax.y then -- Get the relative position (in range [0, 1]) of the mouse point from the mapMin point -- 0 in a direction means that the cursor is in mapMin which is the top-left corner of the map -- 1 in a direction means that the cursor is in mapMax which is the bottom-right corner of the map local relPos = Vector2((cursorPos.x - mapMin.x) / (mapMax.x - mapMin.x), (cursorPos.y - mapMin.y) / (mapMax.y - mapMin.y)) -- Translate that relative position to 2D world coordinates -- Assumes the world map is a square whose side is 6000 units long local worldPlanePos = Vector2(6000 * (relPos.x - 0.5), 3000 - (relPos.y * 6000)) -- Get a 3D world position by adding the highest ground Z coordinate, which is what we usually want local worldPos = Vector3(worldPlanePos.x, worldPlanePos.y, getGroundPosition(worldPlanePos.x, worldPlanePos.y, 3000)) -- wordPos = a Vector3 containing the X, Y world position that was highlighted on the map and the Z of the ground position at that X, Y position. end The code used here is taken from the second example for getPlayerMapBoundingBox which is actually more applicable to your situation, I only show the important parts here.
-
Oh. In that case I'd just modify the original code I gave, to select the lowest index rather than value local lowest = math.huge for key, value in pairs(sortedTable) do if type(key)=="number" and key < lowest then lowest = key end end -- or alternatively, use a loop that doesn't use pairs function local lowest = 0 while (true) do -- warning: this will loop indefinitely if the table has no indices that aren't numbered lowest = lowest + 1 -- keep incremeting the index if sortedTable[i] then -- until an index is found with a logically non-false value break -- and escape the while-loop end end -- Now here, -- lowest = the lowest number index in the table, and of course, -- sortedTable[lowest] = the value of the lowest index of the table
-
If it's already sorted, you should be able to pick the first value and it should be the lowest, and the last value which would be the highest sortedTable[1] -- first value, the lowest if sorted properly sortedTable[#sortedTable] -- last value, the highest if sorted properly
-
I'm unsure which method is faster or more optimised, but you can do either function getLowestValue(haystack) assert(haystack and type(haystack) == "table", "Bad argument @ 'getLowestValue' [Expected 'table' at argument 1, got '"..type(haystack).."']") local lowest, thekey = math.huge, nil -- set lowest to value of infinity for key, value in pairs(haystack) do if value < lowest then -- if this value is lower than the lowest value found so far (infinity to begin with) lowest, thekey = value, key -- set that lowest value to this value and store the key/index where we found the value end end return lowest, thekey -- return the lowest value found along with the key/index under which it was found (nil if there was nothing lower than infinity) end or try using table.sort to sort the table by value from lowest to highest (not sure if this works for tables with non-integer/non-sequential keys/indices) and simply access the first index of that table. Table.sort is part of Lua's standard libraries, which means it is implemented in C. Both methods definitely iterate the table, and I've heard that in some instances, table.sort can be slower than other sorting algorithms written in pure Lua.
-
The issue is you're trying to create a vehicle using it's name rather than model ID. Either try: function makeVehicles() local modelName = guiGridListGetItemData(carGridList, guiGridListGetSelectedItem(carGridList), 1) local modelID = getVehicleModelFromName(modelName) --try to get the model ID from the model name local x, y, z = getElementPosition(localPlayer) local veh = createVehicle(modelID, x, y+5,z) local vx, vy, vz = getElementPosition(veh) setCameraMatrix(vx, vy, vz, vx, vy+10, vz+5) setTimer( function() destroyElement(veh) setCameraTarget(localPlayer) end, 10000, 1) end Or store the model ID as grid-list item data: -- lines 16 to 21 for i,v in ipairs (cars) do local carName = getVehicleNameFromModel (v[1]) local row = guiGridListAddRow (carGridList) guiGridListSetItemText (carGridList, row, 1, carName, false, true) --display the model name guiGridListSetItemData (carGridList, row, 1, v[1], false, true) --store the model ID guiGridListSetItemText (carGridList, row, 2, tostring(v[2]), false, true) end -- then function makeVehicles() local modelID = guiGridListGetItemData(carGridList, guiGridListGetSelectedItem(carGridList), 1) --get the item data which is ID, not the name local x, y, z = getElementPosition(localPlayer) local veh = createVehicle(modelID, x, y+5,z) local vx, vy, vz = getElementPosition(veh) setCameraMatrix(vx, vy, vz, vx, vy+10, vz+5) setTimer( function() destroyElement(veh) setCameraTarget(localPlayer) end, 10000, 1) end
-
I believe -(getElementData(gov, "id")) is the arithmetic error. The data of gov (which was defined as the team of name "Government of Los Santos" on line 25) is not a number but a boolean, therefore you cannot stick a minus sign in front.
-
First of all, I'm very concerned about lines 9 through 11 setTimer(function() triggerServerEvent("online",getLocalPlayer()) end, 10000, 1, true) being inside a function called every frame. You're creating a new timer as frequently as 60 times a second for clients which run on 60 FPS. The code as you've written it simply delays the queries for online players by 10 seconds but still calls it as many times a second as the amount of frame rendered per second, rather than reducing the frequency to once every 10 seconds which you can do by setting a timer when the resource starts (onClientResourceStart or simply outside any function) with the interval set to 10000ms (as you have it now) and repetitions to 0 (infinite). But to answer your question, when making resolutions relative, there are a couple approaches - the laziest is to simply change the numbers into fractions of the native resolution (on which they were designed) and multiplied by the one where they're displayed, for example the width of 780px can be made relative by using (780/1920)*screenW where 1920 is the native screen width, and screenW is the result of guiGetScreenSize()
-
You can make the search case insensitive by simply searching for lower case characters in a lowercased text as so: string.find(string.lower(stringToSearchIn), substringToFind) -- or stringToSearchIn:lower():find(substringToFind) -- OOP style As long as substringToFind is lower case, it will find lowercase substrings, but because everything it searches is lowercase, it will find the substring regardless of the case of the original stringToSearchIn (this also returns the start and end index, should you want to use it to index the original mixed-case stringToSearchIn using string.sub for example)
-
I'm afraid we do not give support in regards to stolen/leaked scripts, which this appears to be one of such leaked scripts, to my eyes.
-
First of all, I'd point out that, regarding line 3, there is a difference between (not text1 and text2) (this one will only evaluate true if text1 is logically false or nil and text2 is logically true or not nil) and (not text1 or not text2) (this one will only evaluate true if one or both of text1 or text2 is logically false or nil). The latter is, I believe, what you intended. Secondly, you're outputting "Error" even when it succeeds (line 12). Thirdly, setElementData on line 11 has the wrong syntax - it takes in 3 arguments, not 2 - and it appears you meant setElementDimension rather than setElementData. Helpful tip: In order to debug this yourself, you should add iprint(results) between line 5 and 6, and open /debugscript 3 in game to see what the database query returns.
-
As the error message clearly suggests, you're attempting to string.lower() a boolean value. In other words, permission variable is a boolean (true/false), not a string.
-
getPlayerWantedLevel, when used on clientside, only returns the local player's wanted level. You would need to either store other players' wanted levels in element data, sync the data yourself or trigger a server event to list wanted players into a table and send it back to client by triggering a client event.
- 8 replies
-
- 1
-
- portuguese
- english
- (and 6 more)
-
function replacemodels(player) for i,OBJ in ipairs(Garage_OBJ_COL) do -- OBJ[1] is the file name -- OBJ[2] is the model id local col = engineLoadCOL(OBJ[1], OBJ[2]) engineReplaceCOL(col, OBJ[2]) end end addEventHandler("onResourceStart",root,replacemodels)
-
Thank you, how did you got this link? Internet browser's dev tools (Ctrl+Shift+I) (Network logging, filtered by XHR, and just look through those listed there and check each's response data, one of 'em will have the song name (in this case, it's streamdata.php) (How it looks on macOS Safari, most browsers like Chrome should look very similar) Edit: After looking into this a little bit more, you can easily modify the URL I gave to collect the song name of any stream. http://player.181fm.com/streamdata.php?h=<host>&p=<port>&i=<file>
-
After inspecting the website, you wouldn't find the name of the song on it since it is loaded from a different page via javascript, more specifically, loaded from http://player.181fm.com/streamdata.php?h=listen.181fm.com&p=7080&i=181-power_128k.mp3. So you should try to fetchRemote that and (if necessary, decode JSON).
-
Why not just use aclGroupListObjects(aclGetGroup ("Admin")) This will return all objects in the ACL group, with the prefix I believe, so now all you need to do is filter out everything other than what starts with "user." When it comes to the code you posted above, you cannot use return in a loop in the way you used it on line 8. This aborts the loop, so as soon as an account that isn't in the admin group is iterated, the loop completely ends. In such loops, I believe the only way is to have all the code conditional on the if, rather than a return statement on the if.
-
Sorry but we don't do requests here. If you're looking for a script you should check out https://community.multitheftauto.com. If you need someone to script it for you then you should hire someone.
-
setVehicleOverrideLights from 0 (auto) to 1 (off) or 2 (on) for every vehicle you spawn.
-
A lot of this code doesn't make sense. You should try commenting on it to show your intention as its difficult to find out what you were trying to do. objs = {} addCommandHandler ( "explosion", function ( thePlayer ) local x, y, z = getElementPosition ( thePlayer ) local rx, ry, rz = getElementRotation ( thePlayer ) local origX, origY, origZ = getElementPosition ( thePlayer ) --why is this being defined? you're not modifying x, y, z in the code so this is going to remain identical to x, y, z defined earlier local mat = Matrix.create ( x, y, z+20, rx, ry, rz, origX - 30,origY+30,origZ) --I'm pretty sure this does not follow the syntax of Matrix.create which expects two vectors or 6 floats for position and rotation respectively. You've inputted 9 floats. local forward = ( Matrix.getForward ( mat ) * 4) local pos = ( Matrix.getPosition ( mat ) + forward ) --this would be the Vector3 for a position 4 units in front of mat, or in front of the player 20 units above on Z setTimer (createExplosion, 2000, 1,x+10, y, z, 11) --this creates an explostion 10 units to the north of the player (not relative to rotation) objs[thePlayer] = createObject(751, pos) --this creates an object 20 units above the player and 4 units in front local newZ = origZ +0 --this defined a variable that doesn't even get used moveObject( objs[thePlayer], 2000, origX, origY, origZ) --this moves the object to the player's position end )
-
Create a file. Open it in a text editor. Write <meta> <info author="your name" version="1.0" name="friendly name for the resource" description="brief description of the resource" type="script" /> <script src="lua_script.lua" type="client" /> <!-- for client-side scripts --> <script src="lua_script.lua" type="server" /> <!-- for server-side scripts --> </meta> It's as simple as that. There are a lot more things you can add there, all of which can be found on the wiki page for meta.xml. Its a simple XML document - you must make sure all tags are balanced, or closed. So the <meta> tag must have a corresponding </meta> tag at the end. Tags can be self-closing where there is no inner content, such as <script />. Every tag can have attributes, which look as follows: attribute="value", these don't count as inner content so tags with attributes can still be self-closing. It's pretty much that simple.
-
I've loaded the file and in-game it seems to have some dark textures, wrongly mapped, however, afterwards I've increased the mipmaps to 1 (or any non-zero value) and it seems to load properly.
-
What you should do is select a default material, change it's type to GTA Material (by pressing the button next to the material name which says "Standard"), then click on the button on the right of color column which will by default say "None", and then select a bitmap texture. Then you need to rename the map from "Map #1" to the same as the texture name but excluding the file extension (not sure if this is required but I always do that).