ed
This commit is contained in:
parent
19fb68f805
commit
01d047b3cc
53 changed files with 3222 additions and 5 deletions
349
resources/[housing]/ox_doorlock/client/main.lua
Normal file
349
resources/[housing]/ox_doorlock/client/main.lua
Normal file
|
@ -0,0 +1,349 @@
|
|||
if not LoadResourceFile(cache.resource, 'web/build/index.html') then
|
||||
error('Unable to load UI. Build ox_doorlock or download the latest release.\n ^3https://github.com/overextended/ox_doorlock/releases/latest/download/ox_doorlock.zip^0')
|
||||
end
|
||||
|
||||
if not lib.checkDependency('ox_lib', '3.14.0', true) then return end
|
||||
|
||||
local function createDoor(door)
|
||||
local double = door.doors
|
||||
door.zone = GetLabelText(GetNameOfZone(door.coords.x, door.coords.y, door.coords.z))
|
||||
|
||||
if double then
|
||||
for i = 1, 2 do
|
||||
AddDoorToSystem(double[i].hash, double[i].model, double[i].coords.x, double[i].coords.y, double[i].coords.z, false, false, false)
|
||||
DoorSystemSetDoorState(double[i].hash, 4, false, false)
|
||||
DoorSystemSetDoorState(double[i].hash, door.state, false, false)
|
||||
|
||||
if door.doorRate or not door.auto then
|
||||
DoorSystemSetAutomaticRate(double[i].hash, door.doorRate or 10.0, false, false)
|
||||
end
|
||||
end
|
||||
else
|
||||
AddDoorToSystem(door.hash, door.model, door.coords.x, door.coords.y, door.coords.z, false, false, false)
|
||||
DoorSystemSetDoorState(door.hash, 4, false, false)
|
||||
DoorSystemSetDoorState(door.hash, door.state, false, false)
|
||||
|
||||
if door.doorRate or not door.auto then
|
||||
DoorSystemSetAutomaticRate(door.hash, door.doorRate or 10.0, false, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local nearbyDoors = {}
|
||||
local Entity = Entity
|
||||
|
||||
lib.callback('ox_doorlock:getDoors', false, function(data)
|
||||
doors = data
|
||||
|
||||
for _, door in pairs(data) do
|
||||
createDoor(door)
|
||||
end
|
||||
|
||||
while true do
|
||||
table.wipe(nearbyDoors)
|
||||
local coords = GetEntityCoords(cache.ped)
|
||||
|
||||
for _, door in pairs(doors) do
|
||||
local double = door.doors
|
||||
door.distance = #(coords - door.coords)
|
||||
|
||||
if double then
|
||||
if door.distance < 80 then
|
||||
for i = 1, 2 do
|
||||
if not double[i].entity and IsModelValid(double[i].model) then
|
||||
local entity = GetClosestObjectOfType(double[i].coords.x, double[i].coords.y, double[i].coords.z, 1.0, double[i].model, false, false, false)
|
||||
|
||||
if entity ~= 0 then
|
||||
double[i].entity = entity
|
||||
Entity(entity).state.doorId = door.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if door.distance < 20 then
|
||||
nearbyDoors[#nearbyDoors + 1] = door
|
||||
end
|
||||
else
|
||||
for i = 1, 2 do
|
||||
double[i].entity = nil
|
||||
end
|
||||
end
|
||||
elseif door.distance < 80 then
|
||||
if not door.entity and IsModelValid(door.model) then
|
||||
local entity = GetClosestObjectOfType(door.coords.x, door.coords.y, door.coords.z, 1.0, door.model, false, false, false)
|
||||
|
||||
if entity ~= 0 then
|
||||
local min, max = GetModelDimensions(door.model)
|
||||
local points = {
|
||||
GetOffsetFromEntityInWorldCoords(entity, min.x, min.y, min.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, min.x, min.y, max.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, min.x, max.y, max.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, min.x, max.y, min.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, max.x, min.y, min.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, max.x, min.y, max.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, max.x, max.y, max.z).xy,
|
||||
GetOffsetFromEntityInWorldCoords(entity, max.x, max.y, min.z).xy
|
||||
}
|
||||
|
||||
local centroid = vec2(0, 0)
|
||||
|
||||
for i = 1, 8 do
|
||||
centroid += points[i]
|
||||
end
|
||||
|
||||
centroid = centroid / 8
|
||||
door.coords = vec3(centroid.x, centroid.y, door.coords.z)
|
||||
door.entity = entity
|
||||
Entity(entity).state.doorId = door.id
|
||||
end
|
||||
end
|
||||
|
||||
if door.distance < 20 then
|
||||
nearbyDoors[#nearbyDoors + 1] = door
|
||||
end
|
||||
elseif door.entity then
|
||||
door.entity = nil
|
||||
end
|
||||
end
|
||||
|
||||
Wait(500)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('ox_doorlock:setState', function(id, state, source, data)
|
||||
if not doors then return end
|
||||
|
||||
if data then
|
||||
doors[id] = data
|
||||
createDoor(data)
|
||||
|
||||
if NuiHasLoaded then
|
||||
SendNuiMessage(json.encode({
|
||||
action = 'updateDoorData',
|
||||
data = data
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
if Config.Notify and source == cache.serverId then
|
||||
if state == 0 then
|
||||
lib.notify({
|
||||
type = 'success',
|
||||
icon = 'unlock',
|
||||
description = locale('unlocked_door')
|
||||
})
|
||||
else
|
||||
lib.notify({
|
||||
type = 'success',
|
||||
icon = 'lock',
|
||||
description = locale('locked_door')
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local door = data or doors[id]
|
||||
local double = door.doors
|
||||
door.state = state
|
||||
|
||||
if double then
|
||||
DoorSystemSetDoorState(double[1].hash, door.state, false, false)
|
||||
DoorSystemSetDoorState(double[2].hash, door.state, false, false)
|
||||
|
||||
if door.holdOpen then
|
||||
DoorSystemSetHoldOpen(double[1].hash, door.state == 0)
|
||||
DoorSystemSetHoldOpen(double[2].hash, door.state == 0)
|
||||
end
|
||||
|
||||
while door.state == 1 and (not IsDoorClosed(double[1].hash) or not IsDoorClosed(double[2].hash)) do Wait(0) end
|
||||
else
|
||||
DoorSystemSetDoorState(door.hash, door.state, false, false)
|
||||
|
||||
if door.holdOpen then DoorSystemSetHoldOpen(door.hash, door.state == 0) end
|
||||
while door.state == 1 and not IsDoorClosed(door.hash) do Wait(0) end
|
||||
end
|
||||
|
||||
if door.state == state and door.distance and door.distance < 20 then
|
||||
if Config.NativeAudio then
|
||||
RequestScriptAudioBank('dlc_oxdoorlock/oxdoorlock', false)
|
||||
local sound = state == 0 and door.unlockSound or door.lockSound or 'door_bolt'
|
||||
local soundId = GetSoundId()
|
||||
|
||||
PlaySoundFromCoord(soundId, sound, door.coords.x, door.coords.y, door.coords.z, 'DLC_OXDOORLOCK_SET', false, 0, false)
|
||||
ReleaseSoundId(soundId)
|
||||
ReleaseNamedScriptAudioBank('dlc_oxdoorlock/oxdoorlock')
|
||||
else
|
||||
local volume = (0.01 * GetProfileSetting(300)) / (door.distance / 2)
|
||||
if volume > 1 then volume = 1 end
|
||||
local sound = state == 0 and door.unlockSound or door.lockSound or 'door-bolt-4'
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'playSound',
|
||||
data = {
|
||||
sound = sound,
|
||||
volume = volume
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('ox_doorlock:editDoorlock', function(id, data)
|
||||
if source == '' then return end
|
||||
|
||||
local door = doors[id]
|
||||
local double = door.doors
|
||||
local doorState = data and data.state or 0
|
||||
|
||||
if data then
|
||||
data.zone = door.zone or GetLabelText(GetNameOfZone(door.coords.x, door.coords.y, door.coords.z))
|
||||
|
||||
-- hacky method to resolve a bug with "closest door" by forcing a distance recalculation
|
||||
if door.distance < 20 then door.distance = 80 end
|
||||
elseif ClosestDoor?.id == id then
|
||||
ClosestDoor = nil
|
||||
end
|
||||
|
||||
if double then
|
||||
for i = 1, 2 do
|
||||
local doorHash = double[i].hash
|
||||
|
||||
if data then
|
||||
if data.doorRate or door.doorRate or not data.auto then
|
||||
DoorSystemSetAutomaticRate(doorHash, data.doorRate or door.doorRate and 0.0 or 10.0, false, false)
|
||||
end
|
||||
|
||||
DoorSystemSetDoorState(doorHash, doorState, false, false)
|
||||
|
||||
if data.holdOpen then DoorSystemSetHoldOpen(doorHash, doorState == 0) end
|
||||
else
|
||||
DoorSystemSetDoorState(doorHash, 4, false, false)
|
||||
DoorSystemSetDoorState(doorHash, 0, false, false)
|
||||
|
||||
if double[i].entity then
|
||||
Entity(double[i].entity).state.doorId = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if data then
|
||||
if data.doorRate or door.doorRate or not data.auto then
|
||||
DoorSystemSetAutomaticRate(door.hash, data.doorRate or door.doorRate and 0.0 or 10.0, false, false)
|
||||
end
|
||||
|
||||
DoorSystemSetDoorState(door.hash, doorState, false, false)
|
||||
|
||||
if data.holdOpen then DoorSystemSetHoldOpen(door.hash, doorState == 0) end
|
||||
else
|
||||
DoorSystemSetDoorState(door.hash, 4, false, false)
|
||||
DoorSystemSetDoorState(door.hash, 0, false, false)
|
||||
|
||||
if door.entity then
|
||||
Entity(door.entity).state.doorId = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
doors[id] = data
|
||||
|
||||
if NuiHasLoaded then
|
||||
SendNuiMessage(json.encode({
|
||||
action = 'updateDoorData',
|
||||
data = data or id
|
||||
}))
|
||||
end
|
||||
end)
|
||||
|
||||
ClosestDoor = nil
|
||||
|
||||
lib.callback.register('ox_doorlock:inputPassCode', function()
|
||||
return ClosestDoor?.passcode and lib.inputDialog(locale('door_lock'), {
|
||||
{
|
||||
type = 'input',
|
||||
label = locale('passcode'),
|
||||
password = true,
|
||||
icon = 'lock'
|
||||
},
|
||||
})?[1]
|
||||
end)
|
||||
|
||||
local lastTriggered = 0
|
||||
|
||||
local function useClosestDoor()
|
||||
if not ClosestDoor then return false end
|
||||
|
||||
local gameTimer = GetGameTimer()
|
||||
|
||||
if gameTimer - lastTriggered > 500 then
|
||||
lastTriggered = gameTimer
|
||||
TriggerServerEvent('ox_doorlock:setState', ClosestDoor.id, ClosestDoor.state == 1 and 0 or 1)
|
||||
end
|
||||
end
|
||||
|
||||
exports('useClosestDoor', useClosestDoor)
|
||||
|
||||
CreateThread(function()
|
||||
local lockDoor = locale('lock_door')
|
||||
local unlockDoor = locale('unlock_door')
|
||||
local showUI
|
||||
local drawSprite = Config.DrawSprite
|
||||
|
||||
if drawSprite then
|
||||
local sprite1 = drawSprite[0]?[1]
|
||||
local sprite2 = drawSprite[1]?[1]
|
||||
|
||||
if sprite1 then
|
||||
RequestStreamedTextureDict(sprite1, true)
|
||||
end
|
||||
|
||||
if sprite2 then
|
||||
RequestStreamedTextureDict(sprite2, true)
|
||||
end
|
||||
end
|
||||
|
||||
local SetDrawOrigin = SetDrawOrigin
|
||||
local ClearDrawOrigin = ClearDrawOrigin
|
||||
local DrawSprite = drawSprite and DrawSprite
|
||||
|
||||
while true do
|
||||
local num = #nearbyDoors
|
||||
|
||||
if num > 0 then
|
||||
local ratio = drawSprite and GetAspectRatio(true)
|
||||
for i = 1, num do
|
||||
local door = nearbyDoors[i]
|
||||
|
||||
if door.distance < door.maxDistance then
|
||||
if door.distance < (ClosestDoor?.distance or 10) then
|
||||
ClosestDoor = door
|
||||
end
|
||||
|
||||
if drawSprite and not door.hideUi then
|
||||
local sprite = drawSprite[door.state]
|
||||
|
||||
if sprite then
|
||||
SetDrawOrigin(door.coords.x, door.coords.y, door.coords.z)
|
||||
DrawSprite(sprite[1], sprite[2], sprite[3], sprite[4], sprite[5], sprite[6] * ratio, sprite[7], sprite[8], sprite[9], sprite[10], sprite[11])
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else ClosestDoor = nil end
|
||||
|
||||
if ClosestDoor and ClosestDoor.distance < ClosestDoor.maxDistance then
|
||||
if Config.DrawTextUI and not ClosestDoor.hideUi and ClosestDoor.state ~= showUI then
|
||||
lib.showTextUI(ClosestDoor.state == 0 and lockDoor or unlockDoor)
|
||||
showUI = ClosestDoor.state
|
||||
end
|
||||
|
||||
if not PickingLock and IsDisabledControlJustReleased(0, 38) then
|
||||
useClosestDoor()
|
||||
end
|
||||
elseif showUI then
|
||||
lib.hideTextUI()
|
||||
showUI = nil
|
||||
end
|
||||
|
||||
Wait(num > 0 and 0 or 500)
|
||||
end
|
||||
end)
|
410
resources/[housing]/ox_doorlock/client/utils.lua
Normal file
410
resources/[housing]/ox_doorlock/client/utils.lua
Normal file
|
@ -0,0 +1,410 @@
|
|||
local Entity = Entity
|
||||
|
||||
local function getDoorFromEntity(data)
|
||||
local entity = type(data) == 'table' and data.entity or data
|
||||
|
||||
if not entity then return end
|
||||
|
||||
local state = Entity(entity)?.state
|
||||
local doorId = state?.doorId
|
||||
|
||||
if not doorId then return end
|
||||
|
||||
local door = doors[doorId]
|
||||
|
||||
if not door then
|
||||
state.doorId = nil
|
||||
end
|
||||
|
||||
return door
|
||||
end
|
||||
|
||||
exports('getClosestDoorId', function() return ClosestDoor?.id end)
|
||||
exports('getDoorIdFromEntity', function(entityId) return getDoorFromEntity(entityId)?.id end) -- same as Entity(entityId).state.doorId
|
||||
|
||||
local function entityIsNotDoor(data)
|
||||
local entity = type(data) == 'number' and data or data.entity
|
||||
return not getDoorFromEntity(entity)
|
||||
end
|
||||
|
||||
PickingLock = false
|
||||
|
||||
local function canPickLock(entity)
|
||||
if PickingLock then return false end
|
||||
|
||||
local door = getDoorFromEntity(entity)
|
||||
|
||||
return door and door.lockpick and (Config.CanPickUnlockedDoors or door.state == 1)
|
||||
end
|
||||
|
||||
---@param entity number
|
||||
local function pickLock(entity)
|
||||
local door = getDoorFromEntity(entity)
|
||||
|
||||
if not door or PickingLock or not door.lockpick or (not Config.CanPickUnlockedDoors and door.state == 0) then return end
|
||||
|
||||
PickingLock = true
|
||||
|
||||
TaskTurnPedToFaceCoord(cache.ped, door.coords.x, door.coords.y, door.coords.z, 4000)
|
||||
Wait(500)
|
||||
|
||||
local animDict = lib.requestAnimDict('mp_common_heist')
|
||||
|
||||
TaskPlayAnim(cache.ped, animDict, 'pick_door', 3.0, 1.0, -1, 49, 0, true, true, true)
|
||||
|
||||
local success = lib.skillCheck(door.lockpickDifficulty or Config.LockDifficulty)
|
||||
local rand = math.random(1, success and 100 or 5)
|
||||
|
||||
if success then
|
||||
TriggerServerEvent('ox_doorlock:setState', door.id, door.state == 1 and 0 or 1, true)
|
||||
end
|
||||
|
||||
if rand == 1 then
|
||||
TriggerServerEvent('ox_doorlock:breakLockpick')
|
||||
lib.notify({ type = 'error', description = locale('lockpick_broke') })
|
||||
end
|
||||
|
||||
StopEntityAnim(cache.ped, 'pick_door', animDict, 0)
|
||||
RemoveAnimDict(animDict)
|
||||
|
||||
PickingLock = false
|
||||
end
|
||||
|
||||
exports('pickClosestDoor', function()
|
||||
if not ClosestDoor then return end
|
||||
|
||||
pickLock(ClosestDoor.entity)
|
||||
end)
|
||||
|
||||
local tempData = {}
|
||||
|
||||
local function addDoorlock(data)
|
||||
local entity = type(data) == 'number' and data or data.entity
|
||||
local model = GetEntityModel(entity)
|
||||
local coords = GetEntityCoords(entity)
|
||||
|
||||
AddDoorToSystem(`temp`, model, coords.x, coords.y, coords.z, false, false, false)
|
||||
DoorSystemSetDoorState(`temp`, 4, false, false)
|
||||
|
||||
coords = GetEntityCoords(entity)
|
||||
tempData[#tempData + 1] = {
|
||||
entity = entity,
|
||||
model = model,
|
||||
coords = coords,
|
||||
heading = math.floor(GetEntityHeading(entity) + 0.5)
|
||||
}
|
||||
|
||||
RemoveDoorFromSystem(`temp`)
|
||||
end
|
||||
|
||||
local isAddingDoorlock = false
|
||||
|
||||
RegisterNUICallback('notify', function(data, cb)
|
||||
cb(1)
|
||||
lib.notify({ title = data })
|
||||
end)
|
||||
|
||||
RegisterNUICallback('createDoor', function(data, cb)
|
||||
cb(1)
|
||||
SetNuiFocus(false, false)
|
||||
|
||||
data.state = data.state and 1 or 0
|
||||
|
||||
if data.items and not next(data.items) then
|
||||
data.items = nil
|
||||
end
|
||||
|
||||
if data.characters and not next(data.characters) then
|
||||
data.characters = nil
|
||||
end
|
||||
|
||||
if data.lockpickDifficulty and not next(data.lockpickDifficulty) then
|
||||
data.lockpickDifficulty = nil
|
||||
end
|
||||
|
||||
if data.groups and not next(data.groups) then
|
||||
data.groups = nil
|
||||
end
|
||||
|
||||
if not data.id then
|
||||
isAddingDoorlock = true
|
||||
local doorCount = data.doors and 2 or 1
|
||||
local lastEntity = 0
|
||||
|
||||
lib.showTextUI(locale('add_door_textui'))
|
||||
|
||||
repeat
|
||||
DisablePlayerFiring(cache.playerId, true)
|
||||
DisableControlAction(0, 25, true)
|
||||
|
||||
local hit, entity, coords = lib.raycast.cam(1|16)
|
||||
local changedEntity = lastEntity ~= entity
|
||||
local doorA = tempData[1]?.entity
|
||||
|
||||
if changedEntity and lastEntity ~= doorA then
|
||||
SetEntityDrawOutline(lastEntity, false)
|
||||
end
|
||||
|
||||
lastEntity = entity
|
||||
|
||||
if hit then
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
DrawMarker(28, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.2, 255, 42, 24,
|
||||
100, false, false, 0, true, false, false, false)
|
||||
end
|
||||
|
||||
if hit and entity > 0 and GetEntityType(entity) == 3 and (doorCount == 1 or doorA ~= entity) and entityIsNotDoor(entity) then
|
||||
if changedEntity then
|
||||
SetEntityDrawOutline(entity, true)
|
||||
end
|
||||
|
||||
if IsDisabledControlJustPressed(0, 24) then
|
||||
addDoorlock(entity)
|
||||
end
|
||||
end
|
||||
|
||||
if IsDisabledControlJustPressed(0, 25) then
|
||||
SetEntityDrawOutline(entity, false)
|
||||
|
||||
if not doorA then
|
||||
isAddingDoorlock = false
|
||||
return lib.hideTextUI()
|
||||
end
|
||||
|
||||
SetEntityDrawOutline(doorA, false)
|
||||
table.wipe(tempData)
|
||||
end
|
||||
until tempData[doorCount]
|
||||
|
||||
lib.hideTextUI()
|
||||
SetEntityDrawOutline(tempData[1].entity, false)
|
||||
|
||||
if data.doors then
|
||||
SetEntityDrawOutline(tempData[2].entity, false)
|
||||
tempData[1].entity = nil
|
||||
tempData[2].entity = nil
|
||||
data.doors = tempData
|
||||
else
|
||||
data.model = tempData[1].model
|
||||
data.coords = tempData[1].coords
|
||||
data.heading = tempData[1].heading
|
||||
end
|
||||
else
|
||||
if data.doors then
|
||||
for i = 1, 2 do
|
||||
local coords = data.doors[i].coords
|
||||
data.doors[i].coords = vector3(coords.x, coords.y, coords.z)
|
||||
data.doors[i].entity = nil
|
||||
end
|
||||
else
|
||||
data.entity = nil
|
||||
end
|
||||
|
||||
data.coords = vector3(data.coords.x, data.coords.y, data.coords.z)
|
||||
data.distance = nil
|
||||
data.zone = nil
|
||||
end
|
||||
|
||||
isAddingDoorlock = false
|
||||
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
if PropertyID ~= nil then
|
||||
if data.name:match("^(.-)_") == nil or data.name:match("^(.-)_") ~= PropertyID then
|
||||
data.name = PropertyID.."_"..data.name
|
||||
end
|
||||
|
||||
local coords = data.coords or data.doors[1].coords
|
||||
if coords ~= nil then
|
||||
if #(coords - vector3(PropertyCoords.x, PropertyCoords.y, PropertyCoords.z)) > MaxDoorlockDistance then
|
||||
TriggerEvent('brutal_housing:client:SendNotifyNumber', 75)
|
||||
return
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
PropertyID = nil
|
||||
PropertyCoords = nil
|
||||
end
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
|
||||
TriggerServerEvent('ox_doorlock:editDoorlock', data.id or false, data)
|
||||
table.wipe(tempData)
|
||||
end)
|
||||
|
||||
RegisterNUICallback('deleteDoor', function(id, cb)
|
||||
cb(1)
|
||||
TriggerServerEvent('ox_doorlock:editDoorlock', id)
|
||||
end)
|
||||
|
||||
RegisterNUICallback('teleportToDoor', function(id, cb)
|
||||
cb(1)
|
||||
SetNuiFocus(false, false)
|
||||
local doorCoords = doors[id].coords
|
||||
if not doorCoords then return end
|
||||
SetEntityCoords(cache.ped, doorCoords.x, doorCoords.y, doorCoords.z, false, false, false, false)
|
||||
end)
|
||||
|
||||
RegisterNUICallback('exit', function(_, cb)
|
||||
cb(1)
|
||||
SetNuiFocus(false, false)
|
||||
end)
|
||||
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
|
||||
PropertyID = nil
|
||||
PropertyCoords = nil
|
||||
MaxDoorlockDistance = 50.0
|
||||
|
||||
RegisterNetEvent("ox_doorlock:dataFromHousing")
|
||||
AddEventHandler("ox_doorlock:dataFromHousing", function(propertyID, coords, maxdoorlockdistance)
|
||||
PropertyID = propertyID
|
||||
PropertyCoords = coords
|
||||
MaxDoorlockDistance = maxdoorlockdistance
|
||||
|
||||
if isAddingDoorlock then return end
|
||||
|
||||
NuiHasLoaded = true
|
||||
|
||||
local allowedDoors = {}
|
||||
for k,v in pairs(doors) do
|
||||
print(v.name:match("^(.-)_"), PropertyID)
|
||||
if v.name:match("^(.-)_") == PropertyID then
|
||||
table.insert(allowedDoors, v)
|
||||
end
|
||||
end
|
||||
|
||||
SendNuiMessage(json.encode({
|
||||
action = 'updateDoorData',
|
||||
data = allowedDoors
|
||||
}, { with_hole = false }))
|
||||
Wait(100)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'setSoundFiles',
|
||||
data = lib.callback.await('ox_doorlock:getSounds', false)
|
||||
})
|
||||
|
||||
SetNuiFocus(true, true)
|
||||
SendNuiMessage(json.encode({
|
||||
action = 'setVisible',
|
||||
data = id
|
||||
}))
|
||||
end)
|
||||
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
|
||||
local function openUi(id)
|
||||
if source == '' or isAddingDoorlock then return end
|
||||
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
PropertyID = nil
|
||||
PropertyCoords = nil
|
||||
------------------------------------
|
||||
------- Brutal Housing Editing -----
|
||||
------------------------------------
|
||||
|
||||
NuiHasLoaded = true
|
||||
|
||||
SendNuiMessage(json.encode({
|
||||
action = 'updateDoorData',
|
||||
data = doors
|
||||
}, { with_hole = false }))
|
||||
Wait(100)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'setSoundFiles',
|
||||
data = lib.callback.await('ox_doorlock:getSounds', false)
|
||||
})
|
||||
|
||||
SetNuiFocus(true, true)
|
||||
SendNuiMessage(json.encode({
|
||||
action = 'setVisible',
|
||||
data = id
|
||||
}))
|
||||
end
|
||||
|
||||
RegisterNetEvent('ox_doorlock:triggeredCommand', function(closest)
|
||||
openUi(closest and ClosestDoor?.id or nil)
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
local target
|
||||
|
||||
if GetResourceState('ox_target'):find('start') then
|
||||
target = {
|
||||
ox = true,
|
||||
exp = exports.ox_target
|
||||
}
|
||||
elseif GetResourceState('qb-target'):find('start') then
|
||||
target = {
|
||||
qb = true,
|
||||
exp = exports['qb-target']
|
||||
}
|
||||
elseif GetResourceState('qtarget'):find('start') then
|
||||
target = {
|
||||
qt = true,
|
||||
exp = exports.qtarget
|
||||
}
|
||||
end
|
||||
|
||||
if not target then return end
|
||||
|
||||
if target.ox then
|
||||
target.exp:addGlobalObject({
|
||||
{
|
||||
name = 'pickDoorlock',
|
||||
label = locale('pick_lock'),
|
||||
icon = 'fas fa-user-lock',
|
||||
onSelect = pickLock,
|
||||
canInteract = canPickLock,
|
||||
items = Config.LockpickItems,
|
||||
anyItem = true,
|
||||
distance = 1
|
||||
}
|
||||
})
|
||||
else
|
||||
local options = {
|
||||
{
|
||||
label = locale('pick_lock'),
|
||||
icon = 'fas fa-user-lock',
|
||||
action = pickLock,
|
||||
canInteract = canPickLock,
|
||||
item = Config.LockpickItems[1],
|
||||
distance = 1
|
||||
}
|
||||
}
|
||||
|
||||
---@cast target table
|
||||
|
||||
if target.qt then
|
||||
target.exp:Object({ options = options })
|
||||
elseif target.qb then
|
||||
target.exp:AddGlobalObject({ options = options })
|
||||
end
|
||||
|
||||
options = { locale('pick_lock') }
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
if resource == cache.resource then
|
||||
if target.qt then
|
||||
return target.exp:RemoveObject(options)
|
||||
end
|
||||
|
||||
if target.qb then
|
||||
return target.exp:RemoveGlobalObject(options)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
Loading…
Add table
Add a link
Reference in a new issue