Skip to content

Commit

Permalink
Merge pull request #226 from AvarianKnight/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
AvarianKnight authored Jan 12, 2022
2 parents d24a9f2 + 8932aac commit b14e1a9
Show file tree
Hide file tree
Showing 23 changed files with 6,954 additions and 7,079 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2020 Dillon Skaggs
Copyright (c) 2021 Dillon Skaggs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ You can access the state with `Player(source).state['state bag here']`
| [proximity](docs/state-getters/stateBagGetters.md) | Returns a table with the mode index, distance, and mode name | table |
| [radioChannel](docs/state-getters/stateBagGetters.md) | Returns the players current radio channel, or 0 for none | int |
| [callChannel](docs/state-getters/stateBagGetters.md) | Returns the players current call channel, or 0 for none | int |

| [voiceIntent](docs/state-getters/stateBagGetters.md) | Returns the players current voice intent, either 'speech' or 'music' | string |

###### Exports

Expand Down
4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## TODO
- [ ] Add the ability to override proximity with exports
- [ ] Rename everything that uses 'phone' to 'call' for consistency.
- [ ] Ability to display radio members on the client
- [ ] Use commands to define voiceModes in shared.lua and only leave debug logs in shared.lua
- [ ] Convert the UI to React.
- [ ] Multiple radio channels

