Scripts/resources/[qb]/[qb_shops]/qb-diving/client/main.lua

422 lines
16 KiB
Lua
Raw Normal View History

2024-12-29 20:06:22 +00:00
local QBCore = exports['qb-core']:GetCoreObject()
local isLoggedIn = LocalPlayer.state['isLoggedIn']
local zones = {}
local currentArea = 0
local inSellerZone = false
local iswearingsuit = false
local oxgenlevell = 0
local currentDivingLocation = {
area = 0,
blip = {
radius = nil,
label = nil
}
}
local currentGear = {
mask = 0,
tank = 0,
oxygen = 0,
enabled = false
}
-- Functions
local function callCops()
local call = math.random(1, 3)
local chance = math.random(1, 3)
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
if call == chance then
TriggerServerEvent('qb-diving:server:CallCops', coords)
end
end
local function deleteGear()
if currentGear.mask ~= 0 then
DetachEntity(currentGear.mask, 0, 1)
DeleteEntity(currentGear.mask)
currentGear.mask = 0
end
if currentGear.tank ~= 0 then
DetachEntity(currentGear.tank, 0, 1)
DeleteEntity(currentGear.tank)
currentGear.tank = 0
end
end
local function gearAnim()
RequestAnimDict("clothingshirt")
while not HasAnimDictLoaded("clothingshirt") do
Wait(0)
end
TaskPlayAnim(PlayerPedId(), "clothingshirt", "try_shirt_positive_d", 8.0, 1.0, -1, 49, 0, 0, 0, 0)
end
local function takeCoral(coral)
if Config.CoralLocations[currentDivingLocation.area].coords.Coral[coral].PickedUp then return end
local ped = PlayerPedId()
local times = math.random(2, 5)
if math.random() > Config.CopsChance then callCops() end
FreezeEntityPosition(ped, true)
QBCore.Functions.Progressbar("take_coral", Lang:t("info.collecting_coral"), times * 1000, false, true, {
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = "weapons@first_person@aim_rng@generic@projectile@thermal_charge@",
anim = "plant_floor",
flags = 16,
}, {}, {}, function() -- Done
Config.CoralLocations[currentDivingLocation.area].coords.Coral[coral].PickedUp = true
TriggerServerEvent('qb-diving:server:TakeCoral', currentDivingLocation.area, coral, true)
ClearPedTasks(ped)
FreezeEntityPosition(ped, false)
end, function() -- Cancel
ClearPedTasks(ped)
FreezeEntityPosition(ped, false)
end)
end
local function setDivingLocation(divingLocation)
if currentDivingLocation.area ~= 0 then
for k in pairs(Config.CoralLocations[currentDivingLocation.area].coords.Coral) do
if Config.UseTarget then
exports['qb-target']:RemoveZone(k)
else
if next(zones) then zones[k]:destroy() end
end
end
end
currentDivingLocation.area = divingLocation
for _, blip in pairs(currentDivingLocation.blip) do if blip then RemoveBlip(blip) end end
local radiusBlip = AddBlipForRadius(Config.CoralLocations[currentDivingLocation.area].coords.Area, 100.0)
SetBlipRotation(radiusBlip, 0)
SetBlipColour(radiusBlip, 47)
currentDivingLocation.blip.radius = radiusBlip
local labelBlip = AddBlipForCoord(Config.CoralLocations[currentDivingLocation.area].coords.Area)
SetBlipSprite(labelBlip, 597)
SetBlipDisplay(labelBlip, 4)
SetBlipScale(labelBlip, 0.7)
SetBlipColour(labelBlip, 0)
SetBlipAsShortRange(labelBlip, true)
BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(Lang:t("info.diving_area"))
EndTextCommandSetBlipName(labelBlip)
currentDivingLocation.blip.label = labelBlip
for k, v in pairs(Config.CoralLocations[currentDivingLocation.area].coords.Coral) do
if Config.UseTarget then
exports['qb-target']:AddBoxZone('diving_coral_zone_'..k, v.coords, v.length, v.width, {
name = 'diving_coral_zone_'..k,
heading = v.heading,
debugPoly = false,
minZ = v.coords.z - 3,
maxZ = v.coords.z + 2
}, {
options = {
{
label = Lang:t("info.collect_coral"),
icon = 'fa-solid fa-water',
action = function()
takeCoral(k)
end
}
},
distance = 2.0
})
else
zones[k] = BoxZone:Create(v.coords, v.length, v.width, {
name = 'diving_coral_zone_'..k,
heading = v.heading,
debugPoly = false,
minZ = v.coords.z - 3,
maxZ = v.coords.z + 2
})
zones[k]:onPlayerInOut(function(inside)
if inside then
currentArea = k
exports['qb-core']:DrawText(Lang:t("info.collect_coral_dt"), 'top')
else
currentArea = 0
exports['qb-core']:HideText()
end
end)
end
end
end
local function sellCoral()
local playerPed = PlayerPedId()
LocalPlayer.state:set("inv_busy", true, true)
TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_STAND_IMPATIENT", 0, true)
QBCore.Functions.Progressbar("sell_coral_items", Lang:t("info.checking_pockets"), math.random(2000, 4000), false, true, {}, {}, {}, {}, function() -- Done
ClearPedTasks(playerPed)
TriggerServerEvent('qb-diving:server:SellCoral')
LocalPlayer.state:set("inv_busy", false, true)
end, function() -- Cancel
ClearPedTasksImmediately(playerPed)
QBCore.Functions.Notify(Lang:t("error.canceled"), "error")
LocalPlayer.state:set("inv_busy", false, true)
end)
end
local function createSeller()
for i = 1, #Config.SellLocations do
local current = Config.SellLocations[i]
current.model = type(current.model) == 'string' and GetHashKey(current.model) or current.model
RequestModel(current.model)
while not HasModelLoaded(current.model) do
Wait(0)
end
local currentCoords = vector4(current.coords.x, current.coords.y, current.coords.z - 1, current.coords.w)
local ped = CreatePed(0, current.model, currentCoords, false, false)
FreezeEntityPosition(ped, true)
SetEntityInvincible(ped, true)
SetBlockingOfNonTemporaryEvents(ped, true)
if Config.UseTarget then
exports['qb-target']:AddTargetEntity(ped, {
options = {
{
label = Lang:t("info.sell_coral"),
icon = 'fa-solid fa-dollar-sign',
action = function()
sellCoral()
end
}
},
distance = 2.0
})
else
local zone = BoxZone:Create(current.coords.xyz, current.zoneOptions.length, current.zoneOptions.width, {
name = 'diving_coral_seller_'..i,
heading = current.coords.w,
debugPoly = false,
minZ = current.coords.z - 1.5,
maxZ = current.coords.z + 1.5
})
zone:onPlayerInOut(function(inside)
if inside then
inSellerZone = true
exports['qb-core']:DrawText(Lang:t("info.sell_coral_dt"), 'top')
else
inSellerZone = false
exports['qb-core']:HideText()
end
end)
end
end
end
-- Events
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
QBCore.Functions.TriggerCallback('qb-diving:server:GetDivingConfig', function(config, area)
Config.CoralLocations = config
setDivingLocation(area)
createSeller()
isLoggedIn = true
end)
end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
isLoggedIn = false
end)
RegisterNetEvent('qb-diving:client:NewLocations', function()
QBCore.Functions.TriggerCallback('qb-diving:server:GetDivingConfig', function(config, area)
Config.CoralLocations = config
setDivingLocation(area)
end)
end)
RegisterNetEvent('qb-diving:client:UpdateCoral', function(area, coral, bool)
Config.CoralLocations[area].coords.Coral[coral].PickedUp = bool
end)
RegisterNetEvent('qb-diving:client:CallCops', function(coords, msg)
PlaySound(-1, "Lose_1st", "GTAO_FM_Events_Soundset", 0, 0, 1)
TriggerEvent("chatMessage", Lang:t("error.911_chatmessage"), "error", msg)
local transG = 100
local blip = AddBlipForRadius(coords.x, coords.y, coords.z, 100.0)
SetBlipSprite(blip, 9)
SetBlipColour(blip, 1)
SetBlipAlpha(blip, transG)
SetBlipAsShortRange(blip, false)
BeginTextCommandSetBlipName('STRING')
AddTextComponentString(Lang:t("info.blip_text"))
EndTextCommandSetBlipName(blip)
while transG ~= 0 do
Wait(180 * 4)
transG = transG - 1
SetBlipAlpha(blip, transG)
if transG == 0 then
SetBlipSprite(blip, 2)
RemoveBlip(blip)
return
end
end
end)
RegisterNetEvent("qb-diving:client:setoxygenlevel", function()
if oxgenlevell == 0 then
oxgenlevell = Config.oxygenlevel -- oxygenlevel
QBCore.Functions.Notify(Lang:t("success.tube_filled"), 'success')
TriggerServerEvent('qb-diving:server:removeItemAfterFill')
else
QBCore.Functions.Notify(Lang:t("error.oxygenlevel", {oxygenlevel = oxgenlevell}), 'error')
end
end)
function DrawText2(text)
SetTextFont(4)
SetTextProportional(1)
SetTextScale(0.0, 0.45)
SetTextDropshadow(1, 0, 0, 0, 255)
SetTextEdge(1, 0, 0, 0, 255)
SetTextDropShadow()
SetTextOutline()
SetTextEntry("STRING")
AddTextComponentString(text)
DrawText(0.45, 0.90)
end
RegisterNetEvent('qb-diving:client:UseGear', function()
local ped = PlayerPedId()
if iswearingsuit == false then
if oxgenlevell > 0 then
iswearingsuit = true
if not IsPedSwimming(ped) and not IsPedInAnyVehicle(ped) then
gearAnim()
QBCore.Functions.Progressbar("equip_gear", Lang:t("info.put_suit"), 5000, false, true, {}, {}, {}, {},
function() -- Done
deleteGear()
local maskModel = `p_d_scuba_mask_s`
local tankModel = `p_s_scuba_tank_s`
RequestModel(tankModel)
while not HasModelLoaded(tankModel) do
Wait(0)
end
currentGear.tank = CreateObject(tankModel, 1.0, 1.0, 1.0, 1, 1, 0)
local bone1 = GetPedBoneIndex(ped, 24818)
AttachEntityToEntity(currentGear.tank, ped, bone1, -0.25, -0.25, 0.0, 180.0, 90.0, 0.0, 1, 1, 0,
0, 2, 1)
RequestModel(maskModel)
while not HasModelLoaded(maskModel) do
Wait(0)
end
currentGear.mask = CreateObject(maskModel, 1.0, 1.0, 1.0, 1, 1, 0)
local bone2 = GetPedBoneIndex(ped, 12844)
AttachEntityToEntity(currentGear.mask, ped, bone2, 0.0, 0.0, 0.0, 180.0, 90.0, 0.0, 1, 1, 0, 0, 2
, 1)
SetEnableScuba(ped, true)
SetPedMaxTimeUnderwater(ped, 2000.00)
currentGear.enabled = true
ClearPedTasks(ped)
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
oxgenlevell = oxgenlevell
Citizen.CreateThread(function()
while currentGear.enabled do
if IsPedSwimmingUnderWater(PlayerPedId()) then
oxgenlevell = oxgenlevell - 1
if oxgenlevell == 90 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 80 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 70 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 60 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 50 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 40 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 30 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 20 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 10 then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "breathdivingsuit", 0.25)
elseif oxgenlevell == 0 then
-- deleteGear()
SetEnableScuba(ped, false)
SetPedMaxTimeUnderwater(ped, 1.00)
currentGear.enabled = false
iswearingsuit = false
TriggerServerEvent("InteractSound_SV:PlayOnSource", nil, 0.25)
end
end
Wait(1000)
end
end)
end)
else
QBCore.Functions.Notify(Lang:t("error.not_standing_up"), 'error')
end
else
QBCore.Functions.Notify(Lang:t("error.need_otube"), 'error')
end
elseif iswearingsuit == true then
gearAnim()
QBCore.Functions.Progressbar("remove_gear", Lang:t("info.pullout_suit"), 5000, false, true, {}, {}, {}, {},
function() -- Done
SetEnableScuba(ped, false)
SetPedMaxTimeUnderwater(ped, 50.00)
currentGear.enabled = false
ClearPedTasks(ped)
deleteGear()
QBCore.Functions.Notify(Lang:t("success.took_out"))
TriggerServerEvent("InteractSound_SV:PlayOnSource", nil, 0.25)
iswearingsuit = false
oxgenlevell = oxgenlevell
end)
end
end)
-- Threads
CreateThread(function()
if isLoggedIn then
QBCore.Functions.TriggerCallback('qb-diving:server:GetDivingConfig', function(config, area)
Config.CoralLocations = config
setDivingLocation(area)
createSeller()
end)
end
if Config.UseTarget then return end
while true do
local sleep = 1000
if isLoggedIn then
if currentArea ~= 0 then
sleep = 0
if IsControlJustPressed(0, 51) then -- E
takeCoral(currentArea)
exports['qb-core']:KeyPressed()
Wait(500)
exports['qb-core']:HideText()
sleep = 3000
end
end
if inSellerZone then
sleep = 0
if IsControlJustPressed(0, 51) then -- E
sellCoral()
exports['qb-core']:KeyPressed()
Wait(500)
exports['qb-core']:HideText()
sleep = 3000
end
end
end
Wait(sleep)
end
end)
CreateThread(function()
while true do
Wait(0)
if currentGear.enabled == true and iswearingsuit == true then
if IsPedSwimmingUnderWater(PlayerPedId()) then
DrawText2(oxgenlevell..'')
end
end
end
end)