Jump to content

Scoreboard Flags (again)


h4x7o0r

Recommended Posts

First of all, i have to mention that i've already seen other topics regarding this subject and tried to put the code together, but i couldn't figure it out how to make it work.

I've also read that the scoreboard resource itself, can't display images so it should be modified to make it work so the following code should be added (somewhere after the line 704 from dxscoreboard_client) :

  
    elseif column.name == "Home" then 
    dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI ) 
    else 
  

Some user suggested to post the entire scoreboard_client script because my scoreboard could be kinda different.

So here's my dxscoreboard_client.lua

  
-- THESE CAN BE CHANGED
triggerKey = "tab" -- default button to open/close scoreboard
settingsKey = "F7" -- default button to open the settings window
drawOverGUI = true -- draw scoreboard over gui?
seperationSpace = 80 -- the space between top/bottom screen and scoreboard top/bottom in pixels
 
-- BUT DON'T TOUCH THESE
scoreboardToggled = false
scoreboardForced = false
scoreboardDrawn = false
forceScoreboardUpdate = false
useAnimation = true
scoreboardIsToggleable = false
showServerInfo = false
showGamemodeInfo = false
showTeams = true
useColors = true
drawSpeed = 1
scoreboardScale = 1
teamHeaderFont = "clear"
contentFont = "default-bold"
columnFont = "default-bold"
serverInfoFont = "default"
rmbFont = "clear"
cBlack = tocolor( 0, 0, 0 )
cWhite = tocolor( 255, 255, 255 )
cSettingsBox = tocolor( 255, 255, 255, 150 )
MAX_PRIRORITY_SLOT = 500
 
scoreboardColumns = {}
resourceColumns = {}
scoreboardDimensions = { ["width"] = 0, ["height"] = 0, ["phase"] = 1, ["lastSeconds"] = 0 }
scoreboardTicks = { ["lastUpdate"] = 0, ["updateInterval"] = 500 }
scoreboardContent = {}
firstVisibleIndex = 1
sortBy = { ["what"] = "__NONE__", ["dir"] = -1 } -- -1 = dec, 1 = asc
sbOutOffset, sbInOffset = 1, 1
sbFont = "clear"
sbFontScale = 0.68
serverInfo = {}
fontScale = { -- To make all fonts be equal in height
    ["default"] = 1.0,
    ["default-bold"] = 1.0,
    ["clear"] = 1.0,
    ["arial"] = 1.0,
    ["sans"] = 1.0,
    ["pricedown"] = 0.5,
    ["bankgothic"] = 0.5,
    ["diploma"] = 0.5,
    ["beckett"] = 0.5
}
selectedRows = {}
 
addEvent( "onClientPlayerScoreboardClick" )
 
addEventHandler( "onClientResourceStart", getResourceRootElement( getThisResource() ),
    function ( resource )
        cScoreboardBackground = tocolor( defaultSettings.bg_color.r, defaultSettings.bg_color.g, defaultSettings.bg_color.b, defaultSettings.bg_color.a )
        cSelection = tocolor( defaultSettings.selection_color.r, defaultSettings.selection_color.g, defaultSettings.selection_color.b, defaultSettings.selection_color.a )
        cHighlight = tocolor( defaultSettings.highlight_color.r, defaultSettings.highlight_color.g, defaultSettings.highlight_color.b, defaultSettings.highlight_color.a )
        cHeader = tocolor( defaultSettings.header_color.r, defaultSettings.header_color.g, defaultSettings.header_color.b, defaultSettings.header_color.a )
        cTeam = tocolor( defaultSettings.team_color.r, defaultSettings.team_color.g, defaultSettings.team_color.b, defaultSettings.team_color.a )
        cBorder = tocolor( defaultSettings.border_color.r, defaultSettings.border_color.g, defaultSettings.border_color.b, defaultSettings.border_color.a )
        cServerInfo = tocolor( defaultSettings.serverinfo_color.r, defaultSettings.serverinfo_color.g, defaultSettings.serverinfo_color.b, defaultSettings.serverinfo_color.a )
        cContent = tocolor( defaultSettings.content_color.r, defaultSettings.content_color.g, defaultSettings.content_color.b, defaultSettings.content_color.a )
       
        bindKey( triggerKey, "down", "Toggle scoreboard", "1" )
        bindKey( triggerKey, "up", "Toggle scoreboard", "0" )
        bindKey( settingsKey, "down", "Open scoreboard settings", "1" )
       
        addEventHandler( "onClientRender", getRootElement(), drawScoreboard )
        triggerServerEvent( "onClientDXScoreboardResourceStart", getRootElement() )
        readScoreboardSettings()
        triggerServerEvent( "requestServerInfo", getRootElement() )
 
        colorPicker.constructor()
    end
)
 
