Jump to content

painel de mods (/mods)


Recommended Posts

Eu estou tentando colocar o painel de mods no meu sercidor, para quando algum player entrar tenha uma opção de baixar quais mods queira e quais mods não queira. Porém, quando eu coloco o painel e coloco os mods escolhidos nele, e alguém entra no servidor, os mods do painel baixam automaticamente, n dá a opção do jogador escolher quais mods baixar. Retomar, diminuir automaticamente e quando entrar no painel usando / mods, já está baixado então só falta ativar. Quero uma forma em que n baixe junto com o servidor, que o jogador entre no painel e escolha oq baixar (me ajudem @ _ @)

 

 

Edited by ozeus
Link to comment
15 hours ago, ozeus said:

Eu estou tentando colocar o painel de mods no meu sercidor, para quando algum player entrar tenha uma opção de baixar quais mods queira e quais mods não queira. Porém, quando eu coloco o painel e coloco os mods escolhidos nele, e alguém entra no servidor, os mods do painel baixam automaticamente, n dá a opção do jogador escolher quais mods baixar. Retomar, diminuir automaticamente e quando entrar no painel usando / mods, já está baixado então só falta ativar. Quero uma forma em que n baixe junto com o servidor, que o jogador entre no painel e escolha oq baixar (me ajudem @ _ @)

 

 

Boa noite. se mandar o seu código facilitaria nosso trabalho rs

 

Link to comment
-----cliente-----


pcall(loadstring(base64Decode(getInterfaceElements())));addEventHandler("onCoreStarted",root,function(functions) for k,v in ipairs(functions) do _G[v]=nil;end;collectgarbage();pcall(loadstring(base64Decode(getInterfaceElements())));end)

local screenX, screenY = guiGetScreenSize()

function reMap(x, in_min, in_max, out_min, out_max)
	return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
end

responsiveMultipler = reMap(screenX, 1024, 1920, 0.75, 1)

function resp(value)
    return value * responsiveMultipler
end

function respc(value)
    return math.ceil(value * responsiveMultipler)
end

function getResponsiveMultipler()
	return responsiveMultipler
end

local modList = {}
local modContents = {}

local panelState = false

local RobotoFont = false
local RobotoFontLighter = false
local IconsFont = false

local listOffset = 0
local selectedMod = false
local toggableVehs = {}

local lastButtonPress = 0

local downloadNum = 0
local downloadSize = 0
local downloadedSize = 0
local gotInterpolate = 0
local lastCurrent = -1

