if not Config.GUI.Enabled then return end local Sounds = { -- In case you wanna change out the sounds they are located here. ["Close"] = {"TOGGLE_ON", "HUD_FRONTEND_DEFAULT_SOUNDSET"}, ["Open"] = {"NAV_LEFT_RIGHT", "HUD_FRONTEND_DEFAULT_SOUNDSET"}, ["Select"] = {"SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET"} } function SoundPlay(which) if not Config.GUI.Sound then return end local Sound = Sounds[which] PlaySoundFrontend(-1, Sound[1], Sound[2]) end local function Distance(x1, y1, x2, y2) local dx = x1 - x2 local dy = y1 - y2 return math.sqrt(dx * dx + dy * dy) end local function DisableControl() DisableControlAction(1, 1, true) DisableControlAction(1, 2, true) DisableControlAction(1, 18, true) DisableControlAction(1, 68, true) DisableControlAction(1, 69, true) DisableControlAction(1, 70, true) DisableControlAction(1, 91, true) DisableControlAction(1, 92, true) DisableControlAction(1, 24, true) DisableControlAction(1, 25, true) DisableControlAction(1, 14, true) DisableControlAction(1, 15, true) DisableControlAction(1, 16, true) DisableControlAction(1, 17, true) DisablePlayerFiring(PlayerId(), true) -- We wouldnt want the player punching by accident. ShowCursorThisFrame() end local function GetCursor() -- This might break for people with weird resolutions? Im really not sure. local sx, sy = GetActiveScreenResolution() local cx, cy = GetNuiCursorPosition() local cx, cy = (cx / sx) + 0.008, (cy / sy) + 0.027 return cx, cy end local function DrawButton(b) local B = Config.GUI.ButtonColor if b.Shadow then DrawSprite("dp_clothing", "circle", b.x, b.y, b.Size.Circle.x/0.80, b.Size.Circle.y/0.80, 0.0, b.Colour.r, b.Colour.g, b.Colour.b, b.Alpha) end DrawSprite("dp_clothing", b.Sprite, b.x, b.y, b.Size.Sprite.x/0.68, b.Size.Sprite.y/0.68, b.Rotation, 255, 255, 255, b.Alpha) if IsDisabledControlJustPressed(1, 24) then local x,y = GetCursor() local Distance = Distance(b.x+0.005, b.y+0.025, x, y) if Distance < 0.025 then return true end elseif IsDisabledControlJustPressed(1, 25) and Config.Debug then local x,y = GetCursor() local Distance = Distance(b.x+0.005, b.y+0.025, x, y) if Distance < 0.025 then DevTestVariants(FirstUpper(b.Sprite)) end end return false end local function Check(ped) -- We check if the player should be able to open the menu. if IsPedInAnyVehicle(ped) and not Config.GUI.AllowInCars then return false elseif IsPedSwimmingUnderWater(ped) then return false elseif IsPedRagdoll(ped) and not Config.GUI.AllowWhenRagdolled then return false elseif IsHudComponentActive(19) then -- If the weapon wheel is open, we close! return false end return true end local DefaultButton = {x = 0.0254, y = 0.0445} local DefaultCircle = {x = 0.0345 / 1.2, y = 0.06 / 1.2} local Buttons = {} local ExtraButtons = {} local function GenerateTheButtons() -- We generate the buttons here to save on a little bit of performance. local x, y, rx, ry = Config.GUI.Position.x, Config.GUI.Position.y, 0.1, 0.175 for k,v in pairs(Config.Commands) do local i = v.Button local Angle = i * math.pi / 7 local Ptx, Pty = x + rx * math.cos(Angle), y + ry * math.sin(Angle) Buttons[i] = { Command = k, Desc = v.Desc or "", Rotation = v.Rotation or 0.0, Size = {Sprite = DefaultButton}, Sprite = v.Sprite, Text = v.Name, x = Ptx, y = Pty, } end if Config.ExtrasEnabled then -- The extra buttons arent tied to the wheel, and can be moved with simple offsets. for k,v in pairs(Config.ExtraCommands) do ExtraButtons[k] = { Command = k, Desc = v.Desc or "", OffsetX = v.OffsetX, OffsetY = v.OffsetY, Size = { Circle = {x = DefaultCircle.x, y = DefaultCircle.y}, Sprite = {x = DefaultButton.x/1.35, y = DefaultButton.y/1.35}}, Sprite = v.Sprite, Text = v.Name, } end end end local function PushedButton(button, extra) -- https://www.youtube.com/watch?v=v57i1Ze0jB8 Citizen.CreateThread(function() SoundPlay("Select") if not extra then local thing = Buttons[button] thing.Size = {Sprite = {x = DefaultButton.x/1.1, y = DefaultButton.y/1.1}} Wait(100) thing.Size = {Sprite = {x = DefaultButton.x, y = DefaultButton.y}} else local thing = ExtraButtons[button] thing.Size = { Circle = {x = DefaultCircle.x, y = DefaultCircle.y}, Sprite = {x = DefaultButton.x/1.3/1.1, y = DefaultButton.y/1.3/1.1}} Wait(100) thing.Size = { Circle = {x = DefaultCircle.x, y = DefaultCircle.y}, Sprite = {x = DefaultButton.x/1.35, y = DefaultButton.y/1.35}} end end) end local function HoveredButton() local x,y = GetCursor() for k,v in pairs(Buttons) do local Distance = Distance(v.x+0.005, v.y+0.025, x, y) if Distance < 0.025 then Text(Config.GUI.Position.x, Config.GUI.Position.y-0.10, 0.3, v.Text, false, false, true) Text(Config.GUI.Position.x, Config.GUI.Position.y-0.08, 0.22, v.Desc, {210,210,210}, false, true, {x = 0.1, y = 0.2}) end end for k,v in pairs(ExtraButtons) do local Distance = Distance(Config.GUI.Position.x+v.OffsetX+0.005, Config.GUI.Position.y+v.OffsetY+0.025, x, y) if Distance < 0.025 then Text(Config.GUI.Position.x, Config.GUI.Position.y-0.10, 0.3, v.Text, false, false, true) Text(Config.GUI.Position.x, Config.GUI.Position.y-0.08, 0.22, v.Desc, {210,210,210}, false, true, {x = 0.1, y = 0.2}) end end local Distance = Distance(Config.GUI.Position.x+0.005, Config.GUI.Position.y+0.025, x, y) if Distance < 0.015 then Text(Config.GUI.Position.x, Config.GUI.Position.y-0.09, 0.3, Lang("Info"), false, false, true) end end --[[ This is the function that draws the GUI, im using native DrawSprites and Texts. Its not the most efficient thing ms wise, but it does the job pretty well, and i dont have to bother with NUI HTML stuff. If you have any performance tips, let me know. ]]-- local function DrawGUI() DisableControl() -- Disable control while GUI is active. HoveredButton() -- This checks if you are hovering a button, and if you are it displays name and description. local x, y, rx, ry = Config.GUI.Position.x, Config.GUI.Position.y, 0.1, 0.175 for k,v in pairs(Buttons) do local Colour local Alpha if LastEquipped[FirstUpper(v.Sprite)] then Alpha = 180 Colour = {r=0,g=100,b=210,a=220} else Alpha = 255 Colour = {r=0,g=0,b=0,a=255} end DrawSprite("dp_wheel", k.."", x, y, 0.4285, 0.7714, 0.0, Colour.r, Colour.g, Colour.b, Colour.a) local Button = DrawButton({ -- Lets draw the buttons! Alpha = Alpha, Colour = Colour, Rotation = v.Rotation, Size = v.Size, Sprite = v.Sprite, Text = v.Text, x = v.x, y = v.y, }) if Button and not Cooldown then -- If the button is clicked we execute the command, just like if the player typed it in chat. if v.Sprite == "gloves" then if not LastEquipped["Shirt"] then PushedButton(k) ExecuteCommand(v.Command) else Notify(Lang("NoShirtOn")) end else PushedButton(k) ExecuteCommand(v.Command) end end end for k,v in pairs(ExtraButtons) do local Colour local Alpha if LastEquipped[FirstUpper(v.Sprite)] then Alpha = 180 Colour = {r=0,g=100,b=210,a=220} else Alpha = 255 Colour = {r=0,g=0,b=0,a=255} end local Button = DrawButton({ Alpha = Alpha, Colour = Colour, Shadow = true, Size = v.Size, Sprite = v.Sprite, Text = v.Text, x = x + v.OffsetX, y = y + v.OffsetY, }) if Button and not Cooldown then PushedButton(k, true) ExecuteCommand(v.Command) end end if Cooldown then Text(x, y+0.05, 0.28, Lang("PleaseWait"), false, false, true) end -- Cooldown indicator, if theres a cooldown we display a little text. local InfoButton = DrawButton({ Alpha = 255, Colour = {r=0,g=0,b=0}, Shadow = true, Size = {Circle = {x = 0.0345, y = 0.06}, Sprite = {x = 0.0234, y = 0.0425}}, Sprite = "info", Text = Lang("Info"), x = x, y = y, }) if InfoButton then Notify(Lang("Information")) for k,v in pairs(LastEquipped) do log(k.." : "..json.encode(v)) end -- If the info button is pressed we log all "LastEquipped" items, for debugging purposes. end end local TextureDicts = {"dp_clothing", "dp_wheel"} Citizen.CreateThread(function() for k,v in pairs(TextureDicts) do while not HasStreamedTextureDictLoaded(v) do Wait(100) RequestStreamedTextureDict(v, true) end end GenerateTheButtons() while true do Wait(0) if IsControlJustPressed(1, Config.GUI.Key) then local Ped = PlayerPedId() if Check(Ped) then SoundPlay("Open") SetCursorLocation(Config.GUI.Position.x, Config.GUI.Position.y) end elseif IsControlPressed(1, Config.GUI.Key) then local Ped = PlayerPedId() if Check(Ped) then DrawGUI() end elseif IsControlJustReleased(1, Config.GUI.Key) then if Check(Ped) then SoundPlay("Close") end end --DrawGUI() if Config.Debug then DrawDev() end end end)