1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-14 18:34:49 +02:00
parent 19fb68f805
commit 01d047b3cc
53 changed files with 3222 additions and 5 deletions

View 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)