From add667ad295ed9c1b0a7fdf61779c421d3c73ee5 Mon Sep 17 00:00:00 2001 From: iseeyoucopy Date: Sun, 24 Nov 2024 16:16:39 +0000 Subject: [PATCH] New feature alert with gps coordinates - Alert with gps coordinates sending when doctor is online - updated readme - added cached for translation --- README.md | 7 +++- client/client.lua | 35 ++++++++++++++++++ configs/config.lua | 25 ++++++++++++- languages/de_lang.lua | 5 +-- languages/en_lang.lua | 5 +-- languages/fr_lang.lua | 3 +- languages/ro_lang.lua | 5 ++- locale.lua | 45 +++++++++++++++------- server/server.lua | 86 ++++++++++++++++++++++++++++++++++++++++++- version | 2 +- 10 files changed, 189 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index a15ff5f..7ef391a 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ Planned to come: Checking cause of death plus some pretty UI stuff and more! ;) - Bandages and Revive items Config - Webhook for revivals - Doctors offices for collecting equipment +- Alert with gps coordinates sending when doctor is online +- Shaman item that allows players to skip the job check +- Additional possibility to have the NPC-Doc take a percentage amount of money +- Additional possibility for the NPC-Doc to steal items and/or weapons from the player inventory after being revived ## Bleeding - Database bleed values @@ -59,4 +63,5 @@ Planned to come: Checking cause of death plus some pretty UI stuff and more! ;) - Restart server ## GitHub -- https://github.com/BryceCanyonCounty/bcc-medical \ No newline at end of file +- https://github.com/BryceCanyonCounty/bcc-medical +- Need more help? Join the bcc discord here: https://discord.gg/VrZEEpBgZJ \ No newline at end of file diff --git a/client/client.lua b/client/client.lua index ac39f66..48b5b35 100644 --- a/client/client.lua +++ b/client/client.lua @@ -623,3 +623,38 @@ AddEventHandler('onResourceStop', function(resourceName) NpcDoctor = 0 end end) + +RegisterNetEvent('bcc-medical:notify') +AddEventHandler('bcc-medical:notify', function(data) + --clientDebugPrint("Received notification: " .. data.message) + + -- Displaying the notification using VORP core method + VORPcore.NotifyLeft(data.message, "", "scoretimer_textures", "scoretimer_generic_cross", 5000) + + -- Handling blip setup + if data.x and data.y and data.z then + if globalBlip then + BccUtils.Blips:RemoveBlip(globalBlip.rawblip) -- Cleanup any existing blip + end + + globalBlip = BccUtils.Blips:SetBlip(data.blipLabel, data.blipSprite, data.blipScale, data.x, data.y, data.z) + SetTimeout(data.blipDuration, function() + BccUtils.Blips:RemoveBlip(globalBlip.rawblip) + globalBlip = nil -- Reset the global blip reference + end) + + -- GPS route setup if required + if data.useGpsRoute then + StartGpsMultiRoute(GetHashKey("COLOR_RED"), true, true) + AddPointToGpsMultiRoute(data.x, data.y, data.z) + SetGpsMultiRouteRender(true) + + -- Set a timeout to clear the GPS route after a specified duration + SetTimeout(data.gpsRouteDuration or data.blipDuration, function() + ClearGpsMultiRoute() -- This will clear the GPS route + SetGpsMultiRouteRender(false) -- Ensure it's no longer rendered on the map + --clientDebugPrint("GPS route cleared.") + end) + end + end +end) \ No newline at end of file diff --git a/configs/config.lua b/configs/config.lua index 1de6473..f1c284f 100644 --- a/configs/config.lua +++ b/configs/config.lua @@ -87,8 +87,8 @@ Config.doctors = { amount = 25, -- Currency Amount or Percentage for Revive from NPC Doctor gonegative = false, -- Can you go negative paying for NPC revival // Works only if useFixCost = true timer = 1, -- How many minutes between calls - toHospital = true, -- if true, player will be respawned to nearby hospital else will be revived on spot - RandomRemove = true, -- NPC Revive randomly takes items from the inventory. Either nothing, just items, just weapons or everything + toHospital = false, -- if true, player will be respawned to nearby hospital else will be revived on spot + RandomRemove = false, -- NPC Revive randomly takes items from the inventory. Either nothing, just items, just weapons or everything } ----------------------------------------------------- @@ -129,6 +129,27 @@ Config.MedicAssistantLocations = { NpcModel = 'CS_SDDoctor_01' } } + +Config.Alerts = true +Config.alertPermissions = { + ["medicalEmergency"] = { + allowedJobs = { + doctor = { minGrade = 1, maxGrade = 5 }, -- Doctors of grade 1 to 5 + doctorval = { minGrade = 1, maxGrade = 5 }, -- Doctors of grade 1 to 5 + doctorstraw = { minGrade = 1, maxGrade = 5 }, -- Doctors of grade 1 to 5 + doctorrho = { minGrade = 1, maxGrade = 5 }, -- Doctors of grade 1 to 5 + --nurse = {minGrade = 2, maxGrade = 5} -- Nurses of grade 2 to 5 + }, + blipSettings = { + blipLabel = "Medical Emergency", + blipSprite = 'blip_ambient_companion', -- Actual sprite name or hash + blipScale = 1.0, + blipColor = 1, + blipDuration = 60000, -- Time in milliseconds + gpsRouteDuration = 30000 -- Time in milliseconds for GPS route + } + }, +} ----------------------------------------------------- Config.BlipColors = { diff --git a/languages/de_lang.lua b/languages/de_lang.lua index 7c7a6b6..efd8eb7 100644 --- a/languages/de_lang.lua +++ b/languages/de_lang.lua @@ -25,7 +25,6 @@ Locales["de_lang"] = { you_do_not_have_job = "Du hast nicht den richtigen Job", cooldown = "Bitte warte ", Wound = "Meine Wunden: ", - PlayerMenu = 'Gesundheit', DoctorMenu = 'Doctor-Menü', quantity = "Menge: ", @@ -54,7 +53,6 @@ Locales["de_lang"] = { onYourself = ", um mich selbst zu versorgen!", notBleeding = 'Ich habe keine Blutung!', patientNotBleeding = 'Mein Patient hat keine Blutung!', - distance = "Distanz: ", meters = " Meter", tooFarFromPlayer = "Dein Patient ist zu weit weg", @@ -66,8 +64,7 @@ Locales["de_lang"] = { notEnoughMoney = "You don't have enough money, you need $", medicalAssistantTreated = "The doctor treated you and you paid $", medicalAssistantRevive = "You were revived by the doctor and you paid $", - - -- Take Items + medicalReportedMessage = "An urgent medical report has been made! Please intervene.", TakeItems1 = "Du siehst ja noch erbärmlicher aus, als ich. Aber etwas von deinem Geld will zu mir!", TakeItems2 = "Oh, schöne Sachen. Na die und dein Geld ist nun mein!", TakeItems3 = "Heute scheint dein Pechtag zu sein. All deins ist nun meins!", diff --git a/languages/en_lang.lua b/languages/en_lang.lua index 0999b05..9f89d90 100644 --- a/languages/en_lang.lua +++ b/languages/en_lang.lua @@ -36,7 +36,7 @@ Locales["en_lang"] = { revived = "You have been revived for ", notenough = "You do not have enough money!", doctoractive = "A Doctor is available, /alert instead", - doctoractive2 = "A Doctor is available, use voice instead", ----------- REMOVE + doctoractive2 = "A Doctor is available, alert has been sent", you_do_not_have_job = "You are missing the job needed", cooldown = "Please wait ", doctorBag = "Doctors Bag", @@ -64,8 +64,7 @@ Locales["en_lang"] = { notEnoughMoney = "You don't have enough money, you need $", medicalAssistantTreated = "The doctor treated you and you paid $", medicalAssistantRevive = "You were revived by the doctor and you paid $", - - -- Take Items + medicalReportedMessage = "An urgent medical report has been made! Please intervene.", TakeItems1 = "Take nothing!", TakeItems2 = "Take Items!", TakeItems3 = "Take All!", diff --git a/languages/fr_lang.lua b/languages/fr_lang.lua index f7b8b7d..92e2ee3 100644 --- a/languages/fr_lang.lua +++ b/languages/fr_lang.lua @@ -64,8 +64,7 @@ Locales["fr_lang"] = { notEnoughMoney = "You don't have enough money, you need $", medicalAssistantTreated = "The doctor treated you and you paid $", medicalAssistantRevive = "You were revived by the doctor and you paid $", - - -- Take Items Sorry, not my Language + medicalReportedMessage = "An urgent medical report has been made! Please intervene.", TakeItems1 = "Take nothing!", TakeItems2 = "Take Items!", TakeItems3 = "Take All!", diff --git a/languages/ro_lang.lua b/languages/ro_lang.lua index 98ea275..f76e02c 100644 --- a/languages/ro_lang.lua +++ b/languages/ro_lang.lua @@ -36,7 +36,7 @@ Locales["ro_lang"] = { revived = "Ai fost reinviat pentru ", notenough = "Nu ai bani indeajuns!", doctoractive = "Un doctor este disponibil, foloseste /alert in loc", - doctoractive2 = "Un doctor este disponibil, foloseste vocea in loc", + doctoractive2 = "Un doctor este disponibil, alerta a fost trimisa", you_do_not_have_job = "Iti lipseste slujba necesara", cooldown = "Te rog asteapta ", doctorBag = "Geanta doctorului", @@ -64,10 +64,11 @@ Locales["ro_lang"] = { notEnoughMoney = "Nu aveti suficienti bani, va trebuie $", medicalAssistantTreated = "Doctorul te-a tratat si ai platit $", medicalAssistantRevive = "Te-ai trezit din lesin datorita doctorului si ai platit $", - + medicalReportedMessage = "A fost raportata o urgenta medicala! Va rugam sa interveniti.", -- Take Items Sorry, not my Language TakeItems1 = "Take nothing!", TakeItems2 = "Take Items!", TakeItems3 = "Take All!", TakeItems4 = "Take Weapons!", + } diff --git a/locale.lua b/locale.lua index 425794b..ef0618e 100644 --- a/locale.lua +++ b/locale.lua @@ -1,21 +1,40 @@ Locales = {} -function _(str, ...) -- Translate string - - if Locales[Config.defaultlang] ~= nil then +local translationCache = {} -- Cache for translations - if Locales[Config.defaultlang][str] ~= nil then - return string.format(Locales[Config.defaultlang][str], ...) - else - return 'Translation [' .. Config.defaultlang .. '][' .. str .. '] does not exist' - end +function _(str, ...) -- Translate string + -- Check cache first + if translationCache[str] then + return string.format(translationCache[str], ...) + end - else - return 'Locale [' .. Config.defaultlang .. '] does not exist' - end + local lang = Config.defaultlang + local defaultLang = "en_lang" -- Set your fallback language here (e.g., 'en') + if Locales[lang] ~= nil then + if Locales[lang][str] ~= nil then + translationCache[str] = Locales[lang][str] -- Cache the translation for faster future access + if ... then + return string.format(Locales[lang][str], ...) + else + return Locales[lang][str] + end + elseif Locales[defaultLang] ~= nil and Locales[defaultLang][str] ~= nil then + if ... then + return string.format(Locales[defaultLang][str], ...) + else + return Locales[defaultLang][str] + end + else + return 'Translation [' .. lang .. '][' .. str .. '] and fallback [' .. defaultLang .. '] do not exist' + end + else + return 'Locale [' .. lang .. '] does not exist' + end end function _U(str, ...) -- Translate string first char uppercase - return tostring(_(str, ...):gsub("^%l", string.upper)) -end \ No newline at end of file + -- Use cached translation if available + local translation = _(str, ...) + return translation:sub(1, 1):upper() .. translation:sub(2) +end diff --git a/server/server.lua b/server/server.lua index f765b61..6f835b4 100644 --- a/server/server.lua +++ b/server/server.lua @@ -1,5 +1,14 @@ local VORPcore = exports.vorp_core:GetCore() +-- Helper function for debugging in DevMode +if Config.devMode then + function devPrint(message) + print("^1[DEV MODE] ^4" .. message) + end +else + function devPrint(message) end -- No-op if DevMode is disabled +end + local StaffTable = {} local TempHealed = {} @@ -54,6 +63,7 @@ RegisterNetEvent('bcc-medical:AlertJobs', function() local user = VORPcore.getUser(src) if not user then return end local docs = 0 + local pos = GetEntityCoords(GetPlayerPed(src)) if Config.synsociety then if CheckPlayer(StaffTable, MedicJobs[1]) or CheckPlayer(StaffTable, MedicJobs[2]) then VORPcore.NotifyRightTip(src, _U('doctoractive'), 4000) @@ -74,7 +84,9 @@ RegisterNetEvent('bcc-medical:AlertJobs', function() TriggerClientEvent('bcc-medical:CallNpcDoctor', src) else VORPcore.NotifyRightTip(src, _U('doctoractive2'), 4000) - --VORPcore.NotifyRightTip(src, _U('doctoractive'), 4000) -- Send /alert... needs to be added + if Config.Alerts then + AlertJob("medicalEmergency", _U('medicalReportedMessage'), { x = pos.x, y = pos.y, z = pos.z }) + end end end) @@ -497,3 +509,75 @@ function printTable(t) sub_printTable(t, " ") end end + +function CheckAlertJob(src, alertType) + local user = VORPcore.getUser(src) + if not user then + devPrint("No user found for source " .. tostring(src)) + return false + end + + local character = user.getUsedCharacter + if not character then + devPrint("No character data available for source " .. tostring(src)) + return false + end + + local alertConfig = Config.alertPermissions[alertType] + if not alertConfig then + devPrint("No alert configuration found for alert type: " .. tostring(alertType)) + return false + end + + if not character.job or not character.jobGrade then + devPrint("Job or job grade data missing for source: " .. tostring(src)) + return false + end + + -- Check job eligibility and grade within the allowed range + local jobConfig = alertConfig.allowedJobs[character.job] + if jobConfig then + local jobGrade = tonumber(character.jobGrade) + if jobGrade >= jobConfig.minGrade and jobGrade <= jobConfig.maxGrade then + return true + else + devPrint("User does not meet job grade requirements for alert type: " .. + tostring(alertType) .. " with job: " .. character.job .. " at grade: " .. character.jobGrade) + return false + end + else + devPrint("Job " .. tostring(character.job) .. " not permitted for alert type: " .. tostring(alertType)) + return false + end +end + +-- Server-side function to alert users about specific events and include location data +function AlertJob(alertType, message, coords) + local alertConfig = Config.alertPermissions[alertType] + if not alertConfig then + devPrint("Alert configuration missing for type: " .. alertType) + return + end + + local users = VORPcore.getUsers() + for _, user in pairs(users) do + if user and CheckAlertJob(user.source, alertType) then + TriggerClientEvent('bcc-medical:notify', user.source, { + message = message, + notificationType = "alert", + x = coords.x, + y = coords.y, + z = coords.z, + blipSprite = alertConfig.blipSettings.blipSprite, + blipScale = alertConfig.blipSettings.blipScale, + blipColor = alertConfig.blipSettings.blipColor, + blipLabel = alertConfig.blipSettings.blipLabel, + blipDuration = alertConfig.blipSettings.blipDuration, + gpsRouteDuration = alertConfig.blipSettings.gpsRouteDuration, --- Newly added + useGpsRoute = true + }) + else + devPrint("User does not match job requirements for " .. alertType .. ": " .. user.source) + end + end +end diff --git a/version b/version index 0171771..7db3f6e 100644 --- a/version +++ b/version @@ -1,2 +1,2 @@ -<0.5.0> +<1.0.0> See GitHub for details!