addEventHandler( "onClientPlayerQuit", getRootElement(),
    function()
        selectedRows[source] = nil
    end
)
 
function sendServerInfo( output )
    serverInfo = output
end
addEvent( "sendServerInfo", true )
addEventHandler( "sendServerInfo", getResourceRootElement( getThisResource() ), sendServerInfo )
 
function toggleScoreboard( _, state )
    state = iif( state == "1", true, false )
    if scoreboardIsToggleable and state then
        scoreboardToggled = not scoreboardToggled
    elseif not scoreboardIsToggleable then
        scoreboardToggled = state
    end
end
addCommandHandler( "Toggle scoreboard", toggleScoreboard )
 
function openSettingsWindow()
    if scoreboardDrawn then
        local sX, sY = guiGetScreenSize()
        if not (windowSettings and isElement( windowSettings ) and guiGetVisible( windowSettings )) then
            createScoreboardSettingsWindow( sX-323, sY-350 )
            showCursor( true )
        elseif isElement( windowSettings ) then
            destroyScoreboardSettingsWindow()
        end
    end
end
addCommandHandler( "Open scoreboard settings", openSettingsWindow )
 
addCommandHandler( "scoreboard",
    function ()
        scoreboardToggled = not scoreboardToggled
    end
)
 
function iif( cond, arg1, arg2 )
    if cond then
        return arg1
    end
    return arg2
end
 
