local Radio = {
	Has = true,
	Open = false,
	On = false,
	Enabled = true,
	Handle = nil,
	Prop = GetHashKey('prop_cs_hand_radio'), -- only ran once and doesn't break my syntax viewer
	Bone = 28422,
	Offset = vector3(0.0, 0.0, 0.0),
	Rotation = vector3(0.0, 0.0, 0.0),
	Dictionary = {
		"cellphone@",
		"cellphone@in_car@ds",
		"cellphone@str",
		"random@arrests",
	},
	Animation = {
		"cellphone_text_in",
		"cellphone_text_out",
		"cellphone_call_listen_a",
		"generic_radio_chatter",
	},
	Clicks = true, -- Radio clicks
}
Radio.Labels = {
	{ "FRZL_RADIO_HELP", "~s~" .. (radioConfig.Controls.Secondary.Enabled and "~" .. radioConfig.Controls.Secondary.Name .. "~ + ~" .. radioConfig.Controls.Activator.Name .. "~" or "~" .. radioConfig.Controls.Activator.Name .. "~") .. " to hide.~n~~" .. radioConfig.Controls.Toggle.Name .. "~ to turn radio ~g~on~s~.~n~~" .. radioConfig.Controls.Decrease.Name .. "~ or ~" .. radioConfig.Controls.Increase.Name .. "~ to switch frequency~n~~" .. radioConfig.Controls.Input.Name .. "~ to choose frequency~n~~" .. radioConfig.Controls.ToggleClicks.Name .. "~ to ~a~ mic clicks~n~Frequency: ~1~ MHz" },
	{ "FRZL_RADIO_HELP2", "~s~" .. (radioConfig.Controls.Secondary.Enabled and "~" .. radioConfig.Controls.Secondary.Name .. "~ + ~" .. radioConfig.Controls.Activator.Name .. "~" or "~" .. radioConfig.Controls.Activator.Name .. "~") .. " to hide.~n~~" .. radioConfig.Controls.Toggle.Name .. "~ to turn radio ~r~off~s~.~n~~" .. radioConfig.Controls.Broadcast.Name .. "~ to broadcast.~n~Frequency: ~1~ MHz" },
	{ "FRZL_RADIO_INPUT", "Enter Frequency" },
}
local unarmed = GetHashKey('weapon_unarmed')
Radio.Commands = {
	{
		Enabled = true, -- Add a command to be able to open/close the radio
		Name = "radio", -- Command name
		Help = "Toggle hand radio", -- Command help shown in chatbox when typing the command
		Params = {},
		Handler = function(src, args, raw)
			local playerPed = PlayerPedId()
			local isFalling = IsPedFalling(playerPed)
			local isDead = IsEntityDead(playerPed)

			if not isFalling and Radio.Enabled and Radio.Has and not isDead then
				Radio:Toggle(not Radio.Open)
			elseif (Radio.Open or Radio.On) and ((not Radio.Enabled) or (not Radio.Has) or isDead) then
				Radio:Toggle(false)
				Radio.On = false
				Radio:Remove()
				exports["pma-voice"]:setVoiceProperty("radioEnabled", false)
			elseif Radio.Open and isFalling then
				Radio:Toggle(false)
			end
		end,
	},
	{
		Enabled = true, -- Add a command to choose radio frequency
		Name = "frequency", -- Command name
		Help = "Change radio frequency", -- Command help shown in chatbox when typing the command
		Params = {
			{name = "number", "Enter frequency"}
		},
		Handler = function(src, args, raw)
			if Radio.Has then
				if args[1] then
					local newFrequency = tonumber(args[1])
					if newFrequency then
						local minFrequency = radioConfig.Frequency.List[1]
						if newFrequency >= minFrequency and newFrequency <= radioConfig.Frequency.List[#radioConfig.Frequency.List] and newFrequency == math.floor(newFrequency) then
							if not radioConfig.Frequency.Private[newFrequency] or radioConfig.Frequency.Access[newFrequency] then
								local idx = nil

								for i = 1, #radioConfig.Frequency.List do
									if radioConfig.Frequency.List[i] == newFrequency then
										idx = i
										break
									end
								end

								if idx ~= nil then
									if Radio.Enabled then
										Radio:Remove()
									end

									radioConfig.Frequency.CurrentIndex = idx
									radioConfig.Frequency.Current = newFrequency

									if Radio.On then
										Radio:Add(radioConfig.Frequency.Current)
									end
								end
							end
						end
					end
				end
			end
		end,
	},
}

-- Setup each radio command if enabled
for i = 1, #Radio.Commands do
	if Radio.Commands[i].Enabled then
		RegisterCommand(Radio.Commands[i].Name, Radio.Commands[i].Handler, false)
		TriggerEvent("chat:addSuggestion", "/" .. Radio.Commands[i].Name, Radio.Commands[i].Help, Radio.Commands[i].Params)
	end
end

-- Create/Destroy handheld radio object
function Radio:Toggle(toggle)
	local playerPed = PlayerPedId()
	local count = 0

	if not self.Has or IsEntityDead(playerPed) then
		self.Open = false

		DetachEntity(self.Handle, true, false)
		DeleteEntity(self.Handle)

		return
	end

	if self.Open == toggle then
		return
	end

	self.Open = toggle

	if self.On and not radioConfig.AllowRadioWhenClosed then
		exports["pma-voice"]:setVoiceProperty("radioEnabled", toggle)
	end

	local dictionaryType = 1 + (IsPedInAnyVehicle(playerPed, false) and 1 or 0)
	local animationType = 1 + (self.Open and 0 or 1)
	local dictionary = self.Dictionary[dictionaryType]
	local animation = self.Animation[animationType]

	RequestAnimDict(dictionary)

	while not HasAnimDictLoaded(dictionary) do
		Citizen.Wait(150)
	end

	if self.Open then
		RequestModel(self.Prop)

		while not HasModelLoaded(self.Prop) do
			Citizen.Wait(150)
		end

		self.Handle = CreateObject(self.Prop, 0.0, 0.0, 0.0, true, true, false)

		local bone = GetPedBoneIndex(playerPed, self.Bone)

		SetCurrentPedWeapon(playerPed, unarmed, true)
		AttachEntityToEntity(self.Handle, playerPed, bone, self.Offset.x, self.Offset.y, self.Offset.z, self.Rotation.x, self.Rotation.y, self.Rotation.z, true, false, false, false, 2, true)

		SetModelAsNoLongerNeeded(self.Handle)

		TaskPlayAnim(playerPed, dictionary, animation, 4.0, -1, -1, 50, 0, false, false, false)
	else
		TaskPlayAnim(playerPed, dictionary, animation, 4.0, -1, -1, 50, 0, false, false, false)

		Citizen.Wait(700)

		StopAnimTask(playerPed, dictionary, animation, 1.0)

		NetworkRequestControlOfEntity(self.Handle)

		while not NetworkHasControlOfEntity(self.Handle) and count < 5000 do
			Citizen.Wait(0)
			count = count + 1
		end

		DetachEntity(self.Handle, true, false)
		DeleteEntity(self.Handle)
	end
end

-- Add player to radio channel
function Radio:Add(id)
	exports["pma-voice"]:setRadioChannel(id)
end

-- Remove player from radio channel
function Radio:Remove()
	exports["pma-voice"]:setRadioChannel(0)
end

-- Increase radio frequency
function Radio:Decrease()
	if self.On then
		if radioConfig.Frequency.CurrentIndex - 1 < 1 and radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex] == radioConfig.Frequency.Current then
			self:Remove(radioConfig.Frequency.Current)
			radioConfig.Frequency.CurrentIndex = #radioConfig.Frequency.List
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
			self:Add(radioConfig.Frequency.Current)
		elseif radioConfig.Frequency.CurrentIndex - 1 < 1 and radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex] ~= radioConfig.Frequency.Current then
			self:Remove(radioConfig.Frequency.Current)
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
			self:Add(radioConfig.Frequency.Current)
		else
			self:Remove(radioConfig.Frequency.Current)
			radioConfig.Frequency.CurrentIndex = radioConfig.Frequency.CurrentIndex - 1
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
			self:Add(radioConfig.Frequency.Current)
		end
	else
		if radioConfig.Frequency.CurrentIndex - 1 < 1 and radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex] == radioConfig.Frequency.Current then
			radioConfig.Frequency.CurrentIndex = #radioConfig.Frequency.List
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
		elseif radioConfig.Frequency.CurrentIndex - 1 < 1 and radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex] ~= radioConfig.Frequency.Current then
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
		else
			radioConfig.Frequency.CurrentIndex = radioConfig.Frequency.CurrentIndex - 1

			if radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex] == radioConfig.Frequency.Current then
				radioConfig.Frequency.CurrentIndex = radioConfig.Frequency.CurrentIndex - 1
			end

			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
		end
	end
end

-- Decrease radio frequency
function Radio:Increase()
	if self.On then
		if radioConfig.Frequency.CurrentIndex + 1 > #radioConfig.Frequency.List then
			self:Remove(radioConfig.Frequency.Current)
			radioConfig.Frequency.CurrentIndex = 1
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
			self:Add(radioConfig.Frequency.Current)
		else
			self:Remove(radioConfig.Frequency.Current)
			radioConfig.Frequency.CurrentIndex = radioConfig.Frequency.CurrentIndex + 1
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
			self:Add(radioConfig.Frequency.Current)
		end
	else
		if #radioConfig.Frequency.List == radioConfig.Frequency.CurrentIndex + 1 then
			if radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex + 1] == radioConfig.Frequency.Current then
				radioConfig.Frequency.CurrentIndex = radioConfig.Frequency.CurrentIndex + 1
			end
		end

		if radioConfig.Frequency.CurrentIndex + 1 > #radioConfig.Frequency.List then
			radioConfig.Frequency.CurrentIndex = 1
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
		else
			radioConfig.Frequency.CurrentIndex = radioConfig.Frequency.CurrentIndex + 1
			radioConfig.Frequency.Current = radioConfig.Frequency.List[radioConfig.Frequency.CurrentIndex]
		end
	end
end

-- Generate list of available frequencies
function GenerateFrequencyList()
	radioConfig.Frequency.List = {}

	for i = radioConfig.Frequency.Min, radioConfig.Frequency.Max do
		if not radioConfig.Frequency.Private[i] or radioConfig.Frequency.Access[i] then
			radioConfig.Frequency.List[#radioConfig.Frequency.List + 1] = i
		end
	end
end

-- Check if radio is open
function IsRadioOpen()
	return Radio.Open
end

-- Check if radio is switched on
function IsRadioOn()
	return Radio.On
end

-- Check if player has radio
function IsRadioAvailable()
	return Radio.Has
end

-- Check if radio is enabled or not
function IsRadioEnabled()
	return not Radio.Enabled
end

-- Check if radio can be used
function CanRadioBeUsed()
	return Radio.Has and Radio.On and Radio.Enabled
end

-- Set if the radio is enabled or not
function SetRadioEnabled(value)
	if type(value) == "string" then
		value = value == "true"
	elseif type(value) == "number" then
		value = value == 1
	end

	Radio.Enabled = value and true or false
end

-- Set if player has a radio or not
function SetRadio(value)
	if type(value) == "string" then
		value = value == "true"
	elseif type(value) == "number" then
		value = value == 1
	end

	Radio.Has = value and true or false
end

-- Set if player has access to use the radio when closed
function SetAllowRadioWhenClosed(value)
	radioConfig.AllowRadioWhenClosed = value

	if Radio.On and not Radio.Open and radioConfig.AllowRadioWhenClosed then
		exports["pma-voice"]:setVoiceProperty("radioEnabled", true)
	end
end

-- Add new frequency
function AddPrivateFrequency(value)
	local frequency = tonumber(value)

	if frequency ~= nil then
		if not radioConfig.Frequency.Private[frequency] then -- Only add new frequencies
			radioConfig.Frequency.Private[frequency] = true

			GenerateFrequencyList()
		end
	end
end

-- Remove private frequency
function RemovePrivateFrequency(value)
	local frequency = tonumber(value)

	if frequency ~= nil then
		if radioConfig.Frequency.Private[frequency] then -- Only remove existing frequencies
			radioConfig.Frequency.Private[frequency] = nil

			GenerateFrequencyList()
		end
	end
end

-- Give access to a frequency
function GivePlayerAccessToFrequency(value)
	local frequency = tonumber(value)

	if frequency ~= nil then
		if radioConfig.Frequency.Private[frequency] then -- Check if frequency exists
			if not radioConfig.Frequency.Access[frequency] then -- Only add new frequencies
				radioConfig.Frequency.Access[frequency] = true

				GenerateFrequencyList()
		end
		end
	end
end

-- Remove access to a frequency
function RemovePlayerAccessToFrequency(value)
	local frequency = tonumber(value)

	if frequency ~= nil then
		if radioConfig.Frequency.Access[frequency] then -- Check if player has access to frequency
			radioConfig.Frequency.Access[frequency] = nil

			GenerateFrequencyList()
		end
	end
end

-- Give access to multiple frequencies
function GivePlayerAccessToFrequencies(...)
	local frequencies = { ... }
	local newFrequencies = {}

	for i = 1, #frequencies do
		local frequency = tonumber(frequencies[i])

		if frequency ~= nil then
			if radioConfig.Frequency.Private[frequency] then -- Check if frequency exists
				if not radioConfig.Frequency.Access[frequency] then -- Only add new frequencies
					newFrequencies[#newFrequencies + 1] = frequency
			end
			end
		end
	end

	if #newFrequencies > 0 then
		for i = 1, #newFrequencies do
			radioConfig.Frequency.Access[newFrequencies[i]] = true
		end

		GenerateFrequencyList()
	end
end

-- Remove access to multiple frequencies
function RemovePlayerAccessToFrequencies(...)
	local frequencies = { ... }
	local removedFrequencies = {}

	for i = 1, #frequencies do
		local frequency = tonumber(frequencies[i])

		if frequency ~= nil then
			if radioConfig.Frequency.Access[frequency] then -- Check if player has access to frequency
				removedFrequencies[#removedFrequencies + 1] = frequency
			end
		end
	end

	if #removedFrequencies > 0 then
		for i = 1, #removedFrequencies do
			radioConfig.Frequency.Access[removedFrequencies[i]] = nil
		end

		GenerateFrequencyList()
	end
end

-- Define exports
exports("IsRadioOpen", IsRadioOpen)
exports("IsRadioOn", IsRadioOn)
exports("IsRadioAvailable", IsRadioAvailable)
exports("IsRadioEnabled", IsRadioEnabled)
exports("CanRadioBeUsed", CanRadioBeUsed)
exports("SetRadioEnabled", SetRadioEnabled)
exports("SetRadio", SetRadio)
exports("SetAllowRadioWhenClosed", SetAllowRadioWhenClosed)
exports("AddPrivateFrequency", AddPrivateFrequency)
exports("RemovePrivateFrequency", RemovePrivateFrequency)
exports("GivePlayerAccessToFrequency", GivePlayerAccessToFrequency)
exports("RemovePlayerAccessToFrequency", RemovePlayerAccessToFrequency)
exports("GivePlayerAccessToFrequencies", GivePlayerAccessToFrequencies)
exports("RemovePlayerAccessToFrequencies", RemovePlayerAccessToFrequencies)

local isBroadcasting = false

AddEventHandler('pma-voice:radioActive', function(broadCasting)
	isBroadcasting = broadCasting
end)

Citizen.CreateThread(function()
	-- Add Labels
	for i = 1, #Radio.Labels do
		AddTextEntry(Radio.Labels[i][1], Radio.Labels[i][2])
	end

	GenerateFrequencyList()

	while true do
		Citizen.Wait(0)
		-- Init local vars
		local playerPed = PlayerPedId()
		local isActivatorPressed = IsControlJustPressed(0, radioConfig.Controls.Activator.Key)
		local isSecondaryPressed = (radioConfig.Controls.Secondary.Enabled == false and true or IsControlPressed(0, radioConfig.Controls.Secondary.Key))
		local isFalling = IsPedFalling(playerPed)
		local isDead = IsEntityDead(playerPed)
		local minFrequency = radioConfig.Frequency.List[1]
		local broadcastType = 3 + (radioConfig.AllowRadioWhenClosed and 1 or 0) + ((Radio.Open and radioConfig.AllowRadioWhenClosed) and -1 or 0)
		local broadcastDictionary = Radio.Dictionary[broadcastType]
		local broadcastAnimation = Radio.Animation[broadcastType]
		local isPlayingBroadcastAnim = IsEntityPlayingAnim(playerPed, broadcastDictionary, broadcastAnimation, 3)

		-- Open radio settings
		if isActivatorPressed and isSecondaryPressed and not isFalling and Radio.Enabled and Radio.Has and not isDead then
			Radio:Toggle(not Radio.Open)
		elseif (Radio.Open or Radio.On) and ((not Radio.Enabled) or (not Radio.Has) or isDead) then
			Radio:Remove()
			exports["pma-voice"]:setVoiceProperty("radioEnabled", false)
			Radio:Toggle(false)
			Radio.On = false
		elseif Radio.Open and isFalling then
			Radio:Toggle(false)
		end

		-- Remove player from private frequency that they don't have access to
		if not radioConfig.Frequency.Access[radioConfig.Frequency.Current] and radioConfig.Frequency.Private[radioConfig.Frequency.Current] then
			if Radio.On then
				Radio:Remove()
			end

			radioConfig.Frequency.CurrentIndex = 1
			radioConfig.Frequency.Current = minFrequency

			if Radio.On then
				Radio:Add(radioConfig.Frequency.Current)
			end
		end

		-- Check if player is holding radio
		if Radio.Open then
			local dictionaryType = 1 + (IsPedInAnyVehicle(playerPed, false) and 1 or 0)
			local openDictionary = Radio.Dictionary[dictionaryType]
			local openAnimation = Radio.Animation[1]
			local isPlayingOpenAnim = IsEntityPlayingAnim(playerPed, openDictionary, openAnimation, 3)
			local hasWeapon, currentWeapon = GetCurrentPedWeapon(playerPed, 1)

			-- Remove weapon in hand as we are using the radio
			if currentWeapon ~= unarmed then
				SetCurrentPedWeapon(playerPed, unarmed, true)
			end

			-- Display help text
			BeginTextCommandDisplayHelp(Radio.Labels[Radio.On and 2 or 1][1])

			if not Radio.On then
				AddTextComponentSubstringPlayerName(Radio.Clicks and "~r~disable~w~" or "~g~enable~w~")
			end

			AddTextComponentInteger(radioConfig.Frequency.Current)
			EndTextCommandDisplayHelp(false, false, false, -1)

			-- Play animation if player is broadcasting to radio
			if Radio.On then
				if isBroadcasting and not isPlayingBroadcastAnim then
					RequestAnimDict(broadcastDictionary)

					while not HasAnimDictLoaded(broadcastDictionary) do
						Citizen.Wait(150)
					end

					TaskPlayAnim(playerPed, broadcastDictionary, broadcastAnimation, 8.0, -8, -1, 49, 0, 0, 0, 0)
				elseif not isBroadcasting and isPlayingBroadcastAnim then
					StopAnimTask(playerPed, broadcastDictionary, broadcastAnimation, -4.0)
				end
			end

			-- Play default animation if not broadcasting
			if not isBroadcasting and not isPlayingOpenAnim then
				RequestAnimDict(openDictionary)

				while not HasAnimDictLoaded(openDictionary) do
					Citizen.Wait(150)
				end

				TaskPlayAnim(playerPed, openDictionary, openAnimation, 4.0, -1, -1, 50, 0, false, false, false)
			end

			-- Turn radio on/off
			if IsControlJustPressed(0, radioConfig.Controls.Toggle.Key) then
				Radio.On = not Radio.On

				exports["pma-voice"]:setVoiceProperty("radioEnabled", Radio.On)

				if Radio.On then
					SendNUIMessage({ sound = "audio_on", volume = 0.3})
					Radio:Add(radioConfig.Frequency.Current)
				else
					SendNUIMessage({ sound = "audio_off", volume = 0.5})
					Radio:Remove()
				end
			end

			-- Change radio frequency
			if not Radio.On then
				DisableControlAction(0, radioConfig.Controls.ToggleClicks.Key, false)

				if not radioConfig.Controls.Decrease.Pressed then
					if IsControlJustPressed(0, radioConfig.Controls.Decrease.Key) then
						radioConfig.Controls.Decrease.Pressed = true
						Citizen.CreateThread(function()
							while IsControlPressed(0, radioConfig.Controls.Decrease.Key) do
								Radio:Decrease()
								Citizen.Wait(125)
							end

							radioConfig.Controls.Decrease.Pressed = false
						end)
					end
				end

				if not radioConfig.Controls.Increase.Pressed then
					if IsControlJustPressed(0, radioConfig.Controls.Increase.Key) then
						radioConfig.Controls.Increase.Pressed = true
						Citizen.CreateThread(function()
							while IsControlPressed(0, radioConfig.Controls.Increase.Key) do
								Radio:Increase()
								Citizen.Wait(125)
							end

							radioConfig.Controls.Increase.Pressed = false
						end)
					end
				end

				if not radioConfig.Controls.Input.Pressed then
					if IsControlJustPressed(0, radioConfig.Controls.Input.Key) then
						radioConfig.Controls.Input.Pressed = true
						Citizen.CreateThread(function()
							DisplayOnscreenKeyboard(1, Radio.Labels[3][1], "", radioConfig.Frequency.Current, "", "", "", 3)

							while UpdateOnscreenKeyboard() ~= 1 and UpdateOnscreenKeyboard() ~= 2 do
								Citizen.Wait(150)
							end

							local input = nil

							if UpdateOnscreenKeyboard() ~= 2 then
								input = GetOnscreenKeyboardResult()
							end

							Citizen.Wait(500)

							input = tonumber(input)

							if input ~= nil then
								if input >= minFrequency and input <= radioConfig.Frequency.List[#radioConfig.Frequency.List] and input == math.floor(input) then
									if not radioConfig.Frequency.Private[input] or radioConfig.Frequency.Access[input] then
										local idx = nil

										for i = 1, #radioConfig.Frequency.List do
											if radioConfig.Frequency.List[i] == input then
												idx = i
												break
											end
										end

										if idx ~= nil then
											radioConfig.Frequency.CurrentIndex = idx
											radioConfig.Frequency.Current = input
										end
									end
								end
							end

							radioConfig.Controls.Input.Pressed = false
						end)
					end
				end

				-- Turn radio mic clicks on/off
				if IsDisabledControlJustPressed(0, radioConfig.Controls.ToggleClicks.Key) then
					Radio.Clicks = not Radio.Clicks

					SendNUIMessage({ sound = "audio_off", volume = 0.5})

					exports["pma-voice"]:setVoiceProperty("micClicks", Radio.Clicks)
				end
			end
		else
			-- Play emergency services radio animation
			if radioConfig.AllowRadioWhenClosed then
				if Radio.Has and Radio.On and isBroadcasting and not isPlayingBroadcastAnim then
					RequestAnimDict(broadcastDictionary)

					while not HasAnimDictLoaded(broadcastDictionary) do
						Citizen.Wait(150)
					end

					TaskPlayAnim(playerPed, broadcastDictionary, broadcastAnimation, 8.0, 0.0, -1, 49, 0, 0, 0, 0)
				elseif not isBroadcasting and isPlayingBroadcastAnim then
					StopAnimTask(playerPed, broadcastDictionary, broadcastAnimation, -4.0)
				end
			end
		end
	end
end)

AddEventHandler("onClientResourceStart", function(resName)
	if GetCurrentResourceName() ~= resName and "pma-voice" ~= resName then
		return
	end

	exports["pma-voice"]:setVoiceProperty("radioEnabled", false) -- Disable radio control

	if Radio.Open then
		Radio:Toggle(false)
	end

	Radio.On = false
end)

RegisterNetEvent("Radio.Toggle")
AddEventHandler("Radio.Toggle", function()
	local playerPed = PlayerPedId()
	local isFalling = IsPedFalling(playerPed)
	local isDead = IsEntityDead(playerPed)

	if not isFalling and not isDead and Radio.Enabled and Radio.Has then
		Radio:Toggle(not Radio.Open)
	end
end)

RegisterNetEvent("Radio.Set")
AddEventHandler("Radio.Set", function(value)
	if type(value) == "string" then
		value = value == "true"
	elseif type(value) == "number" then
		value = value == 1
	end

	Radio.Has = value and true or false
end)
 

Ruby Online Compiler

Write, Run & Share Ruby code online using OneCompiler's Ruby online compiler for free. It's one of the robust, feature-rich online compilers for Ruby language, running on the latest version 2.3.1. Getting started with the OneCompiler's Ruby compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Ruby and start coding.

Read input from STDIN in Ruby

OneCompiler's Ruby online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Ruby program which takes name as input and prints hello message with your name.

name = gets.chomp               
print "Hello #{name}.\n" 

About Ruby

Ruby is a general purpose object oriented programming language developed by Yukihiro Matsumoto.

Key features

  • More commonly used in Rails applications.
  • Concise and simple to read and powerful too.
  • Open-source
  • Expressive features and visual appearance
  • Flexible language

Syntax help

Data types

Data typeDescriptionUsage
FixnumRepresents normal numbersx = 10
BignumRepresents big numbersx =9999999999
FloatRepresents decimal numbersx = 3.14
ComplexRepresents imaginary numbersx = 1 + 2i
RationalRepresents fractional numbersx = 1/4
BigDecimalRepresents precision decimal numbersx=1.0
HashRepresents key value pairs{"Website"=>"onecompiler","message" => "Happy learning"}

Variables

In Ruby, there is no need to explicitly declare variables to reserve memory space. When you assign a value to a variable, declaration happens automatically and a prefix is needed to indicate the following variable types.

Variable typeDescription
Local variablesScope is limited to the block of the variable initialization. Variable name must start with either _ or lowercase letter.
Class variablesClass variables belongs to whole class and can be accessible anywhere inside the class. Variable name must start with @@. They must be initialized before use.
Instance variablesInstance variables belongs to a instance of the class. They can be accessed from any instance of the class within a method. Variable name must start @
Global variablesScope is global and hence they can be accessible anywhere in the program. Variable name must start with $

Loops and conditional statements

1. If family:

If, If-else, Nested-Ifs are used when you want to perform a certain set of operations based on conditional expressions.

If

if(conditional-expression)
    #code    
end

If-else

if(conditional-expression)  
    #code if condition is true  
else   
    #code if condition is false  
end 

Nested-If-else

if(condition-expression1)   
    #code if above condition is true  
 elsif(condition-expression2)  
    #code if above condition is true  
elsif(condition-expression3)   
    #code if above condition is true  
...  
else   
    #code if all the conditions are false  
end  

2. Case:

Case is similar to Switch statement, where it is used to execute one set of a statement from multiple conditions.

case expression  
[when expression [, expression ...] [then]  
   # code ]...  
[else  
   # code ]  
end  

3. For:

For loop is used to iterate a set of statements based on a condition.

for variable in expression do   
  # code  
end

4. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while condition do   
 # code 
end  

5. Do-while:

Do-while is also used to iterate a set of statements based on a condition. It is mostly used when you need to execute the statements atleast once.

loop do   
  #code  
  break if conditional-expression  
end