Jump to content

[HELP] createMarker() ignores 'size' attribute.


koragg

Recommended Posts

As some of you know I'm working on a resource which makes spectating the vehicle created from the race_ghost resource possible. I wanted to create markers on the spots where checkpoints would be so that it seems more like spectating a normal player rather than an object. And I have this problem:

The createMarker() function ignores the 'size' attribute on maps which were converted with the batch converter from the old MTA format to the newer one. Here is that part of code: client-side

local checkpoints = {}
local CPMarker = {}
addEvent("onClientMapStarting", true)
function onClientMapStarting()
	checkpoints = getAll("checkpoint")
addEventHandler("onClientMapStarting", root, onClientMapStarting)
-------------------------------------------------------------------------------------------------------------------------
function checkAndFixTabData()
	if checkpoints and #checkpoints > 0 then
		for i = 1, #checkpoints do
			local color = { 255, 255, 255, 128 }
			local CPposX, CPposY, CPposZ = unpack(checkpoints[i].position)
			if not isElement(CPMarker[i]) then
				CPMarker[i] = createMarker(CPposX, CPposY, CPposZ, checkpoints[i].type, checkpoints[i].size, color[1], color[2], color[3], color[4])
			end
		end
	end
end
addEventHandler("onClientRender", root, checkAndFixTabData)
-------------------------------------------------------------------------------------------------------------------------
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 rotation = 0
		if getElementData(element,"rotation") then
		    rotation = tonumber(getElementData(element,"rotation"))
		elseif getElementData(element,"rotZ") then
		    rotation = tonumber(getElementData(element,"rotZ"))
		else
			rotation = 0
		end
		local vehicle = tonumber(getElementData(element,"vehicle"))
		local size
		if getElementData(element,"size") then
			size = tonumber(getElementData(element,"size"))
		else
			size = 3.0
		end
		local type
		if getElementData(element,"type") then
			type = tostring(getElementData(element,"type"))
		else
			type = "checkpoint"
		end
		result[i].position = position;
		result[i].rotation = rotation;
		result[i].vehicle = vehicle;
		result[i].size = size;
		result[i].type = type;
		result[i].element = element;
	end
	return result
end

I tried to make the 'size' a number with 'tonumber' but it still didn't work. I tried to round it up to an integer (although wiki says that it can be a float as well) - no change. I tried to get the 'size' attribute via searching the map's .map file = not working, same as before. When I output the 'size' in the chatbox it shows up as a number. There are no errors in debug whatsoever. Everything seems perfect yet the marker size is not the same size as the size of the checkpoint that's supposed to be there (checkpoints.size). And all of this happens on maps which were converted from a very old MTA map format to a newer one via the race wiki's batch converter. Maps made on the new MTA editor work fine - marker gets created and the size is the one that the checkpoint has in the .map file. Another note: both formats have the exact same way of indicating the checkpoint's size in the .map file. They use an attribute 'size' in an identical way, yet createMarker() ignores the value of 'size' on converted maps while it works fine on maps made on new editor. Below are examples of old and new .map format so you see that the attribute is the same in both formats:

old format:

<?xml version="1.0" encoding="utf-16"?>
<map mod="deathmatch">
	<checkpoint posX="2343.127930" posY="267.152954" posZ="25.335938" size="3.950000" color="#7bd465" id="checkpoint4" nextid="checkpoint5" />
</map>

new format:

<map edf:definitions="race,editor_main">
	<checkpoint id="checkpoint () (5)" type="checkpoint" color="#F56D0999" size="10" alpha="255" interior="0" nextid="checkpoint () (6)" posX="-2204.84253" posY="508.3909" posZ="34.054" rotX="0" rotY="0" rotZ="0"></checkpoint>
</map>

All other attributes work perfect and marker gets created on the checkpoint's spot on both map formats, just the 'size' is ignored on older ones. HELP! This is driving me nuts because there're no errors or anything and the code does indeed work on new maps, so why not on converted old  ones as well?!?

Here's the other way I tried (via xmlLoadFile, etc)...not that it made a difference:

server-side

