581 lines
30 KiB
Lua
581 lines
30 KiB
Lua
|
local QBCore = exports['qb-core']:GetCoreObject()
|
||
|
local inside = false
|
||
|
local currentHouse = nil
|
||
|
local closestHouse
|
||
|
local inRange
|
||
|
local IsLockpicking = false
|
||
|
local houseObj = {}
|
||
|
local POIOffsets = nil
|
||
|
local usingAdvanced = false
|
||
|
local requiredItemsShowed = false
|
||
|
local requiredItems = {}
|
||
|
local CurrentCops = 0
|
||
|
local openingDoor = false
|
||
|
local SucceededAttempts = 0
|
||
|
local NeededAttempts = 4
|
||
|
|
||
|
-- Functions
|
||
|
|
||
|
local function DrawText3Ds(x, y, z, text)
|
||
|
SetTextScale(0.35, 0.35)
|
||
|
SetTextFont(4)
|
||
|
SetTextProportional(1)
|
||
|
SetTextColour(255, 255, 255, 215)
|
||
|
SetTextEntry("STRING")
|
||
|
SetTextCentre(true)
|
||
|
AddTextComponentString(text)
|
||
|
SetDrawOrigin(x,y,z, 0)
|
||
|
DrawText(0.0, 0.0)
|
||
|
local factor = (string.len(text)) / 370
|
||
|
DrawRect(0.0, 0.0+0.0125, 0.017+ factor, 0.03, 0, 0, 0, 75)
|
||
|
ClearDrawOrigin()
|
||
|
end
|
||
|
|
||
|
local function loadAnimDict(dict)
|
||
|
while (not HasAnimDictLoaded(dict)) do
|
||
|
RequestAnimDict(dict)
|
||
|
Wait(5)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function openHouseAnim()
|
||
|
loadAnimDict("anim@heists@keycard@")
|
||
|
TaskPlayAnim( PlayerPedId(), "anim@heists@keycard@", "exit", 5.0, 1.0, -1, 16, 0, 0, 0, 0 )
|
||
|
Wait(400)
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
end
|
||
|
|
||
|
local function enterRobberyHouse(house)
|
||
|
TriggerServerEvent("InteractSound_SV:PlayOnSource", "houses_door_open", 0.25)
|
||
|
openHouseAnim()
|
||
|
Wait(250)
|
||
|
local coords = { x = Config.Houses[house]["coords"]["x"], y = Config.Houses[house]["coords"]["y"], z= Config.Houses[house]["coords"]["z"] - Config.MinZOffset}
|
||
|
local data
|
||
|
if Config.Houses[house]["tier"] == 1 then
|
||
|
data = exports['qb-interior']:CreateHouseRobbery(coords)
|
||
|
elseif Config.Houses[house]["tier"] == 2 then
|
||
|
data = exports['qb-interior']:CreateHouseRobbery(coords)
|
||
|
elseif Config.Houses[house]["tier"] == 3 then
|
||
|
data = exports['qb-interior']:CreateHouseRobbery(coords)
|
||
|
end
|
||
|
Wait(100)
|
||
|
houseObj = data[1]
|
||
|
POIOffsets = data[2]
|
||
|
inside = true
|
||
|
currentHouse = house
|
||
|
Wait(500)
|
||
|
TriggerEvent('qb-weathersync:client:DisableSync')
|
||
|
end
|
||
|
|
||
|
local function leaveRobberyHouse(house)
|
||
|
local ped = PlayerPedId()
|
||
|
TriggerServerEvent("InteractSound_SV:PlayOnSource", "houses_door_open", 0.25)
|
||
|
openHouseAnim()
|
||
|
Wait(250)
|
||
|
DoScreenFadeOut(250)
|
||
|
Wait(500)
|
||
|
exports['qb-interior']:DespawnInterior(houseObj, function()
|
||
|
TriggerEvent('qb-weathersync:client:EnableSync')
|
||
|
Wait(250)
|
||
|
DoScreenFadeIn(250)
|
||
|
SetEntityCoords(ped, Config.Houses[house]["coords"]["x"], Config.Houses[house]["coords"]["y"], Config.Houses[house]["coords"]["z"] + 0.5)
|
||
|
SetEntityHeading(ped, Config.Houses[house]["coords"]["h"])
|
||
|
inside = false
|
||
|
currentHouse = nil
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
local function PoliceCall()
|
||
|
local chance = 75
|
||
|
if GetClockHours() >= 1 and GetClockHours() <= 6 then
|
||
|
chance = 25
|
||
|
end
|
||
|
if math.random(1, 150) <= chance then
|
||
|
if Config.PoliceNotifyType == 'qb' then
|
||
|
TriggerServerEvent('police:server:policeAlert', Lang:t("info.palert"))
|
||
|
elseif Config.PoliceNotifyType == 'ps' then
|
||
|
exports['ps-dispatch']:HouseRobbery()
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function lockpickFinish(success)
|
||
|
if success then
|
||
|
TriggerServerEvent('qb-houserobbery:server:enterHouse', closestHouse)
|
||
|
QBCore.Functions.Notify(Lang:t("success.worked"), "success", 2500)
|
||
|
else
|
||
|
if usingAdvanced then
|
||
|
if math.random(1, 100) < 20 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeAdvancedLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["advancedlockpick"], "remove")
|
||
|
end
|
||
|
else
|
||
|
if math.random(1, 100) < 40 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["lockpick"], "remove")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
QBCore.Functions.Notify(Lang:t("error.didnt_work"), "error", 2500)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function LockpickDoorAnim()
|
||
|
openingDoor = true
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
if openingDoor then
|
||
|
TaskPlayAnim(PlayerPedId(), "veh@break_in@0h@p_m_one@", "low_force_entry_ds", 3.0, 3.0, -1, 16, 0, 0, 0, 0)
|
||
|
else
|
||
|
StopAnimTask(PlayerPedId(), "veh@break_in@0h@p_m_one@", "low_force_entry_ds", 1.0)
|
||
|
break
|
||
|
end
|
||
|
Wait(1000)
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
local function IsWearingGloves()
|
||
|
local armIndex = GetPedDrawableVariation(PlayerPedId(), 3)
|
||
|
local model = GetEntityModel(PlayerPedId())
|
||
|
local retval = true
|
||
|
if model == `mp_m_freemode_01` then
|
||
|
if Config.MaleNoGloves[armIndex] ~= nil and Config.MaleNoGloves[armIndex] then
|
||
|
retval = false
|
||
|
end
|
||
|
else
|
||
|
if Config.FemaleNoGloves[armIndex] ~= nil and Config.FemaleNoGloves[armIndex] then
|
||
|
retval = false
|
||
|
end
|
||
|
end
|
||
|
return retval
|
||
|
end
|
||
|
|
||
|
local function searchCabin(cabin)
|
||
|
local ped = PlayerPedId()
|
||
|
local Skillbar = exports['qb-skillbar']:GetSkillbarObject()
|
||
|
if math.random(1, 100) <= 85 and not IsWearingGloves() then
|
||
|
local pos = GetEntityCoords(PlayerPedId())
|
||
|
TriggerServerEvent("evidence:server:CreateFingerDrop", pos)
|
||
|
end
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"kneel"})
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, true)
|
||
|
FreezeEntityPosition(ped, true)
|
||
|
IsLockpicking = true
|
||
|
if Config.MiniGameSettings.Searching.Type == 'skillbar' then
|
||
|
Skillbar.Start({
|
||
|
duration = Config.MiniGameSettings.Searching.SkillBar.Start.SkillBarDuration,
|
||
|
pos = Config.MiniGameSettings.Searching.SkillBar.Start.SkillBarPosition,
|
||
|
width = Config.MiniGameSettings.Searching.SkillBar.Start.SkillBarWidth,
|
||
|
}, function()
|
||
|
if SucceededAttempts + 1 >= NeededAttempts then
|
||
|
openingDoor = false
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
TriggerServerEvent('qb-houserobbery:server:searchCabin', cabin, currentHouse)
|
||
|
Config.Houses[currentHouse]["furniture"][cabin]["searched"] = true
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, false)
|
||
|
SucceededAttempts = 0
|
||
|
FreezeEntityPosition(ped, false)
|
||
|
SetTimeout(500, function()
|
||
|
IsLockpicking = false
|
||
|
end)
|
||
|
else
|
||
|
Skillbar.Repeat({
|
||
|
duration = Config.MiniGameSettings.Searching.SkillBar.Repeat.SkillBarDuration,
|
||
|
pos = Config.MiniGameSettings.Searching.SkillBar.Repeat.SkillBarPosition,
|
||
|
width = Config.MiniGameSettings.Searching.SkillBar.Repeat.SkillBarWidth,
|
||
|
})
|
||
|
SucceededAttempts = SucceededAttempts + 1
|
||
|
end
|
||
|
end, function()
|
||
|
openingDoor = false
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, false)
|
||
|
QBCore.Functions.Notify(Lang:t("error.process_cancelled"), "error", 3500)
|
||
|
SucceededAttempts = 0
|
||
|
FreezeEntityPosition(ped, false)
|
||
|
SetTimeout(500, function()
|
||
|
IsLockpicking = false
|
||
|
end)
|
||
|
end)
|
||
|
elseif Config.MiniGameSettings.Searching.Type == 'ps-ui' then
|
||
|
exports['ps-ui']:Circle(function(success)
|
||
|
if success then
|
||
|
openingDoor = false
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
TriggerServerEvent('qb-houserobbery:server:searchCabin', cabin, currentHouse)
|
||
|
Config.Houses[currentHouse]["furniture"][cabin]["searched"] = true
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, false)
|
||
|
FreezeEntityPosition(ped, false)
|
||
|
SetTimeout(500, function()
|
||
|
IsLockpicking = false
|
||
|
end)
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
else
|
||
|
print("fail")
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
openingDoor = false
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, false)
|
||
|
QBCore.Functions.Notify(Lang:t("error.process_cancelled"), "error", 3500)
|
||
|
FreezeEntityPosition(ped, false)
|
||
|
SetTimeout(500, function()
|
||
|
IsLockpicking = false
|
||
|
end)
|
||
|
end
|
||
|
end, Config.MiniGameSettings.Searching.SkillCircle.Circles, Config.MiniGameSettings.Searching.SkillCircle.Time)
|
||
|
elseif Config.MiniGameSettings.Searching.Type == 'keydrop' then
|
||
|
exports['boii_ui']:keydrop(Config.MiniGameSettings.Searching.KeyDrop.ScoreLimit, Config.MiniGameSettings.Searching.KeyDrop.MissLimit, Config.MiniGameSettings.Searching.KeyDrop.FallDelay, Config.MiniGameSettings.Searching.KeyDrop.NewLetterDelay, function(success) --[[callback]]
|
||
|
if success then
|
||
|
print('keydrop success')
|
||
|
openingDoor = false
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
TriggerServerEvent('qb-houserobbery:server:searchCabin', cabin, currentHouse)
|
||
|
Config.Houses[currentHouse]["furniture"][cabin]["searched"] = true
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, false)
|
||
|
FreezeEntityPosition(ped, false)
|
||
|
SetTimeout(500, function()
|
||
|
IsLockpicking = false
|
||
|
end)
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
else
|
||
|
print('keydrop failed')
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
openingDoor = false
|
||
|
ClearPedTasks(PlayerPedId())
|
||
|
TriggerServerEvent('qb-houserobbery:server:SetBusyState', cabin, currentHouse, false)
|
||
|
QBCore.Functions.Notify(Lang:t("error.process_cancelled"), "error", 3500)
|
||
|
FreezeEntityPosition(ped, false)
|
||
|
SetTimeout(500, function()
|
||
|
IsLockpicking = false
|
||
|
end)
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Events
|
||
|
|
||
|
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||
|
QBCore.Functions.TriggerCallback('qb-houserobbery:server:GetHouseConfig', function(HouseConfig)
|
||
|
Config.Houses = HouseConfig
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-houserobbery:client:ResetHouseState', function(house)
|
||
|
Config.Houses[house]["opened"] = false
|
||
|
for _, v in pairs(Config.Houses[house]["furniture"]) do
|
||
|
v["searched"] = false
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('police:SetCopCount', function(amount)
|
||
|
CurrentCops = amount
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-houserobbery:client:enterHouse', function(house)
|
||
|
enterRobberyHouse(house)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-houserobbery:client:setHouseState', function(house, state)
|
||
|
Config.Houses[house]["opened"] = state
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-houserobbery:client:setCabinState', function(house, cabin, state)
|
||
|
Config.Houses[house]["furniture"][cabin]["searched"] = state
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-houserobbery:client:SetBusyState', function(cabin, house, bool)
|
||
|
Config.Houses[house]["furniture"][cabin]["isBusy"] = bool
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('lockpicks:UseLockpick', function(isAdvanced)
|
||
|
local hours = GetClockHours()
|
||
|
if hours >= Config.MinimumTime or hours <= Config.MaximumTime then
|
||
|
usingAdvanced = isAdvanced
|
||
|
if usingAdvanced then
|
||
|
if closestHouse ~= nil then
|
||
|
if CurrentCops >= Config.MinimumHouseRobberyPolice then
|
||
|
if not Config.Houses[closestHouse]["opened"] then
|
||
|
PoliceCall()
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"kneel"})
|
||
|
if Config.MiniGameSettings.LockPicking.Type == 'lockpick' then
|
||
|
LockpickDoorAnim()
|
||
|
TriggerEvent('qb-lockpick:client:openLockpick', lockpickFinish)
|
||
|
elseif Config.MiniGameSettings.LockPicking.Type == 'ps-ui' then
|
||
|
exports['ps-ui']:Circle(function(success)
|
||
|
if success then
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
print("success")
|
||
|
LockpickDoorAnim()
|
||
|
TriggerServerEvent('qb-houserobbery:server:enterHouse', closestHouse)
|
||
|
QBCore.Functions.Notify(Lang:t("success.worked"), "success", 2500)
|
||
|
if usingAdvanced then
|
||
|
if math.random(1, 100) < 20 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeAdvancedLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["advancedlockpick"], "remove")
|
||
|
end
|
||
|
else
|
||
|
if math.random(1, 100) < 40 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["lockpick"], "remove")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
QBCore.Functions.Notify(Lang:t("error.didnt_work"), "error", 2500)
|
||
|
print("fail")
|
||
|
end
|
||
|
end, Config.MiniGameSettings.LockPicking.SkillCircle.Circles, Config.MiniGameSettings.LockPicking.SkillCircle.Time)
|
||
|
elseif Config.MiniGameSettings.LockPicking.Type == 'keydrop' then
|
||
|
exports['boii_ui']:keydrop(Config.MiniGameSettings.LockPicking.KeyDrop.ScoreLimit, Config.MiniGameSettings.LockPicking.KeyDrop.MissLimit, Config.MiniGameSettings.LockPicking.KeyDrop.FallDelay, Config.MiniGameSettings.LockPicking.KeyDrop.NewLetterDelay, function(success) --[[callback]]
|
||
|
if success then
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
print("success")
|
||
|
LockpickDoorAnim()
|
||
|
TriggerServerEvent('qb-houserobbery:server:enterHouse', closestHouse)
|
||
|
QBCore.Functions.Notify(Lang:t("success.worked"), "success", 2500)
|
||
|
if usingAdvanced then
|
||
|
if math.random(1, 100) < 20 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeAdvancedLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["advancedlockpick"], "remove")
|
||
|
end
|
||
|
else
|
||
|
if math.random(1, 100) < 40 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["lockpick"], "remove")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
QBCore.Functions.Notify(Lang:t("error.didnt_work"), "error", 2500)
|
||
|
print("fail")
|
||
|
end
|
||
|
end)
|
||
|
elseif Config.MiniGameSettings.LockPicking.Type == 't3' then
|
||
|
local success = exports["t3_lockpick"]:startLockpick(1.0, Config.MiniGameSettings.LockPicking.T3Lockpick.Difficulty, Config.MiniGameSettings.LockPicking.T3Lockpick.Pins)
|
||
|
if success then
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
print("success")
|
||
|
LockpickDoorAnim()
|
||
|
TriggerServerEvent('qb-houserobbery:server:enterHouse', closestHouse)
|
||
|
QBCore.Functions.Notify(Lang:t("success.worked"), "success", 2500)
|
||
|
if usingAdvanced then
|
||
|
if math.random(1, 100) < 20 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeAdvancedLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["advancedlockpick"], "remove")
|
||
|
end
|
||
|
else
|
||
|
if math.random(1, 100) < 40 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["lockpick"], "remove")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
QBCore.Functions.Notify(Lang:t("error.didnt_work"), "error", 2500)
|
||
|
print("fail")
|
||
|
end
|
||
|
end
|
||
|
if math.random(1, 100) <= 85 and not IsWearingGloves() then
|
||
|
local pos = GetEntityCoords(PlayerPedId())
|
||
|
TriggerServerEvent("evidence:server:CreateFingerDrop", pos)
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t("error.door_open"), "error", 3500)
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t("error.not_enough_police"), "error", 3500)
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
local result = QBCore.Functions.HasItem("screwdriverset")
|
||
|
if closestHouse ~= nil then
|
||
|
if result then
|
||
|
if CurrentCops >= Config.MinimumHouseRobberyPolice then
|
||
|
if not Config.Houses[closestHouse]["opened"] then
|
||
|
PoliceCall()
|
||
|
if Config.MiniGameSettings.LockPicking.Type == 'lockpick' then
|
||
|
LockpickDoorAnim()
|
||
|
TriggerEvent('qb-lockpick:client:openLockpick', lockpickFinish)
|
||
|
elseif Config.MiniGameSettings.LockPicking.Type == 'ps-ui' then
|
||
|
exports['ps-ui']:Circle(function(success)
|
||
|
if success then
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
print("success")
|
||
|
LockpickDoorAnim()
|
||
|
TriggerServerEvent('qb-houserobbery:server:enterHouse', closestHouse)
|
||
|
QBCore.Functions.Notify(Lang:t("success.worked"), "success", 2500)
|
||
|
if usingAdvanced then
|
||
|
if math.random(1, 100) < 20 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeAdvancedLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["advancedlockpick"], "remove")
|
||
|
end
|
||
|
else
|
||
|
if math.random(1, 100) < 40 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["lockpick"], "remove")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
QBCore.Functions.Notify(Lang:t("error.didnt_work"), "error", 2500)
|
||
|
print("fail")
|
||
|
end
|
||
|
end, Config.MiniGameSettings.LockPicking.SkillCircle.Circles, Config.MiniGameSettings.LockPicking.SkillCircle.Time)
|
||
|
elseif Config.MiniGameSettings.LockPicking.Type == 'keydrop' then
|
||
|
exports['boii_ui']:keydrop(Config.MiniGameSettings.Searching.KeyDrop.ScoreLimit, Config.MiniGameSettings.Searching.KeyDrop.MissLimit, Config.MiniGameSettings.Searching.KeyDrop.FallDelay, Config.MiniGameSettings.Searching.KeyDrop.NewLetterDelay, function(success) --[[callback]]
|
||
|
if success then
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
print("success")
|
||
|
LockpickDoorAnim()
|
||
|
TriggerServerEvent('qb-houserobbery:server:enterHouse', closestHouse)
|
||
|
QBCore.Functions.Notify(Lang:t("success.worked"), "success", 2500)
|
||
|
if usingAdvanced then
|
||
|
if math.random(1, 100) < 20 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeAdvancedLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["advancedlockpick"], "remove")
|
||
|
end
|
||
|
else
|
||
|
if math.random(1, 100) < 40 then
|
||
|
TriggerServerEvent("qb-houserobbery:server:removeLockpick")
|
||
|
TriggerEvent('inventory:client:ItemBox', QBCore.Shared.Items["lockpick"], "remove")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
TriggerEvent('animations:client:EmoteCommandStart', {"c"})
|
||
|
QBCore.Functions.Notify(Lang:t("error.didnt_work"), "error", 2500)
|
||
|
print("fail")
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
if math.random(1, 100) <= 85 and not IsWearingGloves() then
|
||
|
local pos = GetEntityCoords(PlayerPedId())
|
||
|
TriggerServerEvent("evidence:server:CreateFingerDrop", pos)
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t("error.door_open"), "error", 3500)
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t("error.not_enough_police"), "error", 3500)
|
||
|
end
|
||
|
else
|
||
|
QBCore.Functions.Notify(Lang:t("error.missing_something"), "error", 3500)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- Threads
|
||
|
|
||
|
CreateThread(function()
|
||
|
Wait(500)
|
||
|
requiredItems = {
|
||
|
[1] = {name = QBCore.Shared.Items["advancedlockpick"]["name"], image = QBCore.Shared.Items["advancedlockpick"]["image"]},
|
||
|
[2] = {name = QBCore.Shared.Items["screwdriverset"]["name"], image = QBCore.Shared.Items["screwdriverset"]["image"]},
|
||
|
}
|
||
|
while true do
|
||
|
inRange = false
|
||
|
local PlayerPed = PlayerPedId()
|
||
|
local PlayerPos = GetEntityCoords(PlayerPed)
|
||
|
closestHouse = nil
|
||
|
if QBCore ~= nil then
|
||
|
local hours = GetClockHours()
|
||
|
if hours >= Config.MinimumTime or hours <= Config.MaximumTime then
|
||
|
if not inside then
|
||
|
for k, _ in pairs(Config.Houses) do
|
||
|
local dist = #(PlayerPos - vector3(Config.Houses[k]["coords"]["x"], Config.Houses[k]["coords"]["y"], Config.Houses[k]["coords"]["z"]))
|
||
|
if dist <= 1.5 then
|
||
|
closestHouse = k
|
||
|
inRange = true
|
||
|
if CurrentCops >= Config.MinimumHouseRobberyPolice then
|
||
|
if Config.Houses[k]["opened"] then
|
||
|
DrawText3Ds(Config.Houses[k]["coords"]["x"], Config.Houses[k]["coords"]["y"], Config.Houses[k]["coords"]["z"], Lang:t("info.henter"))
|
||
|
if IsControlJustPressed(0, 38) then
|
||
|
enterRobberyHouse(k)
|
||
|
end
|
||
|
else
|
||
|
if not requiredItemsShowed then
|
||
|
requiredItemsShowed = true
|
||
|
TriggerEvent('inventory:client:requiredItems', requiredItems, true)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
if inside then Wait(1000) end
|
||
|
if not inRange then
|
||
|
if requiredItemsShowed then
|
||
|
requiredItemsShowed = false
|
||
|
TriggerEvent('inventory:client:requiredItems', requiredItems, false)
|
||
|
end
|
||
|
Wait(1000)
|
||
|
end
|
||
|
end
|
||
|
Wait(5)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
CreateThread(function()
|
||
|
while true do
|
||
|
local ped = PlayerPedId()
|
||
|
local pos = GetEntityCoords(ped)
|
||
|
|
||
|
if inside then
|
||
|
if #(pos - vector3(Config.Houses[currentHouse]["coords"]["x"] + POIOffsets.exit.x, Config.Houses[currentHouse]["coords"]["y"] + POIOffsets.exit.y, Config.Houses[currentHouse]["coords"]["z"] - Config.MinZOffset + POIOffsets.exit.z)) < 1.5 then
|
||
|
DrawText3Ds(Config.Houses[currentHouse]["coords"]["x"] + POIOffsets.exit.x, Config.Houses[currentHouse]["coords"]["y"] + POIOffsets.exit.y, Config.Houses[currentHouse]["coords"]["z"] - Config.MinZOffset + POIOffsets.exit.z, Lang:t("info.hleave"))
|
||
|
if IsControlJustPressed(0, 38) then
|
||
|
leaveRobberyHouse(currentHouse)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
for k, _ in pairs(Config.Houses[currentHouse]["furniture"]) do
|
||
|
if #(pos - vector3(Config.Houses[currentHouse]["coords"]["x"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["x"], Config.Houses[currentHouse]["coords"]["y"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["y"], Config.Houses[currentHouse]["coords"]["z"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["z"] - Config.MinZOffset)) < 1 then
|
||
|
if not Config.Houses[currentHouse]["furniture"][k]["searched"] then
|
||
|
if not Config.Houses[currentHouse]["furniture"][k]["isBusy"] then
|
||
|
DrawText3Ds(Config.Houses[currentHouse]["coords"]["x"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["x"], Config.Houses[currentHouse]["coords"]["y"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["y"], Config.Houses[currentHouse]["coords"]["z"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["z"] - Config.MinZOffset, Lang:t("info.aint")..Config.Houses[currentHouse]["furniture"][k]["text"])
|
||
|
if not IsLockpicking then
|
||
|
if IsControlJustReleased(0, 38) then
|
||
|
searchCabin(k)
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
DrawText3Ds(Config.Houses[currentHouse]["coords"]["x"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["x"], Config.Houses[currentHouse]["coords"]["y"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["y"], Config.Houses[currentHouse]["coords"]["z"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["z"] - Config.MinZOffset, Lang:t("info.hsearch"))
|
||
|
end
|
||
|
else
|
||
|
DrawText3Ds(Config.Houses[currentHouse]["coords"]["x"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["x"], Config.Houses[currentHouse]["coords"]["y"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["y"], Config.Houses[currentHouse]["coords"]["z"] + Config.Houses[currentHouse]["furniture"][k]["coords"]["z"] - Config.MinZOffset, Lang:t("info.hsempty"))
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not inside then
|
||
|
Wait(5000)
|
||
|
end
|
||
|
Wait(3)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- Util Command (can be commented out - used for setting new spots in the config)
|
||
|
|
||
|
RegisterCommand('gethroffset', function()
|
||
|
local coords = GetEntityCoords(PlayerPedId())
|
||
|
local houseCoords = vector3(
|
||
|
Config.Houses[currentHouse]["coords"]["x"],
|
||
|
Config.Houses[currentHouse]["coords"]["y"],
|
||
|
Config.Houses[currentHouse]["coords"]["z"] - Config.MinZOffset
|
||
|
)
|
||
|
if inside then
|
||
|
local xdist = coords.x - houseCoords.x
|
||
|
local ydist = coords.y - houseCoords.y
|
||
|
local zdist = coords.z - houseCoords.z
|
||
|
print('X: '..xdist)
|
||
|
print('Y: '..ydist)
|
||
|
print('Z: '..zdist)
|
||
|
end
|
||
|
end, false)
|
||
|
|