function doDrawScoreboard( rtPass, onlyAnim, sX, sY )
    if #scoreboardColumns ~= 0 then
 
        --
        -- In/out animation
        --
        local currentSeconds = getTickCount() / 1000
        local deltaSeconds = currentSeconds - scoreboardDimensions.lastSeconds
        scoreboardDimensions.lastSeconds = currentSeconds
        deltaSeconds = math.clamp( 0, deltaSeconds, 1/25 )
           
        if scoreboardToggled or scoreboardForced then
            local phases = {
                [1] = {
                    ["width"]       = s(10),
                    ["height"]      = s(5),
                   
                    ["incToWidth"]  = s(10),
                    ["incToHeight"] = s(5),
               
                    ["decToWidth"]  = 0,
                    ["decToHeight"] = 0
                },
                [2] = {
                    ["width"]   = s(40),
                    ["height"]  = s(5),
                       
                    ["incToWidth"]  = calculateWidth(),
                    ["incToHeight"] = s(5),
                       
                    ["decToWidth"]  = s(10),
                    ["decToHeight"] = s(5)
                       
                },
                [3] = {
                    ["width"]       = calculateWidth(),
                    ["height"]      = s(30),
                       
                    ["incToWidth"]  = calculateWidth(),
                    ["incToHeight"] = calculateHeight(),
                       
                    ["decToWidth"]  = calculateWidth(),
                    ["decToHeight"] = s(5)
                }
            }
       
            if not useAnimation then
                scoreboardDimensions.width = calculateWidth()
                scoreboardDimensions.height = calculateHeight()
                scoreboardDimensions.phase = #phases
            end
           
            local maxChange = deltaSeconds * 30*drawSpeed
            local maxWidthDiff = math.clamp( -maxChange, phases[scoreboardDimensions.phase].incToWidth - scoreboardDimensions.width, maxChange )
            local maxHeightDiff = math.clamp( -maxChange, phases[scoreboardDimensions.phase].incToHeight - scoreboardDimensions.height, maxChange ) 
           
            if scoreboardDimensions.width < phases[scoreboardDimensions.phase].incToWidth then
                scoreboardDimensions.width = scoreboardDimensions.width + maxWidthDiff * phases[scoreboardDimensions.phase].width
                if scoreboardDimensions.width > phases[scoreboardDimensions.phase].incToWidth then
                    scoreboardDimensions.width = phases[scoreboardDimensions.phase].incToWidth
                end
            elseif scoreboardDimensions.width > phases[scoreboardDimensions.phase].incToWidth and not scoreboardDrawn then
                scoreboardDimensions.width = scoreboardDimensions.width - maxWidthDiff * phases[scoreboardDimensions.phase].width
                if scoreboardDimensions.width < phases[scoreboardDimensions.phase].incToWidth then
                    scoreboardDimensions.width = phases[scoreboardDimensions.phase].incToWidth
                end
            end
               
            if scoreboardDimensions.height < phases[scoreboardDimensions.phase].incToHeight then
                scoreboardDimensions.height = scoreboardDimensions.height + maxHeightDiff * phases[scoreboardDimensions.phase].height
                if scoreboardDimensions.height > phases[scoreboardDimensions.phase].incToHeight then
                    scoreboardDimensions.height = phases[scoreboardDimensions.phase].incToHeight
                end
            elseif scoreboardDimensions.height > phases[scoreboardDimensions.phase].incToHeight and not scoreboardDrawn then
                scoreboardDimensions.height = scoreboardDimensions.height - maxHeightDiff * phases[scoreboardDimensions.phase].height
                if scoreboardDimensions.height < phases[scoreboardDimensions.phase].incToHeight then
                    scoreboardDimensions.height = phases[scoreboardDimensions.phase].incToHeight
                end
            end
               
            if  scoreboardDimensions.width == phases[scoreboardDimensions.phase].incToWidth and
                scoreboardDimensions.height == phases[scoreboardDimensions.phase].incToHeight then
                if phases[scoreboardDimensions.phase + 1] then
                    scoreboardDimensions.phase = scoreboardDimensions.phase + 1
                else
                    if not scoreboardDrawn then
                        bindKey( "mouse2", "both", showTheCursor )
                        bindKey( "mouse_wheel_up", "down", scrollScoreboard, -1 )
                        bindKey( "mouse_wheel_down", "down", scrollScoreboard, 1 )
                        addEventHandler( "onClientClick", getRootElement(), scoreboardClickHandler )
                        if not (windowSettings and isElement( windowSettings )) then
                            showCursor( false )
                        end
                        triggerServerEvent( "requestServerInfo", getRootElement() )
                    end
                    scoreboardDrawn = true
                end
            end
        elseif scoreboardDimensions.width ~= 0 and scoreboardDimensions.height ~= 0 then
            local phases = {
                [1] = {
                    ["width"]       = s(10),
                    ["height"]      = s(5),
                   
                    ["incToWidth"]  = s(10),
                    ["incToHeight"] = s(5),
               
                    ["decToWidth"]  = 0,
                    ["decToHeight"] = 0
                },
                [2] = {
                    ["width"]   = s(40),
                    ["height"]  = s(5),
                       
                    ["incToWidth"]  = calculateWidth(),
                    ["incToHeight"] = s(5),
                       
                    ["decToWidth"]  = s(10),
                    ["decToHeight"] = s(5)
                       
                },
                [3] = {
                    ["width"]       = calculateWidth(),
                   
Link to comment

As some ppl related before, the scoreboard itself can't render images by default so it needs to have inserted some other rows.

Here's the related topic where those things have been discussed before: https://forum.multitheftauto.com/viewtop ... 91&t=41069

I should insert that part of script somewhere between (700-710 line) but idk where exactly. When i've tried to put it somewhere , the resource has stopped working, that' why i've posted all code.

Thank you for you time.

LE: No errors or stuff, just flag with the image isn't rendered.

Link to comment

Warning: scoareboard\dxscoreboard_client.lua:719:Bad usage @ 'dxDrawImage' [Can't load file]

                                    end 
                                    local partOfName = string.sub( playerName, firstCodePos, secondCodePos ) 
                                    local textLength = dxGetTextWidth( partOfName, fontscale(contentFont, s(1)), contentFont ) 
                                    dxDrawText( partOfName, xPos+s(1),  y+s(1), topX+x+s(1+column.width),   y+s(11)+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ),    tocolor( 0, 0, 0, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI ) 
                                    dxDrawText( partOfName, xPos,       y,      topX+x+s(column.width),     y+dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ),          tocolor( r or 255, g or 255, b or 255, a or 255 ), fontscale(contentFont, s(1)), contentFont, "left", "top", true, false, drawOverGUI ) 
                                    xPos = xPos + textLength 
                                end 
                                    elseif column.name == "Home" then 
        dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI ) 
                            elseif type( content ) == "table" and column.name ~= "name" then 
                                if content.type == "image" and content.src then 
                                    local itemHeight = dxGetFontHeight( fontscale(contentFont, scoreboardScale), contentFont ) 
                                    content.height = content.height or itemHeight 
                                    content.width = content.width or itemHeight 
                                    local itemWidth = itemHeight/content.height * content.width 
  

This is the line #719:

  
       dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI ) 
  

Link to comment

You've been right, the flags weren't in that location. Thank you very much for your help.

Now i'm having something like this :

302ur85.png

To be more explicit, i'm using 2 scripts (1 for Home and 1 for Country)

