Jump to content

[Question] Creating and destroying blips with getDistanceBetweenPoints3D


kieran

Recommended Posts

So I have been struggling with one thing in particular lately, I made a script for am ATM system, and added a command to show blips for all the ATM's, I have used getDistanceBetweenPoints3D and it works, showing the nearest blips, the only problem is they will not all go away when I use my function to destroy them, only a small amount go away after the timer is completed.

local ATM_Locations = { --Location table, numbers are commented so I know what goes where
	{1505.16626, -1750.68909, 13.54688},--1 <-This one goes away after 10 seconds as well as 3 others close to it.
	{1690.0927734375, -2334.8369140625, 13.546875},--2
	{1951.19543, -2175.53784, 13.55421},--3
	{2041.50390625, -1430.728515625, 17.1640625},--4 <-Yet this one doesn't or any others north of it.
	{1878.06372, 2073.94067, 11.06250},--5
	{2280.76465, 2431.10596, 10.82031},--6
	{2020.86316, 1016.50653, 10.82031},--7
	{-1210.31104, 1834.64917, 41.92969},--8
	{174.82074, 1175.05469, 14.75781},--9
	{1380.58093, 260.50055, 19.56693},--10
	{1238.48145, 327.90039, 19.75551},--11
	{1626.68469, 1815.06384, 10.82031}--12
}


local Blips = {}--My table to store the blips

local destroyTimer --So I can get the timer

function blips()
	if isTimer (destroyTimer) then --If my timer exists I stop the function here
		return
	end
    for i=1,#ATM_Locations do --For all the locations in the table at the top of the script 
        local x,y,z = ATM_Locations[i][1],ATM_Locations[i][2],ATM_Locations[i][3]--Get the x y z coordinates of ATM_Locations table
        local lx,ly,lz = getElementPosition( localPlayer ) --Get the Players x y z position
		distance = getDistanceBetweenPoints3D (x, y, z, lx, ly, lz) --Get the distance between the ATM's and the Player
		if (distance) <= tonumber(500) then --If the distance is under 500 then create a blip
		Blips[i] = createBlip ( x, y, z, 52, 1) --I create the blips
		destroyTimer = setTimer( destroyBlips, 10000, 1)--And set a 10 second timer to destroy the blips
		end
    end
end

addCommandHandler( "ATM", blips, false )--This is the command to show blips

function destroyBlips()
	for i=1, #Blips do --For the blips in the table
	local blip = Blips[i] --Get the blips 
		if isElement(blip) then --If the blip is in the table
			destroyElement(blip) --Destroy it.
		end
	end
end

So if you try it at LS airport you'll get 4 blips that will go away, but if it's anywhere else and distance is still 500, then the blips will stay :/ anyone see where I went wrong? it's as if it only gets a select amount from the Blips table then stops.

Thanks for any help, been struggling and don't know why it's doing this, all blips go after 10 seconds when it doesn't use distance... :)

Edited by kieran
Link to comment
  • Moderators

Info: You create for every blip a timer. But when the function is recalled, you only destroy 1 timer. The variable `destroyTimer` can only contain 1 value at the same time, so only one timer.

Info: The distance check is within function `blips`, which is only executed when you write the command. So it doesn't recheck after that.

 

Solution:

See on page: https://wiki.multitheftauto.com/wiki/CreateBlip

visibleDistance

If you set this, you don't have to destroy blips any more. It will simply stream them out.

 

 


Alternative method to destroy multiple elements.

See this tutorial, it will make your life a lot easier.

 

In the tutorial you can see that I set a parent element of all children. If you do the same and destroy the parent element instead, all children will also be destroyed.

local blipGroupElement = createElement("blipGroupElement")
-- for loop
-- ADD here your blips
setElementParent(blip, blipGroupElement)
-- end

destroyElement(blipGroupElement) -- All blips are destroyed

 

  • Confused 1
Link to comment
1 hour ago, IIYAMA said:

Info: You create for every blip a timer. But when the function is recalled, you only destroy 1 timer. The variable `destroyTimer` can only contain 1 value at the same time, so only one timer.

Info: The distance check is within function `blips`, which is only executed when you write the command. So it doesn't recheck after that.

 

Solution:

See on page: https://wiki.multitheftauto.com/wiki/CreateBlip


 
  1. visibleDistance

If you set this, you don't have to destroy blips any more. It will simply stream them out.

 

 


Alternative method to destroy multiple elements.

See this tutorial, it will make your life a lot easier.

 

In the tutorial you can see that I set a parent element of all children. If you do the same and destroy the parent element instead, all children will also be destroyed.


local blipGroupElement = createElement("blipGroupElement")
-- for loop
-- ADD here your blips
setElementParent(blip, blipGroupElement)
-- end

destroyElement(blipGroupElement) -- All blips are destroyed

 

I tried setting visible distance, all blips are created on map, and visible distance works on HUD, but not on the map, every blip still shows on map... :/

And what do you mean by add blips?  I tried this and it failed.

local destroyTimer

function blips()
	if isTimer (destroyTimer) then 
		return
	end
	local blipGroupElement = createElement("blipGroupElement")
    for i=1,#ATM_Locations do 
        local x,y,z = ATM_Locations[i][1],ATM_Locations[i][2],ATM_Locations[i][3]
		blip = createBlip ( x, y, z, 52, 1, 0, 0, 0, 255, 0, 500)
		setElementParent(blip, blipGroupElement)
		destroyTimer = setTimer( destroyBlips, 10000, 1)
	end
end

addCommandHandler( "ATM", blips, false )


function destroyBlips()
	if isElement(blipGroupElement) then
		destroyElement(blipGroupElement)
	end
end

 

Link to comment
  • Moderators
