Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Custom Car Tags for Assetto Corsa Server
- -- Parallelogram-style player tags with name, input type, country flag, and ping bars
- local driverData = {}
- local nametagCanvas = {}
- local numberOfCars = 0
- local globaldt = 0.016
- -- Initialize data for all cars
- for i = 0, 1000 do
- if not ac.getCar(i) then
- break
- end
- numberOfCars = numberOfCars + 1
- driverData[i] = {
- nationCode = "" -- Initialize nation code
- }
- nametagCanvas[i] = {
- canvas = ui.ExtraCanvas(vec2(480, 120), 1, render.AntialiasingMode.ExtraSharpCMAA),
- fadeCurrent = 0,
- fadeTarget = 0,
- lastUpdate = 0
- }
- end
- local tagsDistance = 150
- local updateInterval = 0.1
- -- Function to get input type (returns type identifier)
- function getInputType(carIndex)
- local car = ac.getCar(carIndex)
- if not car then return "gamepad" end
- -- Get current input values
- local steer = car.steer
- local gas = car.gas
- local brake = car.brake
- -- Enhanced detection logic
- local steerAbs = math.abs(steer)
- -- Check for digital inputs (keyboard) - very precise on/off values
- if (steerAbs > 0.98 or steerAbs == 0) and (gas > 0.95 or gas == 0) and (brake > 0.95 or brake == 0) then
- return "keyboard"
- end
- -- Check for wheel - smooth analog steering with fine control
- if steerAbs > 0.02 and steerAbs < 0.98 then
- return "wheel"
- end
- -- Default to gamepad/controller
- return "gamepad"
- end
- -- Function to draw country flag
- function drawCountryFlag(carIndex, x, y, alpha)
- -- Get nation code from driver data (this is how AC stores it)
- local nationCode = ""
- -- Try to get nation code from the driver data
- if driverData[carIndex] and driverData[carIndex].nationCode then
- nationCode = driverData[carIndex].nationCode
- end
- if nationCode ~= "" then
- -- Use local AC flag images
- local flagPath = "/content/gui/NationFlags/" .. nationCode .. ".png"
- local flagWidth = 24
- local flagHeight = 18
- local success = pcall(function()
- ui.drawImage(
- flagPath,
- vec2(x, y),
- vec2(x + flagWidth, y + flagHeight),
- rgbm(1, 1, 1, alpha)
- )
- end)
- -- Fallback if flag image doesn't exist - show nation code
- if not success and nationCode then
- ui.drawText(nationCode, vec2(x, y), rgbm(0.8, 0.8, 1.0, alpha))
- end
- else
- -- No country data available - show globe emoji
- ui.drawText("🌍", vec2(x, y), rgbm(0.6, 0.6, 0.6, alpha))
- end
- end
- -- Function to draw input icon (text or image)
- function drawInputIcon(inputType, x, y, alpha)
- if inputType == "wheel" then
- -- Draw steering wheel image
- local wheelURL = "https://i.ibb.co/ds8PPhzj/steering-wheel-1.png"
- local iconSize = 28 -- Size to match text icons
- local success = pcall(function()
- ui.drawImage(
- wheelURL,
- vec2(x, y),
- vec2(x + iconSize, y + iconSize),
- rgbm(1, 1, 1, alpha)
- )
- end)
- -- Fallback if URL loading fails
- if not success then
- ui.drawText("🚗", vec2(x, y), rgbm(1, 0.8, 0.2, alpha))
- end
- else
- -- Draw text icons for keyboard and gamepad
- local icon = "🎮" -- Default gamepad
- if inputType == "keyboard" then
- icon = "⌨️"
- end
- ui.drawText(icon, vec2(x, y), rgbm(1, 0.8, 0.2, alpha))
- end
- end
- -- Function to draw ping bars
- function drawPingBars(x, y, ping)
- local barWidth = 6
- local barHeight = 16
- local barSpacing = 3
- local maxBars = 4
- local bars = 4
- local barColor = rgb(0, 1, 0)
- if ping > 200 then
- bars = 1
- barColor = rgb(1, 0, 0)
- elseif ping > 150 then
- bars = 2
- barColor = rgb(1, 0.5, 0)
- elseif ping > 100 then
- bars = 3
- barColor = rgb(1, 1, 0)
- end
- for i = 1, maxBars do
- local barX = x + (i - 1) * (barWidth + barSpacing)
- local currentBarHeight = barHeight * (i / maxBars)
- local currentY = y + barHeight - currentBarHeight
- local alpha = (i <= bars) and 1.0 or 0.3
- local color = rgbm(barColor.r, barColor.g, barColor.b, alpha)
- ui.drawRectFilled(
- vec2(barX, currentY),
- vec2(barX + barWidth, y + barHeight),
- color
- )
- end
- end
- -- Function to draw parallelogram background
- function drawParallelogram(x, y, width, height, color)
- local skew = 20
- local topLeft = vec2(x + skew, y)
- local topRight = vec2(x + width + skew, y)
- local bottomRight = vec2(x + width, y + height)
- local bottomLeft = vec2(x, y + height)
- ui.drawTriangleFilled(topLeft, topRight, bottomRight, color)
- ui.drawTriangleFilled(topLeft, bottomRight, bottomLeft, color)
- local borderColor = rgbm(0.4, 0.4, 0.4, 0.9)
- ui.drawLine(topLeft, topRight, borderColor, 2)
- ui.drawLine(topRight, bottomRight, borderColor, 2)
- ui.drawLine(bottomRight, bottomLeft, borderColor, 2)
- ui.drawLine(bottomLeft, topLeft, borderColor, 2)
- end
- -- Function to draw main area parallelogram (without right border)
- function drawMainAreaParallelogram(x, y, width, height, color)
- local skew = 20
- local topLeft = vec2(x + skew, y)
- local topRight = vec2(x + width + skew, y)
- local bottomRight = vec2(x + width, y + height)
- local bottomLeft = vec2(x, y + height)
- ui.drawTriangleFilled(topLeft, topRight, bottomRight, color)
- ui.drawTriangleFilled(topLeft, bottomRight, bottomLeft, color)
- -- Only draw top, bottom, and left borders - no right border
- local borderColor = rgbm(0.4, 0.4, 0.4, 0.9)
- ui.drawLine(topLeft, topRight, borderColor, 2)
- ui.drawLine(bottomRight, bottomLeft, borderColor, 2)
- ui.drawLine(bottomLeft, topLeft, borderColor, 2)
- end
- -- Function to draw ping area background (darker section)
- function drawPingAreaBackground(x, y, width, height)
- local skew = 20
- local topLeft = vec2(x + skew, y)
- local topRight = vec2(x + width + skew, y)
- local bottomRight = vec2(x + width, y + height)
- local bottomLeft = vec2(x, y + height)
- -- Draw darker background for ping area
- local pingBgColor = rgbm(0.01, 0.01, 0.01, 0.95) -- Even darker, higher opacity
- ui.drawTriangleFilled(topLeft, topRight, bottomRight, pingBgColor)
- ui.drawTriangleFilled(topLeft, bottomRight, bottomLeft, pingBgColor)
- -- Draw angled separator line - positioned just to the left of ping bars
- local separatorX = x + 2 -- Move separator 2px to the right from ping area start
- local separatorTopLeft = vec2(separatorX + skew, y)
- local separatorBottomLeft = vec2(separatorX, y + height)
- local separatorColor = rgbm(0.5, 0.5, 0.5, 0.8)
- ui.drawLine(separatorTopLeft, separatorBottomLeft, separatorColor, 2)
- end
- -- Function to render the custom nametag
- function renderCustomNametag(carData)
- local canvas = nametagCanvas[carData.index].canvas
- local carIndex = carData.index -- Store the car index for consistency
- canvas:clear()
- -- Get all data for the specific car being processed
- local driverName = ac.getDriverName(carIndex)
- local ping = driverData[carIndex].ping or 50
- local inputType = getInputType(carIndex) -- Use the correct car index
- if string.len(driverName) > 15 then
- driverName = string.sub(driverName, 1, 15) .. "..."
- end
- -- Define layout
- local tagWidth = 440
- local tagHeight = 80
- local tagX = 20
- local tagY = 20
- local centerY = tagY + (tagHeight / 2) -- 60
- -- Define ping area dimensions
- local pingAreaWidth = 135 -- Increased width to accommodate moved separator
- local pingAreaX = tagX + tagWidth - pingAreaWidth -- Position at right side
- -- Draw main parallelogram with more opacity (no right border)
- drawMainAreaParallelogram(tagX, tagY, tagWidth - pingAreaWidth, tagHeight, rgbm(0.05, 0.05, 0.05, 0.7))
- -- Draw darker ping area background
- drawPingAreaBackground(pingAreaX, tagY, pingAreaWidth, tagHeight)
- -- Move ping elements left to fit better in parallelogram
- local pingBarsX = 350 -- Moved left from 385
- local pingBarsY = centerY - 8
- drawPingBars(pingBarsX, pingBarsY, ping)
- -- Using ui.drawText for text elements
- ui.pushFont(ui.Font.Main)
- -- Input icon - use new function that handles both text and image
- drawInputIcon(inputType, 60, centerY - 14, 1.0) -- Adjusted Y to center image better
- -- Country flag - positioned between input icon and name, use correct car index
- drawCountryFlag(carIndex, 130, centerY - 9, 1.0) -- Use carIndex instead of carData.index
- -- Player name - positioned with small gap from flag
- ui.drawText(driverName, vec2(170, centerY - 10), rgb(1, 1, 1)) -- Moved left to accommodate flag
- -- Ping text - positioned relative to ping bars
- ui.drawText(ping .. "ms", vec2(395, centerY - 8), rgb(0.9, 0.9, 0.9))
- ui.popFont()
- end
- -- Main nametag rendering function
- function renderDriverNameTag(carData)
- CurrentlyProcessedCar = carData
- -- Update driver data BEFORE rendering
- driverData[carData.index].racePosition = carData.racePosition
- driverData[carData.index].driverName = ac.getDriverName(carData.index)
- driverData[carData.index].ping = carData.ping or math.random(30, 120) -- Fallback for testing
- driverData[carData.index].distanceToCamera = carData.distanceToCamera
- -- Try to get nation code from available sources
- if not driverData[carData.index].nationCode or driverData[carData.index].nationCode == "" then
- -- Try different methods to get nation code
- local nationCode = ""
- -- Method 1: Try ac.getDriverInfo if it exists
- local success, driverInfo = pcall(function()
- return ac.getDriverInfo(carData.index)
- end)
- if success and driverInfo and driverInfo.nation then
- nationCode = driverInfo.nation
- end
- -- Method 2: Try alternative AC functions for nation code
- if nationCode == "" then
- local success2, nation = pcall(function()
- return ac.getDriverNation(carData.index)
- end)
- if success2 and nation then
- nationCode = nation
- end
- end
- -- Store the nation code (empty string if not found)
- driverData[carData.index].nationCode = nationCode
- end
- local currentTime = os.clock()
- if not driverData[carData.index].lastUpdate then
- driverData[carData.index].lastUpdate = currentTime
- end
- local shouldUpdate = (currentTime - driverData[carData.index].lastUpdate) > updateInterval
- if shouldUpdate and driverData[carData.index].distanceToCamera < tagsDistance then
- nametagCanvas[carData.index].canvas:update(function()
- renderCustomNametag(carData)
- end)
- driverData[carData.index].lastUpdate = currentTime
- end
- if driverData[carData.index].distanceToCamera < tagsDistance then
- local distance = driverData[carData.index].distanceToCamera
- local sizeScale = math.clamp(((tagsDistance - distance) / tagsDistance)^0.5, 0.6, 1.4)
- nametagCanvas[carData.index].fadeTarget = math.clamp((tagsDistance - distance) / (tagsDistance * 0.2), 0, 1)
- local fadeSpeed = globaldt * 4
- if nametagCanvas[carData.index].fadeTarget > nametagCanvas[carData.index].fadeCurrent then
- nametagCanvas[carData.index].fadeCurrent = math.min(
- nametagCanvas[carData.index].fadeCurrent + fadeSpeed,
- nametagCanvas[carData.index].fadeTarget
- )
- else
- nametagCanvas[carData.index].fadeCurrent = math.max(
- nametagCanvas[carData.index].fadeCurrent - fadeSpeed,
- nametagCanvas[carData.index].fadeTarget
- )
- end
- if nametagCanvas[carData.index].fadeCurrent > 0.01 then
- local canvasWidth = 480 * sizeScale
- local canvasHeight = 120 * sizeScale
- local canvasX = (600 - canvasWidth) / 2
- local canvasY = (250 - canvasHeight) / 2
- ui.drawImage(
- nametagCanvas[carData.index].canvas,
- vec2(canvasX, canvasY),
- vec2(canvasWidth, canvasHeight),
- rgbm(1, 1, 1, nametagCanvas[carData.index].fadeCurrent)
- )
- end
- else
- nametagCanvas[carData.index].fadeTarget = 0
- nametagCanvas[carData.index].fadeCurrent = 0
- end
- end
- function script.update(dt)
- globaldt = dt
- end
- ui.onDriverNameTag(
- true,
- rgbm(1, 1, 1, 0),
- renderDriverNameTag,
- {
- mainSize = 1.2,
- mirrorSize = 4,
- distanceMultiplier = 3,
- tagSize = vec2(600, 250)
- }
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement