Skip to content

Commit

Permalink
đŸ“» [v1.0.0] Latest stable
Browse files Browse the repository at this point in the history
  • Loading branch information
imkuroneko authored Apr 21, 2024
1 parent 5c51b67 commit e088349
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 0 deletions.
193 changes: 193 additions & 0 deletions client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
lib.locale()
local QBCore = exports['qb-core']:GetCoreObject()

RadioProp = nil
CurrentChannel = 0
RadioVolume = Config.defaultVolume

-- ===== Bind
if Config.bindRadioMenu ~= nil and Config.bindRadioMenu ~= '' then
local keybind = lib.addKeybind({
name = 'NekoRadioMenĂș',
description = locale('bind_description'),
defaultKey = Config.bindRadioMenu,
onPressed = function(self) TriggerEvent('neko_radio:client:open_radio_menu') end,
})
keybind:disable(false)
end

-- ===== Events
RegisterNetEvent('neko_radio:client:open_radio_menu')
AddEventHandler('neko_radio:client:open_radio_menu', function()
ToggleRadio()
end)

RegisterNetEvent('neko_radio:client:disconnect')
AddEventHandler('neko_radio:client:disconnect', function()
SetRadioChannel(0, false)
ToggleRadioAnimation(false)
CurrentChannel = 0
end)

RegisterNetEvent('neko_radio:client:set_frequency')
AddEventHandler('neko_radio:client:set_frequency', function()
local input = lib.inputDialog(locale('radio_label'), {
{
type = 'number',
icon = { 'fas', 'radio' },
required = true,
label = locale('set_frequency_label'),
min = Config.minFrequency,
max = Config.maxFrequency,
}
})

if not input then return end

local frequency = input[1]

if frequency > Config.maxFrequency or frequency < Config.minFrequency then
return lib.notify({ description = locale('error_frequency_not_available'), type = 'error' })
else
local player = QBCore.Functions.GetPlayerData()

if Config.restrictedForJobs[frequency] ~= nil then
HasRequiredJob = false

for key, type in pairs(Config.restrictedForJobs[frequency]) do
if player.job.type and player.job.type == type then HasRequiredJob = true end
end

if HasRequiredJob then
if not player.job.onduty then
return lib.notify({ description = locale('error_player_not_on_duty'), type = 'error' })
end

SetRadioChannel(frequency, true)
CurrentChannel = frequency
ToggleRadioAnimation(false)
return lib.notify({ description = locale('frequency_updated', frequency), type = 'success' })
else
return lib.notify({ description = locale('error_reserved_frequency'), type = 'info' })
end
else
SetRadioChannel(frequency, true)
CurrentChannel = frequency
ToggleRadioAnimation(false)
return lib.notify({ description = locale('frequency_updated', frequency), type = 'success' })
end
end
end)

RegisterNetEvent('neko_radio:client:change_volume')
AddEventHandler('neko_radio:client:change_volume', function()
if CurrentChannel == 0 then
local input = lib.inputDialog(locale('radio_label'), {
{
type = 'number',
icon = { 'fas', 'volume-high' },
required = true,
label = locale('set_volume_label'),
min = 1,
max = 100,
default = RadioVolume,
}
})

if not input then return end

local volume = input[0]
RadioVolume = volume

ToggleRadio()
exports['pma-voice']:setRadioVolume(RadioVolume)

return lib.notify({ description = locale('volume_updated'), type = 'success' })
else
return lib.notify({ description = locale('info_radio_off_volume'), type = 'info' })
end
end)

RegisterNetEvent('neko_radio:client:build_menu')
AddEventHandler('neko_radio:client:build_menu', function()
local channDescription = ''
local titleCloseMenu = ''
local disableVolume = false
if CurrentChannel == 0 then
channDescription = locale('channel_description_off')
titleCloseMenu = locale('mainmenu_save')
disableVolume = true
else
titleCloseMenu = locale('mainmenu_turn_off')
channDescription = locale('channel_description_on', CurrentChannel)
end

lib.registerContext({
id = 'radio_menu',
title = locale('radio_label'),
onExit = function() ToggleRadioAnimation(false) end,
options = {
{
title = locale('mainmenu_frequency'),
description = channDescription,
icon = 'fa-solid fa-walkie-talkie',
arrow = true,
event = 'neko_radio:client:set_frequency',
},
{
title = locale('mainmenu_volume'),
description = locale('volume_description', RadioVolume..'%'),
icon = 'fa-solid fa-volume-high',
arrow = true,
event = 'neko_radio:client:change_volume',
disabled = disableVolume,
},
{
title = titleCloseMenu,
icon = 'fa-solid fa-right-from-bracket',
arrow = false,
event = 'neko_radio:client:disconnect',
}
}
})
lib.showContext('radio_menu')
end)

-- ===== Functions
function ToggleRadioAnimation(state)
lib.requestAnimDict('cellphone@')
if state then
TriggerEvent("attachItemRadio","radio01")
TaskPlayAnim(PlayerPedId(), "cellphone@", "cellphone_text_read_base", 2.0, 3.0, -1, 49, 0, 0, 0, 0)
RadioProp = CreateObject(`prop_cs_hand_radio`, 1.0, 1.0, 1.0, 1, 1, 0)
AttachEntityToEntity(RadioProp, PlayerPedId(), GetPedBoneIndex(PlayerPedId(), 57005), 0.14, 0.01, -0.02, 110.0, 120.0, -15.0, 1, 0, 0, 0, 2, 1)
else
StopAnimTask(PlayerPedId(), "cellphone@", "cellphone_text_read_base", 1.0)
ClearPedTasks(PlayerPedId())
DeleteObject(RadioProp)
RadioProp = 0
end
end

function ToggleRadio()
local hasItem = lib.callback.await('neko_radio:server:verify_has_item', false)

if not hasItem then
return lib.notify({ description = locale('radio_needs_item'), type = 'error' })
else
ToggleRadioAnimation(false)
ToggleRadioAnimation(true)

TriggerEvent('neko_radio:client:build_menu')
end
end

function SetRadioChannel(channel, events)
if channel == nil then channel = 0 end
if channel == 0 then
exports["pma-voice"]:removePlayerFromRadio()
end
exports['pma-voice']:setVoiceProperty('radioEnabled', events)
exports['pma-voice']:setVoiceProperty('micClicks', events)
exports["pma-voice"]:SetRadioChannel(channel)
end
47 changes: 47 additions & 0 deletions config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Config = {}

Config.requireItem = true -- utilizar item para el sistema de radio?
Config.itemName = { -- se necesita uno de estos items para acceder a la radio
'radio'
}

Config.bindRadioMenu = 'F10'
-- Config.bindRadioMenu = 'F10' -- se podrĂĄ acceder al menĂș de la radio desde esta tecla
-- Config.bindRadioMenu = nil -- al definir 'nil' see deshabilitarĂĄ el bindeo


Config.defaultVolume = 50 -- volumen default para la radio

Config.minFrequency = 1 -- nĂșmero mĂ­nimo de frecuencia
Config.maxFrequency = 1000 -- nĂșmero mĂĄximo de frecuencia


-- estos canales, estarĂĄn disponibles Ășnicamente para estos tipos de facciones
-- los jobs deberĂĄn contar con el parĂĄmetro type para este control
Config.restrictedForJobs = {
[1] = { 'leo' },
[2] = { 'leo' },
[3] = { 'leo' },
[4] = { 'leo' },
[5] = { 'leo' },
[6] = { 'leo' },
[7] = { 'leo' },
[8] = { 'leo' },
[9] = { 'leo' },
[10] = { 'leo' },
[11] = { 'ems' },
[12] = { 'ems' },
[13] = { 'ems' },
[14] = { 'ems' },
[15] = { 'ems' },
[16] = { 'ems' },
[17] = { 'ems' },
[18] = { 'ems' },
[19] = { 'ems' },
[20] = { 'ems' },
[21] = { 'leo', 'ems' },
[22] = { 'leo', 'ems' },
[23] = { 'leo', 'ems' },
[24] = { 'leo', 'ems' },
[25] = { 'leo', 'ems' },
}
16 changes: 16 additions & 0 deletions fxmanifest.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
-- ===========================================================
description 'Sistemas de radio'
author 'KuroNeko'
-- ===========================================================
version '1.0.0'

-- ===========================================================
shared_scripts { '@ox_lib/init.lua', 'config.lua' }
server_scripts { 'server.lua' }
client_scripts { 'client.lua' }
dependency { 'ox_lib', 'ox_inventory', 'pma-voice' }

files { 'locales/*.json' }
20 changes: 20 additions & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"radio_needs_item" : "You need to buy a radio...",
"bind_description" : "Open the radio menu",
"radio_label" : "Radio",
"set_frequency_label" : "Frequency",
"set_volume_label" : "Volume",
"error_reserved_frequency" : "This frequency is reserved",
"error_frequency_not_available" : "Frequency not available",
"error_player_not_on_duty" : "You are not on duty to access this frequency",
"frequency_updated" : "Frequency set to channel %s",
"volume_updated" : "Volume updated",
"info_radio_off_volume" : "You need to be on a channel first to adjust the radio volume",
"mainmenu_frequency" : "Frequency",
"mainmenu_volume" : "Volume",
"mainmenu_turn_off" : "Turn off the radio",
"mainmenu_save" : "Save the radio",
"channel_description_off" : "You are not on a frequency",
"channel_description_on" : "You are on frequency %s",
"volume_description" : "The volume is at %s"
}
20 changes: 20 additions & 0 deletions locales/es.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"radio_needs_item" : "Necesitas comprar una radio...",
"bind_description" : "Abrir el menĂș de la radio",
"radio_label" : "Radio",
"set_frequency_label" : "Frecuencia",
"set_volume_label" : "Volumen",
"error_reserved_frequency" : "Esta frecuencia se encuentra reservada",
"error_frequency_not_available" : "Frecuencia no disponible",
"error_player_not_on_duty" : "No te encuentras en servicio para acceder a esta frecuencia",
"frequency_updated" : "Frecuencia establecida al canal %s",
"volume_updated" : "Volumen actualizado",
"info_radio_off_volume" : "Debes estar en un canal primero para ajustar el volumen de la radio",
"mainmenu_frequency" : "Frecuencia",
"mainmenu_volume" : "Volumen",
"mainmenu_turn_off" : "Apagar la radio",
"mainmenu_save" : "Guardar la radio",
"channel_description_off" : "No te encuentras en una frecuencia",
"channel_description_on" : "Te encuentras en la frecuencia %s",
"volume_description" : "El volumen estĂĄ al %s"
}
20 changes: 20 additions & 0 deletions locales/pt-BR.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"radio_needs_item": "VocĂȘ precisa comprar um rĂĄdio...",
"bind_description": "Abrir o menu do rĂĄdio",
"radio_label": "RĂĄdio",
"set_frequency_label": "FrequĂȘncia",
"set_volume_label": "Volume",
"error_reserved_frequency": "Essa frequĂȘncia estĂĄ reservada",
"error_frequency_not_available": "FrequĂȘncia indisponĂ­vel",
"error_player_not_on_duty": "VocĂȘ nĂŁo estĂĄ de serviço para acessar essa frequĂȘncia",
"frequency_updated": "FrequĂȘncia ajustada para o canal %s",
"volume_updated": "Volume atualizado",
"info_radio_off_volume": "VocĂȘ precisa estar em um canal primeiro para ajustar o volume do rĂĄdio",
"mainmenu_frequency": "FrequĂȘncia",
"mainmenu_volume": "Volume",
"mainmenu_turn_off": "Desligar o rĂĄdio",
"mainmenu_save": "Salvar o rĂĄdio",
"channel_description_off": "VocĂȘ nĂŁo estĂĄ em uma frequĂȘncia",
"channel_description_on": "VocĂȘ estĂĄ na frequĂȘncia %s",
"volume_description": "O volume estĂĄ em %s"
}
26 changes: 26 additions & 0 deletions server.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
lib.locale()
local QBCore = exports['qb-core']:GetCoreObject()
local ox_inventory = exports.ox_inventory

if Config.requireItem then
for key, item in pairs(Config.itemName) do
QBCore.Functions.CreateUseableItem(item, function(source)
TriggerClientEvent('neko_radio:client:open_radio_menu', source)
end)
end
end

lib.callback.register('neko_radio:server:verify_has_item', function(source, cb)
if Config.requireItem then
local hasItem = false
for key, item in pairs(Config.itemName) do
local items = ox_inventory:Search(source, 'count', { item })
if items and items > 0 then
hasItem = true
end
end
return hasItem
else
return true
end
end)

0 comments on commit e088349

Please sign in to comment.