Jump to content

Zango

Discord Moderators
  • Posts

    681
  • Joined

  • Last visited

  • Days Won

    11

Everything posted by Zango

  1. Yes, you can make an URL like this mtasa://127.0.0.1:22003
  2. It's because you are trying to turn table 'v' into a string. As you can find on the wiki for dbPoll, in your case 'p' will be like this { { colname1=value1, colname2=value2, ... }, { colname1=value3, colname2=value4, ... }, ... } So you need to refer to the column name first outputChatBox(k.." = "..v.id); For your purpose, I suggest using inspect instead which converts a table to a readable string. function listTable(queryHandle) local db = dbConnect("sqlite","blips.db") local p = dbPoll(dbQuery(db, "SELECT id,icon,name FROM tabelaBlips"), -1); if (#p > 0) then outputChatBox(inspect(p)) end end addCommandHandler("listTable",listTable,false,false)
  3. This extension has code completion for VS code. It's the only one I know of.
  4. You need to parse radians to it, like this isMouseInCircleSector(sx/2, sy/2, 330, math.rad(0), math.rad(90))
  5. If you only want to see if the point is inside one of the circle's quadrants, it can be done really simple. If you want to check for any sector, I have made the following, where you define the sector from two angles. It would also be possible to define the sectors from vectors instead. local sx, sy = guiGetScreenSize( ) function isMouseInCircleSector(cx, cy, r, angleStart, angleEnd) local mx, my = getCursorPosition() if not mx then return end -- Relativise mouse position to circle center mx = mx * sx - cx my = my * sy - cy -- Convert angles to vectors local x1, y1 = r * math.cos(angleStart), r * math.sin(angleStart) local x2, y2 = r * math.cos(angleEnd), r * math.sin(angleEnd) return mx^2 + my^2 <= r^2 and -- Check if within radius -x1*my + y1*mx <= 0 and -- Check if counterclockwise to angleStart -x2*my + y2*mx > 0 -- Check if clockwise to angleEnd end Where: cx, cy = Circle center r = Circle radius angleStart = start of sector, in radians angleEnd = end of sector, in radians So as an example, here are the angleStart and angleEnd values for each quadrant 270, 0 - First quadrant 180, 270 - Second quadrant 90, 180 - Third quadrant 0, 90 - Fourth quadrant Hope it's useful
  6. addEventHandler("onClientMarkerHit", root, MKH_OPEN) If you bind this event handler to the local player instead addEventHandler("onClientMarkerHit", localPlayer, MKH_OPEN) The GUI should only open when you hit the marker.
  7. setCameraTarget() To focus camera on player again
  8. The map editor can now remove collisionless world objects, if you toggle "Enable collision patches" in the options. This will also make these models selectable when placed as objects. https://mirror.multitheftauto.com/mtasa/resources/
  9. Zango

    MTA CRASH

    Try downloading the latest version, from mtasa.com, and run MTADiag again
  10. Zango

    aiming problem

    What version of MTA are you on? type "ver" in console (F8) Does this happen on one server or several? Can you upload a video of this?
  11. Zango

    [Help] Turf

    Have a look at the radar area functions and colshape functions. What are you looking to do?
  12. The only way right now is it to interrupt the entering task, like you do when you hold movement keys as a player during jacking. If you set the "backwards" control state after jacking starts, you can do this. The current implementation of jacking is very lacking in this aspect. If jacking is aborted for one of many reasons, the server doesn't know how far the jacker is, ie. if he physically pulled out the jacked ped yet, so it relies on the jacker to abort properly. But for peds, if the syncer changes the jacking isn't aborted properly and the jacker will be warped into the car. This is something I plan on improving, and also add a client and server event for when jacking physically starts, as it could be useful in many scripts. -- onClientPedJacked: when a ped/player has been actually jacked from a vehicle by the local player or syncing ped. -- Source: ped that got jacked -- 1st parameter: ped that jacked the other ped addEvent("onClientPedJacked", false) local ENTER_RESPONSE_TIMEOUT = 600 -- Time for server to ack our entry request and we start entering otherwise we consider it declined -- Sub tasks to indicate we are actually jacking now local PED_JACK_TASKS = { ["TASK_SIMPLE_CAR_SHUFFLE"] = true, -- Jacking through passenger seat ["TASK_SIMPLE_CAR_QUICK_DRAG_PED_OUT"] = true, ["TASK_SIMPLE_CAR_SLOW_DRAG_PED_OUT"] = true, ["TASK_SIMPLE_CAR_GET_IN"] = true, -- Jumping on a bike from the front } local timerData = {} local getPedTask = getPedTask local isElement = isElement local getVehicleController = getVehicleController local function stopEnterVehicleTimer() timerData[sourceTimer] = nil killTimer(sourceTimer) end local function onEnterVehicleFrame() if not isElement(timerData[sourceTimer].jackingPed) then return stopEnterVehicleTimer() end local pedTaskComplex, pedTaskSimple = getPedTask(timerData[sourceTimer].jackingPed, "primary", 3) if not pedTaskComplex then pedTaskComplex = "" end if pedTaskComplex:sub(1, 22) ~= "TASK_COMPLEX_ENTER_CAR" then if timerData[sourceTimer].enterTaskActive then return stopEnterVehicleTimer() else if getTickCount() - timerData[sourceTimer].enterTick > ENTER_RESPONSE_TIMEOUT then return stopEnterVehicleTimer() end end return end timerData[sourceTimer].enterTaskActive = true if PED_JACK_TASKS[pedTaskSimple] then triggerEvent("onClientPedJacked", timerData[sourceTimer].jackedPed, timerData[sourceTimer].jackingPed) return stopEnterVehicleTimer() end if not isElement(timerData[sourceTimer].veh) then return stopEnterVehicleTimer() end if not isElement(timerData[sourceTimer].jackedPed) then return stopEnterVehicleTimer() end if getVehicleController(timerData[sourceTimer].veh) ~= timerData[sourceTimer].jackedPed then return stopEnterVehicleTimer() end end local function onClientVehicleStartEnter(jackingPed, seat, door) if jackingPed ~= localPlayer and not isElementSyncer(jackingPed) then return end if seat ~= 0 then return end local jackedPed = getVehicleController(source) if not jackedPed then return end for k,v in ipairs(timerData) do if v.jackingPed == ped then return end end local timer = setTimer(onEnterVehicleFrame, 0, 0) timerData[timer] = { enterTick = getTickCount(), jackingPed = jackingPed, jackedPed = jackedPed, veh = source, enterTaskActive = false, } end addEventHandler("onClientVehicleStartEnter", root, onClientVehicleStartEnter) You can use above snippet, "onClientPedJacked" triggers when ped is physically getting jacked by local player or syncing ped. Set control state "backwards" when this event triggers, and release it again when the ped is no longer entering (see TASK_COMPLEX_ENTER_CAR in the snippet above). Let me know if you need an example for that.
  13. It will give you better results, as in the random numbers wont be the same each time you run the script. But it wont make the Lua random generator better, it has a propensity for certain numbers and patterns like any pseudo-random number generator. If you need better randomness you can consider fetching numbers from random.org, they have an API.
  14. local last_button_action = 0 function onClientKey(button, pressOrRelease) if not pressOrRelease then return end local boundKeys = getBoundKeys("vehicle_secondary_fire") if not boundKeys then return end if not boundKeys[button] then return end local tick = getTickCount() if tick - last_button_action < 500 then cancelEvent() return end last_button_action = tick end addEventHandler("onClientKey", root, onClientKey) This will limit the vehicle_secondary_fire control to once every 500 ms, it should be enough to block the super jump on bike. This applies to all vehicles, so you will need to check for vehicle type if you want to limit it to bikes. I used onClientKey because I can't find a smarter way. An alternative is binding a function to the vehicle_secondary_fire keys, but the user can change his binds midways and you would have to check for that at some interval.
  15. If you want to get the target in the center of the screen, you can use getCameraMatrix. It returns the camera position and lookat position, which is a unit vector from the camera position, so you can easily multiply it to get a point further out. Made the following so you can see if thats what you need. local scrW, scrH = guiGetScreenSize() local maxTargetDistance = 100 addEventHandler("onClientPreRender", root, function() local cx, cy, cz, lx, ly, lz = getCameraMatrix() local px = cx + (lx - cx) * maxTargetDistance local py = cy + (ly - cy) * maxTargetDistance local pz = cz + (lz - cz) * maxTargetDistance local hit, hx, hy, hz, hitElement = processLineOfSight(cx, cy, cz, px, py, pz, true, true, true, true, true, false, false, false, localPlayer) dxDrawRectangle(scrW/2 - 5, scrH/2 - 5, 10, 10) if hit then dxDrawLine3D(hx, hy, hz + 1, hx, hy, hz) end end)
  16. To see errors and warnings from your script, use /debugscript 3. The problem here is you are parsing a resource element into triggerClientEvent where it expects a player. function ShowImage (player) The player here is a resource, because you have bound it to onResourceStart. If you want to send this image to everyone on the server, use root as "sendTo" parameter. triggerClientEvent ( root, "onClientGotImage", root, response ) I've made a few changes to it, see the comments here: -- server function ShowImage() outputChatBox ( "event called, fetching image..." ) fetchRemote ( "https://img.icons8.com/cotton/2x/baby.png", function ( response, error ) if error == 0 then triggerClientEvent ( root, "onClientGotImage", resourceRoot, response ) -- Use resourceRoot as the source of the event outputChatBox ( "data sucessfully send to the player" ) else outputChatBox ( "error "..error.." when fetching image." ) end end ) end addEventHandler("onResourceStart", resourceRoot, ShowImage) -- Use resourceRoot otherwise it triggers when any resource starts -- client local myTexture addEvent( "onClientGotImage", true ) addEventHandler( "onClientGotImage", resourceRoot, -- resourceRoot as source function( pixels ) outputChatBox ( "client: ok." ) if myTexture and isElement ( myTexture ) then destroyElement( myTexture ) end myTexture = dxCreateTexture( pixels ) end ) addEventHandler("onClientRender", root, function() if myTexture then local w,h = dxGetMaterialSize( myTexture ) dxDrawImage( 200, 100, w, h, myTexture ) end end ) This code works for you on your local server, but you will run into issues doing this with other players, because they won't have loaded the clientside script before you send the image to them. Let me know if you need more explanation.
  17. I tested it and it looked fine. Can you show with a screenshot what looks wrong?
  18. Try using modulate_add as blend mode instead of add before fading it (line 18)
  19. What doesn't work? Are you getting an error? Use /debugscript 3
  20. Do you want to fade two images with each other? Or fade the current image to nothing and then fade the next image from nothing? Use alpha in tocolor to fade it. (red, green, blue, alpha). dxDrawImage(0, 0, screenSize.x, screenSize.y, backgroundTexture, angle, 0, -120, tocolor(255, 255, 255, 255)) To fade it a bit dxDrawImage(0, 0, screenSize.x, screenSize.y, backgroundTexture, angle, 0, -120, tocolor(255, 255, 255, 100)) Now you need to add or subtact a bit of alpha every render. If you add 1 alpha, the effect will take 255 frames, so about 4 seconds at 60 FPS. Let me know if you need code/explanation.
  21. If you haven't already, you need to find the scoreboard resource, by default it will be in server\mods\deathmatch\resources\[gameplay]\scoreboard Scoreboard has a few different settings you can adjust. In meta.xml at the bottom you will find settings to toggle whether teams and country flag will always or never be shown. You can also disable colorcoded names there. You probably want to force teams to be shown. Change <setting name="*forceShowTeams" value="false" to <setting name="*forceShowTeams" value="true" Besides those settings there are some the players can change themselves. In the settings box you can toggle "Show info of server" to show server name. In dxscoreboard_clientsettings.lua you will find the default settings. Change ["showserverinfo"] = false, to ["showserverinfo"] = true, In there you can also change the color of the text on the columns. You can't change the background color of separate columns as scoreboard renders 1 background, but it can be changed. When you use the team functions (createTeam and setPlayerTeam) players are automatically grouped on the scoreboard.
  22. Head into server\mods\deathmatch\resources\[managers]\mapmanager. Open meta.xml. Find <setting name="*color" value="#E1AA5A"/> Change the hexadecimal value to fe. value="#0000FF". Go here to convert RGB to Hex: https://www.rgbtohex.net/rgbtohex/
  23. You can open a file handle on server.log and read it periodically. Move the pointer to end of file after opening it initially, and read from it at some interval (500ms should feel like realtime).
  24. I made the below function as you might find it useful to animate multiple floating arrows, as alternative to the static approach above. Use createAnimatedArrow(...) instead of createMarker(...) for your arrow. It uses the stream in/out events so we don't waste CPU on markers that are far away. You could further optimise it to bind/unbind the render event at the first and last stream in / out, saving 1 pairs call. local markers = {} local animationMethod = "InOutQuad" -- What easing function to use, see https://wiki.multitheftauto.com/wiki/Easing local animationTime = 1000 -- The time for the animation to go from bottom to top local animationAmplitude = 0.3 -- How far the marker will move local function onAnimationFrame(dt) for marker,anim in pairs(markers) do -- Check if marker is still valid or destroyed if isElement(marker) then -- Find animation progress from time since last frame local delta = dt / animationTime anim.t = anim.t + delta * anim.direction -- Reverse direction if we are above 1 or below 0 if anim.t < 0 then anim.direction = anim.direction * -1 anim.t = 0 elseif anim.t > 1 then anim.direction = anim.direction * -1 anim.t = 1 end -- Find the easing value (usually a 0-1 value) from our animation progress (0-1) local anim_time = getEasingValue(anim.t, animationMethod) -- Find the z value we want to offset with local z_anim = animationAmplitude * anim_time setElementPosition(marker, anim.x, anim.y, anim.z + z_anim) else -- Dereference it markers[marker] = nil end end end addEventHandler("onClientPreRender", root, onAnimationFrame) local function onArrowMarkerStreamIn() if markers[source] then return end -- Store the position -- 't' to keep track of the animation progress -- 'direction' to keep track of whether we are moving up or down local x, y, z = getElementPosition(source) markers[source] = {t = 0, direction = 1, x = x, y = y, z = z} end local function onArrowMarkerStreamOut() if not markers[source] then return end -- If the marker element is still valid, set it to its original position if isElement(source) then setElementPosition(source, markers[source].x, markers[source].y, markers[source].z) end -- Dereference marker markers[source] = nil end function createAnimatedArrow(x, y, z, markerType, ...) if markerType ~= "arrow" then return false end local marker = createMarker(x, y, z, markerType, ...) if not marker then return false end -- Use the stream in / stream out events to only animate markers that are nearby addEventHandler("onClientElementStreamIn", marker, onArrowMarkerStreamIn) addEventHandler("onClientElementStreamOut", marker, onArrowMarkerStreamOut) return marker end If your markers are serverside, or you want to change its position after creating it, you'll have to change a few things, let me know if you need help.
  25. It's worth mentioning you can carjack a dead ped, if you are looking to make a workaround. However it's almost impossible to create a workaround that looks good and works well. I've considered a lot of approaches for a workaround, but it's ridiculous for such a basic mechanic that should just work. Better to focus our efforts on fixing it in MTA.
×
×
  • Create New...