1
0
Fork 0
forked from Simnation/Main
Main/resources/[housing]/ox_doorlock/client/main.lua

350 lines
9.6 KiB
Lua
Raw Permalink Normal View History

2025-07-14 18:34:49 +02:00
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)