789 lines
26 KiB
Lua
789 lines
26 KiB
Lua
local QBCore = exports['qb-core']:GetCoreObject()
|
|
local UseTarget = GetConvar('UseTarget', 'false') == 'true'
|
|
local InApartment = false
|
|
local ClosestHouse = nil
|
|
local CurrentApartment = nil
|
|
local IsOwned = false
|
|
local CurrentDoorBell = 0
|
|
local CurrentOffset = 0
|
|
local HouseObj = {}
|
|
local POIOffsets = nil
|
|
local RangDoorbell = nil
|
|
|
|
-- target variables
|
|
local InApartmentTargets = {}
|
|
|
|
-- polyzone variables
|
|
local IsInsideEntranceZone = false
|
|
local IsInsideExitZone = false
|
|
local IsInsideStashZone = false
|
|
local IsInsideOutfitsZone = false
|
|
local IsInsideLogoutZone = false
|
|
|
|
-- polyzone integration
|
|
|
|
local function OpenEntranceMenu()
|
|
local headerMenu = {}
|
|
|
|
if IsOwned then
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.enter'),
|
|
params = {
|
|
event = 'apartments:client:EnterApartment',
|
|
args = {}
|
|
}
|
|
}
|
|
elseif not IsOwned then
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.move_here'),
|
|
params = {
|
|
event = 'apartments:client:UpdateApartment',
|
|
args = {}
|
|
}
|
|
}
|
|
end
|
|
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.ring_doorbell'),
|
|
params = {
|
|
event = 'apartments:client:DoorbellMenu',
|
|
args = {}
|
|
}
|
|
}
|
|
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.close_menu'),
|
|
txt = '',
|
|
params = {
|
|
event = 'qb-menu:client:closeMenu'
|
|
}
|
|
}
|
|
|
|
exports['qb-menu']:openMenu(headerMenu)
|
|
end
|
|
|
|
local function OpenExitMenu()
|
|
local headerMenu = {}
|
|
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.open_door'),
|
|
params = {
|
|
event = 'apartments:client:OpenDoor',
|
|
args = {}
|
|
}
|
|
}
|
|
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.leave'),
|
|
params = {
|
|
event = 'apartments:client:LeaveApartment',
|
|
args = {}
|
|
}
|
|
}
|
|
|
|
headerMenu[#headerMenu + 1] = {
|
|
header = Lang:t('text.close_menu'),
|
|
txt = '',
|
|
params = {
|
|
event = 'qb-menu:client:closeMenu'
|
|
}
|
|
}
|
|
|
|
exports['qb-menu']:openMenu(headerMenu)
|
|
end
|
|
|
|
-- exterior entrance (polyzone)
|
|
|
|
local function RegisterApartmentEntranceZone(apartmentID, apartmentData)
|
|
local coords = apartmentData.coords['enter']
|
|
local boxName = 'apartmentEntrance_' .. apartmentID
|
|
local boxData = apartmentData.polyzoneBoxData
|
|
|
|
if boxData.created then
|
|
return
|
|
end
|
|
|
|
local zone = BoxZone:Create(coords, boxData.length, boxData.width, {
|
|
name = boxName,
|
|
heading = 340.0,
|
|
minZ = coords.z - 1.0,
|
|
maxZ = coords.z + 5.0,
|
|
debugPoly = false
|
|
})
|
|
|
|
zone:onPlayerInOut(function(isPointInside)
|
|
if isPointInside and not InApartment then
|
|
exports['qb-core']:DrawText(Lang:t('text.options'), 'left')
|
|
else
|
|
exports['qb-core']:HideText()
|
|
end
|
|
IsInsideEntranceZone = isPointInside
|
|
end)
|
|
|
|
boxData.created = true
|
|
boxData.zone = zone
|
|
end
|
|
|
|
-- exterior entrance (target)
|
|
|
|
local function RegisterApartmentEntranceTarget(apartmentID, apartmentData)
|
|
local coords = apartmentData.coords['enter']
|
|
local boxName = 'apartmentEntrance_' .. apartmentID
|
|
local boxData = apartmentData.polyzoneBoxData
|
|
|
|
if boxData.created then
|
|
return
|
|
end
|
|
|
|
local options = {}
|
|
if apartmentID == ClosestHouse and IsOwned then
|
|
options = {
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:EnterApartment',
|
|
icon = 'fas fa-door-open',
|
|
label = Lang:t('text.enter'),
|
|
},
|
|
}
|
|
else
|
|
options = {
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:UpdateApartment',
|
|
icon = 'fas fa-hotel',
|
|
label = Lang:t('text.move_here'),
|
|
}
|
|
}
|
|
end
|
|
options[#options + 1] = {
|
|
type = 'client',
|
|
event = 'apartments:client:DoorbellMenu',
|
|
icon = 'fas fa-concierge-bell',
|
|
label = Lang:t('text.ring_doorbell'),
|
|
}
|
|
|
|
exports['qb-target']:AddBoxZone(boxName, coords, boxData.length, boxData.width, {
|
|
name = boxName,
|
|
heading = boxData.heading,
|
|
debugPoly = boxData.debug,
|
|
minZ = boxData.minZ,
|
|
maxZ = boxData.maxZ,
|
|
}, {
|
|
options = options,
|
|
distance = boxData.distance
|
|
})
|
|
|
|
boxData.created = true
|
|
end
|
|
|
|
-- interior interactable points (polyzone)
|
|
|
|
local function RegisterInApartmentZone(targetKey, coords, heading, text)
|
|
if not InApartment then
|
|
return
|
|
end
|
|
|
|
if InApartmentTargets[targetKey] and InApartmentTargets[targetKey].created then
|
|
return
|
|
end
|
|
|
|
Wait(1500)
|
|
|
|
local boxName = 'inApartmentTarget_' .. targetKey
|
|
|
|
local zone = BoxZone:Create(coords, 1.5, 1.5, {
|
|
name = boxName,
|
|
heading = heading,
|
|
minZ = coords.z - 1.0,
|
|
maxZ = coords.z + 5.0,
|
|
debugPoly = false
|
|
})
|
|
|
|
zone:onPlayerInOut(function(isPointInside)
|
|
if isPointInside and text then
|
|
exports['qb-core']:DrawText(text, 'left')
|
|
else
|
|
exports['qb-core']:HideText()
|
|
end
|
|
|
|
if targetKey == 'entrancePos' then
|
|
IsInsideExitZone = isPointInside
|
|
end
|
|
|
|
if targetKey == 'stashPos' then
|
|
IsInsideStashZone = isPointInside
|
|
end
|
|
|
|
if targetKey == 'outfitsPos' then
|
|
IsInsideOutfitsZone = isPointInside
|
|
end
|
|
|
|
if targetKey == 'logoutPos' then
|
|
IsInsideLogoutZone = isPointInside
|
|
end
|
|
end)
|
|
|
|
InApartmentTargets[targetKey] = InApartmentTargets[targetKey] or {}
|
|
InApartmentTargets[targetKey].created = true
|
|
InApartmentTargets[targetKey].zone = zone
|
|
end
|
|
|
|
-- interior interactable points (target)
|
|
|
|
local function RegisterInApartmentTarget(targetKey, coords, heading, options)
|
|
if not InApartment then
|
|
return
|
|
end
|
|
|
|
if InApartmentTargets[targetKey] and InApartmentTargets[targetKey].created then
|
|
return
|
|
end
|
|
|
|
local boxName = 'inApartmentTarget_' .. targetKey
|
|
exports['qb-target']:AddBoxZone(boxName, coords, 1.5, 1.5, {
|
|
name = boxName,
|
|
heading = heading,
|
|
minZ = coords.z - 1.0,
|
|
maxZ = coords.z + 5.0,
|
|
debugPoly = false,
|
|
}, {
|
|
options = options,
|
|
distance = 1
|
|
})
|
|
|
|
InApartmentTargets[targetKey] = InApartmentTargets[targetKey] or {}
|
|
InApartmentTargets[targetKey].created = true
|
|
end
|
|
|
|
-- shared
|
|
|
|
local function SetApartmentsEntranceTargets()
|
|
if Apartments.Locations and next(Apartments.Locations) then
|
|
for id, apartment in pairs(Apartments.Locations) do
|
|
if apartment and apartment.coords and apartment.coords['enter'] then
|
|
if UseTarget then
|
|
RegisterApartmentEntranceTarget(id, apartment)
|
|
else
|
|
RegisterApartmentEntranceZone(id, apartment)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SetInApartmentTargets()
|
|
if not POIOffsets then
|
|
-- do nothing
|
|
return
|
|
end
|
|
|
|
local entrancePos = vector3(Apartments.Locations[ClosestHouse].coords.enter.x + POIOffsets.exit.x, Apartments.Locations[ClosestHouse].coords.enter.y + POIOffsets.exit.y, Apartments.Locations[ClosestHouse].coords.enter.z - CurrentOffset + POIOffsets.exit.z)
|
|
local stashPos = vector3(Apartments.Locations[ClosestHouse].coords.enter.x - POIOffsets.stash.x, Apartments.Locations[ClosestHouse].coords.enter.y - POIOffsets.stash.y, Apartments.Locations[ClosestHouse].coords.enter.z - CurrentOffset + POIOffsets.stash.z)
|
|
local outfitsPos = vector3(Apartments.Locations[ClosestHouse].coords.enter.x - POIOffsets.clothes.x, Apartments.Locations[ClosestHouse].coords.enter.y - POIOffsets.clothes.y, Apartments.Locations[ClosestHouse].coords.enter.z - CurrentOffset + POIOffsets.clothes.z)
|
|
local logoutPos = vector3(Apartments.Locations[ClosestHouse].coords.enter.x - POIOffsets.logout.x, Apartments.Locations[ClosestHouse].coords.enter.y + POIOffsets.logout.y, Apartments.Locations[ClosestHouse].coords.enter.z - CurrentOffset + POIOffsets.logout.z)
|
|
|
|
if UseTarget then
|
|
RegisterInApartmentTarget('entrancePos', entrancePos, 0, {
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:OpenDoor',
|
|
icon = 'fas fa-door-open',
|
|
label = Lang:t('text.open_door'),
|
|
},
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:LeaveApartment',
|
|
icon = 'fas fa-door-open',
|
|
label = Lang:t('text.leave'),
|
|
},
|
|
})
|
|
RegisterInApartmentTarget('stashPos', stashPos, 0, {
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:OpenStash',
|
|
icon = 'fas fa-box-open',
|
|
label = Lang:t('text.open_stash'),
|
|
},
|
|
})
|
|
RegisterInApartmentTarget('outfitsPos', outfitsPos, 0, {
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:ChangeOutfit',
|
|
icon = 'fas fa-tshirt',
|
|
label = Lang:t('text.change_outfit'),
|
|
},
|
|
})
|
|
RegisterInApartmentTarget('logoutPos', logoutPos, 0, {
|
|
{
|
|
type = 'client',
|
|
event = 'apartments:client:Logout',
|
|
icon = 'fas fa-sign-out-alt',
|
|
label = Lang:t('text.logout'),
|
|
},
|
|
})
|
|
else
|
|
RegisterInApartmentZone('stashPos', stashPos, 0, '[E] ' .. Lang:t('text.open_stash'))
|
|
RegisterInApartmentZone('outfitsPos', outfitsPos, 0, '[E] ' .. Lang:t('text.change_outfit'))
|
|
RegisterInApartmentZone('logoutPos', logoutPos, 0, '[E] ' .. Lang:t('text.logout'))
|
|
RegisterInApartmentZone('entrancePos', entrancePos, 0, Lang:t('text.options'))
|
|
end
|
|
end
|
|
|
|
local function DeleteApartmentsEntranceTargets()
|
|
if Apartments.Locations and next(Apartments.Locations) then
|
|
for id, apartment in pairs(Apartments.Locations) do
|
|
if UseTarget then
|
|
exports['qb-target']:RemoveZone('apartmentEntrance_' .. id)
|
|
else
|
|
if apartment.polyzoneBoxData.zone then
|
|
apartment.polyzoneBoxData.zone:destroy()
|
|
apartment.polyzoneBoxData.zone = nil
|
|
end
|
|
end
|
|
apartment.polyzoneBoxData.created = false
|
|
end
|
|
end
|
|
end
|
|
|
|
local function DeleteInApartmentTargets()
|
|
IsInsideExitZone = false
|
|
IsInsideStashZone = false
|
|
IsInsideOutfitsZone = false
|
|
IsInsideLogoutZone = false
|
|
|
|
if InApartmentTargets and next(InApartmentTargets) then
|
|
for id, apartmentTarget in pairs(InApartmentTargets) do
|
|
if UseTarget then
|
|
exports['qb-target']:RemoveZone('inApartmentTarget_' .. id)
|
|
else
|
|
if apartmentTarget.zone then
|
|
apartmentTarget.zone:destroy()
|
|
apartmentTarget.zone = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
InApartmentTargets = {}
|
|
end
|
|
|
|
-- utility functions
|
|
|
|
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 EnterApartment(house, apartmentId, new)
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'houses_door_open', 0.1)
|
|
openHouseAnim()
|
|
Wait(250)
|
|
QBCore.Functions.TriggerCallback('apartments:GetApartmentOffset', function(offset)
|
|
if offset == nil or offset == 0 then
|
|
QBCore.Functions.TriggerCallback('apartments:GetApartmentOffsetNewOffset', function(newoffset)
|
|
if newoffset > 230 then
|
|
newoffset = 210
|
|
end
|
|
CurrentOffset = newoffset
|
|
TriggerServerEvent('apartments:server:AddObject', apartmentId, house, CurrentOffset)
|
|
local coords = { x = Apartments.Locations[house].coords.enter.x, y = Apartments.Locations[house].coords.enter.y, z = Apartments.Locations[house].coords.enter.z - CurrentOffset }
|
|
local data = exports['qb-interior']:CreateApartmentFurnished(coords)
|
|
Wait(100)
|
|
HouseObj = data[1]
|
|
POIOffsets = data[2]
|
|
InApartment = true
|
|
CurrentApartment = apartmentId
|
|
ClosestHouse = house
|
|
RangDoorbell = nil
|
|
Wait(500)
|
|
TriggerEvent('qb-weathersync:client:DisableSync')
|
|
Wait(100)
|
|
TriggerServerEvent('qb-apartments:server:SetInsideMeta', house, apartmentId, true, false)
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'houses_door_close', 0.1)
|
|
TriggerServerEvent('apartments:server:setCurrentApartment', CurrentApartment)
|
|
end, house)
|
|
else
|
|
if offset > 230 then
|
|
offset = 210
|
|
end
|
|
CurrentOffset = offset
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'houses_door_open', 0.1)
|
|
TriggerServerEvent('apartments:server:AddObject', apartmentId, house, CurrentOffset)
|
|
local coords = { x = Apartments.Locations[ClosestHouse].coords.enter.x, y = Apartments.Locations[ClosestHouse].coords.enter.y, z = Apartments.Locations[ClosestHouse].coords.enter.z - CurrentOffset }
|
|
local data = exports['qb-interior']:CreateApartmentFurnished(coords)
|
|
Wait(100)
|
|
HouseObj = data[1]
|
|
POIOffsets = data[2]
|
|
InApartment = true
|
|
CurrentApartment = apartmentId
|
|
Wait(500)
|
|
TriggerEvent('qb-weathersync:client:DisableSync')
|
|
Wait(100)
|
|
TriggerServerEvent('qb-apartments:server:SetInsideMeta', house, apartmentId, true, true)
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'houses_door_close', 0.1)
|
|
TriggerServerEvent('apartments:server:setCurrentApartment', CurrentApartment)
|
|
end
|
|
|
|
if new ~= nil then
|
|
if new then
|
|
TriggerEvent('qb-interior:client:SetNewState', true)
|
|
else
|
|
TriggerEvent('qb-interior:client:SetNewState', false)
|
|
end
|
|
else
|
|
TriggerEvent('qb-interior:client:SetNewState', false)
|
|
end
|
|
end, apartmentId)
|
|
end
|
|
|
|
local function LeaveApartment(house)
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'houses_door_open', 0.1)
|
|
openHouseAnim()
|
|
TriggerServerEvent('qb-apartments:returnBucket')
|
|
DoScreenFadeOut(500)
|
|
while not IsScreenFadedOut() do Wait(10) end
|
|
exports['qb-interior']:DespawnInterior(HouseObj, function()
|
|
TriggerEvent('qb-weathersync:client:EnableSync')
|
|
SetEntityCoords(PlayerPedId(), Apartments.Locations[house].coords.enter.x, Apartments.Locations[house].coords.enter.y, Apartments.Locations[house].coords.enter.z)
|
|
SetEntityHeading(PlayerPedId(), Apartments.Locations[house].coords.enter.w)
|
|
Wait(1000)
|
|
TriggerServerEvent('apartments:server:RemoveObject', CurrentApartment, house)
|
|
TriggerServerEvent('qb-apartments:server:SetInsideMeta', CurrentApartment, false)
|
|
CurrentApartment = nil
|
|
InApartment = false
|
|
CurrentOffset = 0
|
|
DoScreenFadeIn(1000)
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'houses_door_close', 0.1)
|
|
TriggerServerEvent('apartments:server:setCurrentApartment', nil)
|
|
|
|
DeleteInApartmentTargets()
|
|
DeleteApartmentsEntranceTargets()
|
|
end)
|
|
end
|
|
|
|
local function SetClosestApartment()
|
|
local pos = GetEntityCoords(PlayerPedId())
|
|
local current = nil
|
|
local dist = 100
|
|
for id, _ in pairs(Apartments.Locations) do
|
|
local distcheck = #(pos - vector3(Apartments.Locations[id].coords.enter.x, Apartments.Locations[id].coords.enter.y, Apartments.Locations[id].coords.enter.z))
|
|
if distcheck < dist then
|
|
current = id
|
|
end
|
|
end
|
|
if current ~= ClosestHouse and LocalPlayer.state.isLoggedIn and not InApartment then
|
|
ClosestHouse = current
|
|
QBCore.Functions.TriggerCallback('apartments:IsOwner', function(result)
|
|
IsOwned = result
|
|
DeleteApartmentsEntranceTargets()
|
|
DeleteInApartmentTargets()
|
|
end, ClosestHouse)
|
|
end
|
|
end
|
|
|
|
function MenuOwners()
|
|
QBCore.Functions.TriggerCallback('apartments:GetAvailableApartments', function(apartments)
|
|
if next(apartments) == nil then
|
|
QBCore.Functions.Notify(Lang:t('error.nobody_home'), 'error', 3500)
|
|
CloseMenuFull()
|
|
else
|
|
local apartmentMenu = {
|
|
{
|
|
header = Lang:t('text.tennants'),
|
|
isMenuHeader = true
|
|
}
|
|
}
|
|
|
|
for k, v in pairs(apartments) do
|
|
apartmentMenu[#apartmentMenu + 1] = {
|
|
header = v,
|
|
txt = '',
|
|
params = {
|
|
event = 'apartments:client:RingMenu',
|
|
args = {
|
|
apartmentId = k
|
|
}
|
|
}
|
|
|
|
}
|
|
end
|
|
|
|
apartmentMenu[#apartmentMenu + 1] = {
|
|
header = Lang:t('text.close_menu'),
|
|
txt = '',
|
|
params = {
|
|
event = 'qb-menu:client:closeMenu'
|
|
}
|
|
|
|
}
|
|
exports['qb-menu']:openMenu(apartmentMenu)
|
|
end
|
|
end, ClosestHouse)
|
|
end
|
|
|
|
function CloseMenuFull()
|
|
exports['qb-menu']:closeMenu()
|
|
end
|
|
|
|
-- Event Handlers
|
|
|
|
AddEventHandler('onResourceStop', function(resource)
|
|
if resource == GetCurrentResourceName() then
|
|
if HouseObj ~= nil then
|
|
exports['qb-interior']:DespawnInterior(HouseObj, function()
|
|
CurrentApartment = nil
|
|
TriggerEvent('qb-weathersync:client:EnableSync')
|
|
DoScreenFadeIn(500)
|
|
while not IsScreenFadedOut() do
|
|
Wait(10)
|
|
end
|
|
SetEntityCoords(PlayerPedId(), Apartments.Locations[ClosestHouse].coords.enter.x, Apartments.Locations[ClosestHouse].coords.enter.y, Apartments.Locations[ClosestHouse].coords.enter.z)
|
|
SetEntityHeading(PlayerPedId(), Apartments.Locations[ClosestHouse].coords.enter.w)
|
|
Wait(1000)
|
|
InApartment = false
|
|
DoScreenFadeIn(1000)
|
|
end)
|
|
end
|
|
|
|
DeleteApartmentsEntranceTargets()
|
|
DeleteInApartmentTargets()
|
|
end
|
|
end)
|
|
|
|
|
|
-- Events
|
|
|
|
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
|
|
CurrentApartment = nil
|
|
InApartment = false
|
|
CurrentOffset = 0
|
|
|
|
DeleteApartmentsEntranceTargets()
|
|
DeleteInApartmentTargets()
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:setupSpawnUI', function(cData)
|
|
QBCore.Functions.TriggerCallback('apartments:GetOwnedApartment', function(result)
|
|
if result then
|
|
TriggerEvent('qb-spawn:client:setupSpawns', cData, false, nil)
|
|
TriggerEvent('qb-spawn:client:openUI', true)
|
|
TriggerEvent('apartments:client:SetHomeBlip', result.type)
|
|
else
|
|
if Apartments.Starting then
|
|
TriggerEvent('qb-spawn:client:setupSpawns', cData, true, Apartments.Locations)
|
|
TriggerEvent('qb-spawn:client:openUI', true)
|
|
else
|
|
TriggerEvent('qb-spawn:client:setupSpawns', cData, false, nil)
|
|
TriggerEvent('qb-spawn:client:openUI', true)
|
|
TriggerEvent('apartments:client:SetHomeBlip', nil)
|
|
end
|
|
end
|
|
end, cData.citizenid)
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:SpawnInApartment', function(apartmentId, apartment)
|
|
local pos = GetEntityCoords(PlayerPedId())
|
|
if RangDoorbell ~= nil then
|
|
local doorbelldist = #(pos - vector3(Apartments.Locations[RangDoorbell].coords.enter.x, Apartments.Locations[RangDoorbell].coords.enter.y, Apartments.Locations[RangDoorbell].coords.enter.z))
|
|
if doorbelldist > 5 then
|
|
QBCore.Functions.Notify(Lang:t('error.to_far_from_door'))
|
|
return
|
|
end
|
|
end
|
|
ClosestHouse = apartment
|
|
EnterApartment(apartment, apartmentId, true)
|
|
IsOwned = true
|
|
end)
|
|
|
|
RegisterNetEvent('qb-apartments:client:LastLocationHouse', function(apartmentType, apartmentId)
|
|
ClosestHouse = apartmentType
|
|
EnterApartment(apartmentType, apartmentId, false)
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:SetHomeBlip', function(home)
|
|
CreateThread(function()
|
|
SetClosestApartment()
|
|
for name, _ in pairs(Apartments.Locations) do
|
|
RemoveBlip(Apartments.Locations[name].blip)
|
|
|
|
Apartments.Locations[name].blip = AddBlipForCoord(Apartments.Locations[name].coords.enter.x, Apartments.Locations[name].coords.enter.y, Apartments.Locations[name].coords.enter.z)
|
|
if (name == home) then
|
|
SetBlipSprite(Apartments.Locations[name].blip, 475)
|
|
SetBlipCategory(Apartments.Locations[name].blip, 11)
|
|
else
|
|
SetBlipSprite(Apartments.Locations[name].blip, 476)
|
|
SetBlipCategory(Apartments.Locations[name].blip, 10)
|
|
end
|
|
SetBlipDisplay(Apartments.Locations[name].blip, 4)
|
|
SetBlipScale(Apartments.Locations[name].blip, 0.65)
|
|
SetBlipAsShortRange(Apartments.Locations[name].blip, true)
|
|
SetBlipColour(Apartments.Locations[name].blip, 3)
|
|
AddTextEntry(Apartments.Locations[name].label, Apartments.Locations[name].label)
|
|
BeginTextCommandSetBlipName(Apartments.Locations[name].label)
|
|
EndTextCommandSetBlipName(Apartments.Locations[name].blip)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:RingMenu', function(data)
|
|
RangDoorbell = ClosestHouse
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'doorbell', 0.1)
|
|
TriggerServerEvent('apartments:server:RingDoor', data.apartmentId, ClosestHouse)
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:RingDoor', function(player, _)
|
|
CurrentDoorBell = player
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'doorbell', 0.1)
|
|
QBCore.Functions.Notify(Lang:t('info.at_the_door'))
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:DoorbellMenu', function()
|
|
MenuOwners()
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:EnterApartment', function()
|
|
QBCore.Functions.TriggerCallback('apartments:GetOwnedApartment', function(result)
|
|
if result ~= nil then
|
|
EnterApartment(ClosestHouse, result.name)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:UpdateApartment', function()
|
|
local apartmentType = ClosestHouse
|
|
local apartmentLabel = Apartments.Locations[ClosestHouse].label
|
|
QBCore.Functions.TriggerCallback('apartments:GetOwnedApartment', function(result)
|
|
if result == nil then
|
|
TriggerServerEvent("apartments:server:CreateApartment", apartmentType, apartmentLabel, false)
|
|
else
|
|
TriggerServerEvent('apartments:server:UpdateApartment', apartmentType, apartmentLabel)
|
|
end
|
|
end)
|
|
|
|
IsOwned = true
|
|
|
|
DeleteApartmentsEntranceTargets()
|
|
DeleteInApartmentTargets()
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:OpenDoor', function()
|
|
if CurrentDoorBell == 0 then
|
|
QBCore.Functions.Notify(Lang:t('error.nobody_at_door'))
|
|
return
|
|
end
|
|
TriggerServerEvent('apartments:server:OpenDoor', CurrentDoorBell, CurrentApartment, ClosestHouse)
|
|
CurrentDoorBell = 0
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:LeaveApartment', function()
|
|
LeaveApartment(ClosestHouse)
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:OpenStash', function()
|
|
if CurrentApartment then
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'StashOpen', 0.4)
|
|
TriggerServerEvent('apartments:server:openStash', CurrentApartment)
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:ChangeOutfit', function()
|
|
TriggerServerEvent('InteractSound_SV:PlayOnSource', 'Clothes1', 0.4)
|
|
TriggerEvent('qb-clothing:client:openOutfitMenu')
|
|
end)
|
|
|
|
RegisterNetEvent('apartments:client:Logout', function()
|
|
TriggerServerEvent('qb-houses:server:LogoutLocation')
|
|
end)
|
|
|
|
|
|
-- Threads
|
|
|
|
if UseTarget then
|
|
CreateThread(function()
|
|
local sleep = 5000
|
|
while not LocalPlayer.state.isLoggedIn do
|
|
-- do nothing
|
|
Wait(sleep)
|
|
end
|
|
|
|
while true do
|
|
sleep = 1000
|
|
|
|
if not InApartment then
|
|
SetClosestApartment()
|
|
SetApartmentsEntranceTargets()
|
|
elseif InApartment then
|
|
SetInApartmentTargets()
|
|
end
|
|
Wait(sleep)
|
|
end
|
|
end)
|
|
else
|
|
CreateThread(function()
|
|
local sleep = 5000
|
|
while not LocalPlayer.state.isLoggedIn do
|
|
-- do nothing
|
|
Wait(sleep)
|
|
end
|
|
|
|
while true do
|
|
sleep = 1000
|
|
|
|
if not InApartment then
|
|
SetClosestApartment()
|
|
SetApartmentsEntranceTargets()
|
|
|
|
if IsInsideEntranceZone then
|
|
sleep = 0
|
|
if IsControlJustPressed(0, 38) then
|
|
OpenEntranceMenu()
|
|
exports['qb-core']:HideText()
|
|
end
|
|
end
|
|
elseif InApartment then
|
|
sleep = 0
|
|
|
|
SetInApartmentTargets()
|
|
|
|
if IsInsideExitZone then
|
|
if IsControlJustPressed(0, 38) then
|
|
OpenExitMenu()
|
|
exports['qb-core']:HideText()
|
|
end
|
|
end
|
|
|
|
if IsInsideStashZone then
|
|
if IsControlJustPressed(0, 38) then
|
|
TriggerEvent('apartments:client:OpenStash')
|
|
exports['qb-core']:HideText()
|
|
end
|
|
end
|
|
|
|
if IsInsideOutfitsZone then
|
|
if IsControlJustPressed(0, 38) then
|
|
TriggerEvent('apartments:client:ChangeOutfit')
|
|
exports['qb-core']:HideText()
|
|
end
|
|
end
|
|
|
|
if IsInsideLogoutZone then
|
|
if IsControlJustPressed(0, 38) then
|
|
TriggerEvent('apartments:client:Logout')
|
|
exports['qb-core']:HideText()
|
|
end
|
|
end
|
|
end
|
|
|
|
Wait(sleep)
|
|
end
|
|
end)
|
|
end
|