local destroyTimer

function blips()
	if isTimer (destroyTimer) then 
		return
	end
	local blipGroupElement = createElement("blipGroupElement")
    for i=1,#ATM_Locations do 
        local x,y,z = ATM_Locations[i][1],ATM_Locations[i][2],ATM_Locations[i][3]
		local blip = createBlip ( x, y, z, 52, 1, 0, 0, 0, 255, 0, 500)
		setElementParent(blip, blipGroupElement)
		
	end
	destroyTimer = setTimer( destroyBlips, 10000, 1, blipGroupElement)
end

addCommandHandler( "ATM", blips, false )


function destroyBlips(blipGroupElement)
	if isElement(blipGroupElement) then
		destroyElement(blipGroupElement)
	end
end

Must be working.

 


Local variables can not leave their block.

function blips()
	-- block
	local blipGroupElement = createElement("blipGroupElement")
	-- block
end

-- blipGroupElement can not be used here.

 

 

But lucky setTimer accepts custom parameters.

destroyTimer = setTimer( destroyBlips, 10000, 1, blipGroupElement)

function destroyBlips(blipGroupElement)
	if isElement(blipGroupElement) then
		destroyElement(blipGroupElement)
	end
end

 

destroyTimer = setTimer( destroyBlips, 10000, 1, blipGroupElement)

function destroyBlips(blipGroupElement)
    if isElement(blipGroupElement) then
        destroyElement(blipGroupElement)
    end
end

 

  • Thanks 1
Link to comment
37 minutes ago, kieran said:

@IIYAMA OMG thanks so much. :D works perfect! :)

Isn't as you want, because blib will displayed anyway ..
code ;

 

function blips()
    for i=1,#ATM_Locations do 
        local x,y,z = ATM_Locations[i][1],ATM_Locations[i][2],ATM_Locations[i][3]
	local blip = createBlip ( x, y, z, 52, 1, 0, 0, 0, 255, 0, 500)	
    	local marker = createMarker ( x, y, z, "checkpoint", 500, 0, 0, 0, 0 )
		setElementVisibleTo ( root, blip, false )
		addEventHandler ( "onMarkerHit", marker,
			function ( hit )
				setElementVisibleTo ( hit, blip, true )
			end
		)
		addEventHandler ( "onMarkerLeave", marker,
			function ( hit )
				setElementVisibleTo ( hit, blip, false )
			end
		)
	end
end

addCommandHandler( "ATM", blips, false )

That code wil create blip, and hide it from everone then when anyone hit marker of blip he will see the blip and when leave from marker the blip will hide from him..

 

Edited by iMr.WiFi..!
Link to comment
1 hour ago, iMr.WiFi..! said:

Isn't as you want, because blib will displayed anyway ..

Believe it or not it's exactly what I wanted xD the idea is adding the /atm command for a player to find the closest ATM, not to set the blip visible when the player hits the marker....

Here's the code, trying to educate myself a little on distance so I can make a proper hospital script and other stuff needed on most servers for the community (once I find out why I can't upload images to my resources). :)

local destroyTimer

function blips()
	if isTimer (destroyTimer) then --If timer is active
		return --Do nothing
	end
	local blipGroupElement = createElement("blipGroupElement") --Create an element for the blip
    for i=1,#ATM_Locations do --For all the locations in the table
		--Get the ATM xyz
        local x,y,z = ATM_Locations[i][1],ATM_Locations[i][2],ATM_Locations[i][3]--We will get there x y z coordinates
		--Get the Players xyz
        local lx,ly,lz = getElementPosition( localPlayer )
    	--Get the distance between the ATM's and the Player
		distance = getDistanceBetweenPoints3D (x, y, z, lx, ly, lz)
   		--If the distance is under 500 then create a blip for each location in the table
		if (distance) <= tonumber(500) then
			blip = createBlip ( x, y, z, 52, 1, 0, 0, 0, 255, -32767)
			setElementParent(blip, blipGroupElement) --Set the parent of the blip to the previously created element 
			destroyTimer = setTimer( destroyBlips, 10000, 1, blipGroupElement)--And set a 10 second timer to destroy the blips
		end
	end
end

addCommandHandler( "ATM", blips, false )--Command 


function destroyBlips(blipGroupElement) --Honestly a little puzzled here, guess you carry this here so it can find all elements
	if isElement(blipGroupElement) then --If it's there
		destroyElement(blipGroupElement) --Destroy it.
	end
end

--See? It is simple!  I just got a bit puzzled as I have never done a script like this, it's usually simple stuff. ^.^

 

Link to comment

Then , try it :

for i=1,#ATM_Locations do 
    local x,y,z = ATM_Locations[i][1],ATM_Locations[i][2],ATM_Locations[i][3]
    local blip = createBlip ( x, y, z, 52, 1, 0, 0, 0, 255, 0, 500)	
    local marker = createMarker ( x, y, z, "checkpoint", 500, 0, 0, 0, 0 )
	setElementVisibleTo ( root, blip, false )
	addEventHandler ( "onMarkerHit", marker,
		function ( hit )
			blips [ hit ] = blip;
		end
	)
	addEventHandler ( "onMarkerLeave", marker,
	function ( hit )
      		if visible [ hit ] then
        		setElementVisibleTo ( hit, blips [ hit ], false )
			blips [ hit ] = nil;
        		visible [ hit ] = nil;
        		else
			blips [ hit ] = nil;
        	end
	end
	)
end

function checkBlip( player )
  	if blips [ player ] then
		setElementVisibleTo ( player, blips [ player ], true )
    		visible [ player ] = blips[ player ]
	end
end

addCommandHandler( "ATM", checkBlip, false )

 

Edited by iMr.WiFi..!
false *
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...