forked from Simnation/Main
298 lines
10 KiB
Lua
298 lines
10 KiB
Lua
![]() |
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
|
||
|
local Rot = b.Rotate or 0.0
|
||
|
if b.Shadow then
|
||
|
DrawSprite("dp_clothing", "circle", b.x, b.y, b.Size.Circle.x/0.80, b.Size.Circle.y/0.80, Rot, 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 InfoButtonRot = 0.0
|
||
|
MenuOpened = false
|
||
|
|
||
|
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,
|
||
|
Rotation = 0.0
|
||
|
}
|
||
|
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
|
||
|
local Enabled = v.Enabled if Enabled == nil then Enabled = true end
|
||
|
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,
|
||
|
SpriteFunc = v.SpriteFunc,
|
||
|
Text = v.Name,
|
||
|
Enabled = Enabled,
|
||
|
Rotate = v.Rotate,
|
||
|
Rotation = 0.0
|
||
|
}
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function PushedButton(button, extra, rotate, info) -- https://www.youtube.com/watch?v=v57i1Ze0jB8
|
||
|
Citizen.CreateThread(function()
|
||
|
SoundPlay("Select")
|
||
|
local Button = nil
|
||
|
if extra then Button = ExtraButtons[button] elseif info then Button = InfoButton else Button = Buttons[button] end
|
||
|
if rotate then
|
||
|
for i = 1, 18 do
|
||
|
if not info then Button.Rotation = -i*20+0.0 Wait(1) else InfoButtonRot = -i*20+0.0 Wait(1) end
|
||
|
end return
|
||
|
end
|
||
|
if not extra then
|
||
|
Button.Size = {Sprite = {x = DefaultButton.x/1.1, y = DefaultButton.y/1.1}}
|
||
|
Wait(100)
|
||
|
Button.Size = {Sprite = {x = DefaultButton.x, y = DefaultButton.y}}
|
||
|
else
|
||
|
Button.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)
|
||
|
Button.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
|
||
|
if v.Enabled then
|
||
|
local Distance = Distance(Config.GUI.Position.x+v.OffsetX+0.005, Config.GUI.Position.y+v.OffsetY+0.025, x, y)
|
||
|
local ShouldDisplay = true
|
||
|
if v.SpriteFunc then
|
||
|
local SpriteVar = v.SpriteFunc()
|
||
|
if SpriteVar then
|
||
|
ShouldDisplay = true
|
||
|
else
|
||
|
ShouldDisplay = false
|
||
|
end
|
||
|
end
|
||
|
if ShouldDisplay then
|
||
|
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
|
||
|
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,
|
||
|
Rotation = v.Rotation,
|
||
|
})
|
||
|
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
|
||
|
if v.Enabled then
|
||
|
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 sprite = v.Sprite
|
||
|
if v.SpriteFunc then
|
||
|
local SpriteVar = v.SpriteFunc()
|
||
|
if SpriteVar then
|
||
|
sprite = SpriteVar
|
||
|
else
|
||
|
sprite = false
|
||
|
end
|
||
|
end
|
||
|
if sprite then
|
||
|
local Button = DrawButton({
|
||
|
Alpha = Alpha,
|
||
|
Colour = Colour,
|
||
|
Shadow = true,
|
||
|
Size = v.Size,
|
||
|
Sprite = sprite,
|
||
|
Text = v.Text,
|
||
|
x = x + v.OffsetX,
|
||
|
y = y + v.OffsetY,
|
||
|
Rotation = v.Rotation,
|
||
|
})
|
||
|
if Button and not Cooldown then
|
||
|
PushedButton(k, true, v.Rotate) ExecuteCommand(v.Command)
|
||
|
end
|
||
|
end
|
||
|
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,
|
||
|
Rotation = InfoButtonRot,
|
||
|
})
|
||
|
if InfoButton then
|
||
|
PushedButton(k, true, true, true)
|
||
|
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 not Config.GUI.Toggle then
|
||
|
if IsControlPressed(1, Config.GUI.Key) then
|
||
|
local Ped = PlayerPedId()
|
||
|
if Check(Ped) then MenuOpened = true end
|
||
|
else MenuOpened = false end
|
||
|
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 IsControlJustReleased(1, Config.GUI.Key) then
|
||
|
if Check(Ped) then MenuOpened = false SoundPlay("Close") end
|
||
|
end
|
||
|
else
|
||
|
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) MenuOpened = not MenuOpened end
|
||
|
end
|
||
|
end
|
||
|
if MenuOpened then DrawGUI() end
|
||
|
if Config.Debug then DrawDev() end
|
||
|
end
|
||
|
end)
|