Szerző Téma: Miért nem lehet hallani?  (Megtekintve 1687 alkalommal)

Miért nem lehet hallani?
« Dátum: 2016. November 21. - 16:45:28 »
0
No szeasztok srácok lenne nekem egy olyan gondom, hogy ennél a scriptnél nem játsza le a \"venom hangot\" mikor belerakom a venom tuningot. Segítségeket előre is köszönöm. (Nagyon nagyon kezdő vagyok még scriptelés terén.)
Turbo: Client.lua
 
function turbo()
timer = setTimer(function()
if (getPedOccupiedVehicle(getLocalPlayer())) then
   if not(getElementData(getPedOccupiedVehicle(getLocalPlayer()), \"turbo\") or false) then
      if isTimer(timer) then
         killTimer(timer)
      end
   end
   local cur = getVehicleCurrentGear(getPedOccupiedVehicle(getLocalPlayer()))
   if ((getElementData(getLocalPlayer(), \"tuning.gear\") or 0)<cur) and (cur==2 or cur>=4) then
      setElementData(getLocalPlayer(), \"tuning.gear\", cur)
      playSound(\"turbo/turbo.wav\")
   else
      setElementData(getLocalPlayer(), \"tuning.gear\", cur)
   end
else
   if isTimer(timer) then
      killTimer(timer)
   end
end
end,50,0)
end
addEvent(\"playturboSound\", true)
addEventHandler(\"playturboSound\", getRootElement(), turbo)

 
Rendes client.lua
 
local screenX, screenY = guiGetScreenSize()
local scaleFactor = screenX / 1280
local tuningMarkers = {}
local tuningMarkersCount = 0
local markerImageMaxVisibleDistance = 35
local availableTextures = {
[\"logo\"] = dxCreateTexture(\"files/images/logo.png\", \"argb\", true, \"clamp\"),
[\"hoveredrow\"] = dxCreateTexture(\"files/images/hoveredrow.png\", \"argb\", true, \"clamp\"),
[\"menunav\"] = dxCreateTexture(\"files/images/menunav.png\", \"argb\", true, \"clamp\"),
[\"mouse\"] = dxCreateTexture(\"files/images/navbar/mouse.png\", \"argb\", true, \"clamp\"),
}
local availableIcons = {
[\"wrench\"] = \"\",
[\"long-arrow-up\"] = \"\",
[\"long-arrow-down\"] = \"\",
[\"info-circle\"] = \"\",
[\"check\"] = \"\",
[\"exclamation-triangle\"] = \"\",
}
local mouseTable = {
[\"speed\"] = {0, 0},
[\"last\"] = {0, 0},
[\"move\"] = {0, 0}
}
local panelState = false
local enteredVehicle = false
local availableFonts = nil
local panelWidth, rowHeight = 350 * scaleFactor, 35 * scaleFactor
local panelX, panelY = 32, 32
local logoHeight = panelWidth / 2
local hoveredCategory, selectedCategory, selectedSubCategory = 1, 0, 0
local maxRowsPerPage, currentPage = 7, 1
local compatibleOpticalUpgrades = {}
local equippedTuning = 1
local navbarButtonHeight = 30 * scaleFactor
local navigationBar = {
{\"\", {\"Enter\"}, false},
{\"\", {\"long-arrow-up\", \"long-arrow-down\"}, true},
{\"\", {\"Backspace\"}, false},
{getLocalizedText(\"navbar.camera\"), {\"mouse\"}, \"image\", 30}
}
local noticeData = {
[\"text\"] = false,
[\"type\"] = \"info\",
[\"tick\"] = 0,
[\"state\"] = \"\",
[\"height\"] = 0,
[\"timer\"] = nil
}
local cameraSettings = {}
local promptDialog = {
[\"state\"] = false,
[\"itemName\"] = \"\",
[\"itemPrice\"] = 0
}
local availableOffroadAbilities = {
[\"dirt\"] = {0x100000, 2},
    [\"sand\"] = {0x200000, 3}
}
local availableWheelSizes = {
[\"front\"] = {
[\"verynarrow\"] = {0x100, 1},
[\"narrow\"] = {0x200, 2},
[\"wide\"] = {0x400, 4},
[\"verywide\"] = {0x800, 5}
},
[\"rear\"] = {
[\"verynarrow\"] = {0x1000, 1},
[\"narrow\"] = {0x2000, 2},
[\"wide\"] = {0x4000, 4},
[\"verywide\"] = {0x8000, 5}
}
}
local savedVehicleColors = {[\"all\"] = false, [\"headlight\"] = false}
local moneyChangeTable = {[\"tick\"] = 0, [\"amount\"] = 0}
local vehicleNumberplate = \"\"
addEvent(\"tuning->ShowMenu\", true)
addEvent(\"tuning->HideMenu\", true)
addEventHandler(\"onClientResourceStart\", resourceRoot, function()
for _, value in ipairs(getElementsByType(\"marker\", root, true)) do
if getElementData(value, \"tuningMarkerSettings\") then
   tuningMarkers[value] = true
   tuningMarkersCount = tuningMarkersCount + 1
end
end
for i = 1, 4 do
table.insert(tuningMenu[getMainCategoryIDByName(getLocalizedText(\"menu.color\"))][\"subMenu\"], {
   [\"categoryName\"] = getLocalizedText(\"menu.color\") .. \" \" .. i,
   [\"tuningPrice\"] = 10000,
   [\"tuningData\"] = \"color\" .. i
})
end
end)
addEventHandler(\"onClientResourceStop\", resourceRoot, function()
if panelState and enteredVehicle then
resetOpticalUpgrade()
setVehicleColorsToDefault()
triggerEvent(\"tuning->HideMenu\", localPlayer)
end
end)
addEventHandler(\"onClientElementStreamIn\", root, function()
if getElementType(source) == \"marker\" then
if getElementData(source, \"tuningMarkerSettings\") then
   tuningMarkers[source] = true
   tuningMarkersCount = tuningMarkersCount + 1
end
end
end)
addEventHandler(\"onClientElementStreamOut\", root, function()
if getElementType(source) == \"marker\" then
if getElementData(source, \"tuningMarkerSettings\") then
   tuningMarkers[source] = nil
   tuningMarkersCount = tuningMarkersCount - 1
end
end
end)
addEventHandler(\"onClientRender\", root, function()
--** Tuning marker image
if tuningMarkersCount ~= 0 then
local cameraX, cameraY, cameraZ = getCameraMatrix()
for marker, id in pairs(tuningMarkers) do
   if marker and isElement(marker) then
      if getElementAlpha(marker) ~= 0 and getElementDimension(marker) == getElementDimension(localPlayer) then
         local markerX, markerY, markerZ = getElementPosition(marker)
         local markerDistance = getDistanceBetweenPoints3D(cameraX, cameraY, cameraZ, markerX, markerY, markerZ)
         if markerDistance <= markerImageMaxVisibleDistance then
            if isLineOfSightClear(cameraX, cameraY, cameraZ, markerX, markerY, markerZ, false, false, false, true, false, false, false) then
               local screenX, screenY = getScreenFromWorldPosition(markerX, markerY, markerZ + 1, 1)
               if screenX and screenY then
                  local imageScale = 1 - (markerDistance / markerImageMaxVisibleDistance) * 0.5
                  local alphaScale = 255 - (markerDistance / markerImageMaxVisibleDistance) * 1.0
                  local imageWidth, imageHeight = 256 * imageScale, 128 * imageScale
                  local imageX, imageY = screenX - (imageWidth / 2), screenY - (imageHeight / 2)
                  dxDrawImage(imageX, imageY, imageWidth, imageHeight, availableTextures[\"logo\"], 0, 0, 0, tocolor(255, 255, 255, 255 * alphaScale))
               end
            end
         end
      end
   else
      tuningMarkers[marker] = nil
   end
end
end
-- ** Tuning menu
if panelState and enteredVehicle then
--> Logo
dxDrawRectangle(panelX, panelY, panelWidth, logoHeight * scaleFactor, tocolor(0, 0, 0, 200))
dxDrawImage(panelX, panelY, panelWidth, logoHeight * scaleFactor, availableTextures[\"logo\"])
--> Current Money
drawTextWithBorder(\"$\" .. formatNumber(getPlayerMoney(localPlayer), \",\"), 2, panelX, panelY, panelX + screenX - (panelX * 2), panelY + screenY - (panelY * 2), tocolor(0, 0, 0, 255), tocolor(189, 227, 188, 255), 1.2, 1.3, \"pricedown\", \"right\", \"top\", false, false, false, true)
if moneyChangeTable[\"tick\"] >= getTickCount() then
   drawTextWithBorder(\"-$\" .. formatNumber(moneyChangeTable[\"amount\"], \",\"), 2, panelX, panelY + dxGetFontHeight(1.0, \"pricedown\"), panelX + screenX - (panelX * 2), panelY + screenY - (panelY * 2), tocolor(0, 0, 0, 255), tocolor(200, 80, 80, 255), 1.2, 1.3, \"pricedown\", \"right\", \"top\", false, false, false, true)
end
--> Notification
if noticeData[\"text\"] then
   if noticeData[\"state\"] == \"showNotice\" then
      local animationProgress = (getTickCount() - noticeData[\"tick\"]) / 300
      local animationState = interpolateBetween(0, 0, 0, logoHeight * scaleFactor, 0, 0, animationProgress, \"Linear\")
      noticeData[\"height\"] = animationState
      if animationProgress > 1 then
         noticeData[\"state\"] = \"fixNoticeJumping\"
         noticeData[\"timer\"] = setTimer(function()
            noticeData[\"tick\"] = getTickCount()
            noticeData[\"state\"] = \"hideNotice\"
         end, string.len(noticeData[\"text\"]) * 50, 1)
      end
   elseif noticeData[\"state\"] == \"hideNotice\" then
      local animationProgress = (getTickCount() - noticeData[\"tick\"]) / 300
      local animationState = interpolateBetween(logoHeight * scaleFactor, 0, 0, 0, 0, 0, animationProgress, \"Linear\")
      noticeData[\"height\"] = animationState
      if animationProgress > 1 then
         noticeData[\"text\"] = false
      end
   elseif noticeData[\"state\"] == \"fixNoticeJumping\" then
      noticeData[\"height\"] = (logoHeight * scaleFactor)
   end
   dxDrawRectangle(panelX, panelY, panelWidth, noticeData[\"height\"], tocolor(0, 0, 0, 200))
   if noticeData[\"height\"] == (logoHeight * scaleFactor) then
      local noticeIcon, iconColor = \"\", {255, 255, 255}
      if noticeData[\"type\"] == \"info\" then
         noticeIcon, iconColor = availableIcons[\"info-circle\"], {85, 178, 243}
      elseif noticeData[\"type\"] == \"warning\" then
         noticeIcon, iconColor = availableIcons[\"exclamation-triangle\"], {220, 190, 120}
      elseif noticeData[\"type\"] == \"error\" then
         noticeIcon, iconColor = availableIcons[\"exclamation-triangle\"], {200, 80, 80}
      elseif noticeData[\"type\"] == \"success\" then
         noticeIcon, iconColor = availableIcons[\"check\"], {130, 220, 115}
      end
      dxDrawText(noticeIcon, panelX + 5, panelY + 5, panelX + 5 + panelWidth - 10, panelY + 5 + noticeData[\"height\"] - 10, tocolor(iconColor[1], iconColor[2], iconColor[3], 255), 1.0, availableFonts[\"icons\"], \"left\", \"top\")
      dxDrawText(noticeData[\"text\"], panelX + 10, panelY, panelX + 10 + panelWidth - 20, panelY + noticeData[\"height\"], tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"center\", \"center\", false, true)
   end
end
--> Looping table
loopTable, categoryCount, categoryName = {}, 0, \"N/A\"
if selectedCategory == 0 then
   loopTable = tuningMenu
   categoryName = getLocalizedText(\"menu.mainMenu\")
   navigationBar[1][1] = getLocalizedText(\"navbar.select\")
   navigationBar[3][1] = getLocalizedText(\"navbar.exit\")
elseif selectedCategory ~= 0 and selectedSubCategory == 0 then
   loopTable = tuningMenu[selectedCategory][\"subMenu\"]
   categoryName = tuningMenu[selectedCategory][\"categoryName\"]
   if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then -- Color
      navigationBar[1][1] = getLocalizedText(\"navbar.buy\")
   else
      navigationBar[1][1] = getLocalizedText(\"navbar.select\")
   end
   navigationBar[3][1] = getLocalizedText(\"navbar.back\")
elseif selectedCategory ~= 0 and selectedSubCategory ~= 0 then
   if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then -- Optical
      if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
         loopTable = tuningMenu[selectedCategory][\"availableUpgrades\"]
         categoryName = tuningMenu[selectedCategory][\"categoryName\"]
      else
         loopTable = tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"subMenu\"]
         categoryName = tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"categoryName\"]
      end
   else
      loopTable = tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"subMenu\"]
      categoryName = tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"categoryName\"]
   end
   navigationBar[1][1] = getLocalizedText(\"navbar.buy\")
   navigationBar[3][1] = getLocalizedText(\"navbar.back\")
end
--> Current category
local panelY = panelY + (logoHeight * scaleFactor)
dxDrawRectangle(panelX, panelY, panelWidth, rowHeight, tocolor(0, 0, 0, 255))
dxDrawText(utf8.upper(categoryName), panelX + 10, panelY, panelX + 10 + panelWidth - 20, panelY + rowHeight, tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"left\", \"center\", false, false, false, true)
dxDrawText(hoveredCategory .. \" / \" .. #loopTable, panelX + 10, panelY, panelX + 10 + panelWidth - 20, panelY + rowHeight, tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
--> Menu rows
local panelY = panelY + rowHeight
for id, row in ipairs(loopTable) do
   if id >= currentPage and id <= currentPage + maxRowsPerPage then
      local rowX, rowY, rowWidth, rowHeight = panelX, panelY + (categoryCount * rowHeight), panelWidth, rowHeight
      if selectedCategory == 0 or selectedSubCategory == 0 then
         equippedUpgrade = -1
      elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then
         if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
            if row[\"upgradeID\"] == equippedTuning then
               equippedUpgrade = id
            end
         else
            if id == equippedTuning then
               equippedUpgrade = id
            end
         end
      else
         if id == equippedTuning then
            equippedUpgrade = id
         end
      end
      if hoveredCategory ~= id then
         if categoryCount %2 == 0 then
            dxDrawRectangle(rowX, rowY, rowWidth, rowHeight, tocolor(0, 0, 0, 150))
         else
            dxDrawRectangle(rowX, rowY, rowWidth, rowHeight, tocolor(0, 0, 0, 200))
         end
         dxDrawText(row[\"categoryName\"], rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"left\", \"center\", false, false, false, true)
         if equippedUpgrade ~= id then
            if row[\"tuningPrice\"] then
               if row[\"tuningPrice\"] == 0 then
                  dxDrawText(getLocalizedText(\"tuningPrice.free\"), rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(198, 83, 82, 255), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
               else
                  dxDrawText(\"$ \" .. formatNumber(row[\"tuningPrice\"], \",\"), rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(255, 255, 255, 200), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
               end
            end
         else
            dxDrawText(getLocalizedText(\"tuning.active\"), rowX + 15, rowY, rowX + 15 + rowWidth - 30 - dxGetTextWidth(availableIcons[\"wrench\"], 1.0, availableFonts[\"icons\"]) - 10, rowY + rowHeight, tocolor(150, 255, 150, 255), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
            dxDrawText(availableIcons[\"wrench\"], rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(150, 255, 150, 255), 1.0, availableFonts[\"icons\"], \"right\", \"center\", false, false, false, true)
         end
      else
         dxDrawImage(rowX, rowY, rowWidth, rowHeight, availableTextures[\"hoveredrow\"])
         dxDrawText(row[\"categoryName\"], rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(0, 0, 0, 255), 0.5, availableFonts[\"chalet\"], \"left\", \"center\", false, false, false, true)
         if equippedUpgrade ~= id then
            if row[\"tuningPrice\"] then
               if row[\"tuningPrice\"] == 0 then
                  dxDrawText(getLocalizedText(\"tuningPrice.free\"), rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(0, 0, 0, 255), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
               else
                  dxDrawText(\"$ \" .. formatNumber(row[\"tuningPrice\"], \",\"), rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(0, 0, 0, 200), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
               end
            end
         else
            dxDrawText(getLocalizedText(\"tuning.active\"), rowX + 15, rowY, rowX + 15 + rowWidth - 30 - dxGetTextWidth(availableIcons[\"wrench\"], 1.0, availableFonts[\"icons\"]) - 10, rowY + rowHeight, tocolor(0, 0, 0, 255), 0.5, availableFonts[\"chalet\"], \"right\", \"center\", false, false, false, true)
            dxDrawText(availableIcons[\"wrench\"], rowX + 15, rowY, rowX + 15 + rowWidth - 30, rowY + rowHeight, tocolor(0, 0, 0, 255), 1.0, availableFonts[\"icons\"], \"right\", \"center\", false, false, false, true)
         end
      end
      categoryCount = categoryCount + 1
   end
end
dxDrawImage(panelX, panelY + (categoryCount * rowHeight), panelWidth, rowHeight, availableTextures[\"menunav\"])
--> Scrollbar
if categoryCount >= (maxRowsPerPage + 1) and categoryCount ~= #loopTable then
   local rowVisible = math.max(0.05, math.min(1.0, (maxRowsPerPage + 1) / #loopTable))
   local scrollbarHeight = ((maxRowsPerPage + 1) * rowHeight) * rowVisible
   local scrollbarPosition = math.min((currentPage - 1) / #loopTable, 1.0 - rowVisible) * ((maxRowsPerPage + 1) * rowHeight)
   dxDrawRectangle(panelX + panelWidth - 2, panelY + scrollbarPosition, 2, scrollbarHeight, tocolor(255, 255, 255, 255))
end
--> Navigation Bar
local navbarWidth = getNavbarWidth()
local barOffsetX = 0
drawRoundedRectangle(screenX - navbarWidth - 32 - 10, screenY - 32 - rowHeight, navbarWidth, rowHeight, 1, tocolor(0, 0, 0, 200))
for _, row in ipairs(navigationBar) do
   local textLength = dxGetTextWidth(row[1], 0.5, availableFonts[\"chalet\"]) + 20
   local navX, navY, navHeight = screenX - navbarWidth - 32 + barOffsetX, screenY - 32 - rowHeight, rowHeight
   local navWidth = 0
   for id, icon in ipairs(row[2]) do
      local buttonWidth = 0
      if type(row[3]) == \"string\" and row[3] == \"image\" then
         buttonWidth = row[4]
      elseif type(row[3]) == \"boolean\" and row[3] then
         buttonWidth = dxGetTextWidth(availableIcons[icon], 1.0, availableFonts[\"icons\"]) + 20
      elseif type(row[3]) == \"boolean\" and not row[3] then
         buttonWidth = dxGetTextWidth(icon, 0.5, availableFonts[\"chalet\"]) + 10
      end
      local iconX = navX + textLength - 10 + ((id - 1) * buttonWidth) + ((id - 1) * 5)
      if type(row[3]) == \"boolean\" then
         drawRoundedRectangle(iconX, navY + ((rowHeight / 2) - (navbarButtonHeight / 2)), buttonWidth, navbarButtonHeight, 1, tocolor(255, 255, 255, 255))
      end
      if type(row[3]) == \"string\" and row[3] == \"image\" then
         dxDrawImage(iconX, navY + ((rowHeight / 2) - (navbarButtonHeight / 2)), buttonWidth, navbarButtonHeight, availableTextures[icon])
      elseif type(row[3]) == \"boolean\" and row[3] then
         dxDrawText(availableIcons[icon], iconX, navY + ((rowHeight / 2) - (navbarButtonHeight / 2)), iconX + buttonWidth, navY + ((rowHeight / 2) - (navbarButtonHeight / 2)) + navbarButtonHeight, tocolor(0, 0, 0, 255), 1.0, availableFonts[\"icons\"], \"center\", \"center\")
      elseif type(row[3]) == \"boolean\" and not row[3] then
         dxDrawText(icon, iconX, navY + ((rowHeight / 2) - (navbarButtonHeight / 2)), iconX + buttonWidth, navY + ((rowHeight / 2) - (navbarButtonHeight / 2)) + navbarButtonHeight, tocolor(0, 0, 0, 255), 0.5, availableFonts[\"chalet\"], \"center\", \"center\")
      end
      navWidth = navWidth + buttonWidth + 10
   end
   dxDrawText(row[1], navX, navY, navX + navWidth, navY + navHeight, tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"left\", \"center\")
   barOffsetX = barOffsetX + (navWidth + textLength)
end
--> Prompt dialog
if promptDialog[\"state\"] then
   local promptWidth = dxGetTextWidth(getLocalizedText(\"prompt.text\"), 0.5, availableFonts[\"chalet\"]) + 20
   local promptWidth, promptHeight = promptWidth, 120 * scaleFactor
   local promptX, promptY = (screenX / 2) - (promptWidth / 2), (screenY / 2) - (promptHeight / 2)
   drawRoundedRectangle(promptX, promptY, promptWidth, promptHeight, 1, tocolor(0, 0, 0, 200))
   dxDrawText(getLocalizedText(\"prompt.text\"), promptX + 10, promptY + 5, promptX + 10 + promptWidth - 20, promptY + 5 + promptHeight - 10, tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"left\", \"top\")
   dxDrawText(\"#cccccc\" .. getLocalizedText(\"prompt.info.1\") ..\": #ffffff\" .. promptDialog[\"itemName\"], promptX + 15, promptY + 30, promptX + 15 + promptWidth - 30, promptY + 30 + promptHeight - 60, tocolor(255, 255, 255, 255), 0.45, availableFonts[\"chalet\"], \"left\", \"top\", false, false, false, true)
   dxDrawText(\"#cccccc\" .. getLocalizedText(\"prompt.info.2\") .. \": #ffffff$ \" .. formatNumber(promptDialog[\"itemPrice\"], \",\"), promptX + 15, promptY + 30 + dxGetFontHeight(0.45, availableFonts[\"chalet\"]), promptX + 15 + promptWidth - 30, promptY + 30 + dxGetFontHeight(0.45, availableFonts[\"chalet\"]) + promptHeight - 60, tocolor(255, 255, 255, 255), 0.45, availableFonts[\"chalet\"], \"left\", \"top\", false, false, false, true)
   local buttonX, buttonY, buttonWidth, buttonHeight = promptX + 10, promptY + promptHeight - 10 - navbarButtonHeight, (promptWidth / 2) - 20, navbarButtonHeight
   drawRoundedRectangle(buttonX, buttonY, buttonWidth, buttonHeight, 1, tocolor(110, 207, 112, 255))
   dxDrawText(getLocalizedText(\"prompt.button.1\"), buttonX, buttonY, buttonX + buttonWidth, buttonY + buttonHeight, tocolor(0, 0, 0, 255), 0.5, availableFonts[\"chalet\"], \"center\", \"center\")
   drawRoundedRectangle((buttonX + buttonWidth + 20), buttonY, buttonWidth, buttonHeight, 1, tocolor(200, 80, 80, 255))
   dxDrawText(getLocalizedText(\"prompt.button.2\"), (buttonX + buttonWidth + 20), buttonY, (buttonX + buttonWidth + 20) + buttonWidth, buttonY + buttonHeight, tocolor(0, 0, 0, 255), 0.5, availableFonts[\"chalet\"], \"center\", \"center\")
end
--> License Plate inputbox
if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then
   if selectedSubCategory == 8 and hoveredCategory == 2 then
      local boxX, boxY, boxWidth, boxHeight = panelX + 2, panelY + (categoryCount * rowHeight) + rowHeight, panelWidth - 4, rowHeight
      drawBorderedRectangle(boxX, boxY, boxWidth, boxHeight, 2, tocolor(0, 0, 0, 255), tocolor(30, 30, 30, 255))
      dxDrawText(vehicleNumberplate, boxX, boxY, boxX + boxWidth, boxY + boxHeight, tocolor(255, 255, 255, 255), 0.5, availableFonts[\"chalet\"], \"center\", \"center\")
   end
end
end
end)
addEventHandler(\"onClientPreRender\", root, function(timeSlice)
--> Calculate mouse move speed
if isCursorShowing() then
local cursorX, cursorY = getCursorPosition()
mouseTable[\"speed\"][1] = math.sqrt(math.pow((mouseTable[\"last\"][1] - cursorX) / timeSlice, 2))
mouseTable[\"speed\"][2] = math.sqrt(math.pow((mouseTable[\"last\"][2] - cursorY) / timeSlice, 2))
mouseTable[\"last\"][1] = cursorX
mouseTable[\"last\"][2] = cursorY
end
--> Camera
if panelState and enteredVehicle then
local _, _, _, _, _, _, roll, fov = getCameraMatrix()
local cameraZoomProgress = (getTickCount() - cameraSettings[\"zoomTick\"]) / 500
local cameraZoomAnimation = interpolateBetween(fov, 0, 0, cameraSettings[\"zoom\"], 0, 0, cameraZoomProgress, \"Linear\")
if cameraSettings[\"moveState\"] == \"moveToElement\" then
   local currentCameraX, currentCameraY, currentCameraZ, currentCameraRotX, currentCameraRotY, currentCameraRotZ = getCameraMatrix()
   local cameraProgress = (getTickCount() - cameraSettings[\"moveTick\"]) / 1000
   local cameraX, cameraY, cameraZ, componentX, componentY, componentZ = _getCameraPosition(\"component\")
   local newCameraX, newCameraY, newCameraZ = interpolateBetween(currentCameraX, currentCameraY, currentCameraZ, cameraX, cameraY, cameraZ, cameraProgress, \"Linear\")
   local newCameraRotX, newCameraRotY, newCameraRotZ = interpolateBetween(currentCameraRotX, currentCameraRotY, currentCameraRotZ, componentX, componentY, componentZ, cameraProgress, \"Linear\")
   local newCameraZoom = interpolateBetween(fov, 0, 0, 60, 0, 0, cameraProgress, \"Linear\")
   setCameraMatrix(newCameraX, newCameraY, newCameraZ, newCameraRotX, newCameraRotY, newCameraRotZ, roll, newCameraZoom)
   if cameraProgress > 0.5 then
      cameraSettings[\"moveState\"] = \"freeMode\"
      cameraSettings[\"zoom\"] = 60
   end
elseif cameraSettings[\"moveState\"] == \"backToVehicle\" then
   local currentCameraX, currentCameraY, currentCameraZ, currentCameraRotX, currentCameraRotY, currentCameraRotZ = getCameraMatrix()
   local cameraProgress = (getTickCount() - cameraSettings[\"moveTick\"]) / 1000
   local cameraX, cameraY, cameraZ, vehicleX, vehicleY, vehicleZ = _getCameraPosition(\"vehicle\")
   local newCameraX, newCameraY, newCameraZ = interpolateBetween(currentCameraX, currentCameraY, currentCameraZ, cameraX, cameraY, cameraZ, cameraProgress, \"Linear\")
   local newCameraRotX, newCameraRotY, newCameraRotZ = interpolateBetween(currentCameraRotX, currentCameraRotY, currentCameraRotZ, vehicleX, vehicleY, vehicleZ, cameraProgress, \"Linear\")
   local newCameraZoom = interpolateBetween(fov, 0, 0, 60, 0, 0, cameraProgress, \"Linear\")
   setCameraMatrix(newCameraX, newCameraY, newCameraZ, newCameraRotX, newCameraRotY, newCameraRotZ, roll, newCameraZoom)
   if cameraProgress > 0.5 then
      cameraSettings[\"moveState\"] = \"freeMode\"
      cameraSettings[\"zoom\"] = 60
   end
elseif cameraSettings[\"moveState\"] == \"freeMode\" then
   local cameraX, cameraY, cameraZ, elementX, elementY, elementZ = _getCameraPosition(\"both\")
   setCameraMatrix(cameraX, cameraY, cameraZ, elementX, elementY, elementZ, roll, cameraZoomAnimation)
   if getKeyState(\"mouse1\") and not pickingColor and not pickingLuminance and isCursorShowing() and not isMTAWindowActive() and not promptDialog[\"state\"] then
      cameraSettings[\"freeModeActive\"] = true
   else
      cameraSettings[\"freeModeActive\"] = false
   end
end
end
end)
addEventHandler(\"onClientCursorMove\", root, function(cursorX, cursorY, absoluteX, absoluteY)
if panelState and enteredVehicle then
if cameraSettings[\"freeModeActive\"] then
   lastCursorX = mouseTable[\"move\"][1]
   lastCursorY = mouseTable[\"move\"][2]
   mouseTable[\"move\"][1] = cursorX
   mouseTable[\"move\"][2] = cursorY
   if cursorX > lastCursorX then
      cameraSettings[\"currentX\"] = cameraSettings[\"currentX\"] - (mouseTable[\"speed\"][1] * 100)
   elseif cursorX < lastCursorX then
      cameraSettings[\"currentX\"] = cameraSettings[\"currentX\"] + (mouseTable[\"speed\"][1] * 100)
   end
   if cursorY > lastCursorY then
      cameraSettings[\"currentZ\"] = cameraSettings[\"currentZ\"] + (mouseTable[\"speed\"][2] * 50)
   elseif cursorY < lastCursorY then
      cameraSettings[\"currentZ\"] = cameraSettings[\"currentZ\"] - (mouseTable[\"speed\"][2] * 50)
   end
   cameraSettings[\"currentY\"] = cameraSettings[\"currentX\"]
   cameraSettings[\"currentZ\"] = math.max(cameraSettings[\"minimumZ\"], math.min(cameraSettings[\"maximumZ\"], cameraSettings[\"currentZ\"]))
end
end
end)
addEventHandler(\"onClientCharacter\", root, function(character)
if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then
if selectedSubCategory == 8 and hoveredCategory == 2 then
   if #vehicleNumberplate < 8 then
      local supportedCharacters = {
         [\"q\"] = true, [\"w\"] = true, [\"x\"] = true, [\"4\"] = true,
         [\"e\"] = true, [\"r\"] = true, [\"c\"] = true, [\"5\"] = true,
         [\"t\"] = true, [\"z\"] = true, [\"v\"] = true, [\"6\"] = true,
         [\"u\"] = true, [\"i\"] = true, [\"b\"] = true, [\"7\"] = true,
         [\"o\"] = true, [\"p\"] = true, [\"n\"] = true, [\"8\"] = true,
         [\"a\"] = true, [\"s\"] = true, [\"m\"] = true, [\"9\"] = true,
         [\"d\"] = true, [\"f\"] = true, [\"0\"] = true, [\"-\"] = true,
         [\"g\"] = true, [\"h\"] = true, [\"1\"] = true, [\" \"] = true,
         [\"j\"] = true, [\"k\"] = true, [\"2\"] = true,
         [\"l\"] = true, [\"y\"] = true, [\"3\"] = true,
      }
      if supportedCharacters[character] then
         vehicleNumberplate = vehicleNumberplate .. utf8.upper(character)
         setVehiclePlateText(enteredVehicle, vehicleNumberplate)
      end
   end
end
end
end)
addEventHandler(\"onClientKey\", root, function(key, pressed)
if panelState and enteredVehicle then
if pressed then
   if key == \"arrow_d\" and not promptDialog[\"state\"] then
      if hoveredCategory > #loopTable or hoveredCategory == #loopTable then
         hoveredCategory = #loopTable
      else
         if hoveredCategory > maxRowsPerPage then
            currentPage = currentPage + 1
         end
         hoveredCategory = hoveredCategory + 1
         if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then
            if selectedSubCategory ~= 0 then
               if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
                  showNextOpticalUpgrade()
               else
                  if selectedSubCategory == 12 then -- Neon
                     addNeon(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
                  end
               end
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then
            if selectedSubCategory == 1 then
               triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"front\", loopTable[hoveredCategory][\"tuningData\"])
            elseif selectedSubCategory == 2 then
               triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"rear\", loopTable[hoveredCategory][\"tuningData\"])
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then
            setVehicleColorsToDefault()
            setPaletteType(loopTable[hoveredCategory][\"tuningData\"])
            updatePaletteColor(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
         end
         playSoundEffect(\"menunavigate.mp3\")
      end
   elseif key == \"arrow_u\" and not promptDialog[\"state\"] then
      if hoveredCategory < 1 or hoveredCategory == 1 then
         hoveredCategory = 1
         if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then
            if selectedSubCategory ~= 0 then
               if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
                  showDefaultOpticalUpgrade()
               end
            end
         end
      else
         if currentPage - 1 >= 1 then
            currentPage = currentPage - 1
         end
         hoveredCategory = hoveredCategory - 1
         if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then
            if selectedSubCategory ~= 0 then
               if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
                  if hoveredCategory == 1 then -- Default upgrade
                     removeVehicleUpgrade(enteredVehicle, compatibleOpticalUpgrades[hoveredCategory])
                  else
                     showNextOpticalUpgrade()
                  end
               else
                  if selectedSubCategory == 12 then -- Neon
                     if hoveredCategory == 1 then
                        removeNeon(enteredVehicle, true)
                     else
                        addNeon(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
                     end
                  end
               end
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then
            if selectedSubCategory == 1 then
               triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"front\", loopTable[hoveredCategory][\"tuningData\"])
            elseif selectedSubCategory == 2 then
               triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"rear\", loopTable[hoveredCategory][\"tuningData\"])
            elseif selectedSubCategory == 8 then
               if equippedTuning ~= vehicleNumberplate then
                  setVehiclePlateText(enteredVehicle, equippedTuning)
                  vehicleNumberplate = equippedTuning
               end
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then
            setVehicleColorsToDefault()
            setPaletteType(loopTable[hoveredCategory][\"tuningData\"])
            updatePaletteColor(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
         end
         playSoundEffect(\"menunavigate.mp3\")
      end
   elseif key == \"backspace\" then
      if promptDialog[\"state\"] then
         promptDialog[\"state\"] = false
      else
         if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) and selectedSubCategory == 8 then
            if hoveredCategory == 2 then
               if #vehicleNumberplate - 1 >= 0 then
                  vehicleNumberplate = string.sub(vehicleNumberplate, 1, #vehicleNumberplate - 1)
                  setVehiclePlateText(enteredVehicle, vehicleNumberplate)
               else
                  setVehiclePlateText(enteredVehicle, \"\")
                  vehicleNumberplate = \"\"
               end
               return
            else
               if equippedTuning ~= vehicleNumberplate then
                  setVehiclePlateText(enteredVehicle, equippedTuning)
                  vehicleNumberplate = equippedTuning
               end
            end
         end
         if selectedCategory == 0 and selectedSubCategory == 0 then
            triggerEvent(\"tuning->HideMenu\", localPlayer)
         elseif selectedCategory ~= 0 and selectedSubCategory == 0 then
            if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then -- Color
               destroyColorPicker()
               setVehicleColorsToDefault()
            end
            selectedCategory, hoveredCategory, currentPage = 0, 1, 1
         elseif selectedCategory ~= 0 and selectedSubCategory ~= 0 then
            moveCameraToDefaultPosition()
            if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then -- Optical
               if selectedSubCategory ~= 0 then
                  if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
                     resetOpticalUpgrade() -- reset to equipped upgrade
                     tuningMenu[selectedCategory][\"availableUpgrades\"] = {}
                     equippedTuning = 1
                  else
                     if selectedSubCategory == 11 then -- Lamp color
                        destroyColorPicker()
                        setVehicleColorsToDefault()
                        setVehicleOverrideLights(enteredVehicle, 1)
                     elseif selectedSubCategory == 12 then -- Neon
                        restoreOldNeon(enteredVehicle)
                     end
                  end
               end
            elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then -- Extras
               if selectedSubCategory == 1 then
                  local defaultWheelSize = (equippedTuning == 1 and \"verynarrow\") or (equippedTuning == 2 and \"narrow\") or (equippedTuning == 3 and \"default\") or (equippedTuning == 4 and \"wide\") or (equippedTuning == 5 and \"verywide\")
                  triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"front\", defaultWheelSize)
               elseif selectedSubCategory == 2 then
                  local defaultWheelSize = (equippedTuning == 1 and \"verynarrow\") or (equippedTuning == 2 and \"narrow\") or (equippedTuning == 3 and \"default\") or (equippedTuning == 4 and \"wide\") or (equippedTuning == 5 and \"verywide\")
                  triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"rear\", defaultWheelSize)
               elseif selectedSubCategory == 6 then
                  setVehicleDoorOpenRatio(enteredVehicle, 2, 0, 500)
                  setVehicleDoorOpenRatio(enteredVehicle, 3, 0, 500)
                  setVehicleDoorToLSD(enteredVehicle, ((equippedTuning == 1 and false) or (equippedTuning == 2 and true)))
               end
            end
            selectedSubCategory, hoveredCategory, currentPage = 0, 1, 1
         end
         playSoundEffect(\"menuback.wav\")
         if enteredVehicle then
            for component in pairs(getVehicleComponents(enteredVehicle)) do
               setVehicleComponentVisible(enteredVehicle, component, true)
            end
         end
      end
   elseif key == \"enter\" then
      if not promptDialog[\"state\"] then
         if selectedCategory == 0 then
            selectedCategory, currentPage, hoveredCategory = hoveredCategory, 1, 1
            if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then
               savedVehicleColors[\"all\"] = {getVehicleColor(enteredVehicle, true)}
               savedVehicleColors[\"headlight\"] = {getVehicleHeadLightColor(enteredVehicle)}
               createColorPicker(enteredVehicle, panelX + 2, (panelY + (logoHeight * scaleFactor) + rowHeight + (categoryCount * rowHeight) + rowHeight) + 2, panelWidth - 4, (panelWidth / 2) * scaleFactor, \"color1\")
            end
            playSoundEffect(\"menuenter.mp3\")
         elseif selectedCategory ~= 0 and selectedSubCategory == 0 then
            if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.performance\")) then
               local componentCompatible = false
               if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\", \"Bike\"}) then
                  local tuningDataName = loopTable[hoveredCategory][\"upgradeData\"]
                  local equippedTuningID = getElementData(enteredVehicle, \"tuning.\" .. tuningDataName) or 1
                  if tuningDataName ~= \"nitro\" then
                     equippedTuning = equippedTuningID
                     componentCompatible = true
                  else
                     if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\"}) then
                        equippedTuning = -1
                        componentCompatible = true
                     end
                  end
               end
               if componentCompatible then
                  setCameraAndComponentVisible()
                  selectedSubCategory, hoveredCategory, currentPage = hoveredCategory, 1, 1
               end
            elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then
               if isGTAUpgradeSlot(loopTable[hoveredCategory][\"upgradeSlot\"]) then
                  local upgradeSlot = loopTable[hoveredCategory][\"upgradeSlot\"]
                  local compatibleUpgrades = getVehicleCompatibleUpgrades(enteredVehicle, upgradeSlot)
                  if compatibleUpgrades[1] == nil then
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notCompatible\", loopTable[hoveredCategory][\"categoryName\"]))
                  else
                     setCameraAndComponentVisible()
                     compatibleOpticalUpgrades = compatibleUpgrades
                     equippedTuning = getVehicleUpgradeOnSlot(enteredVehicle, upgradeSlot)
                     table.insert(tuningMenu[selectedCategory][\"availableUpgrades\"], {
                        [\"categoryName\"] = getLocalizedText(\"tuningPack.0\"),
                        [\"tuningPrice\"] = 0,
                        [\"upgradeID\"] = 0
                     })
                     for id, upgrade in pairs(compatibleOpticalUpgrades) do
                        table.insert(tuningMenu[selectedCategory][\"availableUpgrades\"], {
                           [\"categoryName\"] = tuningMenu[selectedCategory][\"subMenu\"][hoveredCategory][\"categoryName\"] .. \" \" .. id,
                           [\"tuningPrice\"] = tuningMenu[selectedCategory][\"subMenu\"][hoveredCategory][\"tuningPrice\"],
                           [\"upgradeID\"] = upgrade
                        })
                     end
                     selectedSubCategory, hoveredCategory, currentPage = hoveredCategory, 1, 1
                     showDefaultOpticalUpgrade()
                  end
               else -- Customs optical elements (Neon, Air-Ride etc..)
                  local componentCompatible = false
                  if hoveredCategory == 10 then -- Air-Ride
                     if isComponentCompatible(enteredVehicle, \"Automobile\") then
                        equippedTuning = (getElementData(enteredVehicle, \"tuning.airRide\") and 2) or 1
                        componentCompatible = true
                     end
                  elseif hoveredCategory == 11 then -- Lamp color
                     if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\", \"Bike\"}) then
                        equippedTuning = -1
                        setVehicleOverrideLights(enteredVehicle, 2)
                        savedVehicleColors[\"all\"] = {getVehicleColor(enteredVehicle, true)}
                        savedVehicleColors[\"headlight\"] = {getVehicleHeadLightColor(enteredVehicle)}
                        createColorPicker(enteredVehicle, panelX + 2, (panelY + (logoHeight * scaleFactor) + (rowHeight * 2) + rowHeight) + 2, panelWidth - 4, (panelWidth / 2) * scaleFactor, \"headlight\")
                        componentCompatible = true
                     end
                  elseif hoveredCategory == 12 then -- Neon
                     if isComponentCompatible(enteredVehicle, \"Automobile\") then
                        local currentNeon = getElementData(enteredVehicle, \"tuning.neon\") or false
                        if currentNeon == \"white\" then currentNeon = 2
                        elseif currentNeon == \"blue\" then currentNeon = 3
                        elseif currentNeon == \"green\" then currentNeon = 4
                        elseif currentNeon == \"red\" then currentNeon = 5
                        elseif currentNeon == \"yellow\" then currentNeon = 6
                        elseif currentNeon == \"pink\" then currentNeon = 7
                        elseif currentNeon == \"orange\" then currentNeon = 8
                        elseif currentNeon == \"lightblue\" then currentNeon = 9
                        elseif currentNeon == \"rasta\" then currentNeon = 10
                        elseif currentNeon == \"ice\" then currentNeon = 11
                        else currentNeon = 1
                        end
                        equippedTuning = currentNeon
                        removeNeon(enteredVehicle, true)
                        componentCompatible = true
                     end
                  end
                  if componentCompatible then
                     setCameraAndComponentVisible()
                     selectedSubCategory, hoveredCategory, currentPage = hoveredCategory, 1, 1
                  end
               end
            elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then
               local componentCompatible = false
               if hoveredCategory == 1 then
                  if isComponentCompatible(enteredVehicle, \"Automobile\") then
                     equippedTuning = getVehicleWheelSize(enteredVehicle, \"front\")
                     triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"front\", loopTable[hoveredCategory][\"subMenu\"][1][\"tuningData\"])
                     componentCompatible = true
                  end
               elseif hoveredCategory == 2 then
                  if isComponentCompatible(enteredVehicle, \"Automobile\") then
                     equippedTuning = getVehicleWheelSize(enteredVehicle, \"rear\")
                     triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, \"rear\", loopTable[hoveredCategory][\"subMenu\"][1][\"tuningData\"])
                     componentCompatible = true
                  end
               elseif hoveredCategory == 3 then
                  if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\", \"Bike\"}) then
                     equippedTuning = getVehicleOffroadAbility(enteredVehicle)
                     componentCompatible = true
                  end
               elseif hoveredCategory == 4 then
                  if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\"}) then
                     local driveType = getVehicleHandling(enteredVehicle)[\"driveType\"]
                     equippedTuning = (driveType == \"fwd\" and 1) or (driveType == \"awd\" and 2) or (driveType == \"rwd\" and 3)
                     componentCompatible = true
                  end
               elseif hoveredCategory == 5 then
                  if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\", \"Bike\"}) then
                     equippedTuning = (getElementData(enteredVehicle, \"tuning.bulletProofTires\") and 2) or 1
                     componentCompatible = true
                  end
               elseif hoveredCategory == 6 then
                  if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\"}) then
                     equippedTuning = (getElementData(enteredVehicle, \"tuning.lsdDoor\") and 2) or 1
                     setVehicleDoorOpenRatio(enteredVehicle, 2, 1, 500)
                     setVehicleDoorOpenRatio(enteredVehicle, 3, 1, 500)
                     setVehicleDoorToLSD(enteredVehicle, true)
                     componentCompatible = true
                  end
               elseif hoveredCategory == 7 then
                  if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\", \"Bike\", \"BMX\"}) then
                     local steeringLock = getVehicleHandling(enteredVehicle)[\"steeringLock\"]
                     equippedTuning = (steeringLock == 30 and 2) or (steeringLock == 40 and 3) or (steeringLock == 50 and 4) or (steeringLock == 60 and 5) or 1
                     componentCompatible = true
                  end
               elseif hoveredCategory == 8 then
                  if isComponentCompatible(enteredVehicle, {\"Automobile\", \"Monster Truck\", \"Quad\", \"Bike\"}) then
                     equippedTuning = getVehiclePlateText(enteredVehicle)
                     vehicleNumberplate = equippedTuning
                     componentCompatible = true
                  end
               end
               if componentCompatible then
                  setCameraAndComponentVisible()
                  selectedSubCategory, hoveredCategory, currentPage = hoveredCategory, 1, 1
               end
            elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then
               promptDialog = {
                  [\"state\"] = true,
                  [\"itemName\"] = categoryName .. \" (\" .. loopTable[hoveredCategory][\"categoryName\"] .. \")\",
                  [\"itemPrice\"] = loopTable[hoveredCategory][\"tuningPrice\"]
               }
            end
            playSoundEffect(\"menuenter.mp3\")
         elseif selectedCategory ~= 0 and selectedSubCategory ~= 0 then
            promptDialog = {
               [\"state\"] = true,
               [\"itemName\"] = categoryName .. \" (\" .. loopTable[hoveredCategory][\"categoryName\"] .. \")\",
               [\"itemPrice\"] = loopTable[hoveredCategory][\"tuningPrice\"]
            }
         end
      else -- Buying item after accepted prompt
         if selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.performance\")) then
            if hoveredCategory == equippedTuning then
               giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
               promptDialog[\"state\"] = false
            else
               if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                  local tuningName = tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeData\"]
                  setElementData(enteredVehicle, \"tuning.\" .. tuningName, hoveredCategory, true)
                  if tuningName ~= \"nitro\" then
                     triggerServerEvent(\"tuning->PerformanceUpgrade\", localPlayer, enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
                     equippedTuning = hoveredCategory
                  else
                     if loopTable[hoveredCategory][\"tuningData\"] == 0 then
                        triggerServerEvent(\"tuning->OpticalUpgrade\", localPlayer, enteredVehicle, \"remove\", 1010)
                     else
                        triggerServerEvent(\"tuning->OpticalUpgrade\", localPlayer, enteredVehicle, \"add\", 1010)
                     end
                     setElementData(enteredVehicle, \"tuning.nitroLevel\", loopTable[hoveredCategory][\"tuningData\"])
                     refreshVehicleNitroLevel(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
                  end
                  moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                  promptDialog[\"state\"] = false
               else
                  giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                  promptDialog[\"state\"] = false
               end
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.optical\")) then
            if isGTAUpgradeSlot(tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"upgradeSlot\"]) then
               if equippedTuning == loopTable[hoveredCategory][\"upgradeID\"] then
                  giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                  promptDialog[\"state\"] = false
               else
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     if getElementData(enteredVehicle, \"tuning.airRide\") and selectedSubCategory == 9 then
                        giveNotification(\"warning\", getLocalizedText(\"notification.warning.airRideInstalled\"))
                     else
                        if loopTable[hoveredCategory][\"upgradeID\"] == 0 then
                           triggerServerEvent(\"tuning->OpticalUpgrade\", localPlayer, enteredVehicle, \"remove\", equippedTuning)
                           equippedTuning = 0
                        else
                           triggerServerEvent(\"tuning->OpticalUpgrade\", localPlayer, enteredVehicle, \"add\", loopTable[hoveredCategory][\"upgradeID\"])
                           equippedTuning = loopTable[hoveredCategory][\"upgradeID\"]
                        end
                        moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     end
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            else
               if selectedSubCategory == 10 then -- Air-Ride
                  if hoveredCategory == equippedTuning then
                     giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                     promptDialog[\"state\"] = false
                  else
                     if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                        setElementData(enteredVehicle, \"tuning.airRide\", loopTable[hoveredCategory][\"tuningData\"], true)
                        if hoveredCategory == 1 then
                           removeAirRide(enteredVehicle)
                        end
                        equippedTuning = hoveredCategory
                        moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                        promptDialog[\"state\"] = false
                     else
                        giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                        promptDialog[\"state\"] = false
                     end
                  end
               elseif selectedSubCategory == 11 then -- Lamp color
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     savedVehicleColors[\"all\"] = {getVehicleColor(enteredVehicle, true)}
                     savedVehicleColors[\"headlight\"] = {getVehicleHeadLightColor(enteredVehicle)}
                     triggerServerEvent(\"tuning->Color\", localPlayer, enteredVehicle, savedVehicleColors[\"all\"], savedVehicleColors[\"headlight\"])
                     equippedTuning = -1
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               elseif selectedSubCategory == 12 then -- Neon
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     saveNeon(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"], true)
                     equippedTuning = hoveredCategory
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.extras\")) then
            if selectedSubCategory == 1 or selectedSubCategory == 2 then
               local vehicleSide = (selectedSubCategory == 1 and \"front\") or (selectedSubCategory == 2 and \"rear\")
               if hoveredCategory == equippedTuning then
                  giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                  promptDialog[\"state\"] = false
               else
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     triggerServerEvent(\"tuning->WheelWidth\", localPlayer, enteredVehicle, vehicleSide, loopTable[hoveredCategory][\"tuningData\"])
                     equippedTuning = hoveredCategory
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            elseif selectedSubCategory == 3 then
               if hoveredCategory == equippedTuning then
                  giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                  promptDialog[\"state\"] = false
               else
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     triggerServerEvent(\"tuning->OffroadAbility\", localPlayer, enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
                     equippedTuning = hoveredCategory
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            elseif selectedSubCategory == 4 or selectedSubCategory == 7 then
               if hoveredCategory == equippedTuning then
                  giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                  promptDialog[\"state\"] = false
               else
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     triggerServerEvent(\"tuning->HandlingUpdate\", localPlayer, enteredVehicle, tuningMenu[selectedCategory][\"subMenu\"][selectedSubCategory][\"propertyName\"], loopTable[hoveredCategory][\"tuningData\"])
                     equippedTuning = hoveredCategory
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            elseif selectedSubCategory == 5 then
               if hoveredCategory == equippedTuning then
                  giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                  promptDialog[\"state\"] = false
               else
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     setElementData(enteredVehicle, \"tuning.bulletProofTires\", loopTable[hoveredCategory][\"tuningData\"], true)
                     equippedTuning = hoveredCategory
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            elseif selectedSubCategory == 6 then
               if hoveredCategory == equippedTuning then
                  giveNotification(\"error\", getLocalizedText(\"notification.error.itemIsPurchased\", loopTable[hoveredCategory][\"categoryName\"]))
                  promptDialog[\"state\"] = false
               else
                  if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                     setVehicleDoorToLSD(enteredVehicle, loopTable[hoveredCategory][\"tuningData\"])
                     equippedTuning = hoveredCategory
                     moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                     promptDialog[\"state\"] = false
                  else
                     giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                     promptDialog[\"state\"] = false
                  end
               end
            elseif selectedSubCategory == 8 then
               if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
                  if loopTable[hoveredCategory][\"tuningData\"] == \"random\" then
                     vehicleNumberplate = generateString(8)
                  elseif loopTable[hoveredCategory][\"tuningData\"] == \"custom\" then
                     vehicleNumberplate = vehicleNumberplate
                  end
                  triggerServerEvent(\"tuning->LicensePlate\", localPlayer, enteredVehicle, vehicleNumberplate)
                  equippedTuning = vehicleNumberplate
                  moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
                  promptDialog[\"state\"] = false
               else
                  giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
                  promptDialog[\"state\"] = false
               end
            end
         elseif selectedCategory == getMainCategoryIDByName(getLocalizedText(\"menu.color\")) then
            if hasPlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"]) then
               savedVehicleColors[\"all\"] = {getVehicleColor(enteredVehicle, true)}
               savedVehicleColors[\"headlight\"] = {getVehicleHeadLightColor(enteredVehicle)}
               triggerServerEvent(\"tuning->Color\", localPlayer, enteredVehicle, savedVehicleColors[\"all\"], savedVehicleColors[\"headlight\"])
               equippedTuning = hoveredCategory
               moneyChange(loopTable[hoveredCategory][\"tuningPrice\"])
               promptDialog[\"state\"] = false
            else
               giveNotification(\"error\", getLocalizedText(\"notification.error.notEnoughMoney\"))
               promptDialog[\"state\"] = false
            end
         end
      end
   end
   if key == \"mouse_wheel_up\" and not promptDialog[\"state\"] then
      if isCursorShowing() and not isMTAWindowActive() then
         cameraSettings[\"zoom\"] = math.max(cameraSettings[\"zoom\"] - 5, 30)
         cameraSettings[\"zoomTick\"] = getTickCount()
      end
   elseif key == \"mouse_wheel_down\" and not promptDialog[\"state\"] then
      if isCursorShowing() and not isMTAWindowActive() then
         cameraSettings[\"zoom\"] = math.min(cameraSettings[\"zoom\"] + 5, 60)
         cameraSettings[\"zoomTick\"] = getTickCount()
      end
   end
end
end
end)
addEventHandler(\"tuning->ShowMenu\", root, function(vehicle)
if source and vehicle then
if not panelState then
   enteredVehicle = vehicle
   createFonts()
   hoveredCategory, selectedCategory, selectedSubCategory = 1, 0, 0
   maxRowsPerPage, currentPage = 7, 1
   navigationBar[1][1] = getLocalizedText(\"navbar.select\")
   navigationBar[2][1] = getLocalizedText(\"navbar.navigate\")
   navigationBar[3][1] = getLocalizedText(\"navbar.back\")
   if noticeData[\"timer\"] then
      if isTimer(noticeData[\"timer\"]) then
         killTimer(noticeData[\"timer\"])
      end
   end
   noticeData = {
      [\"text\"] = false,
      [\"type\"] = \"info\",
      [\"tick\"] = 0,
      [\"state\"] = \"\",
      [\"height\"] = 0,
      [\"timer\"] = nil
   }
   local _, _, vehicleRotation = getElementRotation(enteredVehicle)
   local cameraRotation = vehicleRotation + 60
   cameraSettings = {
      [\"distance\"] = 9,
      [\"movingSpeed\"] = 2,
      [\"currentX\"] = math.rad(cameraRotation),
      [\"defaultX\"] = math.rad(cameraRotation),
      [\"currentY\"] = math.rad(cameraRotation),
      [\"currentZ\"] = math.rad(15),
      [\"maximumZ\"] = math.rad(35),
      [\"minimumZ\"] = math.rad(0),
      [\"freeModeActive\"] = false,
      [\"zoomTick\"] = 0,
      [\"zoom\"] = 60
   }
   cameraSettings[\"moveState\"] = \"freeMode\"
   promptDialog = {
      [\"state\"] = false,
      [\"itemName\"] = \"\",
      [\"itemPrice\"] = 0
   }
   panelState = true
   toggleAllControls(false)
   setPlayerHudComponentVisible(\"all\", false)
   showChat(false)
   showCursor(true)
end
end
end)
addEventHandler(\"tuning->HideMenu\", root, function()
if enteredVehicle and panelState then
panelState = false
toggleAllControls(true)
setPlayerHudComponentVisible(\"all\", true)
showChat(true)
enteredVehicle = nil
destroyFonts()
setCameraTarget(localPlayer)
showCursor(false)
triggerServerEvent(\"tuning->ResetMarker\", root, localPlayer)
end
end)
addEventHandler(\"onClientVehicleDamage\", root, function(_, _, _, _, _, _, tyre) -- Bulletproof tires
if getElementData(source, \"tuning.bulletProofTires\") then
if tyre == 0 or tyre == 1 or tyre == 2 or tyre == 3 then
   cancelEvent()
end
end
end)
function moneyChange(amount)
takePlayerMoney(loopTable[hoveredCategory][\"tuningPrice\"])
giveNotification(\"success\", getLocalizedText(\"notification.success.purchased\"))
playSoundEffect(\"moneychange.wav\")
if amount > 0 then
moneyChangeTable = {
   [\"tick\"] = getTickCount() + 5000,
   [\"amount\"] = amount
}
end
end
function createFonts()
availableFonts = {
chalet = dxCreateFont(\"files/fonts/chalet.ttf\", 22 * scaleFactor, false, \"antialiased\"),
icons = dxCreateFont(\"files/fonts/icons.ttf\", 11 * scaleFactor, false, \"antialiased\")
}
end
function destroyFonts()
if availableFonts then
for fontName, fontElement in pairs(availableFonts) do
   destroyElement(fontElement)
   availableFonts[fontName] = nil
end
availableFonts = nil
end
end
function drawTextWithBorder(text, offset, x, y, w, h, borderColor, color, scale, font, alignX, alignY, clip, wordBreak, postGUI, colorCoded, subPixelPositioning, fRotation, fRotationCenterX, fRotationCenterY)
for offsetX = -offset, offset do
for offsetY = -offset, offset do
   dxDrawText(text:gsub(\"#%x%x%x%x%x%x\", \"\"), x + offsetX, y + offsetY, w + offsetX, h + offsetY, borderColor, scale, font, alignX, alignY, clip, wordBreak, postGUI, colorCoded, subPixelPositioning, fRotation, fRotationCenterX, fRotationCenterY)
end
end
dxDrawText(text, x, y, w, h, color, scale, font, alignX, alignY, clip, wordBreak, postGUI, colorCoded, subPixelPositioning, fRotation, fRotationCenterX, fRotationCenterY)
end
function giveNotification(type, text)
type = type or \"info\"
if noticeData[\"timer\"] then
if isTimer(noticeData[\"timer\"]) then
   killTimer(noticeData[\"timer\"])
end
end
noticeData = {
[\"text\"] = text,
[\"type\"] = type,
[\"tick\"] = getTickCount(),
[\"state\"] = \"showNotice\",
[\"height\"] = 0,
[\"timer\"] = nil
}
playSoundEffect(\"notification.mp3\")
end
function getNavbarWidth()
local barOffsetX = 0
for _, row in ipairs(navigationBar) do
local textLength = dxGetTextWidth(row[1], 0.5, availableFonts[\"chalet\"]) + 20
local navWidth = 0
for id, icon in ipairs(row[2]) do
   local buttonWidth = 0
   if type(row[3]) == \"string\" and row[3] == \"image\" then
      buttonWidth = row[4]
   elseif type(row[3]) == \"boolean\" and row[3] then
      buttonWidth = dxGetTextWidth(availableIcons[icon], 1.0, availableFonts[\"icons\"]) + 20
   elseif type(row[3]) == \"boolean\" and not row[3] then
      buttonWidth = dxGetTextWidth(icon, 0.5, availableFonts[\"chalet\"]) + 10
   end
   navWidth = navWidth + buttonWidth + 10
end
barOffsetX = barOffsetX + (navWidth + textLength)
end
return barOffsetX
end
function hasPlayerMoney(money)
if getPlayerMoney(localPlayer) >= money then
return true
end
return false
end
function drawRoundedRectangle(x, y, w, h, rounding, borderColor, bgColor, postGUI)
borderColor = borderColor or tocolor(0, 0, 0, 200)
bgColor = bgColor or borderColor
rounding = rounding or 2
dxDrawRectangle(x, y, w, h, bgColor, postGUI)
dxDrawRectangle(x + rounding, y - 1, w - (rounding * 2), 1, borderColor, postGUI)
dxDrawRectangle(x + rounding, y + h, w - (rounding * 2), 1, borderColor, postGUI)
dxDrawRectangle(x - 1, y + rounding, 1, h - (rounding * 2), borderColor, postGUI)
dxDrawRectangle(x + w, y + rounding, 1, h - (rounding * 2), borderColor, postGUI)
end
function showDefaultOpticalUpgrade()
if panelState then
if enteredVehicle then
   if equippedTuning ~= 0 then
      removeVehicleUpgrade(enteredVehicle, equippedTuning)
   elseif equippedTuning == 0 then
      removeVehicleUpgrade(enteredVehicle, compatibleOpticalUpgrades[hoveredCategory])
   end
end
end
end
function showNextOpticalUpgrade()
if panelState then
if enteredVehicle then
   addVehicleUpgrade(enteredVehicle, compatibleOpticalUpgrades[hoveredCategory - 1])
end
end
end
function resetOpticalUpgrade()
if panelState then
if enteredVehicle then
   if equippedTuning ~= 0 then
      addVehicleUpgrade(enteredVehicle, equippedTuning)
   else
      if hoveredCategory - 1 == 0 then
         removeVehicleUpgrade(enteredVehicle, compatibleOpticalUpgrades[hoveredCategory])
      else
         removeVehicleUpgrade(enteredVehicle, compatibleOpticalUpgrades[hoveredCategory - 1])
      end
   end
end
end
end
function formatNumber(amount, spacer)
if not spacer then
spacer = \",\"
end
amount = math.floor(amount)
local left, num, right = string.match(tostring(amount), \"^([^%d]*%d)(%d*)(.-)$\")
return left .. (num:reverse():gsub(\"(%d%d%d)\", \"%1\" .. spacer):reverse()) .. right
end
function playSoundEffect(soundFile)
if soundFile then
local soundEffect = playSound(\"files/sounds/\" .. soundFile, false)
setSoundVolume(soundEffect, 0.5)
end
end
function getPositionFromElementOffset(element, offsetX, offsetY, offsetZ)
local elementMatrix = getElementMatrix(element)
    local elementX = offsetX * elementMatrix[1][1] + offsetY * elementMatrix[2][1] + offsetZ * elementMatrix[3][1] + elementMatrix[4][1]
    local elementY = offsetX * elementMatrix[1][2] + offsetY * elementMatrix[2][2] + offsetZ * elementMatrix[3][2] + elementMatrix[4][2]
    local elementZ = offsetX * elementMatrix[1][3] + offsetY * elementMatrix[2][3] + offsetZ * elementMatrix[3][3] + elementMatrix[4][3]
    return elementX, elementY, elementZ
end
function getVehicleOffroadAbility(vehicle)
if vehicle then
local flags = getVehicleHandling(vehicle)[\"handlingFlags\"]
for name, flag in pairs(availableOffroadAbilities) do
   if isFlagSet(flags, flag[1]) then
      return flag[2]
   end
end
return 1
end
end
function getVehicleWheelSize(vehicle, side)
if vehicle and side then
local flags = getVehicleHandling(vehicle)[\"handlingFlags\"]
for name, flag in pairs(availableWheelSizes[side]) do
   if isFlagSet(flags, flag[1]) then
      return flag[2]
   end
end
return 3
end
end
function isGTAUpgradeSlot(slot)
if slot then
for i = 0, 16 do
   if slot == i then
      return true
   end
end
end
return false
end
function isFlagSet(val, flag)
return (bitAnd(val, flag) == flag)
end
function moveCameraToComponent(component, offsetX, offsetZ, zoom)
if component then
local _, _, vehicleRotation = getElementRotation(enteredVehicle)
offsetX = offsetX or cameraSettings[\"defaultX\"]
offsetZ = offsetZ or 15
zoom = zoom or 9
local cameraRotation = vehicleRotation + offsetX
cameraSettings[\"moveState\"] = \"moveToElement\"
cameraSettings[\"moveTick\"] = getTickCount()
cameraSettings[\"viewingElement\"] = component
cameraSettings[\"currentX\"] = math.rad(cameraRotation)
cameraSettings[\"currentY\"] = math.rad(cameraRotation)
cameraSettings[\"currentZ\"] = math.rad(offsetZ)
cameraSettings[\"distance\"] = zoom
end
end
function moveCameraToDefaultPosition()
cameraSettings[\"moveState\"] = \"backToVehicle\"
cameraSettings[\"moveTick\"] = getTickCount()
cameraSettings[\"viewingElement\"] = enteredVehicle
cameraSettings[\"currentX\"] = cameraSettings[\"defaultX\"]
cameraSettings[\"currentY\"] = cameraSettings[\"defaultX\"]
cameraSettings[\"currentZ\"] = math.rad(15)
cameraSettings[\"distance\"] = 9
end
function _getCameraPosition(element)
if element == \"component\" then
local componentX, componentY, componentZ = getVehicleComponentPosition(enteredVehicle, cameraSettings[\"viewingElement\"])
local elementX, elementY, elementZ = getPositionFromElementOffset(enteredVehicle, componentX, componentY, componentZ)
local elementZ = elementZ + 0.2
local cameraX = elementX + math.cos(cameraSettings[\"currentX\"]) * cameraSettings[\"distance\"]
local cameraY = elementY + math.sin(cameraSettings[\"currentY\"]) * cameraSettings[\"distance\"]
local cameraZ = elementZ + math.sin(cameraSettings[\"currentZ\"]) * cameraSettings[\"distance\"]
return cameraX, cameraY, cameraZ, elementX, elementY, elementZ
elseif element == \"vehicle\" then
local elementX, elementY, elementZ = getElementPosition(enteredVehicle)
local elementZ = elementZ + 0.2
local cameraX = elementX + math.cos(cameraSettings[\"currentX\"]) * cameraSettings[\"distance\"]
local cameraY = elementY + math.sin(cameraSettings[\"currentY\"]) * cameraSettings[\"distance\"]
local cameraZ = elementZ + math.sin(cameraSettings[\"currentZ\"]) * cameraSettings[\"distance\"]
return cameraX, cameraY, cameraZ, elementX, elementY, elementZ
elseif element == \"both\" then
if type(cameraSettings[\"viewingElement\"]) == \"string\" then
   local componentX, componentY, componentZ = getVehicleComponentPosition(enteredVehicle, cameraSettings[\"viewingElement\"])
   elementX, elementY, elementZ = getPositionFromElementOffset(enteredVehicle, componentX, componentY, componentZ)
else
   elementX, elementY, elementZ = getElementPosition(enteredVehicle)
end
local elementZ = elementZ + 0.2
local cameraX = elementX + math.cos(cameraSettings[\"currentX\"]) * cameraSettings[\"distance\"]
local cameraY = elementY + math.sin(cameraSettings[\"currentY\"]) * cameraSettings[\"distance\"]
local cameraZ = elementZ + math.sin(cameraSettings[\"currentZ\"]) * cameraSettings[\"distance\"]
return cameraX, cameraY, cameraZ, elementX, elementY, elementZ
end
end
function isValidComponent(vehicle, componentName)
if vehicle and componentName then
for component in pairs(getVehicleComponents(vehicle)) do
   if componentName == component then
      return true
   end
end
end
return false
end
f
« Utoljára szerkesztve: 2016. November 21. - 17:08:20 írta Marley Isuah »

Nem elérhető anGeL

  • Adminisztrátor
  • 2158
    • Profil megtekintése
Miért nem lehet hallani?
« Válasz #1 Dátum: 2016. November 21. - 16:54:23 »
+1
Senki sem fog letölteni semmit. Másold be a scriptet lua codetagek közé. Link törölve.

Miért nem lehet hallani?
« Válasz #2 Dátum: 2016. November 21. - 17:05:26 »
0
Bemásolnám de szerintem van 3 fajta client/server.lua ami szükséges. Az meg így rengeteg lenne. De kérésedre bemásolom..

Miért nem lehet hallani?
« Válasz #3 Dátum: 2016. November 21. - 17:06:35 »
0
Eleve a zene lejátszás csak client oldali script.  :facepalm: :shurg:

Miért nem lehet hallani?
« Válasz #4 Dátum: 2016. November 21. - 17:09:51 »
0
Remek. Csak tudod ennél a scriptnél már nem lepődnék meg ha a server oldaliba lenne gond.. örülök neki hogy hülyének nézel annak ellenére is hogy én leírtam hogy nagyjából szart se tudok.. (ilyentéren)

Miért nem lehet hallani?
« Válasz #5 Dátum: 2016. November 21. - 17:15:29 »
0
Azért egy kis segítséget írhatnál nekünk. Mert hogy venom hangot nem játsza le az oké de pl én azt se tudom mi az a venom hang (és senkinek sincs kedve 1600 sornyi kódot bogarászni) tehát hol a hiba mit nem játsz le?
 
playSound(\"turbo/turbo.wav\")

 
Client.lua ában a 12. sorban ezt?

Miért nem lehet hallani?
« Válasz #6 Dátum: 2016. November 21. - 17:47:21 »
0
Ezért linkeltem el a modot az elején hogy át tudjátok nézni :D a turbo.wav-ot nem játsza le.. mikor mész a kocsival és kiengednek a szelepek vagy mi a tök és kiadja azt a hangot. Egyébként igen azt.

Nem elérhető anGeL

  • Adminisztrátor
  • 2158
    • Profil megtekintése
Miért nem lehet hallani?
« Válasz #7 Dátum: 2016. November 21. - 18:30:53 »
+1
Idézetet írta: Marley Isuah date=1479744326\" data-ipsquote-contentapp=\"forums\" data-ipsquote-contenttype=\"forums\" data-ipsquote-contentid=\"63629\" data-ipsquote-contentclass=\"forums_Topic
Bemásolnám de szerintem van 3 fajta client/server.lua ami szükséges. Az meg így rengeteg lenne. De kérésedre bemásolom..
 
pastebin.com | paste2.org

Miért nem lehet hallani?
« Válasz #8 Dátum: 2016. November 21. - 19:07:39 »
0
Lefut egyátalán ez a turbo függvény? Mi hívja meg a playturboSound eventet?

 

SimplePortal 2.3.7 © 2008-2024, SimplePortal