## DONE
- [ x ] Implement a easy way to get the players current radio channel on the server
- [ x ] Implement a easy way to get the players current radio channel on the server
- [ x ] Add the ability to override proximity with exports
70 changes: 51 additions & 19 deletions client/commands.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
local wasProximityDisabledFromOverride = false
disableProximityCycle = false
RegisterCommand('setvoiceintent', function(source, args)
if GetConvarInt('voice_allowSetIntent', 1) == 1 then
local intent = args[1]
Expand All @@ -6,37 +8,67 @@ RegisterCommand('setvoiceintent', function(source, args)
elseif intent == 'music' then
MumbleSetAudioInputIntent(GetHashKey('music'))
end
LocalPlayer.state:set('voiceIntent', intent, true)
end
end)

-- TODO: Better implementation of this?
RegisterCommand('vol', function(_, args)
if not args[1] then return end
setVolume(args[1])
setVolume(tonumber(args[1]))
end)

RegisterCommand('cycleproximity', function()
if GetConvarInt('voice_enableProximity', 1) ~= 1 then return end
if playerMuted then return end

local voiceMode = mode
local newMode = voiceMode + 1
exports('setAllowProximityCycleState', function(state)
type_check({state, "boolean"})
disableProximityCycle = state
end)

voiceMode = (newMode <= #Cfg.voiceModes and newMode) or 1
local voiceModeData = Cfg.voiceModes[voiceMode]
MumbleSetTalkerProximity(voiceModeData[1] + 0.0)
mode = voiceMode
function setProximityState(proximityRange, isCustom)
local voiceModeData = Cfg.voiceModes[mode]
MumbleSetTalkerProximity(proximityRange + 0.0)
LocalPlayer.state:set('proximity', {
index = voiceMode,
distance = voiceModeData[1],
mode = voiceModeData[2],
index = mode,
distance = proximityRange,
mode = isCustom and "Custom" or voiceModeData[2],
}, true)
-- make sure we update the UI to the latest voice mode
SendNUIMessage({
voiceMode = voiceMode - 1
sendUIMessage({
-- JS expects this value to be - 1, "custom" voice is on the last index
voiceMode = isCustom and #Cfg.voiceModes or mode - 1
})
TriggerEvent('pma-voice:setTalkingMode', voiceMode)
end

exports("overrideProximityRange", function(range, disableCycle)
type_check({range, "number"})
setProximityState(range, true)
if disableCycle then
disableProximityCycle = true
wasProximityDisabledFromOverride = true
end
end)

exports("clearProximityOverride", function()
local voiceModeData = Cfg.voiceModes[mode]
setProximityState(voiceModeData[1], false)
if wasProximityDisabledFromOverride then
disableProximityCycle = false
end
end)

RegisterCommand('cycleproximity', function()
-- Proximity is either disabled, or manually overwritten.
if GetConvarInt('voice_enableProximityCycle', 1) ~= 1 or disableProximityCycle then return end
local newMode = mode + 1

-- If we're within the range of our voice modes, allow the increase, otherwise reset to the first state
if newMode <= #Cfg.voiceModes then
mode = newMode
else
mode = 1
end

setProximityState(Cfg.voiceModes[mode][1], false)
TriggerEvent('pma-voice:setTalkingMode', mode)
end, false)
if gameVersion == 'fivem' then
RegisterKeyMapping('cycleproximity', 'Cycle Proximity', 'keyboard', GetConvar('voice_defaultCycle', 'F11'))
end
end
29 changes: 16 additions & 13 deletions client/events.lua
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
AddEventHandler('mumbleConnected', function(address, isReconnecting)
logger.info('Connected to mumble server with address of %s, is this a reconnect %s', GetConvarInt('voice_hideEndpoints', 1) == 1 and 'HIDDEN' or address, isReconnecting)

logger.log('Connecting to mumble, setting targets.')
-- don't try to set channel instantly, we're still getting data.
function handleInitialState()
local voiceModeData = Cfg.voiceModes[mode]
-- sets how far the player can talk
MumbleSetAudioInputDistance(voiceModeData[1] + 0.0)
LocalPlayer.state:set('proximity', {
index = mode,
distance = voiceModeData[1],
mode = voiceModeData[2],
}, true)

MumbleSetTalkerProximity(voiceModeData[1] + 0.0)
MumbleClearVoiceTarget(voiceTarget)
MumbleSetVoiceTarget(voiceTarget)
Expand All @@ -24,6 +12,21 @@ AddEventHandler('mumbleConnected', function(address, isReconnecting)
MumbleAddVoiceTargetChannel(voiceTarget, playerServerId)

addNearbyPlayers()
end

AddEventHandler('mumbleConnected', function(address, isReconnecting)
logger.info('Connected to mumble server with address of %s, is this a reconnect %s', GetConvarInt('voice_hideEndpoints', 1) == 1 and 'HIDDEN' or address, isReconnecting)

logger.log('Connecting to mumble, setting targets.')
-- don't try to set channel instantly, we're still getting data.
local voiceModeData = Cfg.voiceModes[mode]
LocalPlayer.state:set('proximity', {
index = mode,
distance = voiceModeData[1],
mode = voiceModeData[2],
}, true)

handleInitialState()

logger.log('Finished connection logic')
end)
Expand Down
11 changes: 4 additions & 7 deletions client/init/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ AddEventHandler('onClientResourceStart', function(resource)
SetResourceKvp('pma-voice_enableMicClicks', tostring(true))
micClicks = 'true'
end
Wait(1000)
if GetConvarInt('voice_enableUi', 1) == 1 then
SendNUIMessage({
voiceModes = json.encode(Cfg.voiceModes),
voiceMode = mode - 1
})
end
sendUIMessage({
voiceModes = json.encode(Cfg.voiceModes),
voiceMode = mode - 1
}, true)
print('Script initialization finished.')
end)
8 changes: 3 additions & 5 deletions client/init/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ local volumes = {
['phone'] = tonumber(GetConvar('voice_defaultPhoneVolume', '0.6')) + 0.0,
}

radioEnabled, radioPressed, mode = false, false, Cfg.defaultProximityMode
radioEnabled, radioPressed, mode = true, false, GetConvarInt('voice_defaultVoiceMode', 2)
radioData = {}
callData = {}

Expand Down Expand Up @@ -59,9 +59,7 @@ end)
-- o_freq_lo = 348.0
-- 0_freq_hi = 4900.0


if gameVersion == 'fivem' then
-- radio submix
radioEffectId = CreateAudioSubmix('Radio')
SetAudioSubmixEffectRadioFx(radioEffectId, 0)
SetAudioSubmixEffectParamInt(radioEffectId, 0, GetHashKey('default'), 1)
Expand Down Expand Up @@ -150,7 +148,7 @@ end
---@param clickType boolean whether to play the 'on' or 'off' click.
function playMicClicks(clickType)
if micClicks ~= 'true' then return end
SendNUIMessage({
sendUIMessage({
sound = (clickType and "audio_on" or "audio_off"),
volume = (clickType and (volumes["radio"]) or 0.05)
})
Expand All @@ -176,7 +174,7 @@ exports('toggleMutePlayer', toggleMutePlayer)
function setVoiceProperty(type, value)
if type == "radioEnabled" then
radioEnabled = value
SendNUIMessage({
sendUIMessage({
radioEnabled = value
})
elseif type == "micClicks" then
Expand Down
83 changes: 69 additions & 14 deletions client/init/proximity.lua
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
-- used when muted
local disableUpdates = false
local isListenerEnabled = false
local plyCoords = GetEntityCoords(PlayerPedId())

function addNearbyPlayers()
if disableUpdates then return end
local coords = GetEntityCoords(PlayerPedId())
function orig_addProximityCheck(ply)
local tgtPed = GetPlayerPed(ply)
local voiceModeData = Cfg.voiceModes[mode]
local distance = GetConvar('voice_useNativeAudio', 'false') == 'true' and voiceModeData[1] * 3 or voiceModeData[1]

return #(plyCoords - GetEntityCoords(tgtPed)) < distance
end
local addProximityCheck = orig_addProximityCheck

exports("overrideProximityCheck", function(fn)
addProximityCheck = fn
end)

exports("resetProximityCheck", function()
addProximityCheck = orig_addProximityCheck
end)

function addNearbyPlayers()
if disableUpdates then return end
-- update here so we don't have to update every call of addProximityCheck
plyCoords = GetEntityCoords(PlayerPedId())

MumbleClearVoiceTargetChannels(voiceTarget)
local players = GetActivePlayers()
for i = 1, #players do
Expand All @@ -16,8 +33,7 @@ function addNearbyPlayers()

if serverId == playerServerId then goto skip_loop end

local ped = GetPlayerPed(ply)
if #(coords - GetEntityCoords(ped)) < distance then
if addProximityCheck(ply) then
if isTarget then goto skip_loop end

logger.verbose('Added %s as a voice target', serverId)
Expand Down Expand Up @@ -70,6 +86,7 @@ end)
-- cache talking status so we only send a nui message when its not the same as what it was before
local lastTalkingStatus = false
local lastRadioStatus = false
local voiceState = "proximity"
Citizen.CreateThread(function()
TriggerEvent('chat:addSuggestion', '/muteply', 'Mutes the player with the specified id', {
{ name = "player id", help = "the player to toggle mute" },
Expand All @@ -80,24 +97,62 @@ Citizen.CreateThread(function()
while not MumbleIsConnected() do
Wait(100)
end
-- Leave the check here as we don't want to do any of this logic
if GetConvarInt('voice_enableUi', 1) == 1 then
if lastRadioStatus ~= radioPressed or lastTalkingStatus ~= (MumbleIsPlayerTalking(PlayerId()) == 1) then
local curTalkingStatus = MumbleIsPlayerTalking(PlayerId()) == 1
if lastRadioStatus ~= radioPressed or lastTalkingStatus ~= curTalkingStatus then
lastRadioStatus = radioPressed
lastTalkingStatus = MumbleIsPlayerTalking(PlayerId()) == 1
SendNUIMessage({
lastTalkingStatus = curTalkingStatus
sendUIMessage({
usingRadio = lastRadioStatus,
talking = lastTalkingStatus
})
end
end
addNearbyPlayers()
local isSpectating = NetworkIsInSpectatorMode()
if isSpectating and not isListenerEnabled then
setSpectatorMode(true)
elseif not isSpectating and isListenerEnabled then
setSpectatorMode(false)

if voiceState == "proximity" then
addNearbyPlayers()
local isSpectating = NetworkIsInSpectatorMode()
if isSpectating and not isListenerEnabled then
setSpectatorMode(true)
elseif not isSpectating and isListenerEnabled then
setSpectatorMode(false)
end
end

Wait(GetConvarInt('voice_refreshRate', 200))
end
end)

exports("setVoiceState", function(_voiceState, channel)
if _voiceState ~= "proximity" and _voiceState ~= "channel" then
logger.error("Didn't get a proper voice state, expected proximity or channel, got %s", _voiceState)
end
voiceState = _voiceState
if voiceState == "channel" then
type_check({channel, "number"})
-- 65535 is the highest a client id can go, so we add that to the base channel so we don't manage to get onto a players channel
channel = channel + 65535
MumbleSetVoiceChannel(channel)
while MumbleGetVoiceChannelFromServerId(playerServerId) ~= channel do
Wait(250)
end
MumbleAddVoiceTargetChannel(voiceTarget, channel)
elseif voiceState == "proximity" then
handleInitialState()
end
end)


AddEventHandler("onClientResourceStop", function(resource)
if type(addProximityCheck) == "table" then
local proximityCheckRef = addProximityCheck.__cfx_functionReference
if proximityCheckRef then
local isResource = string.match(proximityCheckRef, resource)
if isResource then
addProximityCheck = orig_addProximityCheck
logger.warn('Reset proximity check to default, the original resource [%s] which provided the function restarted', resource)
end
end
end
end)
8 changes: 3 additions & 5 deletions client/module/phone.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ function setCallChannel(channel)
if GetConvarInt('voice_enablePhones', 1) ~= 1 then return end
TriggerServerEvent('pma-voice:setPlayerCall', channel)
callChannel = channel
if GetConvarInt('voice_enableUi', 1) == 1 then
SendNUIMessage({
callInfo = channel
})
end
sendUIMessage({
callInfo = channel
}, true)
createPhoneThread()
end

Expand Down
Loading

0 comments on commit b14e1a9

Please sign in to comment.