local QBCore = exports['qb-core']:GetCoreObject() local TargetType = Config.CoreSettings.Target.Type or 'qb' local NotifyType = Config.CoreSettings.Notify.Type or 'qb' local InvType = Config.CoreSettings.Inventory.Type or 'qb' local CashSymbol = Config.CoreSettings.Banking.CashSymbol or '£' local PlayerJob = {} local SpawnedZones = {} local JobBlips = {} local busy = false --sends a client debug print function CLDebug(msg) if not Config.CoreSettings.Debug.Prints then return end print(msg) end --sends a client notification function CLNotify(msg,type,time,title) if NotifyType == nil then print('^1| Lusty94_BossMenu | DEBUG | ERROR: NotifyType is nil!') return end if not msg then msg = 'Notification sent with no message!' end if not type then type = 'success' end if not time then time = 5000 end if not title then title = 'Notification' end if NotifyType == 'qb' then QBCore.Functions.Notify(msg,type,time) elseif NotifyType == 'okok' then exports['okokNotify']:Alert(title, msg, time, type, true) elseif NotifyType == 'mythic' then exports['mythic_notify']:DoHudText(type, msg) elseif NotifyType == 'ox' then lib.notify({title = title, description = msg, position = 'top', type = type, duration = time}) elseif NotifyType == 'lation' then exports.lation_ui:notify({title = title, message = msg, type = type, duration = time, icon = 'fa-solid fa-clipboard',}) elseif NotifyType == 'wasabi' then exports.wasabi_notify:notify(title, msg, time, type) elseif NotifyType == 'custom' then --insert your custom notification function here else print('^1| Lusty94_BossMenu | DEBUG | ERROR: Unknown Notify Type Set In Config.CoreSettings.Notify.Type | '..tostring(NotifyType)) end end --get job logos function getJobLogo(jobName) if not jobName then CLDebug('^1| Lusty94_BossMenu | DEBUG | ERROR | No job data received to obtain logo') return end return Config.Locations[jobName].image or 'https://files.fivemerr.com/images/54e9ebe7-df76-480c-bbcb-05b1559e2317.png' end --change clothes function ChangeClothes(jobName) local ClothingType = Config.CoreSettings.Clothing.Type if PlayerJob.name ~= jobName then CLNotify(Config.Language.Notifications.NoAccess, 'error') return end if ClothingType == 'qb' then TriggerEvent('qb-clothing:client:openOutfitMenu') elseif ClothingType == 'illenium' then TriggerEvent('illenium-appearance:client:openOutfitMenu') elseif ClothingType == 'custom' then -- insert your own custom code for opening outfit menu in your clothing script end end --set busy status function setBusy(toggle) busy = toggle CLDebug(('^3| Lusty94_BossMenu | DEBUG | Info | Busy Status | %s'):format(tostring(busy))) end --open boss menu function OpenBossMenu(jobName) if PlayerJob.name ~= jobName then CLNotify(Config.Language.Notifications.NoAccess, 'error') return end local members = lib.callback.await('lusty94_bossmenu:server:getJobMembers', false, jobName) local jobLabel = QBCore.Shared.Jobs[jobName].label local jobImage = getJobLogo(jobName) local jobBank = PlayerJob.isboss and lib.callback.await('lusty94_bossmenu:server:getJobBank', false, jobName) or nil local options = {} local desc = string.format('Toplam Çalışan: %s', members and #members or 0) if jobBank then desc = desc..string.format('\nGüncel Banka Bakiyesi: %s%s', CashSymbol, jobBank) end options[#options+1] = { title = 'İş Unvanı: '..jobLabel, description = desc, icon = jobImage, image = jobImage, } if PlayerJob.isboss then options[#options+1] = { title = 'Çalışanları Görüntüle', event = 'lusty94_bossmenu:client:ViewEmployees', icon = 'fa-solid fa-magnifying-glass', args = { job = jobName }, } options[#options+1] = { title = 'Çalışan İşe Al', event = 'lusty94_bossmenu:client:HireEmployee', icon = 'fa-solid fa-users', args = { job = jobName }, } options[#options+1] = { title = 'Çalışanı Terfi / Tenzil Et', event = 'lusty94_bossmenu:client:PromoDemoEmployee', icon = 'fa-solid fa-arrows-up-down', args = { job = jobName }, } options[#options+1] = { title = 'Çalışanı Kov', event = 'lusty94_bossmenu:client:FireEmployee', icon = 'fa-solid fa-user-xmark', args = { job = jobName }, } options[#options+1] = { title = 'Duyuru Gönder', icon = 'fa-solid fa-bullhorn', onSelect = function() local input = lib.inputDialog('Duyuru Gönder', { { type = 'textarea', label = 'Duyuru Mesajı', required = true, icon = 'fa-solid fa-message' } }) if input and input[1] and input[1]:len() > 2 then TriggerServerEvent('lusty94_bossmenu:server:SendJobAnnouncement', jobName, input[1]) else CLNotify(Config.Language.Notifications.Cancelled, 'error') end end } if Config.Locations[jobName].stash and Config.Locations[jobName].stash.enabled then options[#options+1] = { title = 'Depoyu Aç', icon = 'fa-solid fa-box-archive', onSelect = function() TriggerEvent('lusty94_bossmenu:client:OpenBossStash', jobName) end, } end options[#options+1] = { title = 'Nakit Yatır', event = 'lusty94_bossmenu:client:DepositMoney', icon = 'fa-solid fa-money-bill', args = { job = jobName }, } options[#options+1] = { title = 'Çalışana Prim Ver', event = 'lusty94_bossmenu:client:GiveBonus', icon = 'fa-solid fa-money-bill', args = { job = jobName }, } options[#options+1] = { title = 'Çalışan Mesajlarını Oku', icon = 'fa-solid fa-envelope-open-text', onSelect = function() TriggerServerEvent('lusty94_bossmenu:server:GetMessages', jobName) end } end if not PlayerJob.isboss then options[#options+1] = { title = 'Bossa Mesaj Gönder', event = 'lusty94_bossmenu:client:SendMessage', icon = 'fa-solid fa-paper-plane', args = { job = jobName }, } options[#options+1] = { title = 'Boss Yanıtlarını Görüntüle', event = 'lusty94_bossmenu:client:RequestReplies', icon = 'fa-solid fa-inbox', args = { job = jobName }, } end options[#options+1] = { title = 'Mesai Durumunu Değiştir', event = 'lusty94_bossmenu:client:ToggleDuty', icon = 'fa-solid fa-user-clock', } options[#options+1] = { title = 'Kıyafet Değiştir', icon = 'fa-solid fa-shirt', onSelect = function() ChangeClothes(jobName) end, } lib.registerContext({ id = 'boss_menu_main', title = 'Yönetim Menüsü', options = options, }) lib.showContext('boss_menu_main') end --get max job grade function getMaxJobGrade(jobName) local job = QBCore.Shared.Jobs[jobName] if not job or not job.grades then return nil end local maxGrade = 0 for k, v in pairs(job.grades) do local grade = tonumber(k) if grade and grade > maxGrade then maxGrade = grade end end return maxGrade end --refresh blips function SetBlips() while not LocalPlayer.state.isLoggedIn do Wait(500) end for jobName, blip in pairs(JobBlips) do if blip then RemoveBlip(blip) end end JobBlips = {} for jobName, coords in pairs(Config.Locations) do local blipData = Config.Locations[jobName].blip CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Adding management blips for job: '..jobName..' At coords: '.. json.encode(coords.coords)) if blipData and blipData.enabled and PlayerJob.name == jobName then local blip = AddBlipForCoord(coords.coords.x, coords.coords.y, coords.coords.z) SetBlipSprite(blip, blipData.id) SetBlipDisplay(blip, 4) SetBlipScale(blip, blipData.scale) SetBlipColour(blip, blipData.colour) SetBlipAsShortRange(blip, true) BeginTextCommandSetBlipName('STRING') AddTextComponentString(blipData.title or 'Job Management') EndTextCommandSetBlipName(blip) JobBlips[jobName] = blip end end end --create zones CreateThread(function() while not LocalPlayer.state.isLoggedIn do Wait(500) end PlayerJob = QBCore.Functions.GetPlayerData().job for jobName, coords in pairs(Config.Locations) do CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Creating target zone for job: '..jobName..' At coords: '..json.encode(coords.coords)) if TargetType == 'qb' then exports['qb-target']:AddCircleZone('bossMenu_'..jobName, coords.coords, coords.radius or 1.0, { name = 'bossMenu_'..jobName, debugPoly = coords.debug or false, useZ = true, }, { options = { { icon = 'fas fa-clipboard', label = 'İş Yönetimi', canInteract = function() return not busy end, action = function() OpenBossMenu(jobName) end, } }, distance = coords.distance or 2.0 }) SpawnedZones[#SpawnedZones + 1] = { type = 'qb', name = 'bossMenu_'..jobName } elseif TargetType == 'ox' then local zoneId = exports.ox_target:addSphereZone({ coords = coords.coords, radius = coords.radius or 1.0, debug = coords.debug or false, options = { { icon = 'fas fa-clipboard', label = 'İş Yönetimi', canInteract = function() return not busy end, onSelect = function() OpenBossMenu(jobName) end, distance = coords.distance or 2.0, } } }) SpawnedZones[#SpawnedZones + 1] = { type = 'ox', id = zoneId } end end SetBlips() end) --draw markers at boss menu locations CreateThread(function() while not LocalPlayer.state.isLoggedIn do Wait(500) end while true do local playerCoords = GetEntityCoords(PlayerPedId()) local pulse = (math.sin(GetGameTimer() / 500.0) * 0.05) -- animasyonlu nabız etkisi for jobName, data in pairs(Config.Locations) do -- Sadece oyuncunun mesleğiyle eşleşen lokasyonu göster if PlayerJob.name == jobName then local markerCoords = data.coords local dist = #(playerCoords - vector3(markerCoords.x, markerCoords.y, markerCoords.z)) if dist < 40.0 then -- Zemin halkası marker (tip 25) DrawMarker( 25, -- tip: zemin halkası markerCoords.x, markerCoords.y, markerCoords.z - 0.98, -- konum (zemin seviyesinde) 0.0, 0.0, 0.0, -- yön 0.0, 0.0, 0.0, -- rotasyon 1.8 + pulse, 1.8 + pulse, 0.15, -- boyut (nabız animasyonlu) 0, 180, 200, 180, -- renk: siyan/turkuaz, yarı şeffaf false, false, 2, false, nil, nil, false ) -- Yukarıda dönen ok marker (tip 36) DrawMarker( 36, markerCoords.x, markerCoords.y, markerCoords.z + 1.2, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 0.35, 0.35, 0.35, 0, 220, 255, 220, false, false, 2, false, nil, nil, false ) -- Yakınken 3D yazı göster if dist < 5.0 then local textX, textY = markerCoords.x, markerCoords.y local textZ = markerCoords.z + 1.85 SetTextScale(0.35, 0.35) SetTextFont(4) SetTextProportional(1) SetTextColour(0, 220, 255, 255) SetTextOutline() SetTextEntry("STRING") SetTextCentre(true) DrawText(0.5, 0.5) local x2, y2, z2 = World3dToScreen2d(textX, textY, textZ) SetTextScale(0.3, 0.3) SetTextFont(4) SetTextProportional(1) SetTextColour(255, 255, 255, 200) SetTextOutline() SetTextEntry("STRING") SetTextCentre(true) AddTextComponentString("[ ~y~E ~w~] Menüyü Aç") DrawText(x2, y2) end end end end Wait(0) end end) RegisterNetEvent('lusty94_bossmenu:client:ViewEmployees', function(data) local jobName = data.job if not PlayerJob.isboss then CLNotify(Config.Language.Notifications.NoAccess, 'error') return end local members = lib.callback.await('lusty94_bossmenu:server:getJobMembers', false, jobName) if not members then return end local options = {} for _, member in pairs(members) do options[#options+1] = { title = member.name, description = 'Rütbe: '..member.grade.name..'\n Vatandaş ID: '..member.citizenid..'\n Telefon: '..member.phone } CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Employees information for job: '..jobName..' Name: '..member.name..' Rank: '..member.grade.name..' Citizen ID: '..member.citizenid..' Phone number: '..member.phone..'^7') end table.insert(options, { title = 'Ana Menüye Dön', icon = 'fa-solid fa-arrow-left', onSelect = function() OpenBossMenu(jobName) end, }) lib.registerContext({ id = 'employees_menu', title = 'Mevcut Çalışanlar', options = options, }) lib.showContext('employees_menu') end) --hire employee RegisterNetEvent('lusty94_bossmenu:client:HireEmployee', function(data) setBusy(true) local job = data.job local players = lib.callback.await('lusty94_bossmenu:server:getNearbyPlayers', false) if not players or #players == 0 then setBusy(false) CLNotify(Config.Language.Notifications.NoOneNear, 'error') CLDebug('^1| Lusty94_BossMenu | DEBUG | ERROR: No players found nearby^7') return end local playerChoices = {} for _, p in pairs(players) do playerChoices[#playerChoices+1] = { label = p.name..' | ID: '..p.source, value = p.source, playerName = p.name, } CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Nearby players to hire for job: '..job..' Name: '..p.name..' Server ID: '..p.source..'^7') end local playerInput = lib.inputDialog('Çalışan İşe Al', { { type = 'select', label = 'Oyuncu Seç', options = playerChoices } }) if not playerInput then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local targetId = playerInput[1] if not targetId then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local selectedName for _, option in pairs(playerChoices) do if option.value == targetId then selectedName = option.playerName break end end local targetJob = lib.callback.await('lusty94_bossmenu:server:getPlayerJob', false, targetId) if targetJob == job then setBusy(false) CLNotify(Config.Language.Notifications.AlreadyEmployed, 'error') CLDebug('^1| Lusty94_BossMenu | DEBUG | ERROR: Person already employed here^7') return end local gradeChoices = {} for grade, data in pairs(QBCore.Shared.Jobs[job].grades) do gradeChoices[#gradeChoices+1] = { label = data.name or ('Rank '..grade), value = tonumber(grade) } end CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Player selected to be hired for job: '..job..' Name: '..selectedName..'^7') table.sort(gradeChoices, function(a, b) return a.value < b.value end) local rankInput = lib.inputDialog('Rütbe Seç', { { type = 'select', label = 'Rütbe Seç', options = gradeChoices } }) if not rankInput then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local selectedGrade = tonumber(rankInput[1]) local gradeLabel = QBCore.Shared.Jobs[job].grades[tostring(selectedGrade)]?.name or ('Rank '..selectedGrade) local confirm = lib.alertDialog({ header = 'Kiralama Onayla', content = selectedName..' adlı kişiyi '..gradeLabel..' rütbesiyle işe almak istediğinize emin misiniz?', centered = true, cancel = true }) if confirm ~= 'confirm' then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end TriggerServerEvent('lusty94_bossmenu:server:HirePlayer', targetId, job, selectedGrade) setBusy(false) end) --promote or demote employee RegisterNetEvent('lusty94_bossmenu:client:PromoDemoEmployee', function(data) setBusy(true) local job = data.job local members = lib.callback.await('lusty94_bossmenu:server:getJobMembers', false, job) if not members then return end local employeeChoices = {} for _, v in pairs(members) do if v.citizenid ~= QBCore.Functions.GetPlayerData().citizenid then employeeChoices[#employeeChoices+1] = { label = v.name, value = v.citizenid, playerName = v.name } end end local employeeInput = lib.inputDialog('Çalışanı Terfi / Tenzil Et', { { type = 'select', label = 'Çalışan Seç', options = employeeChoices } }) if not employeeInput then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local targetCitizenId = employeeInput[1] local selectedName = employeeChoices[1].playerName local gradeChoices = {} for grade, data in pairs(QBCore.Shared.Jobs[job].grades) do gradeChoices[#gradeChoices+1] = { label = data.name or ('Rank '..grade), value = tonumber(grade) } CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Player selected to be promoted or demoted for job: '..job..' Name: '..selectedName..' Rank: '..data.name..'^7') end table.sort(gradeChoices, function(a, b) return a.value < b.value end) local rankInput = lib.inputDialog('Yeni Rütbe Seç', { { type = 'select', label = 'Yeni Rütbe Seç', options = gradeChoices } }) if not rankInput then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local newGrade = tonumber(rankInput[1]) local gradeLabel = QBCore.Shared.Jobs[job].grades[tostring(newGrade)]?.name or ('Rank '..newGrade) local confirm = lib.alertDialog({ header = 'Terfiyi Onayla', content = selectedName..' adlı kişiyi '..gradeLabel..' rütbesine getirmek istediğinize emin misiniz?', centered = true, cancel = true }) if confirm == 'confirm' then local coords = GetEntityCoords(PlayerPedId()) TriggerServerEvent('lusty94_bossmenu:server:PromoteEmployee', targetCitizenId, job, newGrade, coords) end setBusy(false) end) --fire employee RegisterNetEvent('lusty94_bossmenu:client:FireEmployee', function(data) setBusy(true) local members = lib.callback.await('lusty94_bossmenu:server:getJobMembers', false, data.job) if not members then return end local employees = {} for _, m in pairs(members) do if m.citizenid ~= QBCore.Functions.GetPlayerData().citizenid then employees[#employees+1] = { label = m.name, value = m.citizenid, playerName = m.name } end end local input = lib.inputDialog('Çalışanı Kov', { { type = 'select', label = 'Çalışan Seç', options = employees } }) if not input then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local targetCitizenId = input[1] local selectedName = employees[1].playerName CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Player selected to be fired from job: '..data.job..' Name: '..selectedName..' Citizen ID: '..targetCitizenId..'^7') local confirm = lib.alertDialog({ header = 'Kovmayı Onayla', content = selectedName..' adlı kişiyi kovmak istediğinize emin misiniz?', centered = true, cancel = true }) if confirm == 'confirm' then local coords = GetEntityCoords(PlayerPedId()) TriggerServerEvent('lusty94_bossmenu:server:FirePlayer', targetCitizenId, coords) end setBusy(false) end) --confirm job hire RegisterNetEvent('lusty94_bossmenu:client:ConfirmHire', function(bossId, job, grade, jobLabel, gradeLabel) setBusy(true) CLNotify(Config.Language.Notifications.OfferReceived, 'success') local confirm = lib.alertDialog({ header = 'İş Teklifi', content = jobLabel..' olarak '..gradeLabel..' rütbesiyle iş teklifi alıyorsunuz.\n Kabul ediyor musunuz?', centered = true, cancel = true }) if confirm == 'confirm' then setBusy(false) TriggerServerEvent('lusty94_bossmenu:server:AcceptHire', bossId, job, grade) else setBusy(false) TriggerServerEvent('lusty94_bossmenu:server:DeclineHire', bossId) CLNotify(Config.Language.Notifications.DeclinedOffer, 'error') end end) --refresh employee list RegisterNetEvent('lusty94_bossmenu:client:RefreshEmployeeList', function(job) Wait(1000) TriggerEvent('lusty94_bossmenu:client:ViewEmployees', { job = job }) end) --deposit cash RegisterNetEvent('lusty94_bossmenu:client:DepositMoney', function(data) if PlayerJob.name ~= data.job or not PlayerJob.isboss then CLNotify(Config.Language.Notifications.NoAccess, 'error') return end setBusy(true) local cash = lib.callback.await('lusty94_bossmenu:server:getPlayerCash', false) if cash <= 0 then setBusy(false) CLNotify(Config.Language.Notifications.NoCash, 'error') return end local cashSymbol = Config.CoreSettings.Banking.CashSymbol local input = lib.inputDialog('Nakit Yatır', { { type = 'input', placeholder = 'Nakit: \n'..cashSymbol..math.floor(cash), disabled = true, }, { type = 'number', label = 'Ne kadar yatırmak istiyorsunuz?', min = 1, max = cash, default = 1, } }) if not input then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local amount = tonumber(input[2]) CLDebug('^3| Lusty94_BossMenu | DEBUG | INFO | Player chose to deposit: '..amount..' to job: '..data.job..'^7') if amount and amount > 0 then local coords = GetEntityCoords(PlayerPedId()) TriggerServerEvent('lusty94_bossmenu:server:DepositMoney', data.job, amount, coords) setBusy(false) end setBusy(false) end) --give employee bonus RegisterNetEvent('lusty94_bossmenu:client:GiveBonus', function(data) if PlayerJob.name ~= data.job or not PlayerJob.isboss then CLNotify(Config.Language.Notifications.NoAccess, 'error') return end setBusy(true) local cash = lib.callback.await('lusty94_bossmenu:server:getJobBank', false, data.job) if cash <= 0 then setBusy(false) CLNotify(Config.Language.Notifications.NoCash, 'error') return end local input = lib.inputDialog('Çalışana Prim Ver', { { type = 'input', placeholder = 'şirket Fonu: \n'..CashSymbol..math.floor(cash), disabled = true, }, { type = 'input', label = 'Kim prim alacak?', placeholder = 'Çalışanın Sunucu ID\'si', required = true, }, { type = 'number', label = 'Ne kadar vermek istiyorsunuz?', min = 1, max = cash, default = 1, required = true, }, }) if not input then setBusy(false) CLNotify(Config.Language.Notifications.Cancelled, 'error') return end local amount = tonumber(input[3]) local who = tonumber(input[2]) if amount and amount > 0 then local coords = GetEntityCoords(PlayerPedId()) TriggerServerEvent('lusty94_bossmenu:server:GiveBonus', data.job, amount, who, coords) setBusy(false) end setBusy(false) end) --open boss stash RegisterNetEvent('lusty94_bossmenu:client:OpenBossStash', function(jobName) if not jobName or not Config.Locations[jobName] or not Config.Locations[jobName].stash then return end local stashID = jobName .. '_Management_Stash' local stashData = Config.Locations[jobName].stash local coords = GetEntityCoords(PlayerPedId()) if InvType == 'qb' then TriggerServerEvent('lusty94_bossmenu:server:OpenBossStash',jobName, stashID, stashData, coords) elseif InvType == 'ox' then exports.ox_inventory:openInventory('stash', stashID) elseif InvType == 'custom' then --insert your own logic for adding items here else print('^1| Lusty94_BossMenu | DEBUG | ERROR | Unknown inventory type set in Config.CoreSettings.Inventory.Type | '..tostring(InvType)) end end) --send a message RegisterNetEvent('lusty94_bossmenu:client:SendMessage', function(data) local input = lib.inputDialog('Bossa Mesaj Gönder', { { type = 'textarea', label = 'Mesajınız', required = true, icon = 'fa-solid fa-pen-to-sqaure', } }) if not input or not input[1] or input[1]:len() < 3 then CLNotify(Config.Language.Notifications.InvalidMessage, 'error') return end local char = QBCore.Functions.GetPlayerData().charinfo local senderName = ("%s %s"):format(char.firstname, char.lastname) TriggerServerEvent('lusty94_bossmenu:server:SaveMessage', data.job, senderName, input[1]) end) --read messages RegisterNetEvent('lusty94_bossmenu:client:ReadMessages', function(messages) if not messages or #messages == 0 then CLNotify('Mesaj bulunamadı.', 'error') return end local options = {} for _, msg in ipairs(messages) do options[#options+1] = { title = msg.sender_name, description = msg.message .. (msg.boss_reply and ("\n\nBoss Yanıtı: " .. msg.boss_reply) or ""), icon = 'fa-solid fa-comment-dots', onSelect = function() local contextOptions = {} if not msg.boss_reply then contextOptions[#contextOptions+1] = { title = 'Mesajı Yanıtla', icon = 'fa-solid fa-reply', onSelect = function() local reply = lib.inputDialog(msg.sender_name..' Adlına Yanıtla', { { type = 'textarea', label = 'Yanıt Mesajı', required = true } }) if reply and reply[1] then TriggerServerEvent('lusty94_bossmenu:server:ReplyToMessage', msg.id, reply[1]) end end } end contextOptions[#contextOptions+1] = { title = 'Mesajı Sil', icon = 'fa-solid fa-trash', onSelect = function() local confirm = lib.alertDialog({ header = 'Mesajı Sil', content = 'Bu mesajı silmek istediğinize emin misiniz?', centered = true, cancel = true }) if confirm == 'confirm' then TriggerServerEvent('lusty94_bossmenu:server:DeleteReply', msg.id) end end } lib.registerContext({ id = 'boss_message_action_' .. msg.id, title = 'Mesaj Seçenekleri', options = contextOptions }) lib.showContext('boss_message_action_' .. msg.id) end } end table.insert(options, { title = 'Tüm Mesajları Temizle', icon = 'fa-solid fa-trash', onSelect = function() TriggerServerEvent('lusty94_bossmenu:server:ClearMessages', PlayerJob.name) end }) lib.registerContext({ id = 'boss_message_menu', title = 'Çalışan Mesajları', options = options, }) lib.showContext('boss_message_menu') end) --get replies RegisterNetEvent('lusty94_bossmenu:client:RequestReplies', function(data) TriggerServerEvent('lusty94_bossmenu:server:RequestReplies', data.job) end) --view replies RegisterNetEvent('lusty94_bossmenu:client:ViewReplies', function(messages) if not messages or #messages == 0 then CLNotify(Config.Language.Notifications.NoReplies, 'error') return end local options = {} for _, msg in pairs(messages) do options[#options+1] = { title = msg.sender_name, description = "Siz dediniz ki:\n" .. msg.message .. "\n\nBoss yanıtladı:\n" .. msg.boss_reply, icon = 'fa-solid fa-envelope-open-text', onSelect = function() local confirm = lib.alertDialog({ header = 'Yanıt Silinsin mi?', content = 'Bu yanıtı silmek istediğinize emin misiniz?', centered = true, cancel = true }) if confirm == 'confirm' then TriggerServerEvent('lusty94_bossmenu:server:DeleteReply', msg.id) end end } end lib.registerContext({ id = 'boss_reply_menu', title = 'Boss Yanıtları', options = options, }) lib.showContext('boss_reply_menu') end) --toggle duty RegisterNetEvent('lusty94_bossmenu:client:ToggleDuty', function() if PlayerJob.onduty then TriggerServerEvent('QBCore:ToggleDuty') else TriggerServerEvent('QBCore:ToggleDuty') end CLNotify('Mesai Durumu Değiştirildi', 'success') end) --cl notify RegisterNetEvent('lusty94_bossmenu:client:notify', function(msg, type, time) CLNotify(msg, type, time) end) --reset flags RegisterNetEvent('lusty94_bossmenu:client:toggleStatus', function() setBusy(false) end) --job update RegisterNetEvent('QBCore:Client:OnJobUpdate', function(job) PlayerJob = job SetBlips() end) --player loaded RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() PlayerJob = QBCore.Functions.GetPlayerData().job SetBlips() end) --clean up AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then for _, blip in ipairs(JobBlips) do RemoveBlip(blip) end JobBlips = {} for _, zone in pairs(SpawnedZones) do if zone.type == 'qb' then exports['qb-target']:RemoveZone(zone.name) elseif zone.type == 'ox' then exports['ox_target']:removeZone(zone.id) elseif zone.type == 'custom' then --insert your own logic here to remove target zones end end SpawnedZones = {} end end)