Home

  
  
     exports.scoreboard:addScoreboardColumn('Home') 
      
            function showcountry() 
            local flag = exports.admin:getPlayerCountry ( source ) 
                     if flag then 
                     setElementData(source,"Home",":admin/client/images/flags/"..flag..".png") 
                     else 
                     flag = "N/A" 
                     end 
             end 
     addEventHandler("onPlayerJoin",getRootElement(),showcountry) 
  

and Country (https://community.multitheftauto.com/index.php?p= ... ls&id=1995)

  
 
 
-- IMPORTANT: If you don't want to read this just don't read it
-- and please if you change the script, keep my credits.
 
 
 
--[[
 
******************************************
*
*    PROJECT:    Country ID Project v1.1.1
*
*    Made by:    Timic
*    Thanks to:  lil_Toady
*
******************************************
 
>> Description
 
"Hello, thanks for using this resource, I'm
very glad to update it to 1.1 and improve it
I'll still continue this project, so report
every bug on the community."
 
==========================================
 
>> Installation
 
Just open countryid.zip and then you'll have
to insert it into a folder, so create a folder
called countryid and then put files into the folder
you created.
You'll also have to put this folder into
"<HARD DISK>:\Program Files\<Your MTA folder>\server\mods\deathmatch\resources\"
folder.
If your server was running at the time of
installation, just type: refresh
in console or /refresh in chat box. Of
course you must be logged in as admin to
use these commands.
 
IMPORTANT:
 
Of course you'll have to put it in the ACL.xml file.
(ACL means Access Control List)
 
Example:
a) Open ACL.XML
b) Add after <group name="Admin"> the following line
c) <object name="resource.CountryID" />
d) Save it
e) Restart the server
f) Type in console refresh or type /refresh in chatbox
g) Start it (Type in console start or type /start in chatbox)
 
==========================================
 
>> LICENCE
 
NO WARRANTY
THE SOFTWARE IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
BUT WITHOUT ANY WARRANTY. IT IS PROVIDED "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE
SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION.
 
]]
 
g_Root = getRootElement()
 
function Initiate()
    country = getPlayerCountry(source)
        if country == nil or country == false then
           country = "n/a"
        end
    setElementData(source, "country", country)
end
addEventHandler('onPlayerJoin', g_Root, Initiate)
 
addEventHandler("onResourceStart",getResourceRootElement(getThisResource()),function()
-- You can remove this if you want
outputChatBox('#ffffff[C_ID] #ffff00Initiating CID system... #ffffffDONE', getRootElement(), 255, 100, 100, true)
        call(getResourceFromName("scoreboard"),"addScoreboardColumn","country", getRootElement(), 9, 50)
        setTimer(
function()
     country = getPlayerCountry(source)
        if country == nil or country == false then
           country = "n/a"
        end
    setElementData(source, "country", country)
end, 4000, 1)
 
    end
)
aCountries = {}
 
 
function getPlayerCountry ( player )
    return getIpCountry ( getPlayerIP ( player ) )
end
function getIpCountry ( ip )
    local ip_group = tonumber ( gettok ( ip, 1, 46 ) )
    local ip_code = ( gettok ( ip, 1, 46 ) * 16777216 ) + ( gettok ( ip, 2, 46 ) * 65536 ) + ( gettok ( ip, 3, 46 ) * 256 ) + ( gettok ( ip, 4, 46 ) )
    if ( #aCountries == 0 ) then
        loadIPGroups ()
    end
    if ( not aCountries[ip_group] ) then
        aCountries[ip_group] = {}
    end
    for id, group in ipairs ( aCountries[ip_group] ) do
        if ( ( group.rstart <= ip_code ) and ( ip_code <= group.rend ) ) then
            return group.rcountry
        end
    end
    return false
end
 
 
-- Load all IP groups from "conf/IpToCountryCompact.csv"
function loadIPGroups ()
    unrelPosReset()
 
    local readFilename = "conf/IpToCountryCompact.csv";
    local hReadFile = fileOpen( readFilename, true )
    if not hReadFile then
        outputHere ( "Cannot read " .. readFilename )
        return
    end
 
    local buffer = ""
    while true do
        local endpos = string.find(buffer, "\n")
 
        -- If can't find CR, try to load more from the file
        if not endpos then
            if fileIsEOF( hReadFile ) then
                break
            end
            buffer = buffer .. fileRead( hReadFile, 500 )
        end
 
        if endpos then
            -- Process line
            local line = string.sub(buffer, 1, endpos - 1)
            buffer = string.sub(buffer, endpos + 1)
 
            local parts = split( line, string.byte(',') )
            if #parts > 2 then
                local rstart = tonumber(parts[1])
                local rend = tonumber(parts[2])
                local rcountry = parts[3]
 
                -- Relative to absolute numbers
                rstart = unrelRange ( rstart )
                rend = unrelRange ( rend )
 
                local group = math.floor( rstart / 0x1000000 )
 
                if not aCountries[group] then
                    aCountries[group] = {}
                end
                local count = #aCountries[group] + 1
                aCountries[group][count] = {}
                aCountries[group][count].rstart = rstart
                aCountries[group][count].rend = rend
                aCountries[group][count].rcountry = rcountry
            end
        end
    end
 
    fileClose(hReadFile)
end
 
 
 
-- Make a stream of absolute numbers relative to each other
local relPos = 0
function relPosReset()
    relPos = 0
end
function relRange( v )
    local rel = v - relPos
    relPos = v
    return rel
end
 
-- Make a stream of relative numbers absolute
local unrelPos = 0
function unrelPosReset()
    unrelPos = 0
end
function unrelRange( v )
    local unrel = v + unrelPos
    unrelPos = unrel
    return unrel
end
 
 
-- IP2C logging
function outputHere( msg )
    --outputServerLog ( msg )
    outputChatBox ( msg )
end
 
 
----------------------------------------------------------------------------------------
--
-- Set to true to enable commands "makecsv" and "iptest"
--
----------------------------------------------------------------------------------------
local makeAndTestCompactCsv = false
 
 
if makeAndTestCompactCsv then
 
    local makeCor
 
    -- Takes a 'IPV4 CSV' file sourced from [url=http://software77.net/geo-ip/]http://software77.net/geo-ip/[/url]
    -- and makes a smaller one for use by Admin
    addCommandHandler ( "makecsv",
        function ()
            local status = makeCor and coroutine.status(makeCor)
            if (status == "suspended") then
                outputHere( "Please wait" )
                return
            end
            makeCor = coroutine.create ( makeCompactCsvWorker )
            coroutine.resume ( makeCor )
        end
    )
 
 
    function makeCompactCsvWorker ()
        outputHere ( "makeCompactCsv started" )
        relPosReset()
 
        local readFilename = "conf/IpToCountry.csv";
        local hReadFile = fileOpen( readFilename, true )
        if not hReadFile then
            outputHere ( "Cannot read " .. readFilename )
            return
        end
 
        local writeFilename = "conf/IpToCountryCompact.csv";
        local hWriteFile = fileCreate( writeFilename, true )
        if not hWriteFile then
           
Link to comment

Thanks again mate.

  
                                    elseif column.name == "Home" then 
        dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI ) 
        dxDrawText ( -- this way ? 
                            elseif type( content ) == "table" and column.name ~= "name" then 
  

Idk how can i call content from another resource with different name.

Oh that's way to complex for me, thank you for all your help.

Link to comment

The country resource has a separate script that's adding a column from there to scoreboard (isn't like this one being in a comparison (elseif column.name =="home")), so i think u told me to remove this line from country resource :

  
        call(getResourceFromName("scoreboard"),"addScoreboardColumn","country", getRootElement(), 9, 50) 
  

but my problem is how can i take the content exported from country without adding a new column? i think i should use dxDrawText

  
        dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI ) 
        dxDrawText ( topX+5 , y+s(1), ... ) 
  

Link to comment
                                    elseif column.name == "Home" then 
        dxDrawImage( topX+theX, y+s(1), 16, 11, content, 0, 0, 0, cWhite, drawOverGUI ) 
        dxDrawText ( topX+theX + 5, y+s(1), 16, 11, getElementData ( player, "country" ), cWhite, 1, "default", "right", "bottom", true, false, drawOverGUI ) 

Try it.

Link to comment

Change where you set the flag to this:

exports.scoreboard:addScoreboardColumn ( 'Home' ) 
  
function showcountry ( ) 
    local flag = exports.admin:getPlayerCountry ( source ) or "N/A" 
    if ( flag ) then 
        setElementData ( source, "Home", { ":admin/client/images/flags/".. flag ..".png", flag } ) 
    end 
end 
addEventHandler ( "onPlayerJoin", root, showcountry ) 

And on scoreboard:

                                   elseif column.name == "Home" then 
        dxDrawImage( topX+theX, y+s(1), 16, 11, content [ 1 ], 0, 0, 0, cWhite, drawOverGUI ) 
        dxDrawText ( tostring ( content [ 2 ] ), topX+theX + 5, y+s(1), 16, 11, cWhite, 1, "default", "right", "bottom", true, false, drawOverGUI ) 

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