Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Improved Voice Commands Plugin #109

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions improvedvoicecommands/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright 2022 DoopieWop

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 changes: 33 additions & 0 deletions improvedvoicecommands/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Improved Voice Commands

## Description
This plugin enhances the default voice commands that come with Half-Life 2 Roleplay. It allows users to chain multiple voice commands together in one message.

## Installation
:warning: **This plugin was made for the Half-Life 2 Roleplay schema!** The plugin might not work with other schemas.
- Download the folder
- Place it into the plugins folder inside the schema.
- Set up the in-game config to your desires. You can find the config options under the plugin name.

## Features
- Chaining multiple voice commands together
- Radio support
- Dynamic sentence adaption (Experimental mode)
- Config options

## Config Options
- Experimental Mode VC
- Adapts casing of voice commands according to the rest of the sentence
- Uses punctuation mark and casing for logic
- Radio VCAllow
- Determines if voice commands can be used on the radio.
- Radio VCClient Only
- Voice command playback on receivers will only be played for every receiver clientside, as such people around them won't hear the sounds.
- Radio VCVolume
- Determines the volume of the radio playback for receivers
- Separator VC
- The separator between voice commands. Can be anything, but it's best to choose a symbol, that isn't used often. Leave it empty if you want commands to be separated by spaces. This might not always work as expected for example with the voice command "10-8 Standing By" as "10-8" on its own is a voice command.

### Developed By DoopieWop

