Jump to content

Distance from player to (next) checkpoint etc.


koragg

Recommended Posts

Hey everyone. I wanna extract some of the functionality from the race_progressbar resource but I'm not sure what to do here. I need the distance from player to the next checkpoint to be drawn somewhere on the screen with dxdraw so that it updates live when the player moves (I can draw it but not sure how to actually use the code I have to get it first). Other things like total map distance and distance from spawn to first checkpoint are a bonus :D If anyone can help out, please reply back. Here's what I found that's connected to the things I need :

function calculateCheckpointDistance()
	local total = 0
	local cps = {}
	local cpsSum = {}
	local pos = g_Spawnpoints[1].position
	local prevX, prevY, prevZ = pos[1],pos[2],pos[3]
	for k,v in ipairs(g_Checkpoints) do
		local pos = v.position
		if prevX ~= nil then
			local distance = getDistanceBetweenPoints3D(pos[1],pos[2],pos[3],prevX,prevY,prevZ)
			total = total + distance
			cps[k] = distance
			cpsSum[k] = total
		end
		prevX = pos[1]
		prevY = pos[2]
		prevZ = pos[3]
	end
	g_CheckpointDistance = cps
	g_CheckpointDistanceSum = cpsSum
	g_TotalDistance = total
end

function distanceFromPlayerToCheckpoint(player, i)
	-- TODO: check if the index exists
	local checkpoint = g_Checkpoints[i]
	if checkpoint == nil then
		return false
	end
	local x, y, z = getElementPosition(player)
	return getDistanceBetweenPoints3D(x, y, z, unpack(checkpoint.position))
end

function calculateDistance(headingForCp,distanceToCp)
	local sum = g_CheckpointDistanceSum[headingForCp]
	if sum == nil then
		return false
	end
	local checkpointDistance = g_CheckpointDistance[headingForCp]
	if distanceToCp > checkpointDistance then
		distanceToCp = checkpointDistance
	end
	return sum - distanceToCp
end
function calculateDistance2(headingForCp,distanceToCp)
	local sum = 0
	for k,v in ipairs(g_CheckpointDistance) do
		sum = sum + v
		if headingForCp == k then
			if distanceToCp > v then
				distanceToCp = v
			end
			sum = sum - distanceToCp
			return sum
		end
	end
	return 0
end