function onMapStarting(mapInfo)
	local mapRes = mapInfo.resname
	local mapMetaFile = xmlLoadFile(":"..mapRes.."/meta.xml")
	local mapMapAttribute
	local mapMapNode
	local mapFileName
	if mapMetaFile then
		mapMapAttribute = xmlFindChild(mapMetaFile, "map", 0)
	end
	if mapMapAttribute then
		mapMapNode = xmlNodeGetAttributes(mapMapAttribute)
	end
	if mapMapNode then
		for name, value in pairs(mapMapNode) do
			mapFileName = value
		end
	end
	if mapMetaFile then
		xmlUnloadFile(mapMetaFile)
	end
	if mapFileName then
		local mapFile = xmlLoadFile(":"..mapRes.."/"..mapFileName.."")
		local totalCPs = getAll("checkpoint")
		local checkpointsAttribute = {}
		local mapCPsNode = {}
		local CPsize = {}
		if mapFile then
			for i = 1, #totalCPs do
				checkpointsAttribute[i] = xmlFindChild(mapFile, "checkpoint", 0)
				if checkpointsAttribute[i] then
					mapCPsNode[i] = xmlNodeGetAttributes(checkpointsAttribute[i])
				end
				if mapCPsNode[i] then
					for name, value in pairs(mapCPsNode[i]) do
						if name == "size" then
							CPsize[i] = tonumber(round(value))
						end
					end
				end
			end
			triggerClientEvent(root, "getCPSizes", resourceRoot, CPsize)
		end
	end
	if mapFile then
		xmlUnloadFile(mapFile)
	end
end
addEventHandler("onMapStarting", root, onMapStarting)
-------------------------------------------------------------------------------------------------------------------------
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 rotation = 0
		if getElementData(element,"rotation") then
		    rotation = tonumber(getElementData(element,"rotation"))
		elseif getElementData(element,"rotZ") then
		    rotation = tonumber(getElementData(element,"rotZ"))
		else
			rotation = 0
		end
		local vehicle = tonumber(getElementData(element,"vehicle"))
		local size
		if getElementData(element,"size") then
			size = tonumber(getElementData(element,"size"))
		else
			size = 3.0
		end
		local type
		if getElementData(element,"type") then
			type = tostring(getElementData(element,"type"))
		else
			type = "checkpoint"
		end
		result[i].position = position;
		result[i].rotation = rotation;
		result[i].vehicle = vehicle;
		result[i].size = size;
		result[i].type = type;
		result[i].element = element;
	end
	return result
end
-------------------------------------------------------------------------------------------------------------------------
--http://lua-users.org/wiki/FormattingNumbers
function round(val, decimal)
  if (decimal) then
    return math.floor( (val * 10^decimal) + 0.5) / (10^decimal)
  else
    return math.floor(val+0.5)
  end
end

client-side

local checkpoints = {}
local CPMarker = {}
local CPsizes = {}
-------------------------------------------------------------------------------------------------------------------------
addEvent("getCPSizes", true)
function getCPSizes(checkpointSizes)
	CPsizes = checkpointSizes
end
addEventHandler("getCPSizes", root, getCPSizes)
-------------------------------------------------------------------------------------------------------------------------
addEvent("onClientMapStarting", true)
	checkpoints = getAll("checkpoint")
addEventHandler("onClientMapStarting", root, onClientMapStarting)
-------------------------------------------------------------------------------------------------------------------------
function checkAndFixTabData()
	if checkpoints and #checkpoints > 0 then
		for i = 1, #checkpoints do
			local color = { 255, 255, 255, 128 }
			local CPposX, CPposY, CPposZ = unpack(checkpoints[i].position)
			if not isElement(CPMarker[i]) then
				CPMarker[i] = createMarker(CPposX, CPposY, CPposZ, checkpoints[i].type, tonumber(round(CPsizes[i])), color[1], color[2], color[3], color[4])
			end
		end
	end
end
addEventHandler("onClientRender", root, checkAndFixTabData)
------------------------------------------------------------------------------------------------------------------------
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 rotation = 0
		if getElementData(element,"rotation") then
		    rotation = tonumber(getElementData(element,"rotation"))
		elseif getElementData(element,"rotZ") then
		    rotation = tonumber(getElementData(element,"rotZ"))
		else
			rotation = 0
		end
		local vehicle = tonumber(getElementData(element,"vehicle"))
		local size
		if getElementData(element,"size") then
			size = tonumber(getElementData(element,"size"))
		else
			size = 3.0
		end
		local type
		if getElementData(element,"type") then
			type = tostring(getElementData(element,"type"))
		else
			type = "checkpoint"
		end
		result[i].position = position;
		result[i].rotation = rotation;
		result[i].vehicle = vehicle;
		result[i].size = size;
		result[i].type = type;
		result[i].element = element;
	end
	return result
end
-------------------------------------------------------------------------------------------------------------------------
--http://lua-users.org/wiki/FormattingNumbers
function round(val, decimal)
  if (decimal) then
    return math.floor( (val * 10^decimal) + 0.5) / (10^decimal)
  else
    return math.floor(val+0.5)
  end
end

Nothing I try works. Out of any sort of ideas for this.

Link to comment

This is the solution 

Turned out old maps use the size attribute in a different way than new ones and the value needs to be multiplied by 4. In the above topic you'll see how to detect if a map is in the old format or not by inspecting it's .map file. If there is a "mod" attribute then the map is in the old format so the checkpoint size value needs to be multiplied four times to have it in real size. Problem fixed :)

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...