[My Steam Profile](https://steamcommunity.com/id/doopiewop/)
5 changes: 5 additions & 0 deletions improvedvoicecommands/cl_plugin.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
netstream.Hook("PlayQueuedSound", function(entity, sounds, delay, spacing, volume, pitch)
entity = entity or LocalPlayer()

ix.util.EmitQueuedSounds(entity, sounds, delay, spacing, volume, pitch)
end)
22 changes: 22 additions & 0 deletions improvedvoicecommands/sh_plugin.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
PLUGIN.name = "Improved Voice Commands"
PLUGIN.description = "Let's users string multiple voice commands together."
PLUGIN.author = "DoopieWop"
PLUGIN.schema = "HL2 RP"
PLUGIN.license = [[
Copyright 2022 DoopieWop

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]

ix.config.Add("experimentalModeVC", false, "This won't always work as expected!!! Adjusts voice command texts to \"fit\" to the rest of the text. If the text continues after a voice command it will remove the end symbol etc.", nil, {category = PLUGIN.name})
ix.config.Add("separatorVC", "|", "Separator symbol between voice commands and text. Leave empty for using spaces as separator. (Using spaces might cause unforseen consequences, 10-8 Standing By will not be recognized, instead it will use the 10-8 voice command and then play the Standing By voice command.", nil, {category = PLUGIN.name})
ix.config.Add("radioVCAllow", true, "Allow voice commands to be used on the radio. This will playback the voice commands on all the recevers.", nil, {category = PLUGIN.name})
ix.config.Add("radioVCVolume", 60, "Sets the volume, radio voice commands are played back for receivers. This is lower than normal as it's coming through a radio.", nil, {category = PLUGIN.name, data = {min = 0, max = 200}})
ix.config.Add("radioVCClientOnly", false, "If set to true, radio voice commands receivers will hear the voice commands only clientside, so nobody around them can hear it.", nil, {category = PLUGIN.name})

ix.util.Include("cl_plugin.lua")
ix.util.Include("sv_plugin.lua")
179 changes: 179 additions & 0 deletions improvedvoicecommands/sv_plugin.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
-- I apologise for the amount of loops in all of this lol, also for the lack of comments, i tend to change my code a lot.
local PLUGIN = PLUGIN
PLUGIN.TempStored = PLUGIN.TempStored or {}

-- if no separator then just seperate at spaces
local function GetVoiceCommands(text, class, separator)
local strings = string.Explode(separator or " ", text)
local finaltable = {}
local usedkeys = {}

for k, v in ipairs(strings) do
if usedkeys[k] then continue end

v = string.Trim(v)

local info = Schema.voices.Get(class, v)

if !info then
if !separator then
local combiner
local temp = {}

for i = k, #strings do
combiner = combiner and combiner .. " " .. strings[i] or strings[i]

info = Schema.voices.Get(class, combiner)

temp[i] = true

if info then
usedkeys = temp
break
end
end
end
end
table.insert(finaltable, !info and {text = v} or table.Copy(info))
end
return finaltable
end

local function ExperimentalFormatting(stringtabl)
local carry
-- carry like in mathematical equations :)
-- the point of the carry is to move question marks or exclamation marks to the end of the text
for k, v in ipairs(stringtabl) do
local before, after = stringtabl[k - 1] and k - 1, stringtabl[k + 1] and k + 1

-- if we are not a voice command, check if we have someone before us, cuz if we do and they are a voice command than only they can have the carry symbol set
if !v.sound then
if before and carry and stringtabl[before].sound and string.sub(stringtabl[before].text, #stringtabl[before].text, #stringtabl[before].text) != "," then
local text = stringtabl[before].text
stringtabl[before].text = string.SetChar(text, #text, carry)
carry = nil
end
-- we only want voice commands to be corrected
continue
end

-- if there is a string before us adjust the casing of our first letter according to the before's symbol
if before then
local sub = string.sub(stringtabl[before].text, #stringtabl[before].text, #stringtabl[before].text)
local case = string.lower(string.sub(v.text, 1, 1))

if sub == "!" or sub == "." or sub == "?" then
case = string.upper(string.sub(v.text, 1, 1))
end

v.text = string.SetChar(v.text, 1, case)
end

-- if there is a string after us adjust our symbol to their casing. if they are a vc always adjust to comma, if they are not, check if the message starts with a lower casing letter, indicating a conntinuation of the sentence
if after then
local firstletterafter = string.sub(stringtabl[after].text, 1, 1)
local endsub = string.sub(v.text, #v.text, #v.text)

if stringtabl[after].sound or string.match(firstletterafter, "%l") then
if endsub == "!" or endsub == "." or endsub == "?" then
v.text = string.SetChar(v.text, #v.text, ",")
if stringtabl[after].sound and endsub != "." then
carry = carry == nil and endsub or carry
end
end
end
end

-- we are a vc so we can also set the carry to us
if carry then
if !after then
v.text = string.SetChar(v.text, #v.text, carry)
carry = nil
continue
end
end
end
return stringtabl
end

function Schema:PlayerMessageSend(speaker, chatType, text, anonymous, receivers, rawText)
local separator = ix.config.Get("separatorVC", nil) != "" and ix.config.Get("separatorVC", nil) or nil

if chatType == "ic" or chatType == "w" or chatType == "y" or chatType == "dispatch" or (ix.config.Get("radioVCAllow", true) and chatType == "radio") then
local class = self.voices.GetClass(speaker)

for k, v in pairs(class) do
local texts = GetVoiceCommands(rawText, v, separator)
local isGlobal = false
local completetext
local sounds = {}
if ix.config.Get("experimentalModeVC", false) == true then
texts = ExperimentalFormatting(texts)
end
for k2, v2 in ipairs(texts) do
if v2.sound then
if v2.global then
isGlobal = true
end
table.insert(sounds, v2.sound)
end

local volume = isGlobal and 0 or 80
if chatType == "w" then
volume = 60
elseif chatType == "y" then
volume = 150
end

completetext = completetext and completetext .. " " .. v2.text or v2.text

if k2 == #texts then
if table.IsEmpty(sounds) then break end

if speaker:IsCombine() and !isGlobal then
speaker.bTypingBeep = nil
table.insert(sounds, "NPC_MetroPolice.Radio.Off")
end

local _ = !isGlobal and ix.util.EmitQueuedSounds(speaker, sounds, nil, nil, volume) or netstream.Start(nil, "PlayQueuedSound", nil, sounds, nil, nil, volume)

if chatType == "radio" then
volume = ix.config.Get("radioVCVolume", 60)
if ix.config.Get("radioVCClientOnly", false) == true then
netstream.Start(receivers, "PlayQueuedSound", nil, sounds, nil, nil, volume)
else
for k3, v3 in pairs(receivers) do
if v3 == speaker then continue end
ix.util.EmitQueuedSounds(v3, sounds, nil, nil, volume)
end
end
end

text = completetext

goto exit
end
end
end

::exit::

PLUGIN.TempStored[CurTime()] = text

if speaker:IsCombine() then
if chatType != "radio" then
return string.format("<:: %s ::>", text)
end
end
return text
end

-- this isnt optimal but it works
if chatType == "radio_eavesdrop" then
if PLUGIN.TempStored[CurTime()] then
text = PLUGIN.TempStored[CurTime()]
PLUGIN.TempStored[CurTime()] = nil
end
end
return text
end
81 changes: 81 additions & 0 deletions tposefixer.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
local PLUGIN = PLUGIN

PLUGIN.name = "T-Pose Fixer"
PLUGIN.author = "DoopieWop"
PLUGIN.description = "Attempts to fix T-Posing for models."
PLUGIN.cached = PLUGIN.cached or {}

local translations = {
male_shared = "citizen_male",
female_shared = "citizen_female",
police_animations = "metrocop",
combine_soldier_anims = "overwatch",
vortigaunt_anims = "vortigaunt",
m_anm = "player",
f_anm = "player",
}

local og = ix.anim.SetModelClass
function ix.anim.SetModelClass(model, class)
if (!ix.anim[class]) then return end

PLUGIN.cached[model:lower()] = class

og(model, class)
end

local function UpdateAnimationTable(client)
local baseTable = ix.anim[client.ixAnimModelClass] or {}

client.ixAnimTable = baseTable[client.ixAnimHoldType]
client.ixAnimGlide = baseTable["glide"]
end

function PLUGIN:PlayerModelChanged(ply, model)
timer.Simple(0, function()
if not IsValid(ply) then
return
end

model = model:lower()

if not self.cached[model] then
local submodels = ply:GetSubModels()
for k, v in ipairs(submodels) do
local class = v.name:gsub(".*/([^/]+)%.%w+$", "%1"):lower()
if translations[class] then
ix.anim.SetModelClass(model, translations[class])
break
end
end
end

ply.ixAnimModelClass = ix.anim.GetModelClass(model)

UpdateAnimationTable(ply)
end)

return true
end

function PLUGIN:OnReloaded()
for k, v in pairs(self.cached) do
ix.anim.SetModelClass(k, v)
end
end

if SERVER then
util.AddNetworkString("TPoseFixerSync")

function PLUGIN:PlayerInitialSpawn(client)
net.Start("TPoseFixerSync")
net.WriteTable(self.cached)
net.Send(client)
end
else
net.Receive("TPoseFixerSync", function()
for k, v in pairs(net.ReadTable()) do
ix.anim.SetModelClass(k, v)
end
end)
end