This was in the client.lua file of the resource (couldn't find mta community link so sry for github one instead).

Link to comment
21 minutes ago, CodyL said:

distanceFromPlayerToCheckpoint(player, i)

That's what you need to use..

Yes but, how to make it output as dxdrawing? I tried adding dxdraw under the 'return' part and it started giving errors that  g_Checkpoints[i] is undefined and stuff like that. Used this but still didn't work I think: 

g_Checkpoints = getAll("checkpoint")

 

Edited by koragg
Link to comment

It draws "false" instead of distance with the following code. No errors in debug at all.

local sx_, sy_ = guiGetScreenSize ( )
local sx, sy = sx_/1440, sy_/900

function distanceFromPlayerToCheckpoint(player, i)
    g_Checkpoints = getAll("checkpoint")
	local checkpoint = g_Checkpoints[i]
	if checkpoint == nil then
		return false
	end
	local x, y, z = getElementPosition(player)
	return getDistanceBetweenPoints3D(x, y, z, unpack(checkpoint.position))
end

function getAll(name)
	local result = {}
	for i,element in ipairs(getElementsByType(name)) do
		result[i] = {}
		result[i].id = getElementID(element) or i
		local position = {
					tonumber(getElementData(element,"posX")),
					tonumber(getElementData(element,"posY")),
					tonumber(getElementData(element,"posZ"))
				}
		result[i].position = position;
	end
	return result
end

function draw()
    dxDrawText(tostring(distanceFromPlayerToCheckpoint(player, i)), sx_ * 1.5200, sy_ * 0.9843, sx_ * 0.2172, sy_ * 1.0167, tocolor(131, 253, 1, 255), 0.55*sy, "bankgothic", "center", "top", false, false, false, false, false)
end
addEventHandler("onClientRender", root, draw)

I did 'tostring' on line 30 as that's what it said in debug as the only error.

Edited by koragg
Link to comment

Sorry for being late to edit the post. Anyways, if you're using the default race gamemode then this code will do the job:

local sx_, sy_ = guiGetScreenSize ( )
local sx, sy = sx_/1440, sy_/900

function distanceFromPlayerToCheckpoint(player, i)
    g_Checkpoints = getAll("checkpoint")
	local checkpoint = g_Checkpoints[getElementData(player, "race.checkpoint")]
	if checkpoint == nil then
		return false
	end
	local x, y, z = getElementPosition(player)
	return getDistanceBetweenPoints3D(x, y, z, unpack(checkpoint.position))
end

function getAll(name)
	local result = {}
	for i,element in ipairs(getElementsByType(name)) do
		result[i] = {}
		result[i].id = getElementID(element) or i
		local position = {
					tonumber(getElementData(element,"posX")),
					tonumber(getElementData(element,"posY")),
					tonumber(getElementData(element,"posZ"))
				}
		result[i].position = position;
	end
	return result
end

function draw() 
    dxDrawText(tostring(distanceFromPlayerToCheckpoint(localPlayer)), sx_ * 1.5200, sy_ * 0.9843, sx_ * 0.2172, sy_ * 1.0167, tocolor(0, 0, 0, 255), 0.55*sy, "bankgothic", "center", "top", false, false, false, false, false)
end
addEventHandler("onClientRender", root, draw)

 

  • Like 1
Link to comment
4 minutes ago, koragg said:

Xiti said this on skype "You need then to subtraction the size of checkpoint to have at accurate" but I couldn't find anything relevant around Google, any thoughts?

Well I don't think so you can achieve the checkpoint(marker) element anyway and then getMarkerSize. However, you can just subtract a specific number from the distance. By viewing the above photo, you can try -15.

Link to comment
2 minutes ago, Gravestone said:

Well I don't think so you can achieve the checkpoint(marker) element anyway and then getMarkerSize. However, you can just subtract a specific number from the distance. By viewing the above photo, you can try -15.

About the -15, isn't that different if cp size is bigger/smaller than the one on the pic? :D

Link to comment

Tried this and while there are no errors, there is no distance now as well.

local sx_, sy_ = guiGetScreenSize ( )
local sx, sy = sx_/1440, sy_/900

function draw()
	for k,v in ipairs(getElementsByType("player")) do
		local state = getElementData(v, "player state")
		if state == "Spectating" or state == "Away" or state == "Dead" or state == "Finished" or state == "Not Ready" then return end
		if distanceFromPlayerToCheckpoint(localPlayer) then
		distance = round(distanceFromPlayerToCheckpoint(localPlayer))
		local cp = getElementByID("checkpoint")
		if cp then
		local size = getMarkerSize (cp)
		if size then
		local fix = distance - size
		dxDrawText(fix.." m to next checkpoint", sx_ * 0.8734, sy_ * 0.2009, sx_ * 0.9510, sy_ * 0.2259, tocolor(254, 254, 34, 255), 1*sy, "default-bold", "center", "top", false, false, false, false, false)
		end
		end
		end
	end
end
addEventHandler("onClientRender", root, draw)

 

Edited by koragg
Link to comment
2 hours ago, koragg said:

Tried this and while there are no errors, there is no distance now as well.

That is because:

2 hours ago, koragg said:

Line 11 checks if the getElementByID had returned the ID of the given element. In this case, you're using the first argument as a string, which has to be an element instead.

Quote
  • id: The ID of the element as it appears in the XML file or as set by setElementID.

Gimme some time, I'll try to figure it out.
Edit: Done, here's how it will work:



local sx_, sy_ = guiGetScreenSize ( )
local sx, sy = sx_/1440, sy_/900

function distanceFromPlayerToCheckpoint(player, i)
    g_Checkpoints = getAll("checkpoint")
	local checkpoint = g_Checkpoints[getElementData(player, "race.checkpoint")]
	if checkpoint == nil then
		return false
	end
	local x, y, z = getElementPosition(player)
	for i, v in ipairs(checkpoint) do
		outputChatBox(unpack(v))
	end
	return getDistanceBetweenPoints3D(x, y, z, unpack(checkpoint.position)), unpack(checkpoint.size)
end

function getAll(name)
	local result = {}
	for i,element in ipairs(getElementsByType(name)) do
		result[i] = {}
		result[i].id = getElementID(element) or i
		local position = {
					tonumber(getElementData(element,"posX")),
					tonumber(getElementData(element,"posY")),
					tonumber(getElementData(element,"posZ"))
				}
		local size = {
					tonumber(getElementData(element, "size"))
				}
		result[i].position = position;
		result[i].size = size;
 	end
	return result
end

function draw() 
	local distance, size = distanceFromPlayerToCheckpoint(localPlayer)
    dxDrawText(distance-size*5, sx_ * 1.5200, sy_ * 0.9843, sx_ * 0.2172, sy_ * 1.0167, tocolor(0, 0, 0, 255), 0.55*sy, "bankgothic", "center", "top", false, false, false, false, false)
end
addEventHandler("onClientRender", root, draw)

 

Edited by Gravestone
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...