-----------------------------------------------------
----- Ranking Board Script by Xiti! -----
-----------------------------------------------------
--Keep out soon of bitch!
local sx,sy = guiGetScreenSize()
local clearKillerTimer
local rankingFont = "default-bold"
local spareElems = {}
local donePrecreate = false
local WORLD_DOWN = {0, 0, -1}
local UPSIDE_DOWN_THRESHOLD = math.cos(math.rad(90))
RankingBoard = {}
RankingBoard.__index = RankingBoard
RankingBoard.instances = {}
dxTextCache = {}
dxTextShadowCache = {}
posLabel = {}
playerLabel = {}
setElementData(localPlayer, "firstKiller", nil)
setElementData(localPlayer, "secondKiller", nil)
local screenWidth, screenHeight = guiGetScreenSize()
local topDistance = 250
local bottomDistance = 0.26*screenHeight
local posLeftDistance = 30
local nameLeftDistance = 60
local labelHeight = 16
local maxPositions = math.floor((screenHeight - topDistance - bottomDistance)/labelHeight)
addEventHandler("onClientVehicleCollision", root,
function(hitElement)
if hitElement then
theCar = getPedOccupiedVehicle(localPlayer)
if theCar then
if ( getElementType(hitElement) == "vehicle" and isElementInWater(theCar) == false and getElementHealth(theCar)>250 and getElementHealth(hitElement)>250 and isElementInWater(hitElement) == false and source == theCar) then
local hitPlayer = getVehicleOccupant(hitElement)
if hitPlayer then
local firstKiller = getElementData(localPlayer, "firstKiller")
if isTimer(clearKillerTimer) then killTimer(clearKillerTimer) end
if firstKiller == nil or firstKiller == hitPlayer then
setElementData(localPlayer, "firstKiller", hitPlayer)
clearKillerTimer = setTimer(clearKill, 5000, 1)
elseif firstKiller ~= hitPlayer then
setElementData(localPlayer, "firstKiller", hitPlayer)
setElementData(localPlayer, "secondKiller", firstKiller)
clearKillerTimer = setTimer(clearKill, 5000, 1)
end
end
end
end
end
end)
function clearKill()
local theCar = getPedOccupiedVehicle(localPlayer)
if not theCar then return end
if isVehicleOnGround(theCar) == true and isElementInWater(theCar) == false and isVehicleUpsideDown(theCar) == false and getElementHealth(theCar)>250 then
setElementData(localPlayer, "firstKiller", nil)
setElementData(localPlayer, "secondKiller", nil)
else
setTimer(clearKill, 300, 1)
end
end
addEventHandler("onClientVehicleDamage", root,
function(_,_2,theHP)
local theHealth = getElementHealth(source)
local theoricalHealth = theHealth - 250
local hpToTake = 0
if theHealth > 250 then
if theoricalHealth <= theHP then
hpToTake = theoricalHealth
else
hpToTake = theHP
end
local hpLossPercentage = ((hpToTake*100)/750)
end
end)
function isVehicleUpsideDown (vehicle)
local matrix = getElementMatrix (vehicle)
local vehicleUp = {matrix_rotate (matrix, 0, 0, 1)}
local dotP = math.dotP (vehicleUp, WORLD_DOWN)
return (dotP >= UPSIDE_DOWN_THRESHOLD)
end
function matrix_rotate (matrix, x, y, z)
local tx = x * matrix[1][1] + y * matrix[2][1] + z * matrix[3][1]
local ty = x * matrix[1][2] + y * matrix[2][2] + z * matrix[3][2]
local tz = x * matrix[1][3] + y * matrix[2][3] + z * matrix[3][3]
return tx, ty, tz
end
function math.dotP(v1, v2)
return v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]
end
function RankingBoard.create(id)
RankingBoard.instances[id] = setmetatable({ id = id, direction = 'down', labels = {}, position = 0 }, RankingBoard)
posLabel = {}
playerLabel = {}
end
function RankingBoard.call(id, fn, ...)
RankingBoard[fn](RankingBoard.instances[id], ...)
end
function RankingBoard:setDirection(direction, plrs)
self.direction = direction
if direction == 'up' then
self.highestPos = plrs--#g_Players
self.position = self.highestPos + 1
end
end
function RankingBoard:add(name, time, killerName)
local position
local y
local doBoardScroll = false
local playerName = playerName
local killerName = killerName ~= "" and "#666666"..killerName or ""
if self.direction == 'down' then
self.position = self.position + 1
if self.position > maxPositions then
return
end
y = topDistance + (self.position-1)*labelHeight
elseif self.direction == 'up' then
self.position = self.position - 1
local labelPosition = self.position
if self.highestPos > maxPositions then
labelPosition = labelPosition - (self.highestPos - maxPositions)
if labelPosition < 1 then
labelPosition = 0
doBoardScroll = true
end
elseif labelPosition < 1 then
return
end
y = topDistance + (labelPosition-1)*labelHeight
end
posLabel[name], posLabelShadow = createShadowedLabelFromSpare(posLeftDistance, y, 20, labelHeight, tostring(self.position) .. ')', 'right')
if time then
if not self.firsttime then
self.firsttime = time
time = '#FFFFFF :: ' .. msToTimeStr(time)
else
if time == "Winner" then
time = '#FFFFFF :: Winner!'
else
time = '#FFFFFF :: +' .. msToTimeStr(time - self.firsttime)
end
end
else
time = ''
end
playerLabel[name], playerLabelShadow = createShadowedLabelFromSpare(nameLeftDistance, y, 250, labelHeight, name .. " #27b09e=> " .. killerName)
table.insert(self.labels, posLabel[name])
table.insert(self.labels, posLabelShadow)
table.insert(self.labels, playerLabel[name])
table.insert(self.labels, playerLabelShadow)
if doBoardScroll then
guiSetAlpha(posLabel[name], 0)
guiSetAlpha(posLabelShadow, 0)
guiSetAlpha(playerLabel[name], 0)
guiSetAlpha(playerLabelShadow, 0)
local anim = Animation.createNamed('race.boardscroll', self)
anim:addPhase({ from = 0, to = 1, time = 700, fn = RankingBoard.scroll, firstLabel = posLabel[name] })
anim:addPhase({ fn = RankingBoard.destroyLastLabel, firstLabel = posLabel[name] })
anim:play()
end
end
function RankingBoard:scroll(param, phase)
local firstLabelIndex = table.find(self.labels, phase.firstLabel)
for i=firstLabelIndex,firstLabelIndex+3 do
guiSetAlpha(self.labels[i], param)
end
local x, y
for i=0,#self.labels/4-1 do
for j=1,4 do
x = (j <= 2 and posLeftDistance or nameLeftDistance)
y = topDistance + ((maxPositions - i - 1) + param)*labelHeight
if j % 2 == 0 then
x = x + 1
y = y + 1
end
guiSetPosition(self.labels[i*4+j], sx + x, y, false)
end
end
for i=1,4 do
guiSetAlpha(self.labels[i], 1 - param)
end
end
function RankingBoard:destroyLastLabel(phase)
for i=1,4 do
destroyElementToSpare(self.labels[1])
guiSetVisible(self.labels[1],false)
table.remove(self.labels, 1)
end
local firstLabelIndex = table.find(self.labels, phase.firstLabel)
for i=firstLabelIndex,firstLabelIndex+3 do
guiSetAlpha(self.labels[i], 1)
end
end
function RankingBoard:addMultiple(items)
for i,item in ipairs(items) do
self:add(item.name, item.time)
end
end
function RankingBoard:clear()
table.each(self.labels, destroyElementToSpare)
self.labels = {}
end
function RankingBoard:destroy()
self:clear()
RankingBoard.instances[self.id] = nil
end
-- Label cache
function RankingBoard.precreateLabels(count)
donePrecreate = false
while #spareElems/4 < count do
local label, shadow = createShadowedLabel(10, 1, 20, 10, 'a' )
guiSetAlpha(shadow,0)
guiSetVisible(label, false)
guiSetVisible(shadow, false)
destroyElementToSpare(label)
destroyElementToSpare(shadow)
end
donePrecreate = true
end
function destroyElementToSpare(elem)
table.insertUnique( spareElems, elem )
guiSetVisible(elem, false)
end
function dxDrawColoredLabel(str, ax, ay, bx, by, color,tcolor,scale, font)
local rax = ax
if not dxTextShadowCache[str] then
dxTextShadowCache[str] = string.gsub( str, '#%x%x%x%x%x%x', '' )
end
dxDrawText(dxTextShadowCache[str], ax+1,ay+1,ax+1,by,tocolor(0,0,0, 0.8 * tcolor[4]),scale,font, "left", "center", false,false,false)
if dxTextCache[str] then
for id, text in ipairs(dxTextCache[str]) do
local w = text[2] * ( scale / text[4] )
dxDrawText(text[1], ax + w, ay, ax + w, by, tocolor(text[3][1],text[3][2],text[3][3],tcolor[4]), scale, font, "left", "center", false,false,false)
end
else
dxTextCache[str] = {}
local pat = "(.-)#(%x%x%x%x%x%x)"
local s, e, cap, col = str:find(pat, 1)
local last = 1
local r = tcolor[1]
local g = tcolor[2]
local b = tcolor[3]
local textalpha = tcolor[4]
while s do
if cap == "" and col then
r = tonumber("0x"..col:sub(1, 2))
g = tonumber("0x"..col:sub(3, 4))
b = tonumber("0x"..col:sub(5, 6))
color = tocolor(r, g, b, textalpha)
end
if s ~= 1 or cap ~= "" then
local w = dxGetTextWidth(cap, scale, font)
dxDrawText(cap, ax, ay, ax + w, by, color, scale, font, "left", "center")
table.insert(dxTextCache[str], { cap, ax-rax, {r,g,b}, scale } )
ax = ax + w
r = tonumber("0x"..col:sub(1, 2))
g = tonumber("0x"..col:sub(3, 4))
b = tonumber("0x"..col:sub(5, 6))
color = tocolor( r, g, b, textalpha)
end
last = e + 1
s, e, cap, col = str:find(pat, last)
end
if last <= #str then
cap = str:sub(last)
local w = dxGetTextWidth(cap, scale, font)
dxDrawText(cap, ax, ay, ax + w, by, color, scale, font, "left", "center")
table.insert(dxTextCache[str], { cap, ax-rax, {r,g,b}, scale } )
end
end
end
addEventHandler("onClientRender", getRootElement(),
function()
for id, elem in pairs(playerLabel) do
if guiGetVisible(elem) and string.len(guiGetText(elem)) > 4 then
local x,y = guiGetPosition(elem, false)
local a = guiGetAlpha(elem) * 255
if not getKeyState("tab") then
dxDrawColoredLabel(string.gsub(guiGetText(elem)," ", " #ffffff",1), 45,y,200,y+20, tocolor(255,255,255,a),{255,255,255,a}, 1, rankingFont, "left", "center", false,false,false)
end
if x < 100 then guiSetPosition(elem, sx+100,y,false) end
end
end
for id, elem in pairs(posLabel) do
if guiGetVisible(elem) and string.len(guiGetText(elem)) <= 4 then
local x,y = guiGetPosition(elem, false )
local a = guiGetAlpha(elem) * 255
if not getKeyState("tab") then
if getElementData(posLabel[id],"spectated") == true then
dxDrawText(guiGetText(elem), 1,y+1,41,y+21, tocolor(0,0,0,math.floor(a*0.8)), 1, rankingFont, "right", "center", false,false,false)
dxDrawText(guiGetText(elem), 0,y,40,y+20, tocolor(48,110,255,a), 1, rankingFont, "right", "center", false,false,false)
else
dxDrawText(guiGetText(elem), 1,y+1,41,y+21, tocolor(0,0,0,math.floor(a*0.8)), 1, rankingFont, "right", "center", false,false,false)
dxDrawText(guiGetText(elem), 0,y,40,y+20, tocolor(255,255,255,a), 1, rankingFont, "right", "center", false,false,false)
end
end
if x < 100 then
guiSetPosition(elem, sx+100,y,false)
end
end
end
end)
function createShadowedLabelFromSpare(x, y, width, height, text, align)
if #spareElems < 2 then
if not donePrecreate then
outputDebug( 'OPTIMIZATION', 'createShadowedLabel' )
end
return createShadowedLabel(x, y, width, height, text, align)
else
local shadow = table.popLast( spareElems )
guiSetSize(shadow, width, height, false)
guiSetText(shadow, text)
guiSetPosition(shadow, sx + x + 1, y + 1, false)
guiSetVisible(shadow, false)
local label = table.popLast( spareElems )
guiSetSize(label, width, height, false)
guiSetText(label, text)
guiSetPosition(label, sx + x, y, false)
guiSetVisible(label, true)
if align then
guiLabelSetHorizontalAlign(shadow, align)
guiLabelSetHorizontalAlign(label, align)
else
guiLabelSetHorizontalAlign(shadow, 'left')
guiLabelSetHorizontalAlign(label, 'left')
end
return label, shadow
end
end
addEvent("DeathMessages:addDeath", true)
addEventHandler("DeathMessages:addDeath", getRootElement(), function()
return true or false or nil
end)
addEvent("onNextMap", true)
addEventHandler("onNextMap", getRootElement(), function()
return true or false or nil
end)
yani bir komutla gizlenmesini bir komutla tekrar açılmasını istiyorum uğraştım fakat yapamadım.