Jump to content

Text labels


uBiT

Recommended Posts

Hello, i'm trying to create a function create3DText, to show in-game 3D text, which was created with dxDrawText.

Although function works, but i have a strange problem and i don't know how to solve it.

Here are my client-side script:

local TextLabels = { } 
local i = 0 
  
function create3DText(text, color, font, scale, x, y, z, dist, dimension, hex) 
    if not dimension then dimension = 0 end 
    i = i + 1 
    local elm = createElement('base') 
    setElementPosition(elm, x, y, z) 
    setElementDimension(elm, dimension) 
    TextLabels[i] = elm 
    local elmData = { } 
    elmData['text'] = text 
    elmData['color'] = color 
    elmData['font'] = font 
    elmData['scale'] = scale 
    elmData['dist'] = dist 
    elmData['hex'] = hex 
    setElementData(elm, 'text.elm.Data', elmData) 
    return i 
end 
  
function destroy3DText(labelID) 
    if not labelID or not TextLabels[labelID] then return end 
    table.remove(TextLabels, labelID) 
    setElementData(TextLabels[labelID], 'text.elm.Data', false) 
    if isElement(TextLabels[labelID]) then destroyElement(TextLabels[labelID]) end 
end 
  
function showLabels() 
    for i, label in pairs(TextLabels) do 
        if isElement(label) then 
            local elmData = getElementData(label, 'text.elm.Data') 
            if isElement(elmData['attach']) then 
                local posX, posY, posZ = getElementPosition(elmData['attach']) 
                setElementPosition(label, posX, posY, posZ) 
            end 
            create3DText_(label, elmData['text'], elmData['color'], elmData['font'], elmData['scale'], elmData['dist'], elmData['hex'], elmData['aX'], elmData['aY'], elmData['aZ']) 
        else 
            table.remove(TextLabels, i) 
        end 
    end 
end 
addEventHandler('onClientRender', getRootElement(), showLabels) 
  
function create3DText_(elm, text, color, font, scale, dist, hex, x, y, z) 
    if not x then x = 0.0 end 
    if not y then y = 0.0 end 
    if not z then z = 0.0 end 
    local mX, mY, mZ = getElementPosition(elm) 
    local cX, cY, cZ = getCameraMatrix() 
    if isLineOfSightClear(cX, cY, cZ, mX, mY, mZ, false, false, false, false, false, false, false, elm) then 
        local distance = getDistanceBetweenPoints3D(cX, cY, cZ, mX, mY, mZ) 
        if distance <= dist then 
            local pX, pY = getScreenFromWorldPosition(mX + x, mY + y, mZ + z, 0.06) 
            if pX then 
                dxDrawText(text, pX, pY, pX, pY, color, scale, font, 'center', 'center', false, false, false, hex) 
            end 
        end 
    end 
end 
  
function attach3DText(labelID, element, x, y, z) 
    if not element or not labelID then return end 
    for i, label in pairs(TextLabels) do 
        if i == labelID then 
            local elmData = getElementData(label, 'text.elm.Data') 
            elmData['attach'] = element 
            elmData['aX'] = x 
            elmData['aY'] = y 
            elmData['aZ'] = z 
            setElementData(label, 'text.elm.Data', elmData) 
            break 
        end 
    end 
end 
  
addCommandHandler('say1', 
function(cmd, ...) 
    if isTimer(timer) then  
        killTimer(timer)  
        destroy3DText(getElementData(getLocalPlayer(), 'text.elm.attach')) 
        setElementData(getLocalPlayer(), 'text.elm.attach', false) 
    end 
    local ontop = create3DText('* '..getPlayerName(getLocalPlayer())..' '..table.concat({...}, ' '), tocolor(194, 162, 218, 255), 'default-bold', 1.05, 1404.7156,238.8190,19.5547, 20.0, 0, false) 
    attach3DText(ontop, getLocalPlayer(), 0.0, 0.0, 1.2) 
    setElementData(getLocalPlayer(), 'text.elm.attach', ontop) 
    timer = setTimer(function(label)  
        destroy3DText(label) 
        setElementData(getLocalPlayer(), 'text.elm.attach', false) 
    end, 1000 * 10, 1, ontop) 
end) 

The problem is, with destroying 3D text's. For a test, i written /say1 command.

Example: if i type '/say1 one' - it shows, everything is ok, and after 10 seconds timer destroys it, same as for '/say1 two', '/say1 three'... BUT Dunno why, but after third test, typing '/say1 four' it shows but timer won't destroy it... Also this part from command:

  
if isTimer(timer) then  
    killTimer(timer)  
    destroy3DText(getElementData(getLocalPlayer(), 'text.elm.attach')) 
    setElementData(getLocalPlayer(), 'text.elm.attach', false) 
end 

won't destroy it and i dunno why this could be happen.

Any solution would be really appreciated.

Link to comment

Nope, no errors/warnings at all.

EDIT: Solved.

Just needed to change in function destroy3DText this line: table.remove(TextLabels, i) to TextLabels = nil

Because with table.remove it removes row in that table and other row's gets a new 'id' - thats why it couldn't destroy a label.

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