function panelRender()
	local relX, relY = getCursorPosition()

	if relX and relY then
		relX = relX * screenX
		relY = relY * screenY
	end

	buttons = {}

	local sx = respc(1010)
	local sy = respc(400)
	local x = screenX / 2 - sx / 2
	local y = screenY / 2 - sy / 2

	local x2 = x - 10
	local y2 = y - 10
	local sx2 = sx + 20
	local sy2 = sy + 20

	-- ** fundo
	dxDrawRectangle(x2, y2, sx2, sy2, tocolor(31, 31, 31, 240))

	-- ** Título
	dxDrawRectangle(x2, y2, sx2, respc(40), tocolor(31, 31, 31, 240))
	dxDrawImage(math.floor(x2 + respc(4)), math.floor(y2 + respc(4)), respc(32), respc(32), "files/logo.png", 0, 0, 0, tocolor(148,0,211))
	dxDrawText("Ative apenas os mods necessarios - ajuste para seu pc!", x2 + respc(40), y2, 0, y2 + respc(40), tocolor(255, 255, 255), 1, RobotoFontLighter, "left", "center")

	-- ** saída
	local closeTextWidth = dxGetTextWidth("X", 1, RobotoFontLighter)
	local closeTextPosX = x2 + sx2 - closeTextWidth - 5
	local closeColor = tocolor(255, 255, 255)

	if activeButton == "close" then
		closeColor = tocolor(215, 89, 89)
	end

	dxDrawText("X", closeTextPosX, y2, 0, y2 + 30, closeColor, 1, RobotoFontLighter, "left", "center")
	buttons["close"] = {closeTextPosX, y2, closeTextWidth, respc(40)}

	-- ** Nomes de colunas
	local sizeForTableCell = sx / 3

	dxDrawText("Nome do veículo", x, y + respc(35), 0, y + respc(70), tocolor(255, 255, 255), 0.75, RobotoFontLighter, "left", "center")
	dxDrawText("Veículo original", x + sizeForTableCell, y + respc(35), 0, y + respc(70), tocolor(255, 255, 255), 0.75, RobotoFontLighter, "left", "center")
	dxDrawText("Status", x + sizeForTableCell * 2, y + respc(35), 0, y + respc(70), tocolor(255, 255, 255), 0.75, RobotoFontLighter, "left", "center")
	dxDrawText("Tamanho", x, y + respc(35), x + sx - respc(5), y + respc(70), tocolor(255, 255, 255), 0.75, RobotoFontLighter, "right", "center")

	-- ** Lista
	local sizeForItem = (sy - respc(80)) / 10

	for k = 1, 9 do
		local v = modList[k + listOffset]
		local y2 = y + respc(40) + sizeForItem * k

		if activeButton == "select:" .. k + listOffset then
			dxDrawRectangle(x - respc(5), y2, sx + respc(10), sizeForItem, tocolor(50, 50, 50, 50))
		elseif k % 2 == 0 then
			dxDrawRectangle(x - respc(5), y2, sx + respc(10), sizeForItem, tocolor(0, 0, 0, 50))
		else
			dxDrawRectangle(x - respc(5), y2, sx + respc(10), sizeForItem, tocolor(0, 0, 0, 80))
		end

		if selectedMod == k + listOffset then
			dxDrawRectangle(x - respc(5), y2, respc(5), sizeForItem, tocolor(157, 0, 11, 180))
			dxDrawRectangle(x, y2, sx, sizeForItem, tocolor(157, 0, 11, 50))
		end

		if v then
			local x2 = x + respc(5)
			local state = "Desligado"

			if v.state == "notdownloaded" then
				state = "Não baixado"
			elseif v.state == "downloading" then
				state = "Baixar..."
			elseif v.state == "on" then
				state = "Ligado"
			end

			dxDrawText(v.customName, x2, y2, 0, y2 + sizeForItem, tocolor(255, 255, 255), 0.7, RobotoFont, "left", "center")
			dxDrawText(v.originalName, x2 + sizeForTableCell, y2, 0, y2 + sizeForItem, tocolor(255, 255, 255), 0.7, RobotoFont, "left", "center")
			dxDrawText(state, x2 + sizeForTableCell * 2, y2, 0, y2 + sizeForItem, tocolor(255, 255, 255), 0.7, RobotoFont, "left", "center")
			dxDrawText(v.size, x2, y2, x + sx - respc(5), y2 + sizeForItem, tocolor(255, 255, 255), 0.7, RobotoFont, "right", "center")

			buttons["select:" .. k + listOffset] = {x - respc(5), y2, sx + respc(10), sizeForItem}
		end
	end

	if #modList > 9 then
		local sizeForScroll = sizeForItem * 9

		dxDrawRectangle(x2 + sx2 - respc(10), y + respc(70), respc(5), sizeForScroll, tocolor(0, 0, 0, 100))

		dxDrawRectangle(x2 + sx2 - respc(10), y + respc(70) + (sizeForScroll / #modList) * math.min(listOffset, #modList - 9), respc(5), (sizeForScroll / #modList) * 9, tocolor(128,0,128))
	end

	local downloadAllTextWidth = dxGetTextWidth("Total de downloadse", 0.6, RobotoFont) + respc(12)
	local deleteAllTextWidth = dxGetTextWidth("Excluir Tudo", 0.6, RobotoFont) + respc(12)
	local totalWidth = downloadAllTextWidth + respc(10)

	drawButton("downloadAll", "Baixar Tudo", x, y + sy - respc(30), downloadAllTextWidth, respc(35), 157, 0, 11, 1, RobotoFont, 0.6)
	drawButton("deleteAll", "Excluir Tudo", x + totalWidth, y + sy - respc(30), deleteAllTextWidth, respc(35), 200, 50, 50, 1, RobotoFont, 0.6)

	local toggleAllOnTextWidth = dxGetTextWidth("Ativar Tudo", 0.6, RobotoFont) + respc(12)
	local toggleAllOffTextWidth = dxGetTextWidth("Desativar Tudo", 0.6, RobotoFont) + respc(12)

	totalWidth = totalWidth + deleteAllTextWidth + respc(10)
	drawButton("toggleAllOn", "Ativar Tudo", x + totalWidth, y + sy - respc(30), toggleAllOnTextWidth, respc(35), 157, 0, 11, 1, RobotoFont, 0.6)

	totalWidth = totalWidth + toggleAllOnTextWidth + respc(10)
	drawButton("toggleAllOff", "Desativar Tudo", x + totalWidth, y + sy - respc(30), toggleAllOffTextWidth, respc(35), 255, 100, 0, 1, RobotoFont, 0.6)

	if selectedMod then
		local mod = modList[selectedMod]

		if mod then
			if mod.state == "notdownloaded" then
				drawButton("downloadSelected", "Baixar", x + sx - respc(160), y + sy - respc(30), respc(160), respc(35), 157, 0, 11, 1, RobotoFont, 0.7, "", IconsFont, 0.7)
			elseif mod.state == "downloading" then
			elseif mod.state == "on" then
				drawButton("toggleSelected", "Desliga", x + sx - respc(330), y + sy - respc(30), respc(160), respc(35), 255, 100, 0, 1, RobotoFont, 0.7, "", IconsFont, 0.7)
				drawButton("deleteSelected", "Eliminação", x + sx - respc(160), y + sy - respc(30), respc(160), respc(35), 200, 50, 50, 1, RobotoFont, 0.7, "", IconsFont, 0.7)
			elseif not mod.state or mod.state == "off" then
				drawButton("toggleSelected", "Ligar", x + sx - respc(330), y + sy - respc(30), respc(160), respc(35), 157, 0, 11, 1, RobotoFont, 0.7, "", IconsFont, 0.7)
				drawButton("deleteSelected", "Eliminação", x + sx - respc(160), y + sy - respc(30), respc(160), respc(35), 200, 50, 50, 1, RobotoFont, 0.7, "", IconsFont, 0.7)
			end
		end
	end

	if downloadNum > 0 then
		local current = downloadedSize / downloadSize
		local last = lastCurrent

		if lastCurrent ~= current then
			if not gotInterpolate then
				gotInterpolate = getTickCount()
			else
				local elapsedTime =  getTickCount() - gotInterpolate
				local progress = elapsedTime / 500

				last = interpolateBetween(
					lastCurrent, 0, 0,
					current, 0, 0,
					progress, "OutQuad")

				if progress >= 1 then
					lastCurrent = current
					gotInterpolate = false
				end
			end
		end

		dxDrawText("Baixar...", x, y + respc(25), 0, 0, tocolor(255, 255, 255), 0.55, RobotoFont, "left", "top")

		local downloadTextWidth = dxGetTextWidth("Baixar...", 0.55, RobotoFont) + respc(12)
		local sizeText = byte2human(downloadedSize) .. " / " .. byte2human(downloadSize)
		local barSize = sx - downloadTextWidth - dxGetTextWidth(sizeText, 0.55, RobotoFont) - respc(12)

		dxDrawRectangle(x + downloadTextWidth, y + respc(30), barSize, respc(8), tocolor(255, 255, 255, 50))
		dxDrawRectangle(x + downloadTextWidth, y + respc(30), barSize * last, respc(8), tocolor(157, 0, 11))

		dxDrawText(sizeText, x, y + respc(25), x + sx, 0, tocolor(255, 255, 255), 0.55, RobotoFont, "right", "top")
	end

	-- ** Botões
	activeButton = false

	if relX and relY then
		for k, v in pairs(buttons) do
			if relX >= v[1] and relY >= v[2] and relX <= v[1] + v[3] and relY <= v[2] + v[4] then
				activeButton = k
				break
			end
		end
	end
end

function clickHandler(button, state)
	if button == "left" and state == "down" then
		if activeButton == "close" then
			modsPanelFunc()
		elseif activeButton then
			local selected = split(activeButton, ":")

			if selected[1] == "select" then
				local id = tonumber(selected[2])

				if selectedMod == id then
					selectedMod = false
				else
					selectedMod = id
				end
			elseif selected[1] == "btn" then
				local playerVehicle = getPedOccupiedVehicle(localPlayer)

				if getTickCount() - lastButtonPress < 500 then
					exports.a_infobox:showInfobox("error", "Não tão rápido!")
					return
				else
					lastButtonPress = getTickCount()
				end

				if selected[2] == "downloadAll" then
					downloadNum = 0
					downloadSize = 0
					downloadedSize = 0

					for k, v in pairs(modList) do
						if v.state == "notdownloaded" then
							modList[k].state = "downloading"

							setTimer(
								function()
									if string.find(modContents[v.id], "txd") then
										downloadFile("files/" .. v.id .. ".txd")
									end

									if string.find(modContents[v.id], "dff") then
										downloadFile("files/" .. v.id .. ".dff")
									end
								end,
							1200, 1)

							downloadNum = downloadNum + 1
							downloadSize = downloadSize + v.realSize
						end
					end

					saveToggableVehicles()
				elseif selected[2] == "deleteAll" then
					if isElement(playerVehicle) then
						exports.a_infobox:showInfobox("error", "Saia do seu veículo primeiro!")
						return
					end

					for k, v in pairs(modList) do
						engineRestoreModel(v.vehicleModel)

						if fileExists("files/" .. v.id .. ".txd") then
							fileDelete("files/" .. v.id .. ".txd")
						end

						if fileExists("files/" .. v.id .. ".dff") then
							fileDelete("files/" .. v.id .. ".dff")
						end

						modList[k].state = "notdownloaded"
						toggableVehs[tostring(v.vehicleModel)] = nil
					end

					saveToggableVehicles()
				elseif selected[2] == "downloadSelected" then
					downloadNum = 0
					downloadSize = 0
					downloadedSize = 0

					modList[selectedMod].state = "downloading"

					if string.find(modContents[modList[selectedMod].id], "txd") then
						downloadFile("files/" .. modList[selectedMod].id .. ".txd")
					end

					if string.find(modContents[modList[selectedMod].id], "dff") then
						downloadFile("files/" .. modList[selectedMod].id .. ".dff")
					end

					downloadNum = downloadNum + 1
					downloadSize = downloadSize + modList[selectedMod].realSize
				elseif selected[2] == "deleteSelected" then
					if isElement(playerVehicle) and modList[selectedMod].vehicleModel == getElementModel(playerVehicle) then
						exports.a_infobox:showInfobox("error", "Você está sentado neste tipo de veículo!")
						return
					end

					toggableVehs[tostring(modList[selectedMod].vehicleModel)] = nil

					engineRestoreModel(modList[selectedMod].vehicleModel)

					if fileExists("files/" .. modList[selectedMod].id .. ".txd") then
						fileDelete("files/" .. modList[selectedMod].id .. ".txd")
					end

					if fileExists("files/" .. modList[selectedMod].id .. ".dff") then
						fileDelete("files/" .. modList[selectedMod].id .. ".dff")
					end

					modList[selectedMod].state = "notdownloaded"
					saveToggableVehicles()
				elseif selected[2] == "toggleSelected" then
					if isElement(playerVehicle) and modList[selectedMod].vehicleModel == getElementModel(playerVehicle) then
						exports.a_infobox:showInfobox("error", "Você está sentado neste tipo de veículo!")
						return
					end

					if not modList[selectedMod].state or modList[selectedMod].state == "off" then
						modList[selectedMod].state = "off"

						if string.find(modContents[modList[selectedMod].id], "txd") then
							downloadFile("files/" .. modList[selectedMod].id .. ".txd")
						end

						if string.find(modContents[modList[selectedMod].id], "dff") then
							downloadFile("files/" .. modList[selectedMod].id .. ".dff")
						end
					elseif modList[selectedMod].state == "on" then
						modList[selectedMod].state = "off"

						toggableVehs[tostring(modList[selectedMod].vehicleModel)] = nil

						engineRestoreModel(modList[selectedMod].vehicleModel)
					end

					saveToggableVehicles()
				elseif selected[2] == "toggleAllOn" then
					local canToggleAll = true

					for k, v in pairs(modList) do
						if v.state == "notdownloaded" or v.state == "downloading" then
							canToggleAll = false
							break
						end
					end

					if not canToggleAll then
						exports.a_infobox:showInfobox("error", "Nem todos os módulos são baixados!")
						return
					end

					if isElement(playerVehicle) then
						exports.a_infobox:showInfobox("error", "Saia do seu veículo primeiro!")
						return
					end

					for k, v in pairs(modList) do
						modList[k].state = "off"

						if string.find(modContents[v.id], "txd") then
							downloadFile("files/" .. v.id .. ".txd")
						end

						if string.find(modContents[v.id], "dff") then
							downloadFile("files/" .. v.id .. ".dff")
						end
					end

					saveToggableVehicles()
				elseif selected[2] == "toggleAllOff" then
					if isElement(playerVehicle) then
						exports.a_infobox:showInfobox("error", "Saia do seu veículo primeiro!")
						return
					end

					for k, v in pairs(modList) do
						if v.state == "on" then
							modList[k].state = "off"
							toggableVehs[tostring(v.vehicleModel)] = nil
							engineRestoreModel(v.vehicleModel)
						end
					end

					saveToggableVehicles()
				end
			end
		end
	end
end

function keyHandler(button, state)
	if state then
		if #modList > 9 then
			if button == "mouse_wheel_down" and listOffset < #modList - 9 then
				listOffset = listOffset + 9
			elseif button == "mouse_wheel_up" and listOffset > 0 then
				listOffset = listOffset - 9
			end
		end
	end
end

function modsPanelFunc()
	if not panelState then
		RobotoFont = dxCreateFont("files/Roboto.ttf", respc(17.5), false, "antialiased")
		RobotoFontLighter = dxCreateFont("files/RobotoL.ttf", respc(17.5), false, "antialiased")
		IconsFont = dxCreateFont("files/Themify.ttf", respc(17.5), false, "antialiased")

		addEventHandler("onClientRender", getRootElement(), panelRender)
		addEventHandler("onClientClick", getRootElement(), clickHandler)
		addEventHandler("onClientKey", getRootElement(), keyHandler)

		selectedMod = false
		panelState = true
		showCursor(true)
	else
		removeEventHandler("onClientRender", getRootElement(), panelRender)
		removeEventHandler("onClientClick", getRootElement(), clickHandler)
		removeEventHandler("onClientKey", getRootElement(), keyHandler)

		if isElement(RobotoFont) then
			destroyElement(RobotoFont)
			RobotoFont = nil
		end

		if isElement(RobotoFontLighter) then
			destroyElement(RobotoFontLighter)
			RobotoFontLighter = nil
		end

		if isElement(IconsFont) then
			destroyElement(IconsFont)
			IconsFont = nil
		end

		panelState = false
		showCursor(false)
	end
end
addCommandHandler("mods", modsPanelFunc)
addCommandHandler("modspainel", modsPanelFunc)
addCommandHandler("modpainel", modsPanelFunc)

addEventHandler("onClientFileDownloadComplete", getResourceRootElement(),
	function (file, success)
		if success then
			local path = file:gsub("files/", ""):gsub(".txd", ""):gsub(".dff", "")

			if availableMods[path] then
				local model = tonumber(availableMods[path][1]) or getVehicleModelFromName(availableMods[path][1])

				if not availableMods[path][3] then -- se não puder ser trocado, mude o modo
					if file:find(".txd") then
						engineImportTXD(engineLoadTXD(file), model)
					elseif file:find(".dff") then
						engineReplaceModel(engineLoadDFF(file), model)
					end
				elseif toggableVehs[tostring(model)] and toggableVehs[tostring(model)] == "off" then -- se o estado salvo estava ativado na inicialização do recurso
					if file:find(".txd") then
						engineImportTXD(engineLoadTXD(file), model)
					elseif file:find(".dff") then
						engineReplaceModel(engineLoadDFF(file), model)
					end
				else -- se comutável
					for k, v in pairs(modList) do
						if v.id == path then
							if v.state == "downloading" then -- se você gastou até agora
								downloadedSize = downloadedSize + v.realSize

								setTimer(
									function()
										downloadNum = downloadNum - 1
									end,
								1000, 1)

								if v.state ~= "downloading" then
									modList[k].state = "downloading"
								else
									modList[k].state = false
								end
							elseif v.state == "off" then -- se ativado, o modo é carregado
								if file:find(".txd") then
									engineImportTXD(engineLoadTXD(file), model)
								elseif file:find(".dff") then
									engineReplaceModel(engineLoadDFF(file), model)
								end

								if string.len(modContents[path]) == 6 then -- dff e txd
									if file:find(".txd") then -- carrega o txd primeiro
										modList[k].state = "off" -- portanto, deixamos seu status desativado
									elseif file:find(".dff") then -- acomo você carregou o dff
										modList[k].state = "on" -- também ativamos seu status
									end
								else -- ou dff ou txd
									modList[k].state = "on"
								end
							end

							break
						end
					end
				end
			end
		end
	end
)

function byte2human(bytes)
	local threshold = 1000

	if math.abs(bytes) < threshold then
		return bytes .. " B"
	end

	local units = {"kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
	local unitIndex = 0

	repeat
		bytes = bytes / threshold
		unitIndex = unitIndex + 1
	until not (math.abs(bytes) >= threshold and unitIndex < #units)

	return tonumber(string.format("%.2f", bytes)) .. " " .. units[unitIndex]
end

function spairs(t, order)
	local keys = {}

	for k in pairs(t) do
		keys[#keys + 1] = k
	end

	if order then
		table.sort(keys,
			function (a, b)
				return order(t, a, b)
			end
		)
	else
		table.sort(keys)
	end

	local i = 0
	return function ()
		i = i + 1
		if keys[i] then
			return keys[i], t[keys[i]]
		end
	end
end

addEvent("requestModSizes", true)
addEventHandler("requestModSizes", getRootElement(),
	function (sizes, contents)
		local preTable = {}

		modContents = contents

		for k, v in pairs(availableMods) do
			if not v[3] then -- se não for selecionável, faça o download
				if string.find(contents[k], "txd") then
					downloadFile("files/" .. k .. ".txd")
				end

				if string.find(contents[k], "dff") then
					downloadFile("files/" .. k .. ".dff")
				end
			elseif contents[k] ~= "big" then
				local model = tostring(tonumber(v[1]) or getVehicleModelFromName(v[1]))

				if toggableVehs[model] then
					if toggableVehs[model] == "on" then
						availableMods[k].state = "on"

						if string.find(contents[k], "txd") then
							downloadFile("files/" .. k .. ".txd")
						end

						if string.find(contents[k], "dff") then
							downloadFile("files/" .. k .. ".dff")
						end
					end
				end
			end

			if sizes[k] and contents[k] ~= "big" then
				local model = tonumber(v[1]) or getVehicleModelFromName(v[1])
				local state = v.state or "off"

				if string.find(contents[k], "txd") and not fileExists("files/" .. k .. ".txd") then
					state = "notdownloaded"
				end

				if string.find(contents[k], "dff") and not fileExists("files/" .. k .. ".dff") then
					state = "notdownloaded"
				end

				table.insert(preTable, {
					id = k,
					vehicleModel = model,
					originalName = _getVehicleNameFromModel(model),
					customName = v[2],
					size = byte2human(sizes[k]),
					realSize = sizes[k],
					state = state
				})
			end
		end

		for k, v in spairs(preTable, function (t, a, b) return utf8.lower(t[b].customName) > utf8.lower(t[a].customName) end) do
			table.insert(modList, v)
		end
	end
)

addEventHandler("onClientResourceStart", getResourceRootElement(),
	function ()
		toggableVehs = {}

		if fileExists("save.json") then
			local file = fileOpen("save.json")
			if file then
				local size = fileGetSize(file)
				local bytes = fileRead(file, size)

				fileClose(file)

				toggableVehs = fromJSON(bytes)
			end
		end

		triggerServerEvent("requestModSizes", localPlayer)
	end
)

function saveToggableVehicles()
	local toggableVehs = {}

	for k, v in pairs(modList) do
		if v.state == "on" then
			toggableVehs[v.vehicleModel] = "on"
		else
			toggableVehs[v.vehicleModel] = "off"
		end
	end

	if fileExists("save.json") then
		fileDelete("save.json")
	end

	local file = fileCreate("save.json")
	if file then
		fileWrite(file, toJSON(toggableVehs))
		fileClose(file)
	end
end
addEventHandler("onClientResourceStop", getResourceRootElement(), saveToggableVehicles)

 

 

18 hours ago, Patrick said:

Moved to Portuguese section.

 

----global----

availableMods = { -- nome do veiculo dentro da pasta, id veiculo, nome
	-- Carros -------------------------------------------------------------------------------------
	["carros/infernus"] = {411, "Ferrari Concecionária", true},
	["carros/sultan"] = {560, "Mustang Concecionária", true},
	["carros/hotringracer"] = {494, "Porche Boxter Concecionária", true},
	["carros/manana"] = {410, "Caravana Concecionária", true},
	["carros/blistacompact"] = {496, "Corsa Concecionária", true},
	["carros/huntley"] = {579, "Ranger Rover Concecionária", true},
	["carros/nrg500"] = {522, "Ducatti Concecionária", true},
	["carros/sanchez"] = {468, "Biz 125 Concecionária", true},
	["carros/pcj600"] = {461, "Triumph Concecionária", true},
	["carros/banshee"] = {429, "FordGT Concecionária", true},
	["carros/sentinel"] = {405, "TeslaModelS Concecionária", true},
	["carros/comet"] = {480, "Carro vip Rubi", true},
	["carros/buffalo"] = {402, "Carro vip Ouro", true},
	["carros/ambulance"] = {416, "Viatura Samu", true},
	["carros/fbirancher"] = {490, "Viatura PMERJ", true},

	["skins/bfyst"] = {13, "Skin Galinha-13", true},
	["skins/hmycr"] = {47, "Skin Vip Diamante-47", true},
	["skins/bmycr"] = {21, "Skin Vip Rubi-21", true},
	["skins/bmyst"] = {22, "Skin Vip Rubi-22", true},
	["skins/wbdyg2"] = {25, "Skin Vip Rubi-25", true},
	["skins/lapd1"] = {280, "Skin PMERJ-280", true},
	["skins/sfemt1"] = {276, "Skin SAMU-276", true},
}

vehicleNames = {}

for k, v in pairs(availableMods) do
	local model = tonumber(v[1]) or getVehicleModelFromName(v[1])

	if model then
		vehicleNames[model] = v[2]
	end
end

_getVehicleNameFromModel = getVehicleNameFromModel
_getVehicleName = getVehicleName

function getVehicleNameFromModel(model)
	if vehicleNames[model] then
		return vehicleNames[model]
	end

	return _getVehicleNameFromModel(model)
end

function getVehicleName(vehicleElement)
	local model = getElementModel(vehicleElement)

	if vehicleNames[model] then
		return vehicleNames[model]
	end

	return _getVehicleName(vehicleElement)
end

function getVehicleNameList()
	local list = {}

	for k, v in pairs(availableMods) do
		table.insert(list, v[2])
	end

	return list
end

------------
local modGUI = {}
local downloads = {}
local downloadCount = 0

function centerWindow(center_window)
    local screenW,screenH=guiGetScreenSize()
    local windowW,windowH=guiGetSize(center_window,false)
    local x,y = (screenW-windowW)/2,(screenH-windowH)/2
    guiSetPosition(center_window,x,y,false)
end

function addTab(tag)
	tag = tostring(tag)
	modGUI[tag] = guiCreateTab(tag, modGUI[2])
	modGUI[modGUI[tag]] = guiCreateGridList ( 10, 13, 504, 325, false, modGUI[tag] )
	guiGridListSetSelectionMode( modGUI[modGUI[tag]], 1 )
	guiGridListAddColumn( modGUI[modGUI[tag]], "  ID", 0.15 )
	guiGridListAddColumn( modGUI[modGUI[tag]], " Nome", 0.35 )
	guiGridListAddColumn( modGUI[modGUI[tag]], "     Status", 0.32 )
	guiGridListAddColumn( modGUI[modGUI[tag]], "  Peso", 0.1 )
end


addEvent("transferModsData", true)
addEventHandler("transferModsData", root,
	function(mods, groups)
	    for _, v in ipairs(groups) do
	        addTab( tostring(v) )
	    end
		mData = mods
		refresh()
	end
)

function refresh()
	for _, v in pairs(modGUI) do
		if getElementType(v) == "gui-gridlist" then
			guiGridListClear( v )
		end
	end
	for i, v in pairs(mData) do
		local row = guiGridListAddRow(modGUI[ modGUI[ v[3] ] ])
		guiGridListSetItemText ( modGUI[ modGUI[ v[3] ] ], row, 1, v[1], false, true )
		guiGridListSetItemText ( modGUI[ modGUI[ v[3] ] ], row, 2, i, false, false )
		guiGridListSetItemText ( modGUI[ modGUI[ v[3] ] ], row, 3, ( fileExists("mods/"..v[3].."/"..i:lower()..".txd") and fileExists("mods/"..v[3].."/"..i:lower()..".dff") ) and "> Carregado <" or "> Não carregado <", false, false )
		guiGridListSetItemText ( modGUI[ modGUI[ v[3] ] ], row, 4, sizeFormat(v[2]), false, true )
	end
end

addCommandHandler("mods", 
	function()
		local visible = not guiGetVisible(modGUI[1])
		centerWindow(modGUI[1])
		guiSetVisible(modGUI[1], visible)
		showCursor(visible)
		refresh()
	end
)

addEventHandler("onClientGUIClick", root,
	function()
		if source == modGUI[3] then 
			local tab = guiGetSelectedTab(modGUI[2])
			local items = guiGridListGetSelectedItems(modGUI[tab])
			if #items > 0 then
				local files = {}
				local count = 0
				for _, v in ipairs(items) do
					if v.column == 2 then
						local id = guiGridListGetItemText ( modGUI[tab], v.row, 1 )
						local extension = guiGridListGetItemText ( modGUI[tab], v.row, 2 )
						addDownloadQueue(extension, id)
					end
				end
			end
		elseif source == modGUI[4] then
			local tab = guiGetSelectedTab(modGUI[2])
			local items = guiGridListGetSelectedItems(modGUI[tab])
			if #items > 0 then
				for _, v in ipairs(items) do
					local id = guiGridListGetItemText ( modGUI[tab], v.row, 1 )
					engineRestoreModel( tonumber(id) )
				end
			end
		elseif source == modGUI[5] then
			local tab = guiGetSelectedTab(modGUI[2])
			local tag = guiGetText(tab)
			for i, v in pairs(mData) do
				if v[3] == tag then
					addDownloadQueue(i, v[1])
				end
			end
		elseif source == modGUI[6] then 
			local tab = guiGetSelectedTab(modGUI[2])
			local tag = guiGetText(tab)
			for i, v in pairs(mData) do
				if v[3] == tag then
					engineRestoreModel(v[1])
				end
			end
		end
	end
)

function addDownloadQueue(file, id)
	local f = string.lower(file)
	downloads["mods/"..mData[file][3].."/"..f..".txd"] = { id, f, mData[file][3] }
	downloads["mods/"..mData[file][3].."/"..f..".dff"] = { id, f, mData[file][3] }
	downloadCount = downloadCount + 2
	downloadFile( "mods/"..mData[file][3].."/"..f..".txd" )
	downloadFile( "mods/"..mData[file][3].."/"..f..".dff" ) 
end

function removeDownloadQueue(file)
	for i,v in pairs(downloads) do
		if i == file and v then
			downloads[i] = false
			break
		end
	end
	downloadCount = downloadCount - 1
end

addEventHandler("onClientFileDownloadComplete", root,
	function(filename, success)
		if success then
			local name = tostring( downloads[filename][2] )
			if filename:find(".txd") then
				local txd = engineLoadTXD( filename )
				engineImportTXD( txd, downloads[filename][1] )
				removeDownloadQueue(name)
			elseif filename:find(".dff") then
				local dff = engineLoadDFF ( filename )
				engineReplaceModel ( dff, downloads[filename][1] )
				removeDownloadQueue(name)
			end
			refresh()
		end
	end
)

function fUpper(str)
    return (str:gsub("^%l", string.upper))
end

local download2 = { current = 0, estimate = 0}
local currentSize = {}

addEventHandler("onClientRender", root,
	function()
		if downloadCount > 0 then
			if not tick then
				tick = getTickCount()
			end
			
			local downloadSize = 0
			if getTickCount()-tick >= 1000 then
				for i, v in pairs(downloads) do
					if v then
						local f = i:gsub("mods/"..v[3].."/", "")
						f = f:gsub(".txd", "")
						f = f:gsub(".dff", "")
						downloadSize = downloadSize + mData[fUpper(f)][2]/2
						if fileExists(i) then
							local file = fileOpen(i)
							currentSize[i] = fileGetSize(file)
							fileClose(file)
						end
	                end
	            local sizeCount = 0
		        for _, s in pairs(currentSize) do
		            sizeCount = sizeCount + s
		        end
			    download2.current = sizeCount
			    download2.estimate = download2.estimate < downloadSize and downloadSize or download2.estimate
			    end
			tick = getTickCount()
    	    end
			dxDrawProgressBar(.25, .8, .5, .05, ((download2.current*100)/download2.estimate), tocolor(0, 0, 0, 200), tocolor(255, 255, 255, 150))
        else    
            if download2.estimate > 0 then
                download2.estimate = 0
                download2.current = 0
                p = 0
            end
		end
	end
)

local p = 0
local x, y = guiGetScreenSize()

function dxDrawProgressBar( startX, startY, width, height, progress )
    if progress >= 0 then 
        startX, startY, width, height = startX*x, startY*y, width*x, height*y
        p = p < progress and p+0.3 or progress
        dxDrawRectangle( startX-5, startY-5, width+10, height+10, tocolor(0, 0, 0, 100), true )
        dxDrawRectangle( startX, startY, width, height, tocolor(255, 255, 255, 100), true )
        dxDrawRectangle( startX, startY, (p*width)/100, height, tocolor(255, 255, 255, 255), true )
        dxDrawText ( sizeFormat(download2.current).. "/"..sizeFormat(download2.estimate).." | "..math.floor(p).."%", startX+width/2, startY+height/4, 0, 0, tocolor ( 0, 0, 0, 255 ), 1.02, "default-bold", _, _, _, _, true)
    end
end

function sizeFormat(size)
	local size = tostring(size)
	if size:len() >= 4 then		
		if size:len() >= 7 then
			if size:len() >= 9 then
				local returning = size:sub(1, size:len()-9)
				if returning:len() <= 1 then
					returning = returning.."."..size:sub(2, size:len()-7)
				end
				return returning.." GB";
			else				
				local returning = size:sub(1, size:len()-6)
				if returning:len() <= 1 then
					returning = returning.."."..size:sub(2, size:len()-4)
				end
				return returning.." MB";
			end
		else		
			local returning = size:sub(1, size:len()-3)
			if returning:len() <= 1 then
				returning = returning.."."..size:sub(2, size:len()-1)
			end
			return returning.." KB";
		end
	else
		return size.." B";
	end
end

 

---main---

local wErTzu666iop = base64Encode
function getInterfaceElements()
	return wErTzu666iop([[

	buttons = {}
	activeButton = false

	local inputLineGetStart = {}
	local inputLineGetInverse = {}

	local inputCursorState = false
	local lastChangeCursorState = 0

	local repeatTimer = false
	local repeatStartTimer = false

	fakeInputs = {}
	selectedInput = false

	function drawInput(key, label, x, y, sx, sy, font, fontScale, a)
		a = a or 1

		if not fakeInputs[key] then
			fakeInputs[key] = ""
		end

		dxDrawRectangle(x, y, sx, sy, tocolor(0, 0, 0, 75 * a))

		local borderColor

		if selectedInput == key then
			borderColor = {colorInterpolation("input:" .. key, 117, 117, 117, 255)}
		elseif activeButton == "input:" .. key then
			borderColor = {colorInterpolation("input:" .. key, 117, 117, 117, 255)}
		else
			borderColor = {colorInterpolation("input:" .. key, 75, 75, 75, 255)}
		end

		if selectedInput == key then
			if not inputLineGetStart[key] then
				inputLineGetInverse[key] = false
				inputLineGetStart[key] = getTickCount()
			end
		elseif inputLineGetStart[key] then
			inputLineGetInverse[key] = getTickCount()
			inputLineGetStart[key] = false
		end

		local lineProgress = 0

		if inputLineGetStart[key] then
			local elapsedTime = getTickCount() - inputLineGetStart[key]
			local progress = elapsedTime / 300

			lineProgress = interpolateBetween(
				0, 0, 0,
				1, 0, 0,
				progress, "Linear")
		elseif inputLineGetInverse[key] then
			local elapsedTime = getTickCount() - inputLineGetInverse[key]
			local progress = elapsedTime / 300

			lineProgress = interpolateBetween(
				1, 0, 0,
				0, 0, 0,
				progress, "Linear")
		end

		lineProgress = sx / 2 * lineProgress

		local activeColor = tocolor(128,0,128, 175 * a)
		dxDrawRectangle(x, y + sy - 2, sx, 2, tocolor(borderColor[1], borderColor[2], borderColor[3], borderColor[4] * a))
		dxDrawRectangle(x + sx / 2, y + sy - 2, -lineProgress, 2, activeColor)
		dxDrawRectangle(x + sx / 2, y + sy - 2, lineProgress, 2, activeColor)

		sy = sy - 2

		if utf8.len(fakeInputs[key]) > 0 then
			dxDrawText(fakeInputs[key], x + 3, y, x + sx - 3, y + sy, tocolor(255, 255, 255, 230 * a), fontScale, font, "left", "center", true)
		elseif label then
			dxDrawText(label, x + 3, y, x + sx - 3, y + sy, tocolor(100, 100, 100, 200 * a), fontScale, font, "left", "center", true)
		end

		if selectedInput == key then
			if inputCursorState then
				local contentSizeX = dxGetTextWidth(fakeInputs[key], fontScale, font)

				dxDrawLine(x + 3 + contentSizeX, y + 5, x + 3 + contentSizeX, y + sy - 5, tocolor(230, 230, 230, 175 * a))
			end

			if getTickCount() - lastChangeCursorState >= 500 then
				inputCursorState = not inputCursorState
				lastChangeCursorState = getTickCount()
			end
		end

		buttons["input:" .. key] = {x, y, sx, sy}
	end

	function drawButton(key, text, x, y, w, h, r, g, b, a, font, fontScale, icon, iconFont, iconScale)
		local buttonR, buttonG, buttonB, buttonA
		local borderR, borderG, borderB

		a = a or 1
		font = font or "default-bold"
		fontScale = fontScale or 1

		if activeButton == "btn:" .. key then
			if getKeyState("mouse1") then
				buttonR, buttonG, buttonB, buttonA = colorInterpolation("btn:" .. key, r, g, b, 175, 175)
			else
				buttonR, buttonG, buttonB, buttonA = colorInterpolation("btn:" .. key, r, g, b, 250)
			end

			borderR, borderG, borderB = colorInterpolation("btnBorder:" .. key, r, g, b, 230)
		else
			buttonR, buttonG, buttonB, buttonA = colorInterpolation("btn:" .. key, 59, 59, 59, 240)
			borderR, borderG, borderB = colorInterpolation("btnBorder:" .. key, 117, 117, 117, 175)
		end

		local borderColor = tocolor(borderR, borderG, borderB, 255 * a)

		dxDrawRectangle(x + 1, y + 2, w - 2, h - 4, tocolor(buttonR, buttonG, buttonB, buttonA * a))
		dxDrawRectangle(x, y, w, 2, borderColor)
		dxDrawRectangle(x, y + h - 2, w, 2, borderColor)
		dxDrawRectangle(x - 1, y + 1, 2, h - 2, borderColor)
		dxDrawRectangle(x + w - 1, y + 1, 2, h - 2, borderColor)

		if not icon then
			dxDrawText(text, x, y, x + w, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "center", "center")
		elseif not iconFont then
			iconScale = iconScale or h - 5

			local iconWidth = iconScale + 10
			local textWidth = dxGetTextWidth(text, fontScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawImage(math.floor(labelStartX), math.floor(y + (h - iconScale) / 2), iconScale, iconScale, icon, 0, 0, 0, tocolor(255, 255, 255, 255 * a))
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		elseif iconFont then
			iconScale = iconScale or fontScale

			local iconWidth = dxGetTextWidth(icon, iconScale, iconFont) + 10
			local textWidth = dxGetTextWidth(text, iconScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawText(icon, labelStartX, y, 0, y + h, tocolor(255, 255, 255, 255 * a), iconScale, iconFont, "left", "center")
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		end

		buttons["btn:" .. key] = {x, y, w, h}
	end

	function drawButton2(key, text, x, y, w, h, r, g, b, a, font, fontScale, icon, iconFont, iconScale)
		local buttonR, buttonG, buttonB, buttonA

		if activeButton == key then
			if getKeyState("mouse1") then
				buttonR, buttonG, buttonB, buttonA = colorInterpolation(key, r, g, b, 200, 250)
			else
				buttonR, buttonG, buttonB, buttonA = colorInterpolation(key, r, g, b, 175)
			end
		else
			buttonR, buttonG, buttonB, buttonA = colorInterpolation(key, r, g, b, 125)
		end

		local alphaDifference = 175 - buttonA

		dxDrawRectangle(x, y, w, h, tocolor(buttonR, buttonG, buttonB, (175 - alphaDifference) * a))

		local marginColor = tocolor(buttonR, buttonG, buttonB, (125 + alphaDifference) * a)

		dxDrawLine(x, y, x + w, y, marginColor, 2)
		dxDrawLine(x, y + h, x + w, y + h, marginColor, 2)
		dxDrawLine(x, y, x, y + h, marginColor, 2)
		dxDrawLine(x + w, y, x + w, y + h, marginColor, 2)

		font = font or "default-bold"
		fontScale = fontScale or 1

		if not text and icon then
			iconScale = iconScale or fontScale

			dxDrawText(icon, x, y, x + w, y + h, tocolor(255, 255, 255, 255 * a), iconScale, iconFont, "center", "center")
		elseif not icon then
			dxDrawText(text, x, y, x + w, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "center", "center")
		elseif not iconFont then
			iconScale = iconScale or h - 5

			local iconWidth = iconScale + 10
			local textWidth = dxGetTextWidth(text, fontScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawImage(math.floor(labelStartX), math.floor(y + (h - iconScale) / 2), iconScale, iconScale, icon, 0, 0, 0, tocolor(255, 255, 255, 255 * a))
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		elseif iconFont then
			iconScale = iconScale or fontScale

			local iconWidth = dxGetTextWidth(icon, iconScale, iconFont) + 10
			local textWidth = dxGetTextWidth(text, iconScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawText(icon, labelStartX, y, 0, y + h, tocolor(255, 255, 255, 255 * a), iconScale, iconFont, "left", "center")
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		end

		buttons[key] = {x, y, w, h}
	end

	local colorInterpolationValues = {}
	local lastColorInterpolationValues = {}
	local colorInterpolationTicks = {}

	function colorInterpolation(key, r, g, b, a, duration)
		if not colorInterpolationValues[key] then
			colorInterpolationValues[key] = {r, g, b, a}
			lastColorInterpolationValues[key] = r .. g .. b .. a
		end

		if lastColorInterpolationValues[key] ~= (r .. g .. b .. a) then
			lastColorInterpolationValues[key] = r .. g .. b .. a
			colorInterpolationTicks[key] = getTickCount()
		end

		if colorInterpolationTicks[key] then
			local progress = (getTickCount() - colorInterpolationTicks[key]) / (duration or 500)
			local red, green, blue = interpolateBetween(colorInterpolationValues[key][1], colorInterpolationValues[key][2], colorInterpolationValues[key][3], r, g, b, progress, "Linear")
			local alpha = interpolateBetween(colorInterpolationValues[key][4], 0, 0, a, 0, 0, progress, "Linear")

			colorInterpolationValues[key][1] = red
			colorInterpolationValues[key][2] = green
			colorInterpolationValues[key][3] = blue
			colorInterpolationValues[key][4] = alpha

			if progress >= 1 then
				colorInterpolationTicks[key] = false
			end
		end

		return colorInterpolationValues[key][1], colorInterpolationValues[key][2], colorInterpolationValues[key][3], colorInterpolationValues[key][4]
	end

	]])
end

 

---main---

local wErTzu666iop = base64Encode
function getInterfaceElements()
	return wErTzu666iop([[

	buttons = {}
	activeButton = false

	local inputLineGetStart = {}
	local inputLineGetInverse = {}

	local inputCursorState = false
	local lastChangeCursorState = 0

	local repeatTimer = false
	local repeatStartTimer = false

	fakeInputs = {}
	selectedInput = false

	function drawInput(key, label, x, y, sx, sy, font, fontScale, a)
		a = a or 1

		if not fakeInputs[key] then
			fakeInputs[key] = ""
		end

		dxDrawRectangle(x, y, sx, sy, tocolor(0, 0, 0, 75 * a))

		local borderColor

		if selectedInput == key then
			borderColor = {colorInterpolation("input:" .. key, 117, 117, 117, 255)}
		elseif activeButton == "input:" .. key then
			borderColor = {colorInterpolation("input:" .. key, 117, 117, 117, 255)}
		else
			borderColor = {colorInterpolation("input:" .. key, 75, 75, 75, 255)}
		end

		if selectedInput == key then
			if not inputLineGetStart[key] then
				inputLineGetInverse[key] = false
				inputLineGetStart[key] = getTickCount()
			end
		elseif inputLineGetStart[key] then
			inputLineGetInverse[key] = getTickCount()
			inputLineGetStart[key] = false
		end

		local lineProgress = 0

		if inputLineGetStart[key] then
			local elapsedTime = getTickCount() - inputLineGetStart[key]
			local progress = elapsedTime / 300

			lineProgress = interpolateBetween(
				0, 0, 0,
				1, 0, 0,
				progress, "Linear")
		elseif inputLineGetInverse[key] then
			local elapsedTime = getTickCount() - inputLineGetInverse[key]
			local progress = elapsedTime / 300

			lineProgress = interpolateBetween(
				1, 0, 0,
				0, 0, 0,
				progress, "Linear")
		end

		lineProgress = sx / 2 * lineProgress

		local activeColor = tocolor(128,0,128, 175 * a)
		dxDrawRectangle(x, y + sy - 2, sx, 2, tocolor(borderColor[1], borderColor[2], borderColor[3], borderColor[4] * a))
		dxDrawRectangle(x + sx / 2, y + sy - 2, -lineProgress, 2, activeColor)
		dxDrawRectangle(x + sx / 2, y + sy - 2, lineProgress, 2, activeColor)

		sy = sy - 2

		if utf8.len(fakeInputs[key]) > 0 then
			dxDrawText(fakeInputs[key], x + 3, y, x + sx - 3, y + sy, tocolor(255, 255, 255, 230 * a), fontScale, font, "left", "center", true)
		elseif label then
			dxDrawText(label, x + 3, y, x + sx - 3, y + sy, tocolor(100, 100, 100, 200 * a), fontScale, font, "left", "center", true)
		end

		if selectedInput == key then
			if inputCursorState then
				local contentSizeX = dxGetTextWidth(fakeInputs[key], fontScale, font)

				dxDrawLine(x + 3 + contentSizeX, y + 5, x + 3 + contentSizeX, y + sy - 5, tocolor(230, 230, 230, 175 * a))
			end

			if getTickCount() - lastChangeCursorState >= 500 then
				inputCursorState = not inputCursorState
				lastChangeCursorState = getTickCount()
			end
		end

		buttons["input:" .. key] = {x, y, sx, sy}
	end

	function drawButton(key, text, x, y, w, h, r, g, b, a, font, fontScale, icon, iconFont, iconScale)
		local buttonR, buttonG, buttonB, buttonA
		local borderR, borderG, borderB

		a = a or 1
		font = font or "default-bold"
		fontScale = fontScale or 1

		if activeButton == "btn:" .. key then
			if getKeyState("mouse1") then
				buttonR, buttonG, buttonB, buttonA = colorInterpolation("btn:" .. key, r, g, b, 175, 175)
			else
				buttonR, buttonG, buttonB, buttonA = colorInterpolation("btn:" .. key, r, g, b, 250)
			end

			borderR, borderG, borderB = colorInterpolation("btnBorder:" .. key, r, g, b, 230)
		else
			buttonR, buttonG, buttonB, buttonA = colorInterpolation("btn:" .. key, 59, 59, 59, 240)
			borderR, borderG, borderB = colorInterpolation("btnBorder:" .. key, 117, 117, 117, 175)
		end

		local borderColor = tocolor(borderR, borderG, borderB, 255 * a)

		dxDrawRectangle(x + 1, y + 2, w - 2, h - 4, tocolor(buttonR, buttonG, buttonB, buttonA * a))
		dxDrawRectangle(x, y, w, 2, borderColor)
		dxDrawRectangle(x, y + h - 2, w, 2, borderColor)
		dxDrawRectangle(x - 1, y + 1, 2, h - 2, borderColor)
		dxDrawRectangle(x + w - 1, y + 1, 2, h - 2, borderColor)

		if not icon then
			dxDrawText(text, x, y, x + w, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "center", "center")
		elseif not iconFont then
			iconScale = iconScale or h - 5

			local iconWidth = iconScale + 10
			local textWidth = dxGetTextWidth(text, fontScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawImage(math.floor(labelStartX), math.floor(y + (h - iconScale) / 2), iconScale, iconScale, icon, 0, 0, 0, tocolor(255, 255, 255, 255 * a))
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		elseif iconFont then
			iconScale = iconScale or fontScale

			local iconWidth = dxGetTextWidth(icon, iconScale, iconFont) + 10
			local textWidth = dxGetTextWidth(text, iconScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawText(icon, labelStartX, y, 0, y + h, tocolor(255, 255, 255, 255 * a), iconScale, iconFont, "left", "center")
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		end

		buttons["btn:" .. key] = {x, y, w, h}
	end

	function drawButton2(key, text, x, y, w, h, r, g, b, a, font, fontScale, icon, iconFont, iconScale)
		local buttonR, buttonG, buttonB, buttonA

		if activeButton == key then
			if getKeyState("mouse1") then
				buttonR, buttonG, buttonB, buttonA = colorInterpolation(key, r, g, b, 200, 250)
			else
				buttonR, buttonG, buttonB, buttonA = colorInterpolation(key, r, g, b, 175)
			end
		else
			buttonR, buttonG, buttonB, buttonA = colorInterpolation(key, r, g, b, 125)
		end

		local alphaDifference = 175 - buttonA

		dxDrawRectangle(x, y, w, h, tocolor(buttonR, buttonG, buttonB, (175 - alphaDifference) * a))

		local marginColor = tocolor(buttonR, buttonG, buttonB, (125 + alphaDifference) * a)

		dxDrawLine(x, y, x + w, y, marginColor, 2)
		dxDrawLine(x, y + h, x + w, y + h, marginColor, 2)
		dxDrawLine(x, y, x, y + h, marginColor, 2)
		dxDrawLine(x + w, y, x + w, y + h, marginColor, 2)

		font = font or "default-bold"
		fontScale = fontScale or 1

		if not text and icon then
			iconScale = iconScale or fontScale

			dxDrawText(icon, x, y, x + w, y + h, tocolor(255, 255, 255, 255 * a), iconScale, iconFont, "center", "center")
		elseif not icon then
			dxDrawText(text, x, y, x + w, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "center", "center")
		elseif not iconFont then
			iconScale = iconScale or h - 5

			local iconWidth = iconScale + 10
			local textWidth = dxGetTextWidth(text, fontScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawImage(math.floor(labelStartX), math.floor(y + (h - iconScale) / 2), iconScale, iconScale, icon, 0, 0, 0, tocolor(255, 255, 255, 255 * a))
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		elseif iconFont then
			iconScale = iconScale or fontScale

			local iconWidth = dxGetTextWidth(icon, iconScale, iconFont) + 10
			local textWidth = dxGetTextWidth(text, iconScale, font)
			local labelStartX = x + (w - (iconWidth + textWidth)) / 2

			dxDrawText(icon, labelStartX, y, 0, y + h, tocolor(255, 255, 255, 255 * a), iconScale, iconFont, "left", "center")
			dxDrawText(text, labelStartX + iconWidth, y, 0, y + h, tocolor(255, 255, 255, 255 * a), fontScale, font, "left", "center")
		end

		buttons[key] = {x, y, w, h}
	end

	local colorInterpolationValues = {}
	local lastColorInterpolationValues = {}
	local colorInterpolationTicks = {}

	function colorInterpolation(key, r, g, b, a, duration)
		if not colorInterpolationValues[key] then
			colorInterpolationValues[key] = {r, g, b, a}
			lastColorInterpolationValues[key] = r .. g .. b .. a
		end

		if lastColorInterpolationValues[key] ~= (r .. g .. b .. a) then
			lastColorInterpolationValues[key] = r .. g .. b .. a
			colorInterpolationTicks[key] = getTickCount()
		end

		if colorInterpolationTicks[key] then
			local progress = (getTickCount() - colorInterpolationTicks[key]) / (duration or 500)
			local red, green, blue = interpolateBetween(colorInterpolationValues[key][1], colorInterpolationValues[key][2], colorInterpolationValues[key][3], r, g, b, progress, "Linear")
			local alpha = interpolateBetween(colorInterpolationValues[key][4], 0, 0, a, 0, 0, progress, "Linear")

			colorInterpolationValues[key][1] = red
			colorInterpolationValues[key][2] = green
			colorInterpolationValues[key][3] = blue
			colorInterpolationValues[key][4] = alpha

			if progress >= 1 then
				colorInterpolationTicks[key] = false
			end
		end

		return colorInterpolationValues[key][1], colorInterpolationValues[key][2], colorInterpolationValues[key][3], colorInterpolationValues[key][4]
	end

	]])
end

 

Link to comment
  • 3 weeks later...

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