fixes etc
|
@ -141,6 +141,19 @@ Config.VendingMachines = {
|
|||
},
|
||||
}
|
||||
},
|
||||
['beer'] = { -- Category: energy
|
||||
['Label'] = 'Bier',
|
||||
['Items'] = {
|
||||
[1] = {
|
||||
['name'] = 'pißwasser',
|
||||
['price'] = 10,
|
||||
['amount'] = 50,
|
||||
['info'] = {},
|
||||
['type'] = 'item',
|
||||
['slot'] = 1
|
||||
},
|
||||
}
|
||||
},
|
||||
['water'] = { -- Category: Water
|
||||
['Label'] = 'Wasser',
|
||||
['Items'] = {
|
||||
|
@ -205,5 +218,9 @@ Config.Vendings = {
|
|||
['Model'] = 'prop_vend_fags_01a', -- Cig vending machine
|
||||
['Category'] = 'cig' -- Linked to cig category
|
||||
},
|
||||
[13] = {
|
||||
['Model'] = 'bzzz_prop_beer_machine', -- Beer vending machine
|
||||
['Category'] = 'cig' -- Linked to cig category
|
||||
},
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ ClientConfig = {
|
|||
-- control_id: https://docs.fivem.net/docs/game-references/controls/)
|
||||
-- control_key: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/
|
||||
|
||||
OPEN_SELF_MENU = { enabled = true, control_id = 246, input_parameter = "Y" }, -- Y Key
|
||||
OPEN_SELF_MENU = { enabled = true, control_id = 246, input_parameter = "Z" }, -- Z Key
|
||||
OPEN_OTHER_MENU = { enabled = true, control_id = 74, input_parameter = "H" }, -- H Key
|
||||
EMERGENCY_DISPATCH = { enabled = true, control_id = 47, input_parameter = "G" }, -- G Key
|
||||
CANCEL_INTERACTION = { enabled = true, control_id = 73, input_parameter = "X" }, -- X Key
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
if not Config.Keybinding then return end
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------------------------------
|
||||
-- Commands / Events --------------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------------------
|
||||
|
||||
for i = 1, #Config.KeybindKeys do
|
||||
local cmd = string.format('emoteSelect%s', i)
|
||||
RegisterCommand(cmd, function()
|
||||
local emote = GetResourceKvpString(string.format('%s_emob%s', Config.keybindKVP, i))
|
||||
if emote and emote ~= "" then
|
||||
EmoteCommandStart(nil, { emote, 0 })
|
||||
end
|
||||
end, false)
|
||||
RegisterKeyMapping(cmd, string.format('Emote bind %s', i), 'keyboard', Config.KeybindKeys[i])
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------------------
|
||||
------ Functions and stuff --------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------------------
|
||||
|
||||
function EmoteBindStart(source, args, raw)
|
||||
if #args > 0 then
|
||||
local numkey = tonumber(args[1])
|
||||
local emote = string.lower(args[2])
|
||||
if type(numkey) == "number" then
|
||||
if RP.Emotes[emote] ~= nil
|
||||
or RP.Dances[emote] ~= nil
|
||||
or RP.PropEmotes[emote] ~= nil
|
||||
or RP.AnimalEmotes[emote] ~= nil
|
||||
then
|
||||
SetResourceKvp(string.format('%s_emob%s', Config.keybindKVP, numkey), emote)
|
||||
else
|
||||
EmoteChatMessage("'" .. emote .. "' " .. Translate('notvalidemote') .. "")
|
||||
end
|
||||
else
|
||||
EmoteChatMessage("'" .. numkey .. "' " .. Translate('notvalidkey'))
|
||||
end
|
||||
else
|
||||
DebugPrint('Invalid number of arguments to \'EmoteBindStart\'')
|
||||
end
|
||||
end
|
||||
|
||||
function ListKeybinds()
|
||||
for i = 1, #Config.KeybindKeys do
|
||||
local emote = GetResourceKvpString(string.format('%s_emob%s', Config.keybindKVP, i))
|
||||
if emote then
|
||||
EmoteChatMessage(string.format('Emote %s : %s',i, emote))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DeleteEmote(args)
|
||||
if #args > 0 then
|
||||
local numkey = tonumber(args[1])
|
||||
if type(numkey) == "number" then
|
||||
DeleteResourceKvp(string.format('%s_emob%s', Config.keybindKVP, numkey))
|
||||
else
|
||||
EmoteChatMessage("'" .. numkey .. "' " .. Translate('notvalidkey'))
|
||||
end
|
||||
else
|
||||
DebugPrint("invalid")
|
||||
end
|
||||
end
|
|
@ -1,100 +0,0 @@
|
|||
if Config.Framework ~= 'esx' then return end
|
||||
|
||||
local framework = 'es_extended'
|
||||
local state = GetResourceState(framework)
|
||||
|
||||
if state == 'missing' or state == "unknown" then
|
||||
-- Framework can't be used if it's missing or unknown
|
||||
return
|
||||
end
|
||||
|
||||
ESX, PlayerData, IsLoggedIn = nil, nil, false
|
||||
|
||||
-- ESX core parts
|
||||
ESX = exports[framework]:getSharedObject()
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
IsLoggedIn = false
|
||||
|
||||
RegisterNetEvent('esx:onPlayerSpawn', function()
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
IsLoggedIn = true
|
||||
end)
|
||||
|
||||
-- This is here to get the player data when the resource is restarted instead of having to log out and back in each time
|
||||
-- This won't set the player data too early as this only triggers when the server side is started and not the client side
|
||||
AddEventHandler('onResourceStart', function(resource)
|
||||
if resource == GetCurrentResourceName() then
|
||||
Wait(200)
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
IsLoggedIn = true
|
||||
end
|
||||
end)
|
||||
|
||||
function CanUseFavKeyBind()
|
||||
return not ESX.PlayerData.dead
|
||||
end
|
||||
|
||||
-- Added events
|
||||
RegisterNetEvent('animations:client:PlayEmote', function(args)
|
||||
if not ESX.PlayerData.dead then
|
||||
EmoteCommandStart(source, args)
|
||||
end
|
||||
end)
|
||||
|
||||
if Config.Keybinding then
|
||||
RegisterNetEvent('animations:client:BindEmote', function(args)
|
||||
if not ESX.PlayerData.dead then
|
||||
EmoteBindStart(nil, args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteBinds', function()
|
||||
if not ESX.PlayerData.dead then
|
||||
ListKeybinds()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteDelete', function(args)
|
||||
if not ESX.PlayerData.dead then
|
||||
DeleteEmote(args)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteMenu', function()
|
||||
if not ESX.PlayerData.dead then
|
||||
OpenEmoteMenu()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:ListEmotes', function()
|
||||
if not ESX.PlayerData.dead then
|
||||
EmotesOnCommand()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:Walk', function(args)
|
||||
if not ESX.PlayerData.dead then
|
||||
WalkCommandStart(args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:ListWalks', function()
|
||||
if not ESX.PlayerData.dead then
|
||||
WalksOnCommand()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Added by https://github.dev/qbcore-framework/dpemotes/
|
||||
|
||||
CanDoEmote = true
|
||||
RegisterNetEvent('animations:ToggleCanDoAnims', function(bool)
|
||||
CanDoEmote = bool
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteCommandStart', function(args)
|
||||
if CanDoEmote then
|
||||
EmoteCommandStart(source, args)
|
||||
end
|
||||
end)
|
|
@ -1,108 +0,0 @@
|
|||
if Config.Framework ~= 'qb-core' then return end
|
||||
|
||||
local framework = 'qb-core'
|
||||
local state = GetResourceState(framework)
|
||||
|
||||
if state == 'missing' or state == "unknown" then
|
||||
-- Framework can't be used if it's missing or unknown
|
||||
return
|
||||
end
|
||||
|
||||
QBCore, PlayerData, isLoggedIn = nil, nil, false
|
||||
|
||||
-- QB core parts
|
||||
QBCore = exports[framework]:GetCoreObject()
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
isLoggedIn = false
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
isLoggedIn = true
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
|
||||
PlayerData = {}
|
||||
isLoggedIn = false
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val)
|
||||
PlayerData = val
|
||||
end)
|
||||
|
||||
-- This is here to get the player data when the resource is restarted instead of having to log out and back in each time
|
||||
-- This won't set the player data too early as this only triggers when the server side is started and not the client side
|
||||
AddEventHandler('onResourceStart', function(resource)
|
||||
if resource == GetCurrentResourceName() then
|
||||
Wait(200)
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
isLoggedIn = true
|
||||
end
|
||||
end)
|
||||
|
||||
function CanUseFavKeyBind()
|
||||
return not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead']
|
||||
end
|
||||
|
||||
-- Added events
|
||||
RegisterNetEvent('animations:client:PlayEmote', function(args)
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
EmoteCommandStart(source, args)
|
||||
end
|
||||
end)
|
||||
|
||||
if Config.Keybinding then
|
||||
RegisterNetEvent('animations:client:BindEmote', function(args)
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
EmoteBindStart(nil, args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteBinds', function()
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
ListKeybinds()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteDelete', function(args)
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
DeleteEmote(args)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteMenu', function()
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
OpenEmoteMenu()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:ListEmotes', function()
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
EmotesOnCommand()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:Walk', function(args)
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
WalkCommandStart(source, args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:ListWalks', function()
|
||||
if not PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead'] then
|
||||
WalksOnCommand()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Added by https://github.dev/qbcore-framework/dpemotes/
|
||||
|
||||
CanDoEmote = true
|
||||
RegisterNetEvent('animations:ToggleCanDoAnims', function(bool)
|
||||
CanDoEmote = bool
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteCommandStart', function(args)
|
||||
if CanDoEmote then
|
||||
EmoteCommandStart(source, args)
|
||||
end
|
||||
end)
|
|
@ -1,145 +0,0 @@
|
|||
Config = {
|
||||
-- Menu Options
|
||||
MenuLanguage = 'de', -- Change the language of the menu here!.
|
||||
DebugDisplay = false, -- Set this to true to enable some extra prints
|
||||
EnableCancelKeybind = true, -- Set this to false if you have something else on X, and then just use /e c to cancel emotes.
|
||||
CancelEmoteKey = 'x', -- Get the button string here https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
MenuKeybindEnabled = true,
|
||||
MenuKeybind = 'f4', -- Get the button string here https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
FavKeybindEnabled = true, -- You can disable the Favorite emote keybinding here.
|
||||
FavKeybind = 'capital', -- Get the button string here https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
Keybinding = false, -- enable this to turn on keybinding.
|
||||
keybindKVP = "rpemotes", -- The keybind KVP name
|
||||
NotificationsAsChatMessage = false, -- If you don't like native GTA 5 notifications, you can disable them here to have messages in the chat.
|
||||
Framework = 'qb-core', -- Used for few framework-dependent things. Accepted values: 'qb-core', 'esx' or false
|
||||
Search = true, -- Used to enable or disable the search feature in the menu.
|
||||
CancelPreviousEmote = false, -- If turned on, playing an emote will cancel the previous one.
|
||||
DisableControls = false, -- Disable specific controls when menu is open, can be configured in NativeUI.lua:2452 (approximately)
|
||||
|
||||
-- Menu Customization Options
|
||||
MenuTitle = '', -- You can change the name of the menu here or leave it blank to remove the text in front of the custom banners
|
||||
TitleOutline = false,
|
||||
TitleColour = {R = 255, G = 0, B = 255, A = 255}, --- The colour of the menu banner text in RGB. This is white by default aka 255, 255, 255. See https://www.rapidtables.com/web/color/RGB_Color.html for colours.
|
||||
MenuPosition = 'right', -- You can change the menu position here. Use 'left' or 'right'
|
||||
CustomMenuEnabled = true, -- You can change the header image for the menu here, Note this might cause an issue of the image getting stuck on people's screens
|
||||
|
||||
-- Combat Car, and Player Movement Options
|
||||
DisarmPlayer = false, -- Set this to true if you want to disarm the player when they play an emote.
|
||||
AllowPunching = false, -- Set this to true if you want to allow people punching while emotes are playing
|
||||
AllowedInCars = true, -- Set this if you really wanna disable emotes in cars, as of 1.7.2 they only play the upper body part if in a vehicle
|
||||
-- You can disable the menu here / change the keybind. It is currently set to F4
|
||||
-- The keybind you set here will be server-sided for new players. existing players can set their own in the ESC menu keybind settings
|
||||
AllowInWater = false, -- If turned off, opening the menu and playing an emote will not be possible while swimming
|
||||
|
||||
-- Ragdoll options
|
||||
RagdollEnabled = true, -- You can enable or disable the Ragdoll keybinding here.
|
||||
RagdollKeybind = 'u', -- Get the button string here https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
-- You can enable or disable Ragdoll as Toggle here. Only works if RagdollEnabled is set to true.
|
||||
RagdollAsToggle = true,
|
||||
|
||||
-- Expressions, Walks, and More Menu Options
|
||||
ExpressionsEnabled = true, -- You can disable the Facial Expressions menu here.
|
||||
PersistentExpression = true, -- Saves expression style to client and applies them on joining
|
||||
WalkingStylesEnabled = true, -- You can disable the Walking Styles menu here.
|
||||
PersistentWalk = true, -- Saves walk styles to client and applies them on joining
|
||||
SharedEmotesEnabled = true, -- You can disable the Shared Emotes here.
|
||||
AdultEmotesDisabled = false, -- You can disable the Adult Emotes here.
|
||||
AnimalEmotesEnabled = true, -- You can disable the Animal Emotes here.
|
||||
|
||||
-- Hands Up Options
|
||||
HandsupEnabled = false, -- You can disable the handsup here / change the keybind. It is currently set to Y
|
||||
HandsupKeybind = 'Y', -- Get the button string here https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
HandsupKeybindEnabled = false,
|
||||
HandsupKeybindInCarEnabled = false,
|
||||
PersistentEmoteAfterHandsup = true, -- If true, you will play the emote you were playing previously after you stop handsup.
|
||||
HoldToHandsUp = false, -- Hands-up action occurs only while holding the button down
|
||||
|
||||
-- Pointing Options
|
||||
PointingEnabled = true, -- You can disable the finger pointing here / change the keybind. It is currently set to B
|
||||
PointingKeybindEnabled = true,
|
||||
PointingKeybind = 'B', -- Get the button string here https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
PointingKeybindInCarEnabled = false,
|
||||
PersistentEmoteAfterPointing = true, -- If true, you will play the emote you were playing previously after you stop pointing.
|
||||
|
||||
-- Crouching Options
|
||||
CrouchEnabled = false, -- If crouching should be enabled.
|
||||
CrouchKeybindEnabled = true, -- If true, crouching will use keybinds.
|
||||
CrouchKeybind = 'lcontrol', -- The default crouch keybind, get the button string here: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
CrouchOverrideStealthMode = false, -- If true, you won't enter stealth mode even if the crouch key and the 'duck' key are the same.
|
||||
FpsMode = false, -- set this to true if you have first-person shooting to disable the ability to crouch and shoot in third-person
|
||||
|
||||
-- Crawling Options
|
||||
CrawlEnabled = true, -- If crawling should be enabled.
|
||||
CrawlKeybindEnabled = true, -- If true, crawling will use keybinds.
|
||||
CrawlKeybind = 'rcontrol', -- The default crawl keybind, get the button string here: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
|
||||
-- Binocular Options
|
||||
BinocularsEnabled = false, -- If set to true, the /binoculars command will be enabled.
|
||||
AllowVisionsToggling = false, -- If set to true, you'll be able to toggle between different vision modes in the binoculars
|
||||
|
||||
-- News Camera Options
|
||||
NewscamEnabled = false, -- If set to true, the /newscam command will be enabled.
|
||||
|
||||
NoIdleCam = true, -- Controls wether the idle cam can be disabled by players or not
|
||||
|
||||
-- Preview Ped Options
|
||||
PreviewPed = true, -- Shows a preview of the emote on the player's ped next to the emote menu. Note that resmon will increase when this when emotes are being previewed.
|
||||
|
||||
CheckForUpdates = true
|
||||
}
|
||||
|
||||
Config.KeybindKeys = {
|
||||
'NUMPAD1',
|
||||
'NUMPAD2',
|
||||
'NUMPAD3',
|
||||
'NUMPAD4',
|
||||
'NUMPAD5',
|
||||
'NUMPAD6',
|
||||
'NUMPAD7',
|
||||
'NUMPAD8',
|
||||
'NUMPAD9'
|
||||
}
|
||||
|
||||
Config.Credits = {
|
||||
{title = "<b>Thanks to the community<b>", subtitle = "For supporting and using RP Emotes!"},
|
||||
{title = "Thanks <font color=\"#ff451d\">Enzo2991 🇧🇪 </font>", subtitle = "<font color=\"#ff451d\">Enzo2991 🇧🇪 </font> for creating the ped preview functionality, keybind with kvp"},
|
||||
{title = "Thanks ~o~DullPear 🍐~s~", subtitle = "~o~DullPear~s~ for the original dpemotes ❤️"},
|
||||
{title = "Thanks <b>Kibook 🐩</b>", subtitle = "<b>Kibook</b> for the addition of Animal Emotes 🐩 submenu."},
|
||||
{title = "Thanks ~y~AvaN0x 🇫🇷~s~", subtitle = "~y~AvaN0x~s~ 🇫🇷 for reformatting and assisting with code and additional features 🙏"},
|
||||
{title = "Thanks <font color=\"#0e64ed\">Mads 🤖</font>", subtitle = "<font color=\"#0e64ed\">Mads 🤖</font> for the addition of Exit Emotes, Crouch & Crawl ⚙️"},
|
||||
{title = "Thanks <font color=\"#ff451d\">Mathu_lmn 🇫🇷 </font>", subtitle = "<font color=\"#ff451d\">Mathu_lmn 🇫🇷</font> Additional features and fixes 🛠️"},
|
||||
{title = "Thanks <font color=\"#1C9369\">northsqrd ⚙️</font>", subtitle = "<font color=\"#1C9369\">northsqrd</font> for assisting with search feature and phone colours 🔎"},
|
||||
{title = "Thanks <font color=\"#15BCEC\">GeekGarage 🤓</font>", subtitle = "<font color=\"#15BCEC\">GeekGarage</font> for assisting with code and features"},
|
||||
{title = "Thanks <font color=\"#3b8eea\">SMGMissy 🪖</font>", subtitle = "<font color=\"#3b8eea\">SMGMissy</font> for the custom pride flags 🏳️🌈."},
|
||||
{title = "Thanks <font color=\"#a356fa\">Dollie 👧</font>", subtitle = "<font color=\"#a356fa\">DollieMods</font> for the custom emotes 💜."},
|
||||
{title = "Thanks <font color=\"#ff00c3\">Tigerle 🐯</font>", subtitle = "<font color=\"#ff00c3\">Tigerle</font> for assisting with attached Shared Emotes ⚙️."},
|
||||
{title = "Thanks <font color=\"#7dbf7b\">MissSnowie 🐰</font>", subtitle = "<font color=\"#7dbf7b\">MissSnowie</font> for the custom emotes 🐇."},
|
||||
{title = "Thanks <font color=\"#FF6100\">Smokey 💨</font>", subtitle = "<font color=\"#FF6100\">Smokey</font> for the custom emotes 🤙🏼."},
|
||||
{title = "Thanks ~b~Ultrahacx 🧑💻~s~", subtitle = "~b~Ultrahacx~s~ for the custom emotes ☺️."},
|
||||
{title = "Thanks <font color=\"#37DA00\">BzZzi 🤭</font>", subtitle = "<font color=\"#37DA00\">BzZzi</font> for the custom props 🍩."},
|
||||
{title = "Thanks <font color=\"#C40A7D\">Natty3d 🍭</font>", subtitle = "<font color=\"#C40A7D\">Natty3d</font> for the custom lollipop props 🍭."},
|
||||
{title = "Thanks <font color=\"#ff61a0\">Amnilka 🇵🇱</font>", subtitle = "<font color=\"#ff61a0\">Amnilka</font> for the custom emotes ☺️."},
|
||||
{title = "Thanks <font color=\"#ff058f\">LittleSpoon 🥄</font>", subtitle = "<font color=\"#ff058f\">LittleSpoon</font> for the custom emotes 💗."},
|
||||
{title = "Thanks <font color=\"#1a88c9\">Pupppy 🐶</font>", subtitle = "<font color=\"#1a88c9\">Pupppy</font> for the custom emotes 🦴."},
|
||||
{title = "Thanks <font color=\"#53ba04\">SapphireMods</font>", subtitle = "<font color=\"#53ba04\">SapphireMods</font> for the custom emotes ✨."},
|
||||
{title = "Thanks <font color=\"#8526f0\">QueenSisters Animations 👭</font>", subtitle = "<font color=\"#8526f0\">QueenSistersAnimations</font> for the custom emotes 🍧"},
|
||||
{title = "Thanks <font color=\"#0acf52\">BoringNeptune 👽</font>", subtitle = "<font color=\"#0acf52\">BoringNeptune</font> for the custom emotes 🕺"},
|
||||
{title = "Thanks <font color=\"#edae00\">Moses 🐮</font>", subtitle = "<font color=\"#edae00\">-Moses-</font> for the custom emotes 🧡" },
|
||||
{title = "Thanks <font color=\"#D71196\">PataMods 🍓</font>", subtitle = "<font color=\"#D71196\">PataMods</font> for the custom props 🍕"},
|
||||
{title = "Thanks <font color=\"#FB7403\">Crowded1337 👜</font>", subtitle = "<font color=\"#FB7403\">Crowded1337</font> for the custom Gucci bag 👜"},
|
||||
{title = "Thanks <font color=\"#8180E5\">EnchantedBrownie 🍪</font>", subtitle = "<font color=\"#8180E5\">EnchantedBrownie 🍪</font> for the custom animations 🍪"},
|
||||
{title = "Thanks <font color=\"#eb540e\">Copofiscool 🇦🇺</font>", subtitle = "<font color=\"#eb540e\">Copofiscool</font> for the Favorite Emote keybind toggle fix 🇦🇺"},
|
||||
{title = "Thanks <font color=\"#40E0D0\">iSentrie </font>", subtitle = "<font color=\"#40E0D0\">iSentrie</font> for assisting with code 🛠️"},
|
||||
{title = "Thanks <font color=\"#7B3F00\">Chocoholic Animations 🍫</font>", subtitle = "<font color=\"#7B3F00\">Chocoholic Animations</font> for the custom emotes 🍫"},
|
||||
{title = "Thanks <font color=\"#34cf5d\">CrunchyCat 🐱</font>", subtitle = "<font color=\"#34cf5d\">CrunchyCat 🐱</font> for the custom emotes 🐱"},
|
||||
{title = "Thanks <font color=\"#d10870\">KayKayMods</font>", subtitle = "<font color=\"#d10870\">KayKayMods</font> for the custom props 🧋"},
|
||||
{title = "Thanks <font color=\"#de1846\">Dark Animations</font>", subtitle = "<font color=\"#de1846\">Dark Animations</font> for the custom animations 🖤"},
|
||||
{title = "Thanks <font color=\"#00FF12\">Brum 🇬🇧</font>", subtitle = "<font color=\"#00FF12\">Brum</font> for the custom props 🇬🇧"},
|
||||
{title = "Thanks <font color=\"#017a05\">Chico 💀</font>", subtitle = "<font color=\"#017a05\">Chico 💀</font> for fixing persistent walkstyles and moods for QB-Core and ESX." },
|
||||
{title = "Thanks <font color=\"#194ce6\">-EcLiPsE- ✌🏻</font>", subtitle = "<font color=\"#194ce6\">-EcLiPsE- ✌🏻 </font> for NPC prop sets and GTA Online biker animations"},
|
||||
{title = "Thanks <font color=\"#3488c8\">MrWitt 🦑️</font>", subtitle = "<font color=\"#3488c8\">MrWitt 🦑</font> for the custom animations."},
|
||||
{title = "Thanks <font color=\"#ff96b6\">AdoredRose 🌹</font>", subtitle = "<font color=\"#ff96b6\">AdoredRose 🌹</font> for assistance with adding animations."},
|
||||
{title = "Thanks <font color=\"#ff451d\">DRX Animations 👑</font>", subtitle = "<font color=\"#ff451d\">DRX Animations 👑</font> for the custom animations"},
|
||||
{title = "Thanks <font color=\"#12ab0a\">Radial 🫡</font>", subtitle = "<font color=\"#12ab0a\">Radial</font> on discord for contributing animations code"},
|
||||
{title = "<font color=\"#FF25B1\"><b>TayMcKenzieNZ 🇳🇿<b></font>", subtitle = "<font color=\"#FF25B1\">TayMcKenzieNZ 🇳🇿</font> Previous maintainer of RP Emotes."},
|
||||
}
|
Before Width: | Height: | Size: 33 KiB |
|
@ -1,177 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------------
|
||||
-- Shared Emotes Syncing ---------------------------------------------------------------------------
|
||||
-----------------------------------------------------------------------------------------------------
|
||||
|
||||
RegisterNetEvent("ServerEmoteRequest", function(target, emotename, etype)
|
||||
if not Player(source).state.canEmote then return end
|
||||
|
||||
local ped = GetPlayerPed(source)
|
||||
|
||||
if target == -1 then
|
||||
return
|
||||
end
|
||||
local tped = GetPlayerPed(target)
|
||||
local pedcoord = GetEntityCoords(ped)
|
||||
local targetcoord = GetEntityCoords(tped)
|
||||
|
||||
local distance = #(pedcoord - targetcoord)
|
||||
|
||||
if distance > 3 then
|
||||
return
|
||||
end
|
||||
|
||||
TriggerClientEvent("ClientEmoteRequestReceive", target, emotename, etype, source)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("ServerValidEmote", function(target, requestedemote, otheremote)
|
||||
local ped = GetPlayerPed(source)
|
||||
|
||||
if target == -1 then
|
||||
return
|
||||
end
|
||||
local tped = GetPlayerPed(target)
|
||||
local pedcoord = GetEntityCoords(ped)
|
||||
local targetcoord = GetEntityCoords(tped)
|
||||
|
||||
local distance = #(pedcoord - targetcoord)
|
||||
|
||||
if distance > 3 then
|
||||
return
|
||||
end
|
||||
|
||||
TriggerClientEvent("SyncPlayEmote", source, otheremote, target)
|
||||
TriggerClientEvent("SyncPlayEmoteSource", target, requestedemote, source)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("ServerEmoteCancel", function(target)
|
||||
TriggerClientEvent("SyncCancelEmote", target, source)
|
||||
end)
|
||||
|
||||
--#region ptfx
|
||||
RegisterNetEvent("rpemotes:ptfx:sync", function(asset, name, offset, rot, bone, scale, color)
|
||||
if type(asset) ~= "string" or type(name) ~= "string" or type(offset) ~= "vector3" or type(rot) ~= "vector3" then
|
||||
print("[rpemotes] ptfx:sync: invalid arguments for source:", source)
|
||||
return
|
||||
end
|
||||
|
||||
local srcPlayerState = Player(source).state
|
||||
|
||||
srcPlayerState:set("ptfxAsset", asset, true)
|
||||
srcPlayerState:set("ptfxName", name, true)
|
||||
srcPlayerState:set("ptfxOffset", offset, true)
|
||||
srcPlayerState:set("ptfxRot", rot, true)
|
||||
srcPlayerState:set("ptfxBone", bone, true)
|
||||
srcPlayerState:set("ptfxScale", scale, true)
|
||||
srcPlayerState:set("ptfxColor", color, true)
|
||||
srcPlayerState:set("ptfxPropNet", false, true)
|
||||
srcPlayerState:set("ptfx", false, true)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rpemotes:ptfx:syncProp", function(propNet)
|
||||
local srcPlayerState = Player(source).state
|
||||
if propNet then
|
||||
-- Prevent infinite loop to get entity
|
||||
local waitForEntityToExistCount = 0
|
||||
while waitForEntityToExistCount <= 100 and not DoesEntityExist(NetworkGetEntityFromNetworkId(propNet)) do
|
||||
Wait(10)
|
||||
waitForEntityToExistCount = waitForEntityToExistCount + 1
|
||||
end
|
||||
|
||||
-- If below 100 then we could find the loaded entity
|
||||
if waitForEntityToExistCount < 100 then
|
||||
srcPlayerState:set("ptfxPropNet", propNet, true)
|
||||
return
|
||||
end
|
||||
end
|
||||
-- If we reach this point then we couldn"t find the entity
|
||||
srcPlayerState:set("ptfxPropNet", false, true)
|
||||
end)
|
||||
--#endregion ptfx
|
||||
|
||||
-- Emote props extractor
|
||||
local function ExtractEmoteProps(format)
|
||||
local format = tonumber(format)
|
||||
local xt, c, total = "", "", 0
|
||||
if format == 1 then
|
||||
print("Selected format: ^2\"prop_name\",")
|
||||
xt = "\""; c = ","
|
||||
elseif format == 2 then
|
||||
print("Selected format: ^2\"prop_name\",")
|
||||
xt = "\""; c = ","
|
||||
elseif format == 3 then
|
||||
print("Selected format: ^2prop_name,")
|
||||
elseif format == 4 then
|
||||
print("Selected to calculate ^2total amount of emotes^0.")
|
||||
else
|
||||
print(
|
||||
"\n### RPEmotes - Props Extractor ###\n\n^3Select output format^0\nAvailable formats:\n^11^0 - ^2\"prop_name\",\n^12^0 - ^2\"prop_name\",\n^13^0 - ^2prop_name\n^14^0 - ^2calculate total emotes\n\n^0Command usage example: ^5emoteextract 1^0\n")
|
||||
return
|
||||
end
|
||||
|
||||
local animationFile = LoadResourceFile(GetCurrentResourceName(), "client/AnimationList.lua")
|
||||
if not animationFile then return nil end
|
||||
|
||||
local f, err = load(animationFile .. " return RP")
|
||||
if err then return nil end
|
||||
|
||||
local success, res = pcall(f)
|
||||
if not success then return nil end
|
||||
|
||||
if format == 4 then
|
||||
local emoteTypes = { "Shared", "Dances", "AnimalEmotes", "Emotes", "PropEmotes", "Expressions", "Walks" }
|
||||
local countEmotesWith = 0
|
||||
local countEmotes = 0
|
||||
|
||||
for i = 1, #emoteTypes do
|
||||
local emoteType = emoteTypes[i]
|
||||
for _, _ in pairs(res[emoteType]) do
|
||||
if emoteType == "Expressions" or emoteType == "Walks" then
|
||||
countEmotesWith += 1
|
||||
else
|
||||
countEmotes += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local totalEmotes = countEmotesWith + countEmotes
|
||||
|
||||
print("Total Expressions and Walks: ^3" .. countEmotesWith .. "^0")
|
||||
print("Total Emotes without Expressions and Walks: ^3" .. countEmotes .. "^0")
|
||||
print("Total Emotes: ^3" .. totalEmotes .. "^0")
|
||||
else
|
||||
-- table to keep track of exported values
|
||||
local exportedValues = {}
|
||||
-- open file for writing
|
||||
local file = assert(io.open(GetResourcePath(GetCurrentResourceName()) .. "/prop_list.lua", "w"))
|
||||
|
||||
-- tables that has props:
|
||||
-- RP.PropEmotes
|
||||
-- RP.Shared (most likely all props mentioned in here is used in PropEmotes, so I don"t check it)
|
||||
for _, value in pairs(res.PropEmotes) do
|
||||
-- check if the current value is a table and has an AnimationOptions field
|
||||
if type(value) == "table" and value.AnimationOptions then
|
||||
-- extract the Prop and SecondProp values and check if they"re nil and not already exported
|
||||
local propValue = value.AnimationOptions.Prop
|
||||
local secondPropValue = value.AnimationOptions.SecondProp
|
||||
if propValue and not exportedValues[propValue] then
|
||||
file:write(xt .. propValue .. xt .. c .. "\n")
|
||||
exportedValues[propValue] = true
|
||||
total += 1
|
||||
end
|
||||
if secondPropValue and not exportedValues[secondPropValue] then
|
||||
file:write(xt .. secondPropValue .. c .. "\n")
|
||||
exportedValues[secondPropValue] = true
|
||||
total += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print("Exported props: " .. total)
|
||||
file:close()
|
||||
end
|
||||
end
|
||||
|
||||
RegisterCommand("emoteextract", function(source, args)
|
||||
if source > 0 then return end
|
||||
ExtractEmoteProps(args[1])
|
||||
end, true)
|
|
@ -1,59 +0,0 @@
|
|||
if Config.Framework ~= 'esx' then return end
|
||||
|
||||
local framework = 'esx'
|
||||
local state = GetResourceState(framework)
|
||||
|
||||
if state == 'missing' or state == "unknown" then
|
||||
-- Framework can't be used if it's missing or unknown
|
||||
return
|
||||
end
|
||||
|
||||
local ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
ESX.RegisterCommand('e', 'Play an emote', {{ name="emotename", help="dance, camera, sit or any valid emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:PlayEmote', source, args)
|
||||
end)
|
||||
|
||||
ESX.RegisterCommand('emote', 'Play an emote', {{ name="emotename", help="dance, camera, sit or any valid emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:PlayEmote', source, args)
|
||||
end)
|
||||
|
||||
if Config.Keybinding then
|
||||
ESX.RegisterCommand('emotebind', 'user', function(xPlayer, args)
|
||||
local arg = {args.key, args.emotename}
|
||||
xPlayer.triggerEvent('animations:client:BindEmote', arg)
|
||||
end, false, {help = Translate('link_emote_keybind'), arguments= {{name = "key", help= "1, 2, 3, 4, 5, 6", type='number'}, {name="emotename", help="dance, camera, sit or any valid emote.", type='string'}}})
|
||||
|
||||
ESX.RegisterCommand('emotebinds', 'user', function(xPlayer)
|
||||
xPlayer.triggerEvent('animations:client:EmoteBinds')
|
||||
end, false, {help = Translate('show_emote_keybind')})
|
||||
|
||||
ESX.RegisterCommand('emotedelete', 'user', function(xPlayer, args)
|
||||
local arg = {args.key}
|
||||
xPlayer.triggerEvent('animations:client:EmoteDelete', arg)
|
||||
end, false, {help = Translate('remove_emote_keybind'), arguments={{name = "key", help= "1, 2, 3, 4, 5, 6", type='number'}}})
|
||||
end
|
||||
|
||||
ESX.RegisterCommand('emotemenu', 'Open rpemotes menu (F3) by default.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:EmoteMenu', source)
|
||||
end)
|
||||
|
||||
ESX.RegisterCommand('em', 'Open rpemotes menu (F3) by default.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:EmoteMenu', source)
|
||||
end)
|
||||
|
||||
ESX.RegisterCommand('emotes', 'List available emotes.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:ListEmotes', source)
|
||||
end)
|
||||
|
||||
ESX.RegisterCommand('walk', 'Set your walkingstyle.', {{ name="style", help="/walks for a list of valid styles"}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:Walk', source, args)
|
||||
end)
|
||||
|
||||
ESX.RegisterCommand('walks', 'List available walking styles.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:ListWalks', source)
|
||||
end)
|
||||
|
||||
ESX.RegisterCommand('nearby', 'Share emote with a nearby player.', {{ name="emotename", help="hug, handshake, bro or any valid shared emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:Nearby', source, args)
|
||||
end)
|
|
@ -1,58 +0,0 @@
|
|||
if Config.Framework ~= 'qb-core' then return end
|
||||
|
||||
local framework = 'qb-core'
|
||||
local state = GetResourceState(framework)
|
||||
|
||||
if state == 'missing' or state == "unknown" then
|
||||
-- Framework can't be used if it's missing or unknown
|
||||
return
|
||||
end
|
||||
|
||||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
-- https://github.com/qbcore-framework/dpemotes/blob/master/Server/Server.lua#L101-L141
|
||||
QBCore.Commands.Add('e', 'Play an emote', {{ name="emotename", help="dance, camera, sit or any valid emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:PlayEmote', source, args)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('emote', 'Play an emote', {{ name="emotename", help="dance, camera, sit or any valid emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:PlayEmote', source, args)
|
||||
end)
|
||||
|
||||
if Config.Keybinding then
|
||||
QBCore.Commands.Add('emotebind', 'Bind an emote', {{ name="key", help="num4, num5, num6, num7. num8, num9. Numpad 4-9!"}, { name="emotename", help="dance, camera, sit or any valid emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:BindEmote', source, args)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('emotebinds', 'Check your currently bound emotes.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:EmoteBinds', source)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('emotedelete', Translate('remove_emote_keybind'), {}, false, function(source, args)
|
||||
TriggerClientEvent('animations:client:EmoteDelete', source, args)
|
||||
end)
|
||||
end
|
||||
|
||||
QBCore.Commands.Add('emotemenu', 'Open rpemotes menu (F3) by default.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:EmoteMenu', source)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('em', 'Open rpemotes menu (F3) by default.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:EmoteMenu', source)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('emotes', 'List available emotes.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:ListEmotes', source)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('walk', 'Set your walkingstyle.', {{ name="style", help="/walks for a list of valid styles"}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:Walk', source, args)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('walks', 'List available walking styles.', {}, false, function(source)
|
||||
TriggerClientEvent('animations:client:ListWalks', source)
|
||||
end)
|
||||
|
||||
QBCore.Commands.Add('nearby', 'Share emote with a nearby player.', {{ name="emotename", help="hug, handshake, bro or any valid shared emote."}}, true, function(source, args)
|
||||
TriggerClientEvent('animations:client:Nearby', source, args)
|
||||
end)
|
|
@ -477,14 +477,14 @@ function GetByteCount(str)
|
|||
local bytes = 0
|
||||
|
||||
for c in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do
|
||||
local a, b, c, d = c:byte(1, -1)
|
||||
local a, b, cc, d = c:byte(1, -1)
|
||||
if a ~= nil then
|
||||
bytes = bytes + 1
|
||||
end
|
||||
if b ~= nil then
|
||||
bytes = bytes + 1
|
||||
end
|
||||
if c ~= nil then
|
||||
if cc ~= nil then
|
||||
bytes = bytes + 1
|
||||
end
|
||||
if d ~= nil then
|
||||
|
@ -2376,7 +2376,7 @@ end
|
|||
--]]
|
||||
|
||||
function UIMenu.New(Title, Subtitle, X, Y, TxtDictionary, TxtName)
|
||||
local X, Y = tonumber(X) or 0, tonumber(Y) or 0
|
||||
X, Y = tonumber(X) or 0, tonumber(Y) or 0
|
||||
if Title ~= nil then Title = tostring(Title) or "" else Title = "" end
|
||||
if Subtitle ~= nil then Subtitle = tostring(Subtitle) or "" else Subtitle = "" end
|
||||
if TxtDictionary ~= nil then TxtDictionary = tostring(TxtDictionary) or "commonmenu" else TxtDictionary = "commonmenu" end
|
||||
|
@ -2444,7 +2444,7 @@ function UIMenu.New(Title, Subtitle, X, Y, TxtDictionary, TxtName)
|
|||
ResetCursorOnOpen = false,
|
||||
MouseControlsEnabled = false,
|
||||
MouseEdgeEnabled = false,
|
||||
ControlDisablingEnabled = Config.DisableControls,
|
||||
ControlDisablingEnabled = Config.DisableControlsInMenu,
|
||||
Audio = {
|
||||
Library = "HUD_FRONTEND_DEFAULT_SOUNDSET",
|
||||
UpDown = "NAV_UP_DOWN",
|
|
@ -89,9 +89,7 @@ Example Banner:
|
|||
|
||||
Find our documentation [here](https://rpemotes-reborn.gitbook.io/guide)
|
||||
|
||||
When using our emote menu with other scripts, using the `TriggerEvent('animations:client:EmoteCommandStart` won't do anything because the events do not exist. These have simply been replaced with the following exports:
|
||||
|
||||
**Note for legacy use of rpemotes:** if you have resources dependent on or currently using exports from rpemotes, rename rpemotes-reborn's folder to rpemotes to maintain functionality. Or, rename all exports from exports["rpemotes"] to exports["rpemotes-reborn"]
|
||||
The rpemotes-reborn resource has the following exports:
|
||||
|
||||
```lua
|
||||
exports["rpemotes-reborn"]:EmoteCommandStart(emoteName, textureVariation)
|
||||
|
@ -99,15 +97,17 @@ exports["rpemotes-reborn"]:EmoteCancel(forceCancel) – forceCancel is optional
|
|||
exports["rpemotes-reborn"]:CanCancelEmote(state)
|
||||
exports["rpemotes-reborn"]:IsPlayerCrouched()
|
||||
exports["rpemotes-reborn"]:IsPlayerProne()
|
||||
exports["rpemotes-reborn"]:StopPlayerProne(force) -- force is optional
|
||||
exports["rpemotes-reborn"]:GetPlayerProneType() -- returns the type of prone the player is in, either "onfront" or "onback"
|
||||
exports["rpemotes-reborn"]:IsPlayerCrawling()
|
||||
exports["rpemotes-reborn"]:IsPlayerPointing()
|
||||
exports["rpemotes-reborn"]:IsPlayerInAnim() -- returns current animation name or nil
|
||||
exports["rpemotes-reborn"]:IsPlayerInHandsUp()
|
||||
exports["rpemotes-reborn"]:toggleWalkstyle(bool, message) -- bool to allow the user to change their walkstyle in the menu or not / message to show the user (optional, default is :"You are unable to change your walking style right now.")"
|
||||
exports["rpemotes-reborn"]:toggleBinoculars()
|
||||
exports["rpemotes-reborn"]:toggleNewscam()
|
||||
exports["rpemotes-reborn"]:getWalkstyle() -- Gets walk style of player, used to detect certain walk. useful for applying effects while doing certain walks like tripping or other "funny" effects.
|
||||
exports["rpemotes-reborn"]:setWalkstyle(name, force) -- name = "move_m@alien" or any other, force = optional bool. Lets you set or force a walk style, useful for scripts like retrieving a style before drinking and restoring it after sobering up.
|
||||
exports["rpemotes-reborn"]:toggleWalkstyle(bool, message) -- bool to allow the user to change their walkstyle in the menu or not / message to show the user (optional, default is :"You are unable to change your walking style right now.")"
|
||||
```
|
||||
|
||||
Having issues with players using emotes when/where they're not supposed to? Use the following where you need. This would be somewhere like if you want to disable emotes in jail or when someone is handcuffed/escorted:
|
||||
|
@ -133,7 +133,7 @@ Alternatively, the player base can set their menu keybind to open rpemotes-rebor
|
|||
|
||||
`Esc > settings > keybinds > fivem`
|
||||
|
||||
- More keybinds are now using key mappings which means that they are now available in your FiveM settings to change (`FavKeybind` and `RagdollKeybind`)
|
||||
- More keybinds are now using key mappings which means that they are now available in your FiveM settings to change (`RagdollKeybind`)
|
||||
|
||||
# Keybinds 🎛️
|
||||
|
||||
|
@ -260,12 +260,6 @@ No Idle Cam allows players to disable the idle camera animation on foot and in v
|
|||
|
||||
<img src="https://forum.cfx.re/uploads/default/optimized/4X/5/4/e/54e47db5ae45f5afa4b84c2ae4858bc9ab0a8187_2_690x388.jpeg" width="600" height="auto">
|
||||
|
||||
# Favorite Emote
|
||||
|
||||
Players can search for an emote (so long as search is enabled) and press LEFT SHIFT and CAPLOCKS on their keyboard to add it to their 'Favorites'. Pressing CAPLOCKS will toggle the emote.
|
||||
|
||||
Alternatively, you can use the 🌟 Favorite menu to find an emote and press enter.
|
||||
|
||||
# Exit Emotes
|
||||
|
||||
Exit Emotes are used to make cancelling an animation more smoother and dynamic, such as getting up off a chair or throwing a cigarette out instead of dropping it.
|
||||
|
@ -466,59 +460,57 @@ All animation creators have **_specifically_** asked that their content remain f
|
|||
**A huge thank you the following people for their amazing contributions to the menu:**
|
||||
|
||||
- the FiveM community for using RP and updating rpemotes-reborn!
|
||||
### Developers:
|
||||
- [The Popcorn RP community](https://discord.gg/popcornroleplay) for putting up with all my emote menu testing and troubleshooting issues with me
|
||||
- [Mathu_lmn](https://github.com/Mathu-lmn) for maintaining the menu and adding features
|
||||
- [enzo2991](https://github.com/enzo2991) for creating the ped preview functionality, keybind with kvp
|
||||
- [DerDevHD](https://forum.cfx.re/t/fixed-remove-prop-after-scenario-animation/5002332/8) for the insight on deleting scenario props.
|
||||
- [iSentrie](https://forum.cfx.re/u/isentrie/) for additional code, support, and joining the RPEmotes project
|
||||
- [Kibook](https://github.com/kibook) for the addition of the Animal Emotes sub-menu
|
||||
- [AvaN0x](https://github.com/AvaN0x) for reformatting and assisting with code, additional features, and figuring out shared particle effects
|
||||
- [Mads](https://github.com/MadsLeander) for joining the team as Co-Developer
|
||||
- [Mathu_lmn](https://github.com/Mathu-lmn) for joining the team as Co-Developer
|
||||
- [Tigerle](https://forum.cfx.re/u/tigerle_studios) for providing the additional code required to make Shared Emotes work to its full extent
|
||||
- [SMGMissy](https://jenscreations.tebex.io/) for creating the pride flag props
|
||||
- [MissSnowie](https://www.gta5-mods.com/users/MissySnowie) for the Explicit Usage Rights Agreement to add free custom animations either publicly available or on their discord and for the motivational and overall moral support
|
||||
- [GeekGarage](https://github.com/geekgarage) for their knowledge, time, and dedication, helping to bring new and exciting features to the menu
|
||||
- [Smokey](https://www.gta5-mods.com/users/struggleville) for the Explicit Usage Rights Agreement to add free custom animations either publicly available on their discord
|
||||
- [BzZzi](https://forum.cfx.re/u/bzzzi/summary) for the Explicit Usage Rights Agreement to add free donuts, croissants and fire torch props
|
||||
- [Natty3d](https://forum.cfx.re/u/natty3d/summary) for the Explicit Usage Rights Agreement to add free lollipop props
|
||||
- [northsqrd](https://github.com/0sqrd) for adding the search function, Animal Emotes config, mobile phone prop texture variants, and general contributions
|
||||
- Crusopaul and Eki for discussing KVP and initializing it to the menu for persistent walk styles
|
||||
- [Amnilka](https://www.gta5-mods.com/users/frabi) for the Explicit Usage Rights Agreement to add free custom animations either publicly available or on their discord
|
||||
- [LittleSpoon](https://discord.gg/safeword) for the Explicit Usage Rights Agreement to add free custom animations either publicly available or on their discord
|
||||
- [LadyyShamrockk](https://www.gta5-mods.com/users/LadyyShamrockk) For allowing us to include their emotes in rpemotes-reborn
|
||||
- [Pupppy](https://discord.gg/rsN35X4s4N) for the Explicit Usage Rights Agreement to add free custom animations either publicly available or on their discord
|
||||
- [SapphireMods](https://discord.gg/Hf8F4nTyzt) for the Explicit Usage Rights Agreement to add free custom animations either publicly available or on their discord
|
||||
- [QueenSisters Animations](https://discord.gg/qbPtGwQuep) for the Explicit Usage Rights Agreement to add free custom animations either publicly available or on their discord
|
||||
- [Kri's Graphic House](https://discord.gg/JueRG3fCy6) for the custom banners
|
||||
- !MWooM#0597 on Discord for the custom banners
|
||||
- DurtyFree for his work on particle effects and cataloging GTA-related information [DurtyFree GTA V Dump](https://github.com/DurtyFree/gta-v-data-dumps/blob/master/particleEffectsCompact.json).
|
||||
- [BoringNeptune](https://www.gta5-mods.com/users/BoringNeptune) for the custom dance emotes
|
||||
- [CMG Mods](https://www.gta5-mods.com/users/-moses-) for the custom emotes
|
||||
- [prue 颜](discord.gg/lunyxmods) for being a great friend and providing us with exclusive custom animations
|
||||
- [PataMods](https://forum.cfx.re/u/Pata_PataMods) for the custom props
|
||||
- [Crowded1337](https://www.gta5-mods.com/users/crowded1337) for the custom Gucci bag. I have removed the Gucci logo to comply with Rockstar Games & TakeTwo Interactive
|
||||
- [EnchantedBrownie](https://www.gta5-mods.com/users/EnchantedBrownie) for the custom animations
|
||||
- [Copofiscool](https://forum.cfx.re/u/copofiscool/) for adding a toggle to the Favorite Keybinds
|
||||
- [iSentrie](https://forum.cfx.re/u/isentrie/) for additional code, support, and joining the RPEmotes project
|
||||
- Chocoholic Animations for the custom animations
|
||||
- [CrunchyCat](https://www.gta5-mods.com/users/crunchycat) for the custom animations
|
||||
- [KayKayMods](https://discord.gg/5bYQVWVaxG) for the custom props
|
||||
- [MonkeyWhisper](https://github.com/MonkeyWhisper) and [Project Sloth](https://github.com/Project-Sloth) for the custom props
|
||||
- [Brummieee](https://forum.cfx.re/u/brummieee_maps/summary) for the custom props
|
||||
- [Dark Animations](https://www.gta5-mods.com/users/Darks%20Animations) for the custom animations.
|
||||
- [Chico](https://forum.cfx.re/u/chico) for implementing natives to reapply persistent moods and walk styles for ESX and QB-Core frameworks
|
||||
- [-EcLiPsE-](https://www.gta5-mods.com/users/-EcLiPsE-) for allowing me to implement [Improved Prop Sets](https://www.gta5-mods.com/misc/improved-propsets-meta) and [GTA Online Biker Idle Anims](https://www.gta5-mods.com/misc/bike-idle-animations)
|
||||
- [MrWitt](https://www.gta5-mods.com/users/MrWitt)for the custom animations
|
||||
- [AdoredRose](https://forum.cfx.re/u/adoredrose/summary) for assisting with animations
|
||||
- [Vedere](https://discord.gg/XMywAMQ8Ef) for the custom props
|
||||
- [DRX Animations](https://www.gta5-mods.com/users/DRX%2DAnimations) for the custom animations
|
||||
- [VNSIanims](https://discord.gg/cTNrjYSXXG) for the custom animations
|
||||
- [PNWParksFan](https://www.gta5-mods.com/users/PNWParksFan) for the custom props
|
||||
- [LSPDFR member Sam](https://www.lcpdfr.com/downloads/gta5mods/misc/23386-lspd-police-badge/) for their Custom LSPD police badge
|
||||
- [GTA5Mods user Sladus_Slawonkus](https://www.gta5-mods.com/misc/lspd-police-badge-replace-sladus_slawonkus) for their reskinned LSPD badge
|
||||
- [Scully](https://github.com/Scullyy/) for their past work on rpemotes
|
||||
- [EP](https://github.com/EpKouhia) for their ice fishing props and emotes, originally used in scully_emotemenu
|
||||
- [TayMcKenzieNZ](https://github.com/TayMcKenzieNZ) for their past work maintaining RP Emotes
|
||||
- [ESX](https://github.com/esx-framework) for the creation of the translation system
|
||||
- [41anims](https://www.gta5-mods.com/users/41anims) for allowing us to use their custom emotes in rpemotes-reborn
|
||||
- [corbs](https://www.gta5-mods.com/users/corbs) for allowing us to use their custom emotes and poses in rpemotes-reborn
|
||||
- [jaysigx](https://www.gta5-mods.com/misc/improved-umbrella) for allowing us to use their improved umbrella prop
|
||||
- Crusopaul and Eki for discussing KVP and initializing it to the menu for persistent walk styles
|
||||
|
||||
### Emote & Props Creators:
|
||||
- [SMGMissy](https://jenscreations.tebex.io/) for creating the pride flag props
|
||||
- [MissSnowie](https://www.gta5-mods.com/users/MissySnowie)
|
||||
- [Smokey](https://www.gta5-mods.com/users/struggleville)
|
||||
- [BzZzi](https://forum.cfx.re/u/bzzzi/summary)
|
||||
- [Natty3d](https://forum.cfx.re/u/natty3d/summary)
|
||||
- [Amnilka](https://www.gta5-mods.com/users/frabi)
|
||||
- [LittleSpoon](https://discord.gg/safeword)
|
||||
- [LadyyShamrockk](https://www.gta5-mods.com/users/LadyyShamrockk)
|
||||
- [Pupppy](https://discord.gg/rsN35X4s4N)
|
||||
- [SapphireMods](https://discord.gg/Hf8F4nTyzt)
|
||||
- [QueenSisters Animations](https://discord.gg/qbPtGwQuep)
|
||||
- DurtyFree for his work on particle effects and cataloging GTA-related information [DurtyFree GTA V Dump](https://github.com/DurtyFree/gta-v-data-dumps/blob/master/particleEffectsCompact.json)
|
||||
- [BoringNeptune](https://www.gta5-mods.com/users/BoringNeptune)
|
||||
- [CMG Mods](https://www.gta5-mods.com/users/-moses-)
|
||||
- [prue 颜](discord.gg/lunyxmods)
|
||||
- [PataMods](https://forum.cfx.re/u/Pata_PataMods)
|
||||
- [Crowded1337](https://www.gta5-mods.com/users/crowded1337)
|
||||
- [EnchantedBrownie](https://www.gta5-mods.com/users/EnchantedBrownie)
|
||||
- Chocoholic Animations
|
||||
- [CrunchyCat](https://www.gta5-mods.com/users/crunchycat)
|
||||
- [KayKayMods](https://discord.gg/5bYQVWVaxG)
|
||||
- [MonkeyWhisper](https://github.com/MonkeyWhisper) and [Project Sloth](https://github.com/Project-Sloth)
|
||||
- [Brummieee](https://forum.cfx.re/u/brummieee_maps/summary)
|
||||
- [Dark Animations](https://www.gta5-mods.com/users/Darks%20Animations).
|
||||
- [-EcLiPsE-](https://www.gta5-mods.com/users/-EcLiPsE-) for allowing me to implement [Improved Prop Sets](https://www.gta5-mods.com/misc/improved-propsets-meta) and [GTA Online Biker Idle Anims](https://www.gta5-mods.com/misc/bike-idle-animations)
|
||||
- [MrWitt](https://www.gta5-mods.com/users/MrWitt)
|
||||
- [Vedere](https://discord.gg/XMywAMQ8Ef)
|
||||
- [DRX Animations](https://www.gta5-mods.com/users/DRX%2DAnimations)
|
||||
- [VNSIanims](https://discord.gg/cTNrjYSXXG)
|
||||
- [PNWParksFan](https://www.gta5-mods.com/users/PNWParksFan)
|
||||
- [LSPDFR member Sam](https://www.lcpdfr.com/downloads/gta5mods/misc/23386-lspd-police-badge/)
|
||||
- [GTA5Mods user Sladus_Slawonkus](https://www.gta5-mods.com/misc/lspd-police-badge-replace-sladus_slawonkus)
|
||||
- [EP](https://github.com/EpKouhia)
|
||||
- [TayMcKenzieNZ](https://github.com/TayMcKenzieNZ)
|
||||
- [41anims](https://www.gta5-mods.com/users/41anims)
|
||||
- [corbs](https://www.gta5-mods.com/users/corbs)
|
||||
- [jaysigx](https://www.gta5-mods.com/misc/improved-umbrella)
|
|
@ -4,7 +4,7 @@ BigDogs = {
|
|||
"a_c_retriever",
|
||||
"a_c_shepherd",
|
||||
"a_c_rottweiler",
|
||||
"ft-groe"
|
||||
"ft-groe"
|
||||
}
|
||||
|
||||
SmallDogs = {
|
|
@ -246,26 +246,26 @@ RP.Walks = {
|
|||
["Dreyfuss"] = {
|
||||
"move_dreyfuss"
|
||||
},
|
||||
["Drunk"] = {
|
||||
["DrunkWalk"] = {
|
||||
"move_m@drunk@a"
|
||||
},
|
||||
["Drunk2"] = {
|
||||
["DrunkWalk2"] = {
|
||||
"move_m@buzzed",
|
||||
"Drunk 2 - Buzzed"
|
||||
},
|
||||
["Drunk3"] = {
|
||||
["DrunkWalk3"] = {
|
||||
"move_m@drunk@moderatedrunk",
|
||||
"Drunk 3 - Moderate"
|
||||
},
|
||||
["Drunk4"] = {
|
||||
["DrunkWalk4"] = {
|
||||
"move_m@drunk@moderatedrunk_head_up",
|
||||
"Drunk 4 - Moderate 2"
|
||||
},
|
||||
["Drunk5"] = {
|
||||
["DrunkWalk5"] = {
|
||||
"move_m@drunk@slightlydrunk",
|
||||
"Drunk 5 - Slightly Drunk"
|
||||
},
|
||||
["Drunk6"] = {
|
||||
["DrunkWalk6"] = {
|
||||
"move_m@drunk@verydrunk",
|
||||
"Drunk 6 - Very Drunk"
|
||||
},
|
||||
|
@ -442,11 +442,11 @@ RP.Walks = {
|
|||
"move_f@hurry@b",
|
||||
"Hurry Female 2"
|
||||
},
|
||||
["Injured"] = {
|
||||
["InjuredWalk"] = {
|
||||
"move_m@injured",
|
||||
"Injured"
|
||||
},
|
||||
["Injured2"] = {
|
||||
["InjuredWalk2"] = {
|
||||
"move_f@injured",
|
||||
"Injured 2 - Female"
|
||||
},
|
||||
|
@ -6664,7 +6664,7 @@ RP.Emotes = {
|
|||
EmoteMoving = true
|
||||
}
|
||||
},
|
||||
["handshake"] = {
|
||||
["solo_handshake"] = {
|
||||
"mp_ped_interaction",
|
||||
"handshake_guy_a",
|
||||
"Handshake",
|
||||
|
@ -6673,7 +6673,7 @@ RP.Emotes = {
|
|||
EmoteDuration = 3000
|
||||
}
|
||||
},
|
||||
["handshake2"] = {
|
||||
["solo_handshake2"] = {
|
||||
"mp_ped_interaction",
|
||||
"handshake_guy_b",
|
||||
"Handshake 2",
|
||||
|
@ -8026,7 +8026,7 @@ RP.Emotes = {
|
|||
EmoteMoving = true
|
||||
}
|
||||
},
|
||||
["stickup"] = {
|
||||
["solo_stickup"] = {
|
||||
"random@countryside_gang_fight",
|
||||
"biker_02_stickup_loop",
|
||||
"Stick Up",
|
||||
|
@ -8665,7 +8665,7 @@ RP.Emotes = {
|
|||
EmoteMoving = true,
|
||||
}
|
||||
},
|
||||
["slap"] = {
|
||||
["solo_slap"] = {
|
||||
"melee@unarmed@streamed_variations",
|
||||
"plyr_takedown_front_slap",
|
||||
"Slap",
|
||||
|
@ -8675,7 +8675,7 @@ RP.Emotes = {
|
|||
EmoteDuration = 2000
|
||||
}
|
||||
},
|
||||
["headbutt"] = {
|
||||
["solo_headbutt"] = {
|
||||
"melee@unarmed@streamed_variations",
|
||||
"plyr_takedown_front_headbutt",
|
||||
"Headbutt"
|
||||
|
@ -10807,15 +10807,6 @@ RP.Emotes = {
|
|||
EmoteLoop = true,
|
||||
EmoteMoving = false,
|
||||
}
|
||||
},
|
||||
["femaleposeq"] = { -- Custom Emote By DRX Animations
|
||||
"drx@femalestand13",
|
||||
"xrd",
|
||||
"Female Pose Q",
|
||||
AnimationOptions = {
|
||||
EmoteLoop = true,
|
||||
EmoteMoving = false
|
||||
}
|
||||
},
|
||||
["femaleposer"] = { -- Custom Emote By DRX Animations
|
||||
"drx@femalestand14",
|
|
@ -162,7 +162,7 @@ if Config.BinocularsEnabled then
|
|||
end
|
||||
end)
|
||||
|
||||
exports('toggleBinoculars', function()
|
||||
CreateExport('toggleBinoculars', function()
|
||||
UseBinocular()
|
||||
end)
|
||||
end
|
107
resources/[standalone]/rpemotes-reborn/client/Bridge.lua
Normal file
|
@ -0,0 +1,107 @@
|
|||
Framework = 'standalone'
|
||||
PlayerLoaded, PlayerData = nil, {}
|
||||
|
||||
local function InitializeFramework()
|
||||
if GetResourceState('es_extended') == 'started' then
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
Framework = 'esx'
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
|
||||
PlayerData = xPlayer
|
||||
PlayerLoaded = true
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:onPlayerLogout', function()
|
||||
PlayerData = {}
|
||||
PlayerLoaded = false
|
||||
end)
|
||||
|
||||
AddEventHandler('esx:setPlayerData', function(key, value)
|
||||
PlayerData[key] = value
|
||||
end)
|
||||
|
||||
AddEventHandler('onResourceStart', function(resourceName)
|
||||
if GetCurrentResourceName() ~= resourceName then return end
|
||||
PlayerData = ESX.GetPlayerData()
|
||||
PlayerLoaded = true
|
||||
end)
|
||||
elseif GetResourceState('qb-core') == 'started' then
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
Framework = 'qb'
|
||||
|
||||
AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
|
||||
PlayerData = {}
|
||||
end)
|
||||
|
||||
AddEventHandler('onResourceStart', function(resourceName)
|
||||
if GetCurrentResourceName() ~= resourceName then return end
|
||||
PlayerData = QBCore.Functions.GetPlayerData()
|
||||
end)
|
||||
end
|
||||
|
||||
print('[RPEmotes-Reborn] Framework initialized: ' .. Framework)
|
||||
end
|
||||
|
||||
function CanDoAction()
|
||||
if Framework == 'esx' then
|
||||
return PlayerLoaded and not PlayerData.dead
|
||||
elseif Framework == 'qb' then
|
||||
return LocalPlayer.state.isLoggedIn and not (PlayerData.metadata.inlaststand or PlayerData.metadata.isdead)
|
||||
end
|
||||
-- here you can implement your own standalone framework check
|
||||
return true
|
||||
end
|
||||
|
||||
InitializeFramework()
|
||||
|
||||
|
||||
-- EVENTS
|
||||
|
||||
RegisterNetEvent('animations:client:PlayEmote', function(args)
|
||||
if CanDoAction() then
|
||||
EmoteCommandStart(args)
|
||||
end
|
||||
end)
|
||||
|
||||
if Config.Keybinding then
|
||||
RegisterNetEvent('animations:client:BindEmote', function(args)
|
||||
if CanDoAction() then
|
||||
EmoteBindStart(nil, args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteBinds', function()
|
||||
if CanDoAction() then
|
||||
ListKeybinds()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteDelete', function(args)
|
||||
if CanDoAction() then
|
||||
DeleteEmote(args)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteMenu', function()
|
||||
if CanDoAction() then
|
||||
OpenEmoteMenu()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:Walk', function(args)
|
||||
if CanDoAction() then
|
||||
WalkCommandStart(args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('animations:client:ListWalks', function()
|
||||
if CanDoAction() then
|
||||
WalksOnCommand()
|
||||
end
|
||||
end)
|
|
@ -17,10 +17,17 @@ local function ResetCrouch()
|
|||
SetPedCanPlayAmbientAnims(playerPed, true)
|
||||
|
||||
local walkstyle = GetResourceKvpString("walkstyle")
|
||||
if walkstyle ~= nil then
|
||||
RequestWalking(walkstyle)
|
||||
SetPedMovementClipset(PlayerPedId(), walkstyle, 0.5)
|
||||
RemoveClipSet(walkstyle)
|
||||
if walkstyle then
|
||||
local toApply = RP[walkstyle]
|
||||
if not toApply or type(toApply) ~= "table" or toApply.category ~= "Walks" then
|
||||
ResetPedMovementClipset(playerPed, 0.5)
|
||||
DeleteResourceKvp("walkstyle")
|
||||
DebugPrint('Invalid walkstyle found in KVP, resetting to default.')
|
||||
return
|
||||
end
|
||||
RequestWalking(toApply[1])
|
||||
SetPedMovementClipset(PlayerPedId(), toApply[1], 0.5)
|
||||
RemoveClipSet(toApply[1])
|
||||
else
|
||||
ResetPedMovementClipset(playerPed, 0.5)
|
||||
end
|
||||
|
@ -462,36 +469,33 @@ if Config.CrawlEnabled then
|
|||
TriggerEvent('chat:addSuggestion', '/crawl', Translate('crawl'))
|
||||
end
|
||||
|
||||
|
||||
-- Exports --
|
||||
|
||||
---Returns if the player is crouched
|
||||
---@return boolean
|
||||
local function IsPlayerCrouched()
|
||||
return isCrouched
|
||||
end
|
||||
exports('IsPlayerCrouched', IsPlayerCrouched)
|
||||
CreateExport('IsPlayerCrouched', IsPlayerCrouched)
|
||||
|
||||
---Returns if the player is prone (both when laying still and when moving)
|
||||
---@return boolean
|
||||
local function IsPlayerProne()
|
||||
return IsProne
|
||||
end
|
||||
exports('IsPlayerProne', IsPlayerProne)
|
||||
CreateExport('IsPlayerProne', IsPlayerProne)
|
||||
|
||||
---Returns if the player is crawling (only when moving forward/backward)
|
||||
---@return boolean
|
||||
local function IsPlayerCrawling()
|
||||
return isCrawling
|
||||
end
|
||||
exports('IsPlayerCrawling', IsPlayerCrawling)
|
||||
CreateExport('IsPlayerCrawling', IsPlayerCrawling)
|
||||
|
||||
---Returns either "onfront" or "onback", this can be used to check if the player is on his back or on his stomach. NOTE: This will still return a string even if the player is not prone. Use IsPlayerProne() to check if the player is prone.
|
||||
---@return string
|
||||
local function GetPlayerProneType()
|
||||
return proneType
|
||||
end
|
||||
exports('GetPlayerProneType', GetPlayerProneType)
|
||||
CreateExport('GetPlayerProneType', GetPlayerProneType)
|
||||
|
||||
-- Useful to call if the player gets handcuffed etc.
|
||||
exports('StopPlayerProne', stopPlayerProne)
|
||||
CreateExport('StopPlayerProne', stopPlayerProne)
|
895
resources/[standalone]/rpemotes-reborn/client/Emote.lua
Normal file
|
@ -0,0 +1,895 @@
|
|||
-- You probably shouldn't touch these.
|
||||
IsInAnimation = false
|
||||
CurrentAnimationName = nil
|
||||
CurrentTextureVariation = nil
|
||||
InHandsup = false
|
||||
CONVERTED = false
|
||||
|
||||
local ChosenDict = ""
|
||||
local CurrentAnimOptions = false
|
||||
local PlayerGender = "male"
|
||||
local PlayerProps = {}
|
||||
local PreviewPedProps = {}
|
||||
local PtfxNotif = false
|
||||
local PtfxPrompt = false
|
||||
local AnimationThreadStatus = false
|
||||
local CheckStatus = false
|
||||
local CanCancel = true
|
||||
local InExitEmote = false
|
||||
local ExitAndPlay = false
|
||||
local EmoteCancelPlaying = false
|
||||
local currentEmote = {}
|
||||
local attachedProp
|
||||
local scenarioObjects = {
|
||||
`p_amb_coffeecup_01`,
|
||||
`p_amb_joint_01`,
|
||||
`p_cs_ciggy_01`,
|
||||
`p_cs_ciggy_01b_s`,
|
||||
`p_cs_clipboard`,
|
||||
`prop_curl_bar_01`,
|
||||
`p_cs_joint_01`,
|
||||
`p_cs_joint_02`,
|
||||
`prop_acc_guitar_01`,
|
||||
`prop_amb_ciggy_01`,
|
||||
`prop_amb_phone`,
|
||||
`prop_beggers_sign_01`,
|
||||
`prop_beggers_sign_02`,
|
||||
`prop_beggers_sign_03`,
|
||||
`prop_beggers_sign_04`,
|
||||
`prop_bongos_01`,
|
||||
`prop_cigar_01`,
|
||||
`prop_cigar_02`,
|
||||
`prop_cigar_03`,
|
||||
`prop_cs_beer_bot_40oz_02`,
|
||||
`prop_cs_paper_cup`,
|
||||
`prop_cs_trowel`,
|
||||
`prop_fib_clipboard`,
|
||||
`prop_fish_slice_01`,
|
||||
`prop_fishing_rod_01`,
|
||||
`prop_fishing_rod_02`,
|
||||
`prop_notepad_02`,
|
||||
`prop_parking_wand_01`,
|
||||
`prop_rag_01`,
|
||||
`prop_scn_police_torch`,
|
||||
`prop_sh_cigar_01`,
|
||||
`prop_sh_joint_01`,
|
||||
`prop_tool_broom`,
|
||||
`prop_tool_hammer`,
|
||||
`prop_tool_jackham`,
|
||||
`prop_tennis_rack_01`,
|
||||
`prop_weld_torch`,
|
||||
`w_me_gclub`,
|
||||
`p_amb_clipboard_01`
|
||||
}
|
||||
|
||||
if not Config.AnimalEmotesEnabled then
|
||||
RP.AnimalEmotes = {}
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
LocalPlayer.state:set('canEmote', true, true)
|
||||
end)
|
||||
|
||||
local function RunAnimationThread()
|
||||
local pPed = PlayerPedId()
|
||||
if AnimationThreadStatus then return end
|
||||
AnimationThreadStatus = true
|
||||
CreateThread(function()
|
||||
local sleep
|
||||
while AnimationThreadStatus and (IsInAnimation or PtfxPrompt) do
|
||||
sleep = 500
|
||||
|
||||
if IsInAnimation then
|
||||
sleep = 0
|
||||
if IsPlayerAiming(pPed) then
|
||||
EmoteCancel()
|
||||
end
|
||||
if not Config.AllowPunchingDuringEmote then
|
||||
DisableControlAction(2, 140, true)
|
||||
DisableControlAction(2, 141, true)
|
||||
DisableControlAction(2, 142, true)
|
||||
end
|
||||
end
|
||||
|
||||
if PtfxPrompt and CurrentAnimOptions then
|
||||
sleep = 0
|
||||
if not PtfxNotif then
|
||||
SimpleNotify(CurrentAnimOptions.PtfxInfo or Translate('ptfxinfo'))
|
||||
PtfxNotif = true
|
||||
end
|
||||
if IsControlPressed(0, 47) then
|
||||
PtfxStart()
|
||||
Wait(CurrentAnimOptions.PtfxWait)
|
||||
if CurrentAnimOptions.PtfxCanHold then
|
||||
while IsControlPressed(0, 47) and IsInAnimation and AnimationThreadStatus do
|
||||
Wait(5)
|
||||
end
|
||||
end
|
||||
PtfxStop()
|
||||
end
|
||||
end
|
||||
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function CheckStatusThread(dict, anim)
|
||||
CreateThread(function()
|
||||
if CheckStatus then
|
||||
CheckStatus = false
|
||||
Wait(10)
|
||||
end
|
||||
CheckStatus = true
|
||||
while not IsEntityPlayingAnim(PlayerPedId(), dict, anim, 3) do
|
||||
Wait(5)
|
||||
end
|
||||
while CheckStatus and IsInAnimation do
|
||||
if not IsEntityPlayingAnim(PlayerPedId(), dict, anim, 3) then
|
||||
DebugPrint("Animation ended")
|
||||
DestroyAllProps()
|
||||
EmoteCancel()
|
||||
break
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function cleanScenarioObjects(isClone)
|
||||
local ped = isClone and ClonedPed or PlayerPedId()
|
||||
local playerCoords = GetEntityCoords(ped)
|
||||
|
||||
for i = 1, #scenarioObjects do
|
||||
local deleteScenarioObject = GetClosestObjectOfType(playerCoords.x, playerCoords.y, playerCoords.z, 1.0,
|
||||
scenarioObjects[i], false, true, true)
|
||||
if DoesEntityExist(deleteScenarioObject) then
|
||||
SetEntityAsMissionEntity(deleteScenarioObject, false, false)
|
||||
DeleteObject(deleteScenarioObject)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EmoteCancel(force)
|
||||
LocalPlayer.state:set('currentEmote', nil, true)
|
||||
EmoteCancelPlaying = true
|
||||
|
||||
if InExitEmote then
|
||||
return
|
||||
end
|
||||
|
||||
if not CanCancel and not force then return end
|
||||
|
||||
if ChosenDict == "MaleScenario" and IsInAnimation then
|
||||
ClearPedTasksImmediately(PlayerPedId())
|
||||
IsInAnimation = false
|
||||
DebugPrint("Forced scenario exit")
|
||||
elseif ChosenDict == "Scenario" and IsInAnimation then
|
||||
ClearPedTasksImmediately(PlayerPedId())
|
||||
IsInAnimation = false
|
||||
DebugPrint("Forced scenario exit")
|
||||
end
|
||||
|
||||
PtfxNotif = false
|
||||
PtfxPrompt = false
|
||||
Pointing = false
|
||||
|
||||
if IsInAnimation then
|
||||
local ped = PlayerPedId()
|
||||
if LocalPlayer.state.ptfx then
|
||||
PtfxStop()
|
||||
end
|
||||
DetachEntity(ped, true, false)
|
||||
CancelSharedEmote()
|
||||
|
||||
if CurrentAnimOptions and CurrentAnimOptions.ExitEmote then
|
||||
local options = CurrentAnimOptions
|
||||
local ExitEmoteType = options.ExitEmoteType or "Emotes"
|
||||
|
||||
if not RP[options.ExitEmote] then
|
||||
DebugPrint("Exit emote was invalid")
|
||||
IsInAnimation = false
|
||||
ClearPedTasks(ped)
|
||||
return
|
||||
end
|
||||
|
||||
OnEmotePlay(options.ExitEmote)
|
||||
DebugPrint("Playing exit animation")
|
||||
|
||||
local animationOptions = RP[options.ExitEmote].AnimationOptions
|
||||
if animationOptions and animationOptions.EmoteDuration then
|
||||
InExitEmote = true
|
||||
SetTimeout(animationOptions.EmoteDuration, function()
|
||||
InExitEmote = false
|
||||
DestroyAllProps()
|
||||
ClearPedTasks(ped)
|
||||
EmoteCancelPlaying = false
|
||||
end)
|
||||
return
|
||||
end
|
||||
else
|
||||
IsInAnimation = false
|
||||
ClearPedTasks(ped)
|
||||
EmoteCancelPlaying = false
|
||||
end
|
||||
DestroyAllProps()
|
||||
end
|
||||
cleanScenarioObjects(false)
|
||||
AnimationThreadStatus = false
|
||||
CheckStatus = false
|
||||
end
|
||||
|
||||
function EmoteMenuStart(name, category, textureVariation)
|
||||
local emote = RP[name]
|
||||
|
||||
if not emote then
|
||||
return
|
||||
end
|
||||
|
||||
if emote.category ~= category then
|
||||
DebugPrint("Emote category mismatch : " .. emote.category .. " vs " .. category)
|
||||
return
|
||||
end
|
||||
|
||||
if category == "Expressions" then
|
||||
SetPlayerPedExpression(name, true)
|
||||
return
|
||||
end
|
||||
|
||||
if emote.category == "AnimalEmotes" then
|
||||
CheckAnimalAndOnEmotePlay(name)
|
||||
return
|
||||
end
|
||||
|
||||
OnEmotePlay(name, textureVariation)
|
||||
end
|
||||
|
||||
function EmoteMenuStartClone(name, category)
|
||||
if not Config.PreviewPed then return end
|
||||
if not DoesEntityExist(ClonedPed) then return end
|
||||
|
||||
local emote = RP[name]
|
||||
|
||||
if not emote then
|
||||
return
|
||||
end
|
||||
|
||||
if emote.category ~= category then
|
||||
DebugPrint("Emote category mismatch : " .. emote.category .. " vs " .. category)
|
||||
return
|
||||
end
|
||||
|
||||
if category == "Expressions" then
|
||||
SetFacialIdleAnimOverride(ClonedPed, emote[1], true)
|
||||
return
|
||||
end
|
||||
|
||||
OnEmotePlayClone(name)
|
||||
end
|
||||
|
||||
function EmoteCommandStart(args)
|
||||
if #args > 0 then
|
||||
if IsEntityDead(PlayerPedId()) or IsPedRagdoll(PlayerPedId()) or IsPedGettingUp(PlayerPedId()) or IsPedInMeleeCombat(PlayerPedId()) then
|
||||
TriggerEvent('chat:addMessage', {
|
||||
color = { 255, 0, 0 },
|
||||
multiline = true,
|
||||
args = { "RPEmotes", Translate('dead') }
|
||||
})
|
||||
return
|
||||
end
|
||||
if (IsPedSwimming(PlayerPedId()) or IsPedSwimmingUnderWater(PlayerPedId())) and not Config.AllowInWater then
|
||||
TriggerEvent('chat:addMessage', {
|
||||
color = { 255, 0, 0 },
|
||||
multiline = true,
|
||||
args = { "RPEmotes", Translate('swimming') }
|
||||
})
|
||||
return
|
||||
end
|
||||
local name = string.lower(args[1])
|
||||
if name == "c" then
|
||||
if IsInAnimation then
|
||||
EmoteCancel()
|
||||
else
|
||||
EmoteChatMessage(Translate('nocancel'))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local emote = RP[name]
|
||||
if emote then
|
||||
if emote.category == "AnimalEmotes" then
|
||||
if Config.AnimalEmotesEnabled then
|
||||
CheckAnimalAndOnEmotePlay(name)
|
||||
else
|
||||
EmoteChatMessage(Translate('animaldisabled'))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if emote.category == "PropEmotes" and emote.AnimationOptions.PropTextureVariations then
|
||||
if #args > 1 then
|
||||
local textureVariation = tonumber(args[2])
|
||||
if emote.AnimationOptions.PropTextureVariations[textureVariation] then
|
||||
OnEmotePlay(name, textureVariation - 1)
|
||||
return
|
||||
else
|
||||
local str = ""
|
||||
for k, v in ipairs(emote.AnimationOptions.PropTextureVariations) do
|
||||
str = str .. string.format("\n(%s) - %s", k, v.Name)
|
||||
end
|
||||
|
||||
EmoteChatMessage(string.format(Translate('invalidvariation'), str), true)
|
||||
OnEmotePlay(name, 0)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
OnEmotePlay(name)
|
||||
else
|
||||
EmoteChatMessage("'" .. name .. "' " .. Translate('notvalidemote') .. "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CheckAnimalAndOnEmotePlay(name)
|
||||
local playerPed = PlayerPedId()
|
||||
local isValidPet = false
|
||||
|
||||
if string.sub(name, 1, 4) == "bdog" then
|
||||
for _, model in ipairs(BigDogs) do
|
||||
if IsPedModel(playerPed, GetHashKey(model)) then
|
||||
isValidPet = true
|
||||
break
|
||||
end
|
||||
end
|
||||
elseif string.sub(name, 1, 4) == "sdog" then
|
||||
for _, model in ipairs(SmallDogs) do
|
||||
if IsPedModel(playerPed, GetHashKey(model)) then
|
||||
isValidPet = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if isValidPet then
|
||||
OnEmotePlay(name)
|
||||
else
|
||||
EmoteChatMessage(Translate('notvalidpet'))
|
||||
end
|
||||
end
|
||||
|
||||
---@param isClone? boolean
|
||||
function DestroyAllProps(isClone)
|
||||
if isClone then
|
||||
for _, v in pairs(PreviewPedProps) do
|
||||
DeleteEntity(v)
|
||||
end
|
||||
PreviewPedProps = {}
|
||||
else
|
||||
for _, v in pairs(PlayerProps) do
|
||||
DeleteEntity(v)
|
||||
end
|
||||
PlayerProps = {}
|
||||
end
|
||||
DebugPrint("Destroyed Props for " .. (isClone and "clone" or "player"))
|
||||
end
|
||||
|
||||
---@param data table
|
||||
---@return boolean
|
||||
function AddProp(data)
|
||||
assert(data.prop1, 'no prop1 passed')
|
||||
assert(data.bone, 'no bone passed')
|
||||
data.off1 = data.off1 or 0.0
|
||||
data.off2 = data.off2 or 0.0
|
||||
data.off3 = data.off3 or 0.0
|
||||
data.rot1 = data.rot1 or 0.0
|
||||
data.rot2 = data.rot2 or 0.0
|
||||
data.rot3 = data.rot3 or 0.0
|
||||
assert(data.noCollision == nil or type(data.noCollision) == "boolean", 'noCollision must be a boolean')
|
||||
|
||||
local target = data.isClone and ClonedPed or PlayerPedId()
|
||||
local x, y, z = table.unpack(GetEntityCoords(target))
|
||||
|
||||
if not IsModelValid(data.prop1) then
|
||||
DebugPrint(tostring(data.prop1) .. " is not a valid model!")
|
||||
return false
|
||||
end
|
||||
|
||||
LoadPropDict(data.prop1)
|
||||
|
||||
attachedProp = CreateObject(GetHashKey(data.prop1), x, y, z + 0.2, not data.isClone, true, true)
|
||||
|
||||
if data.textureVariation ~= nil then
|
||||
SetObjectTextureVariation(attachedProp, data.textureVariation)
|
||||
end
|
||||
|
||||
if data.noCollision then
|
||||
SetEntityCollision(attachedProp, false, false)
|
||||
end
|
||||
|
||||
AttachEntityToEntity(attachedProp, target, GetPedBoneIndex(target, data.bone), data.off1, data.off2, data.off3, data.rot1, data.rot2, data.rot3,
|
||||
true, true, false, true, 1, true)
|
||||
|
||||
if data.isClone then
|
||||
table.insert(PreviewPedProps, attachedProp)
|
||||
else
|
||||
table.insert(PlayerProps, attachedProp)
|
||||
end
|
||||
|
||||
SetModelAsNoLongerNeeded(data.prop1)
|
||||
DebugPrint("Added prop to " .. (data.isClone and "clone" or "player"))
|
||||
return true
|
||||
end
|
||||
|
||||
function CheckGender()
|
||||
PlayerGender = "male"
|
||||
|
||||
if GetEntityModel(PlayerPedId()) == GetHashKey("mp_f_freemode_01") then
|
||||
PlayerGender = "female"
|
||||
end
|
||||
|
||||
DebugPrint("Set gender to " .. PlayerGender)
|
||||
end
|
||||
|
||||
RegisterNetEvent('animations:ToggleCanDoAnims', function(value)
|
||||
LocalPlayer.state:set('canEmote', value, true)
|
||||
end)
|
||||
|
||||
function OnEmotePlay(name, textureVariation)
|
||||
local emoteData = RP[name]
|
||||
if not emoteData then
|
||||
EmoteChatMessage("'" .. name .. "' " .. Translate('notvalidemote') .. "")
|
||||
return
|
||||
end
|
||||
|
||||
if not LocalPlayer.state.canEmote then return end
|
||||
|
||||
if not DoesEntityExist(PlayerPedId()) then
|
||||
return false
|
||||
end
|
||||
|
||||
cleanScenarioObjects(false)
|
||||
|
||||
InVehicle = IsPedInAnyVehicle(PlayerPedId(), true)
|
||||
Pointing = false
|
||||
|
||||
if not Config.AllowEmoteInVehicle and InVehicle then
|
||||
return
|
||||
end
|
||||
|
||||
if Config.AdultEmotesDisabled and emoteData.AdultAnimation then
|
||||
return EmoteChatMessage(Translate('adultemotedisabled'))
|
||||
end
|
||||
|
||||
if InExitEmote then
|
||||
return false
|
||||
end
|
||||
|
||||
if Config.CancelPreviousEmote and IsInAnimation and not ExitAndPlay and not EmoteCancelPlaying then
|
||||
ExitAndPlay = true
|
||||
DebugPrint("Canceling previous emote and playing next emote")
|
||||
PlayExitAndEnterEmote(name, textureVariation)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
local animOption = emoteData.AnimationOptions
|
||||
if InVehicle then
|
||||
if animOption and animOption.NotInVehicle then
|
||||
return EmoteChatMessage(Translate('not_in_a_vehicle'))
|
||||
end
|
||||
elseif animOption and animOption.onlyInVehicle then
|
||||
return EmoteChatMessage(Translate('in_a_vehicle'))
|
||||
end
|
||||
|
||||
if CurrentAnimOptions and CurrentAnimOptions.ExitEmote and animOption and animOption.ExitEmote then
|
||||
if not (animOption and CurrentAnimOptions.ExitEmote == animOption.ExitEmote) and RP[CurrentAnimOptions.ExitEmote][2] ~= emoteData[2] then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if IsInActionWithErrorMessage() then
|
||||
return false
|
||||
end
|
||||
|
||||
ChosenDict = emoteData[1]
|
||||
local anim = emoteData[2]
|
||||
CurrentAnimationName = name
|
||||
LocalPlayer.state:set('currentEmote', name, true)
|
||||
CurrentTextureVariation = textureVariation
|
||||
CurrentAnimOptions = animOption
|
||||
|
||||
if Config.DisarmPlayerOnEmote then
|
||||
if IsPedArmed(PlayerPedId(), 7) then
|
||||
SetCurrentPedWeapon(PlayerPedId(), GetHashKey('WEAPON_UNARMED'), true)
|
||||
end
|
||||
end
|
||||
|
||||
if animOption and animOption.Prop then
|
||||
DestroyAllProps()
|
||||
end
|
||||
|
||||
if ChosenDict == "MaleScenario" or ChosenDict == "Scenario" or ChosenDict == "ScenarioObject" then
|
||||
if InVehicle then return end
|
||||
CheckGender()
|
||||
ClearPedTasks(PlayerPedId())
|
||||
DestroyAllProps()
|
||||
if ChosenDict == "MaleScenario" then
|
||||
if PlayerGender == "male" then
|
||||
TaskStartScenarioInPlace(PlayerPedId(), anim, 0, true)
|
||||
DebugPrint("Playing scenario = (" .. anim .. ")")
|
||||
else
|
||||
EmoteCancel()
|
||||
EmoteChatMessage(Translate('maleonly'))
|
||||
return
|
||||
end
|
||||
elseif ChosenDict == "ScenarioObject" then
|
||||
local BehindPlayer = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, -0.5, -0.5)
|
||||
TaskStartScenarioAtPosition(PlayerPedId(), anim, BehindPlayer.x, BehindPlayer.y, BehindPlayer.z, GetEntityHeading(PlayerPedId()), 0, true, false)
|
||||
DebugPrint("Playing scenario = (" .. anim .. ")")
|
||||
else
|
||||
TaskStartScenarioInPlace(PlayerPedId(), anim, 0, true)
|
||||
DebugPrint("Playing scenario = (" .. anim .. ")")
|
||||
end
|
||||
IsInAnimation = true
|
||||
RunAnimationThread()
|
||||
return
|
||||
end
|
||||
|
||||
-- Small delay at the start
|
||||
if animOption and animOption.StartDelay then
|
||||
Wait(animOption.StartDelay)
|
||||
end
|
||||
|
||||
if not LoadAnim(ChosenDict) then
|
||||
EmoteChatMessage("'" .. name .. "' " .. Translate('notvalidemote') .. "")
|
||||
return
|
||||
end
|
||||
|
||||
local movementType = 0
|
||||
|
||||
if InVehicle then
|
||||
if animOption and animOption.FullBody then
|
||||
movementType = 35
|
||||
else
|
||||
movementType = 51
|
||||
end
|
||||
elseif animOption then
|
||||
if animOption.EmoteMoving then
|
||||
movementType = 51
|
||||
elseif animOption.EmoteLoop then
|
||||
movementType = 1
|
||||
elseif animOption.EmoteStuck then
|
||||
movementType = 50
|
||||
end
|
||||
end
|
||||
|
||||
DebugPrint("Animation flag = (" .. movementType .. ")")
|
||||
|
||||
if animOption then
|
||||
if animOption.PtfxAsset then
|
||||
Ptfx1, Ptfx2, Ptfx3, Ptfx4, Ptfx5, Ptfx6, PtfxScale = table.unpack(animOption.PtfxPlacement)
|
||||
PtfxNotif = false
|
||||
PtfxPrompt = true
|
||||
RunAnimationThread()
|
||||
TriggerServerEvent("rpemotes:ptfx:sync", animOption.PtfxAsset, animOption.PtfxName, vector3(Ptfx1, Ptfx2, Ptfx3),
|
||||
vector3(Ptfx4, Ptfx5, Ptfx6), animOption.PtfxBone, PtfxScale, animOption.PtfxColor)
|
||||
else
|
||||
PtfxPrompt = false
|
||||
end
|
||||
end
|
||||
|
||||
if IsPedUsingAnyScenario(PlayerPedId()) or IsPedActiveInScenario(PlayerPedId()) then
|
||||
ClearPedTasksImmediately(PlayerPedId())
|
||||
end
|
||||
|
||||
TaskPlayAnim(PlayerPedId(), ChosenDict, anim, animOption?.BlendInSpeed or 5.0, animOption?.BlendOutSpeed or 5.0, animOption?.EmoteDuration or -1, animOption?.Flag or movementType, 0, false, false,
|
||||
false)
|
||||
RemoveAnimDict(ChosenDict)
|
||||
|
||||
IsInAnimation = true
|
||||
RunAnimationThread()
|
||||
|
||||
if not (animOption and animOption.Prop) then
|
||||
CheckStatusThread(ChosenDict, anim)
|
||||
end
|
||||
|
||||
local currentEmoteTable = emoteData
|
||||
for _, tabledata in pairs(RP) do
|
||||
for command, emotedata in pairs(tabledata) do
|
||||
if emotedata == emoteData then
|
||||
table.insert(currentEmoteTable, command)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
currentEmote = currentEmoteTable
|
||||
|
||||
if animOption and animOption.Prop then
|
||||
PropPl1, PropPl2, PropPl3, PropPl4, PropPl5, PropPl6 = table.unpack(animOption.PropPlacement)
|
||||
|
||||
Wait(animOption and animOption.EmoteDuration or 0)
|
||||
|
||||
if not AddProp({
|
||||
prop1 = animOption.Prop,
|
||||
bone = animOption.PropBone,
|
||||
off1 = PropPl1, off2 = PropPl2, off3 = PropPl3,
|
||||
rot1 = PropPl4, rot2 = PropPl5, rot3 = PropPl6,
|
||||
textureVariation = textureVariation,
|
||||
isClone = false,
|
||||
noCollision = animOption.PropNoCollision
|
||||
}) then return end
|
||||
|
||||
if animOption.SecondProp then
|
||||
SecondPropPl1, SecondPropPl2, SecondPropPl3, SecondPropPl4, SecondPropPl5, SecondPropPl6 = table.unpack(animOption.SecondPropPlacement)
|
||||
if not AddProp({
|
||||
prop1 = animOption.SecondProp,
|
||||
bone = animOption.SecondPropBone,
|
||||
off1 = SecondPropPl1, off2 = SecondPropPl2, off3 = SecondPropPl3,
|
||||
rot1 = SecondPropPl4, rot2 = SecondPropPl5, rot3 = SecondPropPl6,
|
||||
textureVariation = textureVariation,
|
||||
isClone = false,
|
||||
noCollision = animOption.SecondPropNoCollision
|
||||
}) then
|
||||
DestroyAllProps()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Ptfx is on the prop, then we need to sync it
|
||||
if not animOption then return end
|
||||
if animOption.PtfxAsset and not animOption.PtfxNoProp then
|
||||
TriggerServerEvent("rpemotes:ptfx:syncProp", ObjToNet(attachedProp))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OnEmotePlayClone(name)
|
||||
if not Config.PreviewPed then return end
|
||||
|
||||
cleanScenarioObjects(true)
|
||||
|
||||
if not DoesEntityExist(ClonedPed) then
|
||||
return false
|
||||
end
|
||||
|
||||
if InExitEmote then
|
||||
return false
|
||||
end
|
||||
|
||||
if Config.CancelPreviousEmote and not ExitAndPlay and not EmoteCancelPlaying then
|
||||
ExitAndPlay = true
|
||||
DebugPrint("Canceling previous emote and playing next emote")
|
||||
return
|
||||
end
|
||||
|
||||
local emoteData = RP[name]
|
||||
local animOption = emoteData.AnimationOptions
|
||||
|
||||
local dict, anim = table.unpack(emoteData)
|
||||
|
||||
if animOption and animOption.Prop then
|
||||
DestroyAllProps(true)
|
||||
end
|
||||
|
||||
if dict == "MaleScenario" or dict == "Scenario" or dict == "ScenarioObject" then
|
||||
CheckGender()
|
||||
ClearPedTasks(ClonedPed)
|
||||
DestroyAllProps(true)
|
||||
if dict == "MaleScenario" then
|
||||
if PlayerGender == "male" then
|
||||
TaskStartScenarioInPlace(ClonedPed, anim, 0, true)
|
||||
end
|
||||
elseif dict == "ScenarioObject" then
|
||||
local BehindPlayer = GetOffsetFromEntityInWorldCoords(ClonedPed, 0.0, -0.5, -0.5)
|
||||
TaskStartScenarioAtPosition(ClonedPed, anim, BehindPlayer.x, BehindPlayer.y, BehindPlayer.z, GetEntityHeading(ClonedPed), 0, true, false)
|
||||
elseif dict == "Scenario" then
|
||||
TaskStartScenarioInPlace(ClonedPed, anim, 0, true)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not LoadAnim(dict) then
|
||||
EmoteChatMessage("'" .. name .. "' " .. Translate('notvalidemote') .. "")
|
||||
return
|
||||
end
|
||||
|
||||
local movementType = 0
|
||||
|
||||
if animOption then
|
||||
if animOption.EmoteMoving then
|
||||
movementType = 51
|
||||
elseif animOption.EmoteLoop then
|
||||
movementType = 1
|
||||
elseif animOption.EmoteStuck then
|
||||
movementType = 50
|
||||
end
|
||||
end
|
||||
|
||||
if IsPedUsingAnyScenario(ClonedPed) or IsPedActiveInScenario(ClonedPed) then
|
||||
ClearPedTasksImmediately(ClonedPed)
|
||||
end
|
||||
|
||||
TaskPlayAnim(ClonedPed, dict, anim, 5.0, 5.0, animOption and animOption.EmoteDuration or -1, animOption?.Flag or movementType, 0, false, false, false)
|
||||
RemoveAnimDict(dict)
|
||||
|
||||
if animOption and animOption.Prop then
|
||||
local PropPl1, PropPl2, PropPl3, PropPl4, PropPl5, PropPl6 = table.unpack(animOption.PropPlacement)
|
||||
|
||||
Wait(animOption and animOption.EmoteDuration or 0)
|
||||
|
||||
if not AddProp({
|
||||
prop1 = animOption.Prop,
|
||||
bone = animOption.PropBone,
|
||||
off1 = PropPl1, off2 = PropPl2, off3 = PropPl3,
|
||||
rot1 = PropPl4, rot2 = PropPl5, rot3 = PropPl6,
|
||||
isClone = true,
|
||||
noCollision = animOption.PropNoCollision
|
||||
}) then return end
|
||||
|
||||
if animOption.SecondProp then
|
||||
local SecondPropPl1, SecondPropPl2, SecondPropPl3, SecondPropPl4, SecondPropPl5, SecondPropPl6 = table.unpack(animOption.SecondPropPlacement)
|
||||
|
||||
if not AddProp({
|
||||
prop1 = animOption.SecondProp,
|
||||
bone = animOption.SecondPropBone,
|
||||
off1 = SecondPropPl1, off2 = SecondPropPl2, off3 = SecondPropPl3,
|
||||
rot1 = SecondPropPl4, rot2 = SecondPropPl5, rot3 = SecondPropPl6,
|
||||
isClone = true,
|
||||
noCollision = animOption.SecondPropNoCollision
|
||||
}) then
|
||||
DestroyAllProps(true)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PlayExitAndEnterEmote(name, textureVariation)
|
||||
local ped = PlayerPedId()
|
||||
if not CanCancel then return end
|
||||
if ChosenDict == "MaleScenario" and IsInAnimation then
|
||||
ClearPedTasksImmediately(ped)
|
||||
IsInAnimation = false
|
||||
DebugPrint("Forced scenario exit")
|
||||
elseif ChosenDict == "Scenario" and IsInAnimation then
|
||||
ClearPedTasksImmediately(ped)
|
||||
IsInAnimation = false
|
||||
DebugPrint("Forced scenario exit")
|
||||
end
|
||||
|
||||
PtfxNotif = false
|
||||
PtfxPrompt = false
|
||||
Pointing = false
|
||||
|
||||
if LocalPlayer.state.ptfx then
|
||||
PtfxStop()
|
||||
end
|
||||
DetachEntity(ped, true, false)
|
||||
CancelSharedEmote()
|
||||
|
||||
if CurrentAnimOptions?.ExitEmote then
|
||||
local options = CurrentAnimOptions or {}
|
||||
|
||||
if not RP[options.ExitEmote] then
|
||||
DebugPrint("Exit emote was invalid")
|
||||
ClearPedTasks(ped)
|
||||
IsInAnimation = false
|
||||
return
|
||||
end
|
||||
OnEmotePlay(options.ExitEmote)
|
||||
DebugPrint("Playing exit animation")
|
||||
|
||||
local animationOptions = RP[options.ExitEmote].AnimationOptions
|
||||
if animationOptions and animationOptions.EmoteDuration then
|
||||
InExitEmote = true
|
||||
SetTimeout(animationOptions.EmoteDuration, function()
|
||||
InExitEmote = false
|
||||
DestroyAllProps(true)
|
||||
ClearPedTasks(ped)
|
||||
OnEmotePlay(name, textureVariation)
|
||||
ExitAndPlay = false
|
||||
end)
|
||||
return
|
||||
end
|
||||
else
|
||||
ClearPedTasks(ped)
|
||||
IsInAnimation = false
|
||||
ExitAndPlay = false
|
||||
DestroyAllProps(true)
|
||||
OnEmotePlay(name, CurrentTextureVariation)
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('animations:client:EmoteCommandStart', function(args)
|
||||
EmoteCommandStart(args)
|
||||
end)
|
||||
|
||||
CreateExport("EmoteCommandStart", function(emoteName, textureVariation)
|
||||
EmoteCommandStart({ emoteName, textureVariation })
|
||||
end)
|
||||
CreateExport("EmoteCancel", EmoteCancel)
|
||||
CreateExport("CanCancelEmote", function(State)
|
||||
CanCancel = State == true
|
||||
end)
|
||||
CreateExport('IsPlayerInAnim', function()
|
||||
return LocalPlayer.state.currentEmote
|
||||
end)
|
||||
CreateExport('getCurrentEmote', function()
|
||||
return currentEmote
|
||||
end)
|
||||
|
||||
-- Door stuff
|
||||
local openingDoor = false
|
||||
AddEventHandler('CEventOpenDoor', function(unk1)
|
||||
if unk1[1] ~= PlayerPedId() then return end
|
||||
if ShowPed then
|
||||
return
|
||||
end
|
||||
|
||||
if not IsInAnimation then
|
||||
return
|
||||
end
|
||||
|
||||
if openingDoor then
|
||||
return
|
||||
end
|
||||
|
||||
openingDoor = true
|
||||
|
||||
while IsPedOpeningADoor(PlayerPedId()) do
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
openingDoor = false
|
||||
|
||||
Wait(200)
|
||||
|
||||
ClearPedTasks(PlayerPedId())
|
||||
DestroyAllProps()
|
||||
OnEmotePlay(CurrentAnimationName, CurrentTextureVariation)
|
||||
end)
|
||||
|
||||
local isBumpingPed = false
|
||||
local timeout = 500
|
||||
|
||||
AddEventHandler("CEventPlayerCollisionWithPed", function(unk1)
|
||||
if unk1[1] ~= PlayerPedId() then return end
|
||||
if not IsInAnimation then
|
||||
return
|
||||
end
|
||||
|
||||
if isBumpingPed then
|
||||
timeout = 500
|
||||
return
|
||||
end
|
||||
isBumpingPed = true
|
||||
timeout = 500
|
||||
-- We wait a bit to avoid collision with the ped resetting the animation again
|
||||
|
||||
while timeout > 0 do
|
||||
Wait(100)
|
||||
timeout = timeout - 100
|
||||
end
|
||||
|
||||
if not IsInAnimation then
|
||||
return
|
||||
end
|
||||
|
||||
isBumpingPed = false
|
||||
ClearPedTasks(PlayerPedId())
|
||||
Wait(125)
|
||||
DestroyAllProps()
|
||||
OnEmotePlay(CurrentAnimationName, CurrentTextureVariation)
|
||||
end)
|
||||
|
||||
AddEventHandler('onResourceStop', function(resource)
|
||||
if resource ~= GetCurrentResourceName() then return end
|
||||
local ped = PlayerPedId()
|
||||
ClosePedMenu()
|
||||
DestroyAllProps()
|
||||
ClearPedTasksImmediately(ped)
|
||||
DetachEntity(ped, true, false)
|
||||
ResetPedMovementClipset(ped, 0.8)
|
||||
end)
|
|
@ -27,39 +27,16 @@ local _menuPool = NativeUI.CreatePool()
|
|||
local mainMenu = NativeUI.CreateMenu(Config.MenuTitle or "", "", menuPosition["x"], menuPosition["y"], menuHeader, menuHeader)
|
||||
_menuPool:Add(mainMenu)
|
||||
|
||||
local sharemenu, shareddancemenu, favmenu, infomenu
|
||||
local sharemenu, shareddancemenu, infomenu
|
||||
|
||||
local EmoteTable = {}
|
||||
local FavEmoteTable = {}
|
||||
local DanceTable = {}
|
||||
local AnimalTable = {}
|
||||
local PropETable = {}
|
||||
local PropTable = {}
|
||||
local WalkTable = {}
|
||||
local FaceTable = {}
|
||||
local ShareTable = {}
|
||||
local FavoriteEmote = ""
|
||||
|
||||
if Config.FavKeybindEnabled then
|
||||
RegisterCommand('emotefav', function() FavKeybind() end, false)
|
||||
RegisterKeyMapping("emotefav", Translate("register_fav_anim"), "keyboard", Config.FavKeybind)
|
||||
|
||||
local doingFavoriteEmote = false
|
||||
|
||||
function FavKeybind()
|
||||
if doingFavoriteEmote == false then
|
||||
doingFavoriteEmote = true
|
||||
if not IsPedSittingInAnyVehicle(PlayerPedId()) then
|
||||
if FavoriteEmote ~= "" and (not CanUseFavKeyBind or CanUseFavKeyBind()) then
|
||||
EmoteCommandStart(nil, { FavoriteEmote, 0 })
|
||||
Wait(500)
|
||||
end
|
||||
end
|
||||
else
|
||||
EmoteCancel()
|
||||
doingFavoriteEmote = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AddEmoteMenu(menu)
|
||||
local submenu = _menuPool:AddSubMenu(menu, Translate('emotes'), "", true, true)
|
||||
|
@ -85,17 +62,7 @@ function AddEmoteMenu(menu)
|
|||
table.insert(EmoteTable, Translate('shareemotes'))
|
||||
end
|
||||
|
||||
-- Temp var to be able to sort every emotes in the fav list
|
||||
local favEmotes = {}
|
||||
if not Config.Keybinding then
|
||||
favmenu = _menuPool:AddSubMenu(submenu, Translate('favoriteemotes'), Translate('favoriteinfo'), true, true)
|
||||
favmenu:AddItem(NativeUI.CreateItem(Translate('prop2info'), ""))
|
||||
favmenu:AddItem(NativeUI.CreateItem(Translate('rfavorite'), Translate('rfavorite')))
|
||||
-- Add two elements as offset
|
||||
table.insert(FavEmoteTable, Translate('rfavorite'))
|
||||
table.insert(FavEmoteTable, Translate('rfavorite'))
|
||||
table.insert(EmoteTable, Translate('favoriteemotes'))
|
||||
else
|
||||
if Config.Keybinding then
|
||||
table.insert(EmoteTable, "keybinds")
|
||||
submenu:AddItem(NativeUI.CreateItem(Translate('keybinds'), Translate('keybindsinfo') .. " /emotebind [~y~num4-9~w~] [~g~emotename~w~]"))
|
||||
end
|
||||
|
@ -104,120 +71,84 @@ function AddEmoteMenu(menu)
|
|||
local x, y, z = table.unpack(b)
|
||||
submenu:AddItem(NativeUI.CreateItem(z, "/e (" .. a .. ")"))
|
||||
table.insert(EmoteTable, a)
|
||||
if not Config.Keybinding then
|
||||
favEmotes[a] = z
|
||||
end
|
||||
end
|
||||
|
||||
for a, b in PairsByKeys(RP.Dances) do
|
||||
local x, y, z = table.unpack(b)
|
||||
dancemenu:AddItem(NativeUI.CreateItem(z, "/e (" .. a .. ")"))
|
||||
local name = '🤼 ' .. b[3]
|
||||
dancemenu:AddItem(NativeUI.CreateItem(name, "/e (" .. a .. ")"))
|
||||
if Config.SharedEmotesEnabled then
|
||||
shareddancemenu:AddItem(NativeUI.CreateItem(z, "/nearby (" .. a .. ")"))
|
||||
shareddancemenu:AddItem(NativeUI.CreateItem(name, "/nearby (" .. a .. ")"))
|
||||
end
|
||||
table.insert(DanceTable, a)
|
||||
if not Config.Keybinding then
|
||||
favEmotes[a] = z
|
||||
end
|
||||
end
|
||||
|
||||
if Config.AnimalEmotesEnabled then
|
||||
for a, b in PairsByKeys(RP.AnimalEmotes) do
|
||||
local x, y, z = table.unpack(b)
|
||||
animalmenu:AddItem(NativeUI.CreateItem(z, "/e (" .. a .. ")"))
|
||||
local name = '🐶 ' .. b[3]
|
||||
animalmenu:AddItem(NativeUI.CreateItem(name, "/e (" .. a .. ")"))
|
||||
table.insert(AnimalTable, a)
|
||||
if not Config.Keybinding then
|
||||
favEmotes[a] = z
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Config.SharedEmotesEnabled then
|
||||
for a, b in PairsByKeys(RP.Shared) do
|
||||
local x, y, z, otheremotename = table.unpack(b)
|
||||
local shareitem = NativeUI.CreateItem(z, "/nearby (~g~" .. a .. "~w~)" .. (otheremotename and " " .. Translate('makenearby') .. " (~y~" .. otheremotename .. "~w~)" or ""))
|
||||
local name = b[3]
|
||||
local shareitem = NativeUI.CreateItem(name, "/nearby (~g~" .. a .. "~w~)" .. (otheremotename and " " .. Translate('makenearby') .. " (~y~" .. otheremotename .. "~w~)" or ""))
|
||||
sharemenu:AddItem(shareitem)
|
||||
table.insert(ShareTable, a)
|
||||
end
|
||||
end
|
||||
|
||||
for a, b in PairsByKeys(RP.PropEmotes) do
|
||||
local x, y, z = table.unpack(b)
|
||||
local name = '📦 ' .. b[3]
|
||||
local propitem = b.AnimationOptions.PropTextureVariations and
|
||||
NativeUI.CreateListItem(z, b.AnimationOptions.PropTextureVariations, 1, "/e (" .. a .. ")") or
|
||||
NativeUI.CreateItem(z, "/e (" .. a .. ")")
|
||||
NativeUI.CreateListItem(name, b.AnimationOptions.PropTextureVariations, 1, "/e (" .. a .. ")") or
|
||||
NativeUI.CreateItem(name, "/e (" .. a .. ")")
|
||||
|
||||
propmenu:AddItem(propitem)
|
||||
|
||||
table.insert(PropETable, a)
|
||||
if not Config.Keybinding then
|
||||
favEmotes[a] = z
|
||||
end
|
||||
table.insert(PropTable, a)
|
||||
end
|
||||
|
||||
if not Config.Keybinding then
|
||||
-- Add the emotes to the fav menu
|
||||
for emoteName, emoteLabel in PairsByKeys(favEmotes) do
|
||||
favmenu:AddItem(NativeUI.CreateItem(emoteLabel, Translate('set') .. emoteLabel .. Translate('setboundemote')))
|
||||
table.insert(FavEmoteTable, emoteName)
|
||||
end
|
||||
|
||||
favmenu.OnItemSelect = function(sender, item, index)
|
||||
if FavEmoteTable[index] == Translate('rfavorite') then
|
||||
FavoriteEmote = ""
|
||||
SimpleNotify(Translate('rfavorite'))
|
||||
return
|
||||
end
|
||||
if Config.FavKeybindEnabled then
|
||||
FavoriteEmote = FavEmoteTable[index]
|
||||
SimpleNotify("~o~" .. FirstToUpper(FavoriteEmote) .. Translate('newsetemote'))
|
||||
end
|
||||
end
|
||||
end
|
||||
favEmotes = nil
|
||||
|
||||
-- Ped Emote on Change Index
|
||||
|
||||
dancemenu.OnIndexChange = function(menu, newindex)
|
||||
dancemenu.OnIndexChange = function(_, newindex)
|
||||
ClearPedTaskPreview()
|
||||
EmoteMenuStartClone(DanceTable[newindex], "dances")
|
||||
EmoteMenuStartClone(DanceTable[newindex], "Dances")
|
||||
end
|
||||
|
||||
propmenu.OnIndexChange = function(menu, newindex)
|
||||
propmenu.OnIndexChange = function(_, newindex)
|
||||
ClearPedTaskPreview()
|
||||
EmoteMenuStartClone(PropETable[newindex], "props")
|
||||
EmoteMenuStartClone(PropTable[newindex], "PropEmotes")
|
||||
end
|
||||
|
||||
submenu.OnIndexChange = function(menu, newindex)
|
||||
if newindex > 6 then
|
||||
submenu.OnIndexChange = function(_, newindex)
|
||||
if newindex > 5 then
|
||||
ClearPedTaskPreview()
|
||||
EmoteMenuStartClone(EmoteTable[newindex], "emotes")
|
||||
EmoteMenuStartClone(EmoteTable[newindex], "Emotes")
|
||||
end
|
||||
end
|
||||
|
||||
dancemenu.OnMenuClosed = function(menu)
|
||||
dancemenu.OnMenuClosed = function()
|
||||
ClearPedTaskPreview()
|
||||
end
|
||||
|
||||
--------
|
||||
|
||||
|
||||
dancemenu.OnItemSelect = function(sender, item, index)
|
||||
EmoteMenuStart(DanceTable[index], "dances")
|
||||
dancemenu.OnItemSelect = function(_, _, index)
|
||||
EmoteMenuStart(DanceTable[index], "Dances")
|
||||
end
|
||||
|
||||
if Config.AnimalEmotesEnabled then
|
||||
animalmenu.OnItemSelect = function(sender, item, index)
|
||||
EmoteMenuStart(AnimalTable[index], "animals")
|
||||
animalmenu.OnItemSelect = function(_, _, index)
|
||||
EmoteMenuStart(AnimalTable[index], "AnimalEmotes")
|
||||
end
|
||||
end
|
||||
|
||||
if Config.SharedEmotesEnabled then
|
||||
sharemenu.OnItemSelect = function(sender, item, index)
|
||||
sharemenu.OnItemSelect = function(_, _, index)
|
||||
if ShareTable[index] ~= 'none' then
|
||||
local target, distance = GetClosestPlayer()
|
||||
if (distance ~= -1 and distance < 3) then
|
||||
TriggerServerEvent("ServerEmoteRequest", GetPlayerServerId(target), ShareTable[index])
|
||||
TriggerServerEvent("rpemotes:server:requestEmote", GetPlayerServerId(target), ShareTable[index])
|
||||
SimpleNotify(Translate('sentrequestto') .. GetPlayerName(target))
|
||||
else
|
||||
SimpleNotify(Translate('nobodyclose'))
|
||||
|
@ -225,10 +156,10 @@ function AddEmoteMenu(menu)
|
|||
end
|
||||
end
|
||||
|
||||
shareddancemenu.OnItemSelect = function(sender, item, index)
|
||||
shareddancemenu.OnItemSelect = function(_, _, index)
|
||||
local target, distance = GetClosestPlayer()
|
||||
if (distance ~= -1 and distance < 3) then
|
||||
TriggerServerEvent("ServerEmoteRequest", GetPlayerServerId(target), DanceTable[index], 'Dances')
|
||||
TriggerServerEvent("rpemotes:server:requestEmote", GetPlayerServerId(target), DanceTable[index], 'Dances')
|
||||
SimpleNotify(Translate('sentrequestto') .. GetPlayerName(target))
|
||||
else
|
||||
SimpleNotify(Translate('nobodyclose'))
|
||||
|
@ -236,23 +167,23 @@ function AddEmoteMenu(menu)
|
|||
end
|
||||
end
|
||||
|
||||
propmenu.OnItemSelect = function(sender, item, index)
|
||||
EmoteMenuStart(PropETable[index], "props")
|
||||
propmenu.OnItemSelect = function(_, _, index)
|
||||
EmoteMenuStart(PropTable[index], "PropEmotes")
|
||||
end
|
||||
|
||||
propmenu.OnListSelect = function(menu, item, itemIndex, listIndex)
|
||||
EmoteMenuStart(PropETable[itemIndex], "props", item:IndexToItem(listIndex).Value)
|
||||
propmenu.OnListSelect = function(_, item, itemIndex, listIndex)
|
||||
EmoteMenuStart(PropTable[itemIndex], "PropEmotes", item:IndexToItem(listIndex).Value)
|
||||
end
|
||||
|
||||
submenu.OnItemSelect = function(sender, item, index)
|
||||
submenu.OnItemSelect = function(_, _, index)
|
||||
if Config.Search and EmoteTable[index] == Translate('searchemotes') then
|
||||
EmoteMenuSearch(submenu)
|
||||
elseif EmoteTable[index] ~= Translate('favoriteemotes') then
|
||||
EmoteMenuStart(EmoteTable[index], "emotes")
|
||||
else
|
||||
EmoteMenuStart(EmoteTable[index], "Emotes")
|
||||
end
|
||||
end
|
||||
|
||||
submenu.OnMenuClosed = function(menu)
|
||||
submenu.OnMenuClosed = function()
|
||||
if not isSearching then
|
||||
ClosePedMenu()
|
||||
end
|
||||
|
@ -269,7 +200,6 @@ if Config.Search then
|
|||
|
||||
function EmoteMenuSearch(lastMenu)
|
||||
ClosePedMenu()
|
||||
local favEnabled = not Config.Keybinding and Config.FavKeybindEnabled
|
||||
AddTextEntry("PM_NAME_CHALL", Translate('searchinputtitle'))
|
||||
DisplayOnscreenKeyboard(1, "PM_NAME_CHALL", "", "", "", "", "", 30)
|
||||
while UpdateOnscreenKeyboard() == 0 do
|
||||
|
@ -279,12 +209,10 @@ if Config.Search then
|
|||
local input = GetOnscreenKeyboardResult()
|
||||
if input ~= nil then
|
||||
local results = {}
|
||||
for k, v in pairs(RP) do
|
||||
if not ignoredCategories[k] then
|
||||
for a, b in pairs(v) do
|
||||
if string.find(string.lower(a), string.lower(input)) or (b[3] ~= nil and string.find(string.lower(b[3]), string.lower(input))) then
|
||||
table.insert(results, {table = k, name = a, data = b})
|
||||
end
|
||||
for a, b in pairs(RP) do
|
||||
if not ignoredCategories[b.category] then
|
||||
if string.find(string.lower(a), string.lower(input)) or (b[3] ~= nil and string.find(string.lower(b[3]), string.lower(input))) then
|
||||
table.insert(results, { table = b.category, name = a, data = b })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -294,9 +222,6 @@ if Config.Search then
|
|||
|
||||
local searchMenu = _menuPool:AddSubMenu(lastMenu, string.format('%s '..Translate('searchmenudesc')..' ~r~%s~w~', #results, input), "", true, true)
|
||||
local sharedDanceMenu
|
||||
if favEnabled then
|
||||
searchMenu:AddItem(NativeUI.CreateItem(Translate('rfavorite'), Translate('rfavorite')))
|
||||
end
|
||||
|
||||
if Config.SharedEmotesEnabled then
|
||||
sharedDanceMenu = _menuPool:AddSubMenu(searchMenu, Translate('sharedanceemotes'), "", true, true)
|
||||
|
@ -313,7 +238,7 @@ if Config.Search then
|
|||
desc = "/nearby (~g~" .. v.name .. "~w~) " .. Translate('makenearby') .. " (~y~" .. otheremotename .. "~w~)"
|
||||
end
|
||||
else
|
||||
desc = "/e (" .. v.name .. ")" .. (favEnabled and "\n" .. Translate('searchshifttofav') or "")
|
||||
desc = "/e (" .. v.name .. ")"
|
||||
end
|
||||
|
||||
if v.data.AnimationOptions and v.data.AnimationOptions.PropTextureVariations then
|
||||
|
@ -327,79 +252,52 @@ if Config.Search then
|
|||
end
|
||||
end
|
||||
|
||||
if favEnabled then
|
||||
table.insert(results, 1, Translate('rfavorite'))
|
||||
end
|
||||
|
||||
|
||||
searchMenu.OnMenuChanged = function(menu, newmenu, forward)
|
||||
searchMenu.OnMenuChanged = function()
|
||||
isSearching = false
|
||||
ShowPedMenu()
|
||||
end
|
||||
|
||||
|
||||
searchMenu.OnIndexChange = function(menu, newindex)
|
||||
searchMenu.OnIndexChange = function(_, newindex)
|
||||
local data = results[newindex]
|
||||
|
||||
ClearPedTaskPreview()
|
||||
if data.table == "Emotes" or data.table == "Dances" then
|
||||
EmoteMenuStartClone(data.name, string.lower(data.table))
|
||||
elseif data.table == "PropEmotes" then
|
||||
EmoteMenuStartClone(data.name, "props")
|
||||
elseif data.table == "AnimalEmotes" then
|
||||
EmoteMenuStartClone(data.name, "animals")
|
||||
end
|
||||
EmoteMenuStartClone(data.name, data.data.category)
|
||||
end
|
||||
|
||||
|
||||
searchMenu.OnItemSelect = function(sender, item, index)
|
||||
searchMenu.OnItemSelect = function(_, _, index)
|
||||
local data = results[index]
|
||||
|
||||
if data == Translate('sharedanceemotes') then return end
|
||||
if data == Translate('rfavorite') then
|
||||
FavoriteEmote = ""
|
||||
SimpleNotify(Translate('rfavorite'))
|
||||
return
|
||||
end
|
||||
|
||||
if favEnabled and IsControlPressed(0, 21) then
|
||||
if data.table ~= "Shared" then
|
||||
FavoriteEmote = data.name
|
||||
SimpleNotify("~o~" .. FirstToUpper(data.name) .. Translate('newsetemote'))
|
||||
else
|
||||
SimpleNotify(Translate('searchcantsetfav'))
|
||||
end
|
||||
elseif data.table == "Emotes" or data.table == "Dances" then
|
||||
EmoteMenuStart(data.name, string.lower(data.table))
|
||||
elseif data.table == "PropEmotes" then
|
||||
EmoteMenuStart(data.name, "props")
|
||||
elseif data.table == "AnimalEmotes" then
|
||||
EmoteMenuStart(data.name, "animals")
|
||||
elseif data.table == "Shared" then
|
||||
if data.table == "Shared" then
|
||||
local target, distance = GetClosestPlayer()
|
||||
if (distance ~= -1 and distance < 3) then
|
||||
TriggerServerEvent("ServerEmoteRequest", GetPlayerServerId(target), data.name)
|
||||
TriggerServerEvent("rpemotes:server:requestEmote", GetPlayerServerId(target), data.name)
|
||||
SimpleNotify(Translate('sentrequestto') .. GetPlayerName(target))
|
||||
else
|
||||
SimpleNotify(Translate('nobodyclose'))
|
||||
end
|
||||
else
|
||||
EmoteMenuStart(data.name, data.data.category)
|
||||
end
|
||||
end
|
||||
|
||||
searchMenu.OnListSelect = function(menu, item, itemIndex, listIndex)
|
||||
EmoteMenuStart(results[itemIndex].name, "props", item:IndexToItem(listIndex).Value)
|
||||
searchMenu.OnListSelect = function(_, item, itemIndex, listIndex)
|
||||
EmoteMenuStart(results[itemIndex].name, "PropEmotes", item:IndexToItem(listIndex).Value)
|
||||
end
|
||||
|
||||
if Config.SharedEmotesEnabled then
|
||||
if #sharedDanceMenu.Items > 0 then
|
||||
table.insert(results, (favEnabled and 2 or 1), Translate('sharedanceemotes'))
|
||||
sharedDanceMenu.OnItemSelect = function(sender, item, index)
|
||||
table.insert(results, 1, Translate('sharedanceemotes'))
|
||||
sharedDanceMenu.OnItemSelect = function(_, _, index)
|
||||
if not LocalPlayer.state.canEmote then return end
|
||||
|
||||
local data = results[index]
|
||||
local target, distance = GetClosestPlayer()
|
||||
if (distance ~= -1 and distance < 3) then
|
||||
TriggerServerEvent("ServerEmoteRequest", GetPlayerServerId(target), data.name, 'Dances')
|
||||
TriggerServerEvent("rpemotes:server:requestEmote", GetPlayerServerId(target), data.name, 'Dances')
|
||||
SimpleNotify(Translate('sentrequestto') .. GetPlayerName(target))
|
||||
else
|
||||
SimpleNotify(Translate('nobodyclose'))
|
||||
|
@ -407,7 +305,7 @@ if Config.Search then
|
|||
end
|
||||
else
|
||||
sharedDanceMenu:Clear()
|
||||
searchMenu:RemoveItemAt((favEnabled and 2 or 1))
|
||||
searchMenu:RemoveItemAt(1)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -439,8 +337,8 @@ function AddCancelEmote(menu)
|
|||
end
|
||||
|
||||
ShowPedPreview = function(menu)
|
||||
menu.OnItemSelect = function(sender, item, index)
|
||||
if (index == 1) then
|
||||
menu.OnItemSelect = function(_, _, index)
|
||||
if index == 1 then
|
||||
isSearching = false
|
||||
ShowPedMenu()
|
||||
elseif index == 4 then
|
||||
|
@ -458,20 +356,19 @@ function AddWalkMenu(menu)
|
|||
|
||||
local sortedWalks = {}
|
||||
for a, b in PairsByKeys(RP.Walks) do
|
||||
local x, label = table.unpack(b)
|
||||
if x == "move_m@injured" then
|
||||
table.insert(sortedWalks, 1, {label = label or a, anim = x})
|
||||
if b[1] == "move_m@injured" then
|
||||
table.insert(sortedWalks, 1, {label = a, anim = b[1]})
|
||||
else
|
||||
table.insert(sortedWalks, {label = label or a, anim = x})
|
||||
table.insert(sortedWalks, {label = a, anim = b[1]})
|
||||
end
|
||||
end
|
||||
|
||||
for _, walk in ipairs(sortedWalks) do
|
||||
submenu:AddItem(NativeUI.CreateItem(walk.label, "/walk (" .. string.lower(walk.label) .. ")"))
|
||||
table.insert(WalkTable, walk.anim)
|
||||
table.insert(WalkTable, walk.label)
|
||||
end
|
||||
|
||||
submenu.OnItemSelect = function(sender, item, index)
|
||||
submenu.OnItemSelect = function(_, item, index)
|
||||
if item == walkreset then
|
||||
ResetWalk()
|
||||
DeleteResourceKvp("walkstyle")
|
||||
|
@ -495,26 +392,26 @@ function AddFaceMenu(menu)
|
|||
end
|
||||
|
||||
|
||||
submenu.OnMenuClosed = function(menu)
|
||||
ClosePedMenu()
|
||||
submenu.OnIndexChange = function(_, newindex)
|
||||
EmoteMenuStartClone(FaceTable[newindex], "Expressions")
|
||||
end
|
||||
|
||||
submenu.OnIndexChange = function(menu, newindex)
|
||||
EmoteMenuStartClone(FaceTable[newindex], "expression")
|
||||
end
|
||||
|
||||
submenu.OnItemSelect = function(sender, item, index)
|
||||
if item ~= facereset then
|
||||
EmoteMenuStart(FaceTable[index], "expression")
|
||||
else
|
||||
DeleteResourceKvp("expression")
|
||||
submenu.OnItemSelect = function(_, item, index)
|
||||
if item == facereset then
|
||||
DeleteResourceKvp("Expressions")
|
||||
ClearFacialIdleAnimOverride(PlayerPedId())
|
||||
else
|
||||
EmoteMenuStart(FaceTable[index], "Expressions")
|
||||
end
|
||||
end
|
||||
|
||||
submenu.OnMenuClosed = function()
|
||||
ClosePedMenu()
|
||||
end
|
||||
end
|
||||
|
||||
function AddInfoMenu(menu)
|
||||
infomenu = _menuPool:AddSubMenu(menu, Translate('infoupdate'), "~h~~y~The RPEmotes Team & Collaborators~h~~y~", true, true)
|
||||
infomenu = _menuPool:AddSubMenu(menu, Translate('infoupdate'), "~h~~y~The RPEmotes Developers~h~~y~", true, true)
|
||||
|
||||
for _,v in ipairs(Config.Credits) do
|
||||
local item = NativeUI.CreateItem(v.title,v.subtitle or "")
|
||||
|
@ -549,21 +446,51 @@ function OpenEmoteMenu()
|
|||
end
|
||||
end
|
||||
|
||||
LoadAddonEmotes()
|
||||
AddEmoteMenu(mainMenu)
|
||||
AddCancelEmote(mainMenu)
|
||||
if Config.PreviewPed then
|
||||
ShowPedPreview(mainMenu)
|
||||
end
|
||||
if Config.WalkingStylesEnabled then
|
||||
AddWalkMenu(mainMenu)
|
||||
end
|
||||
if Config.ExpressionsEnabled then
|
||||
AddFaceMenu(mainMenu)
|
||||
end
|
||||
AddInfoMenu(mainMenu)
|
||||
CreateThread(function()
|
||||
LoadAddonEmotes()
|
||||
AddEmoteMenu(mainMenu)
|
||||
AddCancelEmote(mainMenu)
|
||||
if Config.PreviewPed then
|
||||
ShowPedPreview(mainMenu)
|
||||
end
|
||||
if Config.WalkingStylesEnabled then
|
||||
AddWalkMenu(mainMenu)
|
||||
end
|
||||
if Config.ExpressionsEnabled then
|
||||
AddFaceMenu(mainMenu)
|
||||
end
|
||||
AddInfoMenu(mainMenu)
|
||||
|
||||
_menuPool:RefreshIndex()
|
||||
_menuPool:RefreshIndex()
|
||||
|
||||
local newRP = {}
|
||||
for emoteType, content in pairs(RP) do
|
||||
for emoteName, emoteData in pairs(content) do
|
||||
local shouldRemove = false
|
||||
|
||||
if Config.AdultEmotesDisabled and emoteData.AdultAnimation then
|
||||
shouldRemove = true
|
||||
end
|
||||
if newRP[emoteName] then
|
||||
print('WARNING - Duplicate emote name found: ' .. emoteName .. ' in ' .. emoteType .. ' and ' .. newRP[emoteName].category)
|
||||
end
|
||||
if shouldRemove then
|
||||
elseif type(emoteData) == "table" then
|
||||
newRP[emoteName] = {}
|
||||
for k, v in pairs(emoteData) do
|
||||
newRP[emoteName][k] = v
|
||||
end
|
||||
newRP[emoteName].category = emoteType
|
||||
else
|
||||
newRP[emoteName] = { emoteData }
|
||||
newRP[emoteName].category = emoteType
|
||||
end
|
||||
end
|
||||
newRP[emoteType] = nil
|
||||
end
|
||||
RP = newRP
|
||||
CONVERTED = true
|
||||
end)
|
||||
|
||||
local isMenuProcessing = false
|
||||
function ProcessMenu()
|
||||
|
@ -576,17 +503,6 @@ function ProcessMenu()
|
|||
isMenuProcessing = false
|
||||
end
|
||||
|
||||
RegisterNetEvent("rp:Update", function(state)
|
||||
UpdateAvailable = state
|
||||
AddInfoMenu(mainMenu)
|
||||
_menuPool:RefreshIndex()
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rp:RecieveMenu", function()
|
||||
OpenEmoteMenu()
|
||||
end)
|
||||
|
||||
|
||||
-- While ped is dead, don't show menus
|
||||
CreateThread(function()
|
||||
while true do
|
|
@ -1,46 +1,37 @@
|
|||
function SetPlayerPedExpression(expression, saveToKvp)
|
||||
SetFacialIdleAnimOverride(PlayerPedId(), expression, 0)
|
||||
if Config.PersistentExpression and saveToKvp then SetResourceKvp("expression", expression) end
|
||||
end
|
||||
|
||||
local function DisplayExpressions()
|
||||
local moodsString = ""
|
||||
for name, _ in pairs(RP.Expressions) do
|
||||
moodsString = moodsString .. string.lower(name) .. ", "
|
||||
local emote = RP[expression]
|
||||
if emote and emote.category == "Expressions" then
|
||||
SetFacialIdleAnimOverride(PlayerPedId(), emote[1], 0)
|
||||
if Config.PersistentExpression and saveToKvp then SetResourceKvp("expression", emote[1]) end
|
||||
else
|
||||
ClearFacialIdleAnimOverride(PlayerPedId())
|
||||
DeleteResourceKvp("expression")
|
||||
end
|
||||
|
||||
EmoteChatMessage(moodsString)
|
||||
EmoteChatMessage("To reset do /mood reset")
|
||||
end
|
||||
|
||||
if Config.ExpressionsEnabled then
|
||||
RegisterCommand('mood', function(_source, args, _raw)
|
||||
local expression = FirstToUpper(string.lower(args[1]))
|
||||
if RP.Expressions[expression] ~= nil then
|
||||
SetPlayerPedExpression(RP.Expressions[expression][1], true)
|
||||
local emote = RP[expression]
|
||||
if emote and emote.category == "Expressions" then
|
||||
SetPlayerPedExpression(RP[expression][1], true)
|
||||
elseif expression == "Reset" then
|
||||
ClearFacialIdleAnimOverride(PlayerPedId())
|
||||
DeleteResourceKvp("expression")
|
||||
else
|
||||
EmoteChatMessage("'" .. expression .. "' is not a valid mood, do /moods to see all moods.")
|
||||
EmoteChatMessage("'" .. expression .. "' is not a valid mood")
|
||||
end
|
||||
end, false)
|
||||
|
||||
RegisterCommand('moods', function()
|
||||
DisplayExpressions()
|
||||
end, false)
|
||||
|
||||
-- Chat Suggestions
|
||||
TriggerEvent('chat:addSuggestion', '/mood', 'Set your current mood/expression.',
|
||||
{ { name = "expression", help = "/moods for a list of valid moods" } })
|
||||
TriggerEvent('chat:addSuggestion', '/moods', 'List available walking moods/expressions.')
|
||||
|
||||
|
||||
-- Load the expression once the player has spawned. Standalone, QBCore and ESX --
|
||||
local function LoadPersistentExpression()
|
||||
local expression = GetResourceKvpString("expression")
|
||||
if expression then
|
||||
Wait(2500) -- Delay, to ensure the player ped has loaded in
|
||||
Wait(2500)
|
||||
SetPlayerPedExpression(expression, false)
|
||||
end
|
||||
end
|
||||
|
@ -50,4 +41,10 @@ if Config.ExpressionsEnabled then
|
|||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', LoadPersistentExpression)
|
||||
RegisterNetEvent('esx:playerLoaded', LoadPersistentExpression)
|
||||
end
|
||||
|
||||
AddEventHandler('onResourceStart', function(resource)
|
||||
if resource == GetCurrentResourceName() then
|
||||
LoadPersistentExpression()
|
||||
end
|
||||
end)
|
||||
end
|
86
resources/[standalone]/rpemotes-reborn/client/Handsup.lua
Normal file
|
@ -0,0 +1,86 @@
|
|||
local function HandsUpLoop()
|
||||
CreateThread(function()
|
||||
while InHandsup do
|
||||
if Config.DisabledHandsupControls then
|
||||
for control, state in pairs(Config.DisabledHandsupControls) do
|
||||
DisableControlAction(0, control, state)
|
||||
end
|
||||
end
|
||||
|
||||
if IsPlayerAiming(PlayerId()) then
|
||||
ClearPedSecondaryTask(PlayerPedId())
|
||||
CreateThread(function()
|
||||
Wait(350)
|
||||
InHandsup = false
|
||||
end)
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if Config.HandsupEnabled then
|
||||
local function ToggleHandsUp(commandType)
|
||||
RegisterCommand(commandType, function()
|
||||
if IsPedInAnyVehicle(PlayerPedId(), false) and not Config.HandsupInCar and not InHandsup then
|
||||
return
|
||||
end
|
||||
Handsup()
|
||||
end, false)
|
||||
end
|
||||
|
||||
if Config.HoldToHandsUp then
|
||||
ToggleHandsUp('+handsup')
|
||||
ToggleHandsUp('-handsup')
|
||||
else
|
||||
ToggleHandsUp('handsup')
|
||||
end
|
||||
|
||||
function Handsup()
|
||||
local playerPed = PlayerPedId()
|
||||
if not IsPedHuman(playerPed) then
|
||||
return
|
||||
end
|
||||
if IsInActionWithErrorMessage() then
|
||||
return
|
||||
end
|
||||
|
||||
InHandsup = not InHandsup
|
||||
if InHandsup then
|
||||
LocalPlayer.state:set('currentEmote', 'handsup', true)
|
||||
DestroyAllProps()
|
||||
local dict = "random@mugging3"
|
||||
RequestAnimDict(dict)
|
||||
while not HasAnimDictLoaded(dict) do
|
||||
Wait(0)
|
||||
end
|
||||
TaskPlayAnim(PlayerPedId(), dict, "handsup_standing_base", 3.0, 3.0, -1, 49, 0, false,
|
||||
IsThisModelABike(GetEntityModel(GetVehiclePedIsIn(PlayerPedId(), false))) and 4127 or false, false)
|
||||
HandsUpLoop()
|
||||
else
|
||||
LocalPlayer.state:set('currentEmote', nil, true)
|
||||
ClearPedSecondaryTask(PlayerPedId())
|
||||
if Config.ReplayEmoteAfterHandsup and IsInAnimation then
|
||||
local emote = RP[CurrentAnimationName]
|
||||
if not emote then
|
||||
return
|
||||
end
|
||||
|
||||
Wait(400)
|
||||
DestroyAllProps()
|
||||
OnEmotePlay(CurrentAnimationName, CurrentTextureVariation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/handsup', Translate('handsup'))
|
||||
|
||||
if Config.HandsupKeybindEnabled then
|
||||
RegisterKeyMapping("handsup", Translate('register_handsup'), "keyboard", Config.HandsupKeybind)
|
||||
end
|
||||
|
||||
CreateExport('IsPlayerInHandsUp', function()
|
||||
return InHandsup
|
||||
end)
|
||||
end
|
96
resources/[standalone]/rpemotes-reborn/client/Keybinds.lua
Normal file
|
@ -0,0 +1,96 @@
|
|||
CreateThread(function()
|
||||
TriggerEvent('chat:addSuggestion', '/e', Translate('play_emote'),
|
||||
{ { name = "emotename", help = Translate('help_command') },
|
||||
{ name = "texturevariation", help = Translate('help_variation') } })
|
||||
TriggerEvent('chat:addSuggestion', '/emote', Translate('play_emote'),
|
||||
{ { name = "emotename", help = Translate('help_command') },
|
||||
{ name = "texturevariation", help = Translate('help_variation') } })
|
||||
if Config.Keybinding then
|
||||
TriggerEvent('chat:addSuggestion', '/emotebind', Translate('link_emote_keybind'),
|
||||
{ { name = "key", help = "num4, num5, num6, num7. num8, num9. Numpad 4-9!" },
|
||||
{ name = "emotename", help = Translate('help_command') } })
|
||||
TriggerEvent('chat:addSuggestion', '/emotebinds', Translate('show_emote_keybind'))
|
||||
TriggerEvent('chat:addSuggestion', '/emotedelete', Translate('remove_emote_keybind'),
|
||||
{ { name = "key", help = "num4, num5, num6, num7. num8, num9. Numpad 4-9!" } })
|
||||
end
|
||||
TriggerEvent('chat:addSuggestion', '/emotemenu', Translate('open_menu_emote'))
|
||||
TriggerEvent('chat:addSuggestion', '/emotes', Translate('show_list_emote'))
|
||||
TriggerEvent('chat:addSuggestion', '/emotecancel', Translate('cancel_emote'))
|
||||
end)
|
||||
|
||||
RegisterCommand('e', function(source, args, raw) EmoteCommandStart(args) end, false)
|
||||
RegisterCommand('emote', function(source, args, raw) EmoteCommandStart(args) end, false)
|
||||
RegisterCommand('emotecancel', function() EmoteCancel() end, false)
|
||||
|
||||
if Config.MenuKeybindEnabled then
|
||||
RegisterCommand('emoteui', function() OpenEmoteMenu() end, false)
|
||||
RegisterKeyMapping("emoteui", Translate('register_open_menu'), "keyboard", Config.MenuKeybind)
|
||||
else
|
||||
RegisterCommand('emotemenu', function() OpenEmoteMenu() end, false)
|
||||
end
|
||||
|
||||
if Config.EnableCancelKeybind then
|
||||
RegisterKeyMapping("emotecancel", Translate('register_cancel_emote'), "keyboard", Config.CancelEmoteKey)
|
||||
end
|
||||
|
||||
-- BINDING EMOTES TO KEYS
|
||||
if Config.Keybinding then
|
||||
RegisterCommand('emotebind', function(source, args, raw) EmoteBindStart(source, args, raw) end, false)
|
||||
RegisterCommand('emotebinds', function(source, args, raw) ListKeybinds() end, false)
|
||||
RegisterCommand('emotedelete', function(source, args) DeleteEmote(args) end, false)
|
||||
|
||||
for i = 1, #Config.KeybindKeys do
|
||||
local cmd = string.format('emoteSelect%s', i)
|
||||
RegisterCommand(cmd, function()
|
||||
local emote = GetResourceKvpString(string.format('%s_emob%s', Config.keybindKVP, i))
|
||||
if emote and emote ~= "" then
|
||||
EmoteCommandStart({ emote, 0 })
|
||||
end
|
||||
end, false)
|
||||
RegisterKeyMapping(cmd, string.format('Emote bind %s', i), 'keyboard', Config.KeybindKeys[i])
|
||||
end
|
||||
|
||||
function EmoteBindStart(source, args, raw)
|
||||
if #args > 0 then
|
||||
local numkey = tonumber(args[1])
|
||||
local emote = string.lower(args[2])
|
||||
if not (numkey and emote) then
|
||||
DebugPrint('Invalid arguments to EmoteBindStart')
|
||||
return
|
||||
end
|
||||
if type(numkey) == "number" then
|
||||
if RP[emote] then
|
||||
SetResourceKvp(string.format('%s_emob%s', Config.keybindKVP, numkey), emote)
|
||||
else
|
||||
EmoteChatMessage("'" .. emote .. "' " .. Translate('notvalidemote') .. "")
|
||||
end
|
||||
else
|
||||
EmoteChatMessage("'" .. numkey .. "' " .. Translate('notvalidkey'))
|
||||
end
|
||||
else
|
||||
DebugPrint('Invalid number of arguments to EmoteBindStart')
|
||||
end
|
||||
end
|
||||
|
||||
function ListKeybinds()
|
||||
for i = 1, #Config.KeybindKeys do
|
||||
local emote = GetResourceKvpString(string.format('%s_emob%s', Config.keybindKVP, i))
|
||||
if emote then
|
||||
EmoteChatMessage(string.format('Emote %s : %s',i, emote))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DeleteEmote(args)
|
||||
if #args > 0 then
|
||||
local numkey = tonumber(args[1])
|
||||
if type(numkey) == "number" then
|
||||
DeleteResourceKvp(string.format('%s_emob%s', Config.keybindKVP, numkey))
|
||||
else
|
||||
EmoteChatMessage("'" .. numkey .. "' " .. Translate('notvalidkey'))
|
||||
end
|
||||
else
|
||||
DebugPrint("invalid")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -239,7 +239,7 @@ if Config.NewscamEnabled then
|
|||
end
|
||||
end)
|
||||
|
||||
exports('toggleNewscam', function()
|
||||
CreateExport('toggleNewscam', function()
|
||||
UseNewscam()
|
||||
end)
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
if not Config.NoIdleCam then return end
|
||||
if not Config.DisableIdleCam then return end
|
||||
|
||||
RegisterCommand('idlecamoff', function() -- help2 31, 167, 9
|
||||
TriggerEvent('chat:addMessage', {
|
65
resources/[standalone]/rpemotes-reborn/client/PTFX.lua
Normal file
|
@ -0,0 +1,65 @@
|
|||
local PlayerParticles = {}
|
||||
|
||||
function PtfxThis(asset)
|
||||
while not HasNamedPtfxAssetLoaded(asset) do
|
||||
RequestNamedPtfxAsset(asset)
|
||||
Wait(10)
|
||||
end
|
||||
UseParticleFxAsset(asset)
|
||||
end
|
||||
|
||||
function PtfxStart()
|
||||
LocalPlayer.state:set('ptfx', true, true)
|
||||
end
|
||||
|
||||
function PtfxStop()
|
||||
LocalPlayer.state:set('ptfx', nil, true)
|
||||
end
|
||||
|
||||
AddStateBagChangeHandler('ptfx', '', function(bagName, key, value, _unused, replicated)
|
||||
local plyId = tonumber(bagName:gsub('player:', ''), 10)
|
||||
|
||||
if (PlayerParticles[plyId] and value) or (not PlayerParticles[plyId] and not value) then return end
|
||||
|
||||
local ply = GetPlayerFromServerId(plyId)
|
||||
if ply <= 0 then return end
|
||||
|
||||
local plyPed = GetPlayerPed(ply)
|
||||
if not DoesEntityExist(plyPed) then return end
|
||||
|
||||
local stateBag = Player(plyId).state
|
||||
|
||||
if value then
|
||||
local boneIndex = stateBag.ptfxBone and GetPedBoneIndex(plyPed, stateBag.ptfxBone) or GetEntityBoneIndexByName(stateBag.ptfxName, "VFX")
|
||||
local entityTarget = plyPed
|
||||
|
||||
if stateBag.ptfxPropNet then
|
||||
local propObj = NetToObj(stateBag.ptfxPropNet)
|
||||
if DoesEntityExist(propObj) then
|
||||
entityTarget = propObj
|
||||
end
|
||||
end
|
||||
|
||||
PtfxThis(stateBag.ptfxAsset)
|
||||
|
||||
local offset = stateBag.ptfxOffset
|
||||
local rot = stateBag.ptfxRot
|
||||
PlayerParticles[plyId] = StartNetworkedParticleFxLoopedOnEntityBone(stateBag.ptfxName, entityTarget, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, boneIndex, (stateBag.ptfxScale or 1) + 0.0, false, false, false)
|
||||
|
||||
local color = stateBag.ptfxColor
|
||||
if color then
|
||||
if color[1] and type(color[1]) == 'table' then
|
||||
local randomIndex = math.random(1, #color)
|
||||
color = color[randomIndex]
|
||||
end
|
||||
SetParticleFxLoopedAlpha(PlayerParticles[plyId], color.A)
|
||||
SetParticleFxLoopedColour(PlayerParticles[plyId], color.R / 255, color.G / 255, color.B / 255, false)
|
||||
end
|
||||
DebugPrint("Started PTFX: " .. PlayerParticles[plyId])
|
||||
else
|
||||
DebugPrint("Stopped PTFX: " .. PlayerParticles[plyId])
|
||||
StopParticleFxLooped(PlayerParticles[plyId], false)
|
||||
RemoveNamedPtfxAsset(stateBag.ptfxAsset)
|
||||
PlayerParticles[plyId] = nil
|
||||
end
|
||||
end)
|
|
@ -23,15 +23,15 @@ local function PointingStopped()
|
|||
ClearPedSecondaryTask(playerPed)
|
||||
end
|
||||
RemoveAnimDict("anim@mp_point")
|
||||
if Config.PersistentEmoteAfterPointing and IsInAnimation then
|
||||
local emote = RP.Emotes[CurrentAnimationName] or RP.PropEmotes[CurrentAnimationName] or RP.Dances[CurrentAnimationName] or RP.AnimalEmotes[CurrentAnimationName]
|
||||
if Config.ReplayEmoteAfterPointing and IsInAnimation then
|
||||
local emote = RP[CurrentAnimationName]
|
||||
if not emote then
|
||||
return
|
||||
end
|
||||
|
||||
Wait(400)
|
||||
DestroyAllProps()
|
||||
OnEmotePlay(emote, CurrentAnimationName, CurrentTextureVariation)
|
||||
OnEmotePlay(CurrentAnimationName, CurrentTextureVariation)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -103,7 +103,7 @@ end
|
|||
-- Commands & KeyMapping --
|
||||
if Config.PointingEnabled then
|
||||
RegisterCommand('pointing', function()
|
||||
if IsPedInAnyVehicle(PlayerPedId(), false) and not Config.PointingKeybindInCarEnabled then
|
||||
if IsPedInAnyVehicle(PlayerPedId(), false) and not Config.PointingInCar then
|
||||
return
|
||||
end
|
||||
StartPointing()
|
||||
|
@ -117,11 +117,8 @@ if Config.PointingEnabled then
|
|||
end
|
||||
|
||||
|
||||
-- Exports --
|
||||
|
||||
---@return boolean
|
||||
local function IsPlayerPointing()
|
||||
return Pointing
|
||||
end
|
||||
|
||||
exports('IsPlayerPointing', IsPlayerPointing)
|
||||
CreateExport('IsPlayerPointing', IsPlayerPointing)
|
|
@ -16,7 +16,7 @@ if Config.RagdollEnabled then
|
|||
isRagdolling = true
|
||||
end
|
||||
|
||||
while not isRagdolling do
|
||||
while isRagdolling do
|
||||
ped = PlayerPedId()
|
||||
SetPedRagdollForceFall(ped)
|
||||
ResetPedRagdollTimer(ped)
|
|
@ -1,5 +1,4 @@
|
|||
local isRequestAnim = false
|
||||
local requestedemote = ''
|
||||
local targetPlayerId
|
||||
|
||||
if Config.SharedEmotesEnabled then
|
||||
|
@ -13,9 +12,9 @@ if Config.SharedEmotesEnabled then
|
|||
local emotename = string.lower(args[1])
|
||||
local target, distance = GetClosestPlayer()
|
||||
if (distance ~= -1 and distance < 3) then
|
||||
if RP.Shared[emotename] ~= nil then
|
||||
local _, _, ename = table.unpack(RP.Shared[emotename])
|
||||
TriggerServerEvent("ServerEmoteRequest", GetPlayerServerId(target), emotename)
|
||||
if RP[emotename] ~= nil and RP[emotename].category == "Shared" then
|
||||
local _, _, ename = table.unpack(RP[emotename])
|
||||
TriggerServerEvent("rpemotes:server:requestEmote", GetPlayerServerId(target), emotename)
|
||||
SimpleNotify(Translate('sentrequestto') ..
|
||||
GetPlayerName(target) .. " ~w~(~g~" .. ename .. "~w~)")
|
||||
else
|
||||
|
@ -30,7 +29,7 @@ if Config.SharedEmotesEnabled then
|
|||
end, false)
|
||||
end
|
||||
|
||||
RegisterNetEvent("SyncPlayEmote", function(emote, player)
|
||||
RegisterNetEvent("rpemotes:client:syncEmote", function(emote, player)
|
||||
EmoteCancel()
|
||||
Wait(300)
|
||||
targetPlayerId = player
|
||||
|
@ -40,12 +39,11 @@ RegisterNetEvent("SyncPlayEmote", function(emote, player)
|
|||
return EmoteChatMessage(Translate('not_in_a_vehicle'))
|
||||
end
|
||||
|
||||
-- wait a little to make sure animation shows up right on both clients after canceling any previous emote
|
||||
if RP.Shared[emote] then
|
||||
local options = RP.Shared[emote].AnimationOptions
|
||||
if RP[emote] then
|
||||
local options = RP[emote].AnimationOptions
|
||||
if options and options.Attachto then
|
||||
local targetEmote = RP.Shared[emote][4]
|
||||
if not targetEmote or not RP.Shared[targetEmote] or not RP.Shared[targetEmote].AnimationOptions or not RP.Shared[targetEmote].AnimationOptions.Attachto then
|
||||
local targetEmote = RP[emote][4]
|
||||
if not targetEmote or not RP[targetEmote] or not RP[targetEmote].AnimationOptions or not RP[targetEmote].AnimationOptions.Attachto then
|
||||
local ped = PlayerPedId()
|
||||
local pedInFront = GetPlayerPed(plyServerId ~= 0 and plyServerId or GetClosestPlayer())
|
||||
|
||||
|
@ -69,17 +67,14 @@ RegisterNetEvent("SyncPlayEmote", function(emote, player)
|
|||
end
|
||||
end
|
||||
|
||||
OnEmotePlay(RP.Shared[emote], emote)
|
||||
return
|
||||
elseif RP.Dances[emote] then
|
||||
OnEmotePlay(RP.Dances[emote], emote)
|
||||
OnEmotePlay(emote)
|
||||
return
|
||||
else
|
||||
DebugPrint("SyncPlayEmote : Emote not found")
|
||||
DebugPrint("rpemotes:client:syncEmote : Emote not found")
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("SyncPlayEmoteSource", function(emote, player)
|
||||
RegisterNetEvent("rpemotes:client:syncEmoteSource", function(emote, player)
|
||||
local ped = PlayerPedId()
|
||||
local plyServerId = GetPlayerFromServerId(player)
|
||||
local pedInFront = GetPlayerPed(plyServerId ~= 0 and plyServerId or GetClosestPlayer())
|
||||
|
@ -88,9 +83,8 @@ RegisterNetEvent("SyncPlayEmoteSource", function(emote, player)
|
|||
return EmoteChatMessage(Translate('not_in_a_vehicle'))
|
||||
end
|
||||
|
||||
local options = RP.Shared[emote] and RP.Shared[emote].AnimationOptions or RP.Dances[emote] and RP.Dances[emote].AnimationOptions
|
||||
local options = RP[emote] and RP[emote].AnimationOptions
|
||||
if options then
|
||||
|
||||
if (options.Attachto) then
|
||||
AttachEntityToEntity(
|
||||
ped,
|
||||
|
@ -112,24 +106,21 @@ RegisterNetEvent("SyncPlayEmoteSource", function(emote, player)
|
|||
end
|
||||
end
|
||||
|
||||
local coords = GetOffsetFromEntityInWorldCoords(pedInFront, (options?.SyncOffsetSide or 0) + 0.0, (options?.SyncOffsetFront or 1) + 0.0, (options?.SyncOffsetHeight or 0) + 0.0)
|
||||
local coords = GetOffsetFromEntityInWorldCoords(pedInFront, (options and options.SyncOffsetSide or 0) + 0.0, (options and options.SyncOffsetFront or 1) + 0.0, (options and options.SyncOffsetHeight or 0) + 0.0)
|
||||
local heading = GetEntityHeading(pedInFront)
|
||||
SetEntityHeading(ped, heading - (options?.SyncOffsetHeading or 180) + 0.0)
|
||||
SetEntityHeading(ped, heading - (options and options.SyncOffsetHeading or 180) + 0.0)
|
||||
SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z)
|
||||
EmoteCancel()
|
||||
Wait(300)
|
||||
|
||||
targetPlayerId = player
|
||||
if RP.Shared[emote] ~= nil then
|
||||
OnEmotePlay(RP.Shared[emote], emote)
|
||||
return
|
||||
elseif RP.Dances[emote] ~= nil then
|
||||
OnEmotePlay(RP.Dances[emote], emote)
|
||||
if RP[emote] ~= nil then
|
||||
OnEmotePlay(emote)
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("SyncCancelEmote", function(player)
|
||||
RegisterNetEvent("rpemotes:client:cancelEmote", function(player)
|
||||
if targetPlayerId and targetPlayerId == player then
|
||||
targetPlayerId = nil
|
||||
EmoteCancel()
|
||||
|
@ -138,15 +129,15 @@ end)
|
|||
|
||||
function CancelSharedEmote()
|
||||
if targetPlayerId then
|
||||
TriggerServerEvent("ServerEmoteCancel", targetPlayerId)
|
||||
TriggerServerEvent("rpemotes:server:cancelEmote", targetPlayerId)
|
||||
targetPlayerId = nil
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent("ClientEmoteRequestReceive", function(emotename, etype, target)
|
||||
RegisterNetEvent("rpemotes:client:requestEmote", function(emotename, etype, target)
|
||||
isRequestAnim = true
|
||||
|
||||
local displayed = (etype == 'Dances') and select(3, table.unpack(RP.Dances[emotename])) or select(3, table.unpack(RP.Shared[emotename]))
|
||||
local displayed = RP[emotename] and select(3, table.unpack(RP[emotename]))
|
||||
|
||||
PlaySound(-1, "NAV", "HUD_AMMO_SHOP_SOUNDSET", false, 0, true)
|
||||
SimpleNotify(Translate('doyouwanna') .. displayed .. "~w~)")
|
||||
|
@ -163,8 +154,8 @@ RegisterNetEvent("ClientEmoteRequestReceive", function(emotename, etype, target)
|
|||
if IsControlJustPressed(1, 246) then
|
||||
isRequestAnim = false
|
||||
|
||||
local otheremote = RP.Shared[emotename] and RP.Shared[emotename][4] or RP.Dances[emotename] and RP.Dances[emotename][4] or emotename
|
||||
TriggerServerEvent("ServerValidEmote", target, emotename, otheremote)
|
||||
local otheremote = RP[emotename] and RP[emotename][4] or emotename
|
||||
TriggerServerEvent("rpemotes:server:confirmEmote", target, emotename, otheremote)
|
||||
elseif IsControlJustPressed(1, 182) then
|
||||
isRequestAnim = false
|
||||
SimpleNotify(Translate('refuseemote'))
|
|
@ -1,5 +1,3 @@
|
|||
LocalPlayer.state:set('canEmote', true, true) -- Allow emotes to be played by default
|
||||
|
||||
-- You can edit this function to add support for your favorite notification system
|
||||
function SimpleNotify(message)
|
||||
if Config.NotificationsAsChatMessage then
|
||||
|
@ -11,6 +9,16 @@ function SimpleNotify(message)
|
|||
end
|
||||
end
|
||||
|
||||
-- Don't touch after this line if you don't know what you're doing
|
||||
CreateExport = function(name, func)
|
||||
AddEventHandler('__cfx_export_rpemotes_'..name, function(setCb)
|
||||
setCb(function(...)
|
||||
return func(...)
|
||||
end)
|
||||
end)
|
||||
exports(name, func)
|
||||
end
|
||||
|
||||
function DebugPrint(...)
|
||||
if Config.DebugDisplay then
|
||||
print(...)
|
||||
|
@ -100,11 +108,10 @@ function LoadAnim(dict)
|
|||
end
|
||||
|
||||
function LoadPropDict(model)
|
||||
-- load the model if it's not loaded and wait until it's loaded or timeout
|
||||
if not HasModelLoaded(joaat(model)) then
|
||||
RequestModel(joaat(model))
|
||||
if not HasModelLoaded(GetHashKey(model)) then
|
||||
RequestModel(GetHashKey(model))
|
||||
local timeout = 2000
|
||||
while not HasModelLoaded(joaat(model)) and timeout > 0 do
|
||||
while not HasModelLoaded(GetHashKey(model)) and timeout > 0 do
|
||||
Wait(5)
|
||||
timeout = timeout - 5
|
||||
end
|
||||
|
@ -140,8 +147,10 @@ end
|
|||
|
||||
function NearbysOnCommand(source, args, raw)
|
||||
local NearbysCommand = ""
|
||||
for a in PairsByKeys(RP.Shared) do
|
||||
NearbysCommand = NearbysCommand .. "" .. a .. ", "
|
||||
for a, b in PairsByKeys(RP) do
|
||||
if type(b) == "table" and b.category == "Shared" then
|
||||
NearbysCommand = NearbysCommand .. a .. ", "
|
||||
end
|
||||
end
|
||||
EmoteChatMessage(NearbysCommand)
|
||||
EmoteChatMessage(Translate('emotemenucmd'))
|
||||
|
@ -185,7 +194,7 @@ end
|
|||
|
||||
---@param ignores? table | nil key string is the ignored value
|
||||
function IsInActionWithErrorMessage(ignores)
|
||||
DebugPrint(ignores)
|
||||
if ignores then DebugPrint(ignores) end
|
||||
DebugPrint('IsProne', IsProne)
|
||||
DebugPrint('IsUsingNewscam', IsUsingNewscam)
|
||||
DebugPrint('IsUsingBinoculars', IsUsingBinoculars)
|
|
@ -11,11 +11,17 @@ function WalkMenuStart(name, force)
|
|||
ResetWalk()
|
||||
return
|
||||
end
|
||||
if not RP[name] or type(RP[name]) ~= "table" or RP[name].category ~= "Walks" then
|
||||
EmoteChatMessage("'" .. tostring(name) .. "' is not a valid walk")
|
||||
return
|
||||
end
|
||||
|
||||
local walk = RP[name][1]
|
||||
RequestWalking(walk)
|
||||
SetPedMovementClipset(PlayerPedId(), walk, 0.2)
|
||||
RemoveAnimSet(walk)
|
||||
|
||||
if Config.PersistentWalk then SetResourceKvp("walkstyle", name) end
|
||||
RequestWalking(name)
|
||||
SetPedMovementClipset(PlayerPedId(), name, 0.2)
|
||||
RemoveAnimSet(name)
|
||||
end
|
||||
|
||||
function ResetWalk()
|
||||
|
@ -28,8 +34,10 @@ end
|
|||
|
||||
function WalksOnCommand()
|
||||
local WalksCommand = ""
|
||||
for a in PairsByKeys(RP.Walks) do
|
||||
WalksCommand = WalksCommand .. "" .. string.lower(a) .. ", "
|
||||
for name, data in PairsByKeys(RP) do
|
||||
if type(data) == "table" and data.category == "Walks" then
|
||||
WalksCommand = WalksCommand .. string.lower(name) .. ", "
|
||||
end
|
||||
end
|
||||
EmoteChatMessage(WalksCommand)
|
||||
EmoteChatMessage("To reset do /walk reset")
|
||||
|
@ -48,23 +56,21 @@ function WalkCommandStart(name)
|
|||
return
|
||||
end
|
||||
|
||||
if TableHasKey(RP.Walks, name) then
|
||||
local name2 = table.unpack(RP.Walks[name])
|
||||
WalkMenuStart(name2)
|
||||
else
|
||||
EmoteChatMessage("'" .. name .. "' is not a valid walk")
|
||||
end
|
||||
WalkMenuStart(name, true)
|
||||
end
|
||||
|
||||
-- Persistent Walkstyles are stored to KVP. Once the player has spawned, the walkstyle is applied.
|
||||
|
||||
if Config.WalkingStylesEnabled and Config.PersistentWalk then
|
||||
-- Function to check if walkstyle is available to prevent exploiting
|
||||
local function walkstyleExists(kvp)
|
||||
for _, v in pairs(RP.Walks) do
|
||||
if v[1] == kvp then
|
||||
return true
|
||||
end
|
||||
while not CONVERTED do
|
||||
Wait(0)
|
||||
end
|
||||
if not kvp or kvp == "" then
|
||||
return false
|
||||
end
|
||||
|
||||
local walkstyle = RP[kvp]
|
||||
if walkstyle and type(walkstyle) == "table" and walkstyle.category == "Walks" then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
@ -104,15 +110,15 @@ if Config.WalkingStylesEnabled then
|
|||
TriggerEvent('chat:addSuggestion', '/walks', 'List available walking styles.')
|
||||
end
|
||||
|
||||
exports('toggleWalkstyle', function(bool, message)
|
||||
CreateExport('toggleWalkstyle', function(bool, message)
|
||||
canChange = bool
|
||||
if message then
|
||||
unable_message = message
|
||||
end
|
||||
end)
|
||||
|
||||
exports('getWalkstyle', function()
|
||||
CreateExport('getWalkstyle', function()
|
||||
return GetResourceKvpString("walkstyle")
|
||||
end)
|
||||
|
||||
exports('setWalkstyle', WalkMenuStart)
|
||||
CreateExport('setWalkstyle', WalkMenuStart)
|
164
resources/[standalone]/rpemotes-reborn/config.lua
Normal file
|
@ -0,0 +1,164 @@
|
|||
-- FOR ALL KEYBINDS, GET THE BUTTON STRING HERE: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
|
||||
|
||||
Config = {
|
||||
MenuLanguage = 'de', -- Change the language of the menu here
|
||||
|
||||
EnableCancelKeybind = true,
|
||||
CancelEmoteKey = 'X',
|
||||
|
||||
MenuKeybindEnabled = true,
|
||||
MenuKeybind = 'F4',
|
||||
|
||||
Keybinding = false,
|
||||
keybindKVP = "rpemotes",
|
||||
NotificationsAsChatMessage = false,
|
||||
Search = true, -- Used to enable or disable the search feature in the menu.
|
||||
CancelPreviousEmote = false, -- If turned on, playing an emote will cancel the previous one.
|
||||
DisableControlsInMenu = false,
|
||||
|
||||
MenuTitle = '',
|
||||
TitleOutline = true,
|
||||
TitleColour = { R = 255, G = 0, B = 255, A = 255 },
|
||||
MenuPosition = 'right', -- 'left' / 'right'
|
||||
CustomMenuEnabled = true, -- Change the header.png to your own image
|
||||
|
||||
-- Combat Car, and Player Movement
|
||||
DisarmPlayerOnEmote = false,
|
||||
AllowPunchingDuringEmote = false,
|
||||
AllowEmoteInVehicle = true,
|
||||
AllowInWater = false,
|
||||
|
||||
-- Ragdoll
|
||||
RagdollEnabled = false,
|
||||
RagdollKeybind = 'U',
|
||||
|
||||
RagdollAsToggle = true,
|
||||
|
||||
-- Expressions, Walks, and More
|
||||
ExpressionsEnabled = true,
|
||||
PersistentExpression = true,
|
||||
|
||||
WalkingStylesEnabled = true,
|
||||
PersistentWalk = true,
|
||||
SharedEmotesEnabled = true,
|
||||
AdultEmotesDisabled = false,
|
||||
AnimalEmotesEnabled = true,
|
||||
|
||||
-- Hands Up
|
||||
HandsupEnabled = false,
|
||||
HandsupKeybind = 'Y',
|
||||
HandsupKeybindEnabled = false,
|
||||
HandsupInCar = false,
|
||||
ReplayEmoteAfterHandsup = true,
|
||||
HoldToHandsUp = false,
|
||||
|
||||
-- Pointing
|
||||
PointingEnabled = true,
|
||||
PointingKeybindEnabled = true,
|
||||
PointingKeybind = 'B',
|
||||
PointingInCar = false,
|
||||
ReplayEmoteAfterPointing = true,
|
||||
|
||||
-- Crouching
|
||||
CrouchEnabled = true,
|
||||
CrouchKeybindEnabled = true,
|
||||
CrouchKeybind = 'LCONTROL',
|
||||
CrouchOverrideStealthMode = false, -- If true, you won't enter stealth mode even if the crouch key and the 'duck' key are the same.
|
||||
FpsMode = false, -- set this to true if you have first-person shooting to disable the ability to crouch and shoot in third-person
|
||||
|
||||
-- Crawling
|
||||
CrawlEnabled = true,
|
||||
CrawlKeybindEnabled = true,
|
||||
CrawlKeybind = 'RCONTROL',
|
||||
|
||||
-- Binocular (/binoculars)
|
||||
BinocularsEnabled = false,
|
||||
AllowVisionsToggling = false,
|
||||
|
||||
-- News Camera (/newscam)
|
||||
NewscamEnabled = true,
|
||||
|
||||
DisableIdleCam = true,
|
||||
|
||||
-- Preview Ped : Shows a preview of the emote on the player's ped next to the emote menu. Note that resmon will increase when this when emotes are being previewed.
|
||||
PreviewPed = false,
|
||||
|
||||
CheckForUpdates = true,
|
||||
DebugDisplay = false,
|
||||
}
|
||||
|
||||
Config.KeybindKeys = {
|
||||
'NUMPAD1',
|
||||
'NUMPAD2',
|
||||
'NUMPAD3',
|
||||
'NUMPAD4',
|
||||
'NUMPAD5',
|
||||
'NUMPAD6',
|
||||
'NUMPAD7',
|
||||
'NUMPAD8',
|
||||
'NUMPAD9'
|
||||
}
|
||||
|
||||
Config.DisabledHandsupControls = {
|
||||
[36] = true, -- INPUT_DUCK
|
||||
[44] = true, -- INPUT_COVER
|
||||
[53] = true, -- INPUT_WEAPON_SPECIAL
|
||||
[54] = true, -- INPUT_WEAPON_SPECIAL_TWO
|
||||
[59] = true, -- INPUT_VEH_MOVE_LR
|
||||
[60] = true, -- INPUT_VEH_MOVE_UD
|
||||
[61] = true, -- INPUT_VEH_MOVE_UP_ONLY
|
||||
[62] = true, -- INPUT_VEH_MOVE_DOWN_ONLY
|
||||
[63] = true, -- INPUT_VEH_MOVE_LEFT_ONLY
|
||||
[64] = true, -- INPUT_VEH_MOVE_RIGHT_ONLY
|
||||
[65] = true, -- INPUT_VEH_SPECIAL
|
||||
[66] = true, -- INPUT_VEH_GUN_LR
|
||||
[67] = true, -- INPUT_VEH_GUN_UD
|
||||
[69] = true, -- INPUT_VEH_ATTACK
|
||||
[70] = true, -- INPUT_VEH_ATTACK2
|
||||
[71] = true, -- INPUT_VEH_ACCELERATE
|
||||
[72] = true, -- INPUT_VEH_BRAKE
|
||||
[73] = true, -- INPUT_VEH_DUCK
|
||||
[74] = true, -- INPUT_VEH_HEADLIGHT
|
||||
[77] = true, -- INPUT_VEH_HOTWIRE_LEFT
|
||||
[78] = true, -- INPUT_VEH_HOTWIRE_RIGHT
|
||||
[80] = true, -- INPUT_VEH_CIN_CAM
|
||||
[86] = true, -- INPUT_VEH_HORN
|
||||
[91] = true, -- INPUT_VEH_PASSENGER_AIM
|
||||
[102] = true, -- INPUT_VEH_JUMP
|
||||
[104] = true, -- INPUT_VEH_SHUFFLE
|
||||
[105] = true, -- INPUT_VEH_DROP_PROJECTILE
|
||||
[136] = true, -- INPUT_VEH_PUSHBIKE_PEDAL
|
||||
[137] = true, -- INPUT_VEH_PUSHBIKE_SPRINT
|
||||
[139] = true, -- INPUT_VEH_PUSHBIKE_REAR_BRAKE
|
||||
[140] = true, -- INPUT_MELEE_ATTACK_LIGHT
|
||||
[141] = true, -- INPUT_MELEE_ATTACK_HEAVY
|
||||
[142] = true, -- INPUT_MELEE_ATTACK_ALTERNATE
|
||||
[143] = true, -- INPUT_MELEE_BLOCK
|
||||
[337] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_TOGGLE
|
||||
[338] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_LEFT
|
||||
[339] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_RIGHT
|
||||
[340] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_UP
|
||||
[341] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_DOWN
|
||||
[342] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_UD
|
||||
[343] = true, -- INPUT_VEH_HYDRAULICS_CONTROL_LR
|
||||
[351] = true, -- INPUT_VEH_ROCKET_BOOST
|
||||
[354] = true, -- INPUT_VEH_BIKE_WINGS
|
||||
[357] = true, -- INPUT_VEH_TRANSFORM
|
||||
[345] = true, -- INPUT_VEH_MELEE_HOLD
|
||||
[346] = true, -- INPUT_VEH_MELEE_LEFT
|
||||
[347] = true, -- INPUT_VEH_MELEE_RIGHT
|
||||
}
|
||||
|
||||
Config.Credits = {
|
||||
{ title = "<b>Thanks to the community<b>", subtitle = "For supporting and using RP Emotes!" },
|
||||
{ title = "Thanks ~o~DullPear 🍐~s~", subtitle = "~o~DullPear~s~ for the original dpemotes ❤️" },
|
||||
{ title = "Thanks <font color=\"#ff451d\">Mathu_lmn 🇫🇷 </font>", subtitle = "<font color=\"#ff451d\">Mathu_lmn 🇫🇷</font> Maintainer, additional features and fixes 🛠️" },
|
||||
{ title = "Thanks <font color=\"#ff451d\">Enzo2991 🇧🇪 </font>", subtitle = "<font color=\"#ff451d\">Enzo2991 🇧🇪 </font> for creating the ped preview functionality, keybind with kvp" },
|
||||
{ title = "Thanks <b>Kibook 🐩</b>", subtitle = "<b>Kibook</b> for the addition of Animal Emotes 🐩 submenu." },
|
||||
{ title = "Thanks ~y~AvaN0x 🇫🇷~s~", subtitle = "~y~AvaN0x~s~ 🇫🇷 for reformatting and assisting with code and additional features 🙏" },
|
||||
{ title = "Thanks <font color=\"#40E0D0\">iSentrie </font>", subtitle = "<font color=\"#40E0D0\">iSentrie</font> for assisting with code 🛠️" },
|
||||
{ title = "Thanks <font color=\"#0e64ed\">Mads 🤖</font>", subtitle = "<font color=\"#0e64ed\">Mads 🤖</font> for the addition of Exit Emotes, Crouch & Crawl ⚙️" },
|
||||
{ title = "Thanks <font color=\"#ff00c3\">Tigerle 🐯</font>", subtitle = "<font color=\"#ff00c3\">Tigerle</font> for assisting with attached Shared Emotes ⚙️." },
|
||||
{ title = "Thanks <font color=\"#1C9369\">northsqrd ⚙️</font>", subtitle = "<font color=\"#1C9369\">northsqrd</font> for assisting with search feature and phone colours 🔎" },
|
||||
{ title = "Thanks <font color=\"#15BCEC\">GeekGarage 🤓</font>", subtitle = "<font color=\"#15BCEC\">GeekGarage</font> for assisting with code and features" },
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
fx_version 'cerulean'
|
||||
game 'gta5'
|
||||
description 'rpemotes-reborn'
|
||||
version '1.8.5'
|
||||
version '1.9.0'
|
||||
|
||||
lua54 'yes'
|
||||
use_experimental_fxv2_oal 'yes'
|
||||
|
@ -9,7 +9,6 @@ use_experimental_fxv2_oal 'yes'
|
|||
provide "rpemotes"
|
||||
|
||||
dependencies {
|
||||
-- '/server:7290',
|
||||
'/server:6683',
|
||||
'/onesync'
|
||||
}
|
||||
|
@ -31,12 +30,12 @@ shared_scripts {
|
|||
server_scripts {
|
||||
'server/Server.lua',
|
||||
'server/Updates.lua',
|
||||
'server/frameworks/*.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'NativeUI.lua',
|
||||
'client/Utils.lua',
|
||||
'client/Bridge.lua',
|
||||
'client/AnimationList.lua',
|
||||
'client/AnimationListCustom.lua',
|
||||
'client/Binoculars.lua',
|
||||
|
@ -44,14 +43,15 @@ client_scripts {
|
|||
'client/Emote.lua',
|
||||
'client/EmoteMenu.lua',
|
||||
'client/Expressions.lua',
|
||||
'client/Handsup.lua',
|
||||
'client/Keybinds.lua',
|
||||
'client/NewsCam.lua',
|
||||
'client/NoIdleCam.lua',
|
||||
'client/Pointing.lua',
|
||||
'client/PTFX.lua',
|
||||
'client/Ragdoll.lua',
|
||||
'client/Syncing.lua',
|
||||
'client/Walk.lua',
|
||||
'client/frameworks/*.lua'
|
||||
}
|
||||
|
||||
|
BIN
resources/[standalone]/rpemotes-reborn/header.png
Normal file
After Width: | Height: | Size: 96 KiB |
|
@ -1,9 +1,9 @@
|
|||
Locales = {}
|
||||
|
||||
function Translate(str, ...) -- Translate string
|
||||
function Translate(str, ...)
|
||||
if not str then
|
||||
print(("[^1ERROR^7] Resource ^5%s^7 You did not specify a parameter for the Translate function or the value is nil!"):format(GetInvokingResource() or GetCurrentResourceName()))
|
||||
return "Given translate function parameter is nil!"
|
||||
return "Unknown"
|
||||
end
|
||||
if Locales[Config.MenuLanguage] then
|
||||
if Locales[Config.MenuLanguage][str] then
|
||||
|
@ -20,10 +20,9 @@ function Translate(str, ...) -- Translate string
|
|||
end
|
||||
end
|
||||
|
||||
function TranslateCap(str, ...) -- Translate string first char uppercase
|
||||
function TranslateCap(str, ...)
|
||||
return _(str, ...):gsub("^%l", string.upper)
|
||||
end
|
||||
|
||||
_ = Translate
|
||||
-- luacheck: ignore _U
|
||||
_U = TranslateCap
|
|
@ -4,12 +4,8 @@ Locales['ar'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 حركات الرقص",
|
||||
['animalemotes'] = "~h~~p~ 🐩 حركات الحيوانات",
|
||||
['propemotes'] = "~h~~p~ 📦 حركات الاوبجكتات",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 المفضلة",
|
||||
['favoriteinfo'] = "اختر حركة من هنا لوضعها على خانة المفضلة",
|
||||
['rfavorite'] = "اعادة ضبط المفضلة",
|
||||
['prop2info'] = "❓ حركات الاوبجكتات تكون محددة في النهاية",
|
||||
['set'] = "وضع (",
|
||||
['setboundemote'] = ") لتكون حركة مربوطة ؟",
|
||||
['newsetemote'] = "~w~ هي حركتك المربوطة , اضغط على ~g~CapsLock~w~ لإستخدامها",
|
||||
['cancelemote'] = "~h~~r~ الغاء الحركة 🚷",
|
||||
['cancelemoteinfo'] = "لالغاء لعب الحركة الحالية ~r~X~w~",
|
||||
|
@ -54,8 +50,6 @@ Locales['ar'] = {
|
|||
['searchinputtitle'] = "بحث:",
|
||||
['searchmenudesc'] = " نتيجة لـ ",
|
||||
['searchnoresult'] = "لا يوجد نتيجة للبحث ",
|
||||
['searchshifttofav'] = "اضغط ضغطة مطولة على L-Shift لوضعها في المفضلة",
|
||||
['searchcantsetfav'] = "الحركات المشتركة لا تستطيع وضعها في المفضلة",
|
||||
['invalidvariation'] = "تكستشر غير صالح, الاختيارات الصحيحة هي : %s",
|
||||
['firework'] = "اضغط ~y~G~w~ لاستخدام الالعاب النارية",
|
||||
['poop'] = "اضغط ~y~G~w~ لقضاء الحاجة 2",
|
|
@ -4,12 +4,8 @@ Locales['cs'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Taneční Animace",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Zvířecí Animace",
|
||||
['propemotes'] = "~h~~p~ 📦 Animace s předměty",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Oblíbené",
|
||||
['favoriteinfo'] = "Vyberte si animaci a nastavte ji jako svou oblíbenou.",
|
||||
['rfavorite'] = "Obnovit oblíbené",
|
||||
['prop2info'] = "❓ Pomůcky se mohou nacházet na konci",
|
||||
['set'] = "Nastavit",
|
||||
['setboundemote'] = "Nastavit jako vaši animaci?",
|
||||
['newsetemote'] = "~w~ je nyní vaší novou nastavenou animací. Chcete-li jej použít, stiskněte ~g~CapsLock~w~.",
|
||||
['cancelemote'] = "~h~~r~ Zrušit animaci 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Zruší aktuálně přehrávanou animaci",
|
||||
|
@ -54,8 +50,6 @@ Locales['cs'] = {
|
|||
['searchinputtitle'] = "Vyhledáno:",
|
||||
['searchmenudesc'] = "výsledek pro",
|
||||
['searchnoresult'] = "Žádna animace nebyla nalezena",
|
||||
['searchshifttofav'] = "Podrž L-Shift a stiskni enter pro nastavení animace do oblíbeních.",
|
||||
['searchcantsetfav'] = "Sdílené animace nelze nastavit jako oblíbené.",
|
||||
['invalidvariation'] = "Neplatná variace textury. Platné výběry jsou: %s",
|
||||
['firework'] = "Stiskni ~y~G~w~ pro použití ohňostroje",
|
||||
['poop'] = "Stisknutím ~y~G~w~ se vykakáte",
|
|
@ -4,12 +4,8 @@ Locales['da'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Danse Animationer",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Dyr Animationer",
|
||||
['propemotes'] = "~h~~p~ 📦 Rekvisit Animationer",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favorit",
|
||||
['favoriteinfo'] = "Vælg en animation her for at sætte den som din favorit.",
|
||||
['rfavorite'] = "Nulstil Favorit",
|
||||
['prop2info'] = "❓ Rekvisit animationer findes i slutningen",
|
||||
['set'] = "Sæt (",
|
||||
['setboundemote'] = ") til din favorit animation?",
|
||||
['newsetemote'] = "~w~ er nu din favorit animation, tryk ~g~CapsLock~w~ for at bruge den.",
|
||||
['cancelemote'] = "~h~~r~ Afbryd animation",
|
||||
['cancelemoteinfo'] = "~r~X~w~ annullerer din igangværende animation.",
|
||||
|
@ -54,8 +50,6 @@ Locales['da'] = {
|
|||
['searchinputtitle'] = "Søg:",
|
||||
['searchmenudesc'] = "resultat(er) for",
|
||||
['searchnoresult'] = "Ingen resultater fundet med",
|
||||
['searchshifttofav'] = "Hold L-Shift og tryk enter for at sætte som favorit.",
|
||||
['searchcantsetfav'] = "Delte animationer kan ikke være favoritter.",
|
||||
['invalidvariation'] = "Ugyldig teksturvariation. Gyldige valg er: %s",
|
||||
['firework'] = "Tryk på ~y~G~w~ for at bruge fyrværkeri",
|
||||
['poop'] = "Tryk på ~y~G~w~ for at skide",
|
|
@ -4,12 +4,8 @@ Locales['de'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Tanz-Emotes",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Tier Emotes",
|
||||
['propemotes'] = "~h~~p~ 📦 Prop-Emotes",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favoriten",
|
||||
['favoriteinfo'] = "Wähle hier ein Emote, um es als Favorit festzulegen.",
|
||||
['rfavorite'] = "Favorit zurücksetzen",
|
||||
['prop2info'] = "❓ Prop-Emotes können am Ende platziert werden",
|
||||
['set'] = "Setze (",
|
||||
['setboundemote'] = ") soll dein gebundenes Emote sein?",
|
||||
['newsetemote'] = "~w~ ist jetzt ein gebundenes Emote, drücke ~g~CapsLock~w~, um es zu verwenden.",
|
||||
['cancelemote'] = "~h~~r~ Emote abbrechen 🚷",
|
||||
['cancelemoteinfo'] = "~r~ X ~w~ Bricht das aktuell wiedergegebene Emote ab",
|
||||
|
@ -63,8 +59,6 @@ Locales['de'] = {
|
|||
['searchinputtitle'] = "Suche:",
|
||||
['searchmenudesc'] = "Ergebnis(se) für ",
|
||||
['searchnoresult'] = "Es wurden keine Ergebnisse gefunden für",
|
||||
['searchshifttofav'] = "Halte L-Shift und drücke Enter, um das Emote als Favorit festzulegen.",
|
||||
['searchcantsetfav'] = "Geteilte Emotes können nicht als Favorit gesetzt werden.",
|
||||
['invalidvariation'] = "Ungültige Texturvariante. Gültige Auswahlen sind: %s",
|
||||
['firework'] = "Drücke ~y~G~w~, um das Feuerwerk zu zünden",
|
||||
['poop'] = "Drücke ~y~G~w~, um zu kacken",
|
||||
|
@ -91,7 +85,6 @@ Locales['de'] = {
|
|||
-- Key maps
|
||||
['register_cancel_emote'] = "Aktuellen Emote abbrechen",
|
||||
['register_open_menu'] = "Animationsmenü öffnen",
|
||||
['register_fav_anim'] = "Deinen Favoriten-Emote abspielen",
|
||||
['register_handsup'] = "Hände hoch",
|
||||
['register_crouch'] = "Hocken",
|
||||
['register_crawl'] = "Kriechen",
|
|
@ -4,12 +4,8 @@ Locales['el'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Χοροί",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Ζώα",
|
||||
['propemotes'] = "~h~~p~ 📦 Αντικείμενα",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Αγαπημένα",
|
||||
['favoriteinfo'] = "Διάλεξε κίνηση για να τη βάλεις στα αγαπημένα.",
|
||||
['rfavorite'] = "Διαγραφή αγαπημένων",
|
||||
['prop2info'] = "❓ Τα αντικείμενα βρίσκοντε στο τέλος",
|
||||
['set'] = "Set (",
|
||||
['setboundemote'] = ") να προστεθεί στα αγαπημένα?",
|
||||
['newsetemote'] = "~w~ είναι τώρα στα αγαπημένα σου, πάτησε ~g~CapsLock~w~ για να την χρησιμοποιήσεις.",
|
||||
['cancelemote'] = "~h~~r~ Ακύρωση Κίνησης 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Ακυρώνει την κίνηση που κάνεις τώρα",
|
||||
|
@ -54,8 +50,6 @@ Locales['el'] = {
|
|||
['searchinputtitle'] = "Αναζήτηση:",
|
||||
['searchmenudesc'] = "αποτέλεσμα(ατα) για",
|
||||
['searchnoresult'] = "Κανένα απότέλεσμα για την αναζήτηση",
|
||||
['searchshifttofav'] = "Κράτησε L-Shift και πάτησε enter για να το αποθηκεύσεις ως αγαπημένο.",
|
||||
['searchcantsetfav'] = "Οι κινήσεις που μοιράζοντε με παίκτες δεν μπορούν να μπούν στα αγαπημένα.",
|
||||
['invalidvariation'] = "Μη έγκυρη επιλογή. Σωστές επιλογές είναι: %s",
|
||||
['firework'] = "Πάτησε ~y~G~w~ για να χρησιμοποιήσεις βεγγαλικό",
|
||||
['poop'] = "Πάτησε ~y~G~w~ για χέσιμο",
|
|
@ -4,12 +4,8 @@ Locales['en'] = {
|
|||
['danceemotes'] = "🕺 Dance Emotes",
|
||||
['animalemotes'] = "🐩 Animal Emotes",
|
||||
['propemotes'] = "📦 Prop Emotes",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favorite",
|
||||
['favoriteinfo'] = "Select an emote here to set it as your favorite.",
|
||||
['rfavorite'] = "Reset favorite",
|
||||
['prop2info'] = "❓ Prop Emotes can be located at the end",
|
||||
['set'] = "Set (",
|
||||
['setboundemote'] = ") to be your bound emote?",
|
||||
['newsetemote'] = "~w~ is now your bound emote, press ~g~CapsLock~w~ to use it.",
|
||||
['cancelemote'] = "Cancel Emote 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Cancels the currently playing emote",
|
||||
|
@ -44,15 +40,16 @@ Locales['en'] = {
|
|||
['doyouwanna'] = "~y~Y~w~ to accept, ~r~L~w~ to refuse (~g~",
|
||||
['refuseemote'] = "Emote refused.",
|
||||
['makenearby'] = "makes the nearby player play",
|
||||
['useleafblower'] = "Press ~y~G~w~ to use the leaf blower.",
|
||||
['camera'] = "Press ~y~G~w~ to use camera flash.",
|
||||
['makeitrain'] = "Press ~y~G~w~ to make it rain.",
|
||||
['pee'] = "Hold ~y~G~w~ to pee.",
|
||||
['useleafblower'] = "Press ~y~G~w~ to use the leaf blower",
|
||||
['camera'] = "Press ~y~G~w~ to use camera flash",
|
||||
['makeitrain'] = "Press ~y~G~w~ to make it rain",
|
||||
['pee'] = "Hold ~y~G~w~ to pee",
|
||||
['spraychamp'] = "Hold ~y~G~w~ to spray champagne",
|
||||
['stun'] = "Press ~y~G~w~ to 'use' stun gun.",
|
||||
['smoke'] = "Press ~y~G~w~ to smoke.",
|
||||
['vape'] = "Press ~y~G~w~ to vape.",
|
||||
['candle'] = "press ~y~G~w~ to light candle.",
|
||||
['stun'] = "Press ~y~G~w~ to 'use' stun gun",
|
||||
['smoke'] = "Press ~y~G~w~ to smoke",
|
||||
['vape'] = "Press ~y~G~w~ to vape",
|
||||
['candle'] = "Press ~y~G~w~ to light candle",
|
||||
['ptfxinfo'] = "Press ~y~G~w~ to activate the effects",
|
||||
['boundto'] = "Bound (~y~%s~w~) to ~g~%s~w~",
|
||||
['handsup'] = "Hands up",
|
||||
['currentlyboundemotes'] = "Currently bound emotes:",
|
||||
|
@ -63,8 +60,6 @@ Locales['en'] = {
|
|||
['searchinputtitle'] = "Search:",
|
||||
['searchmenudesc'] = "result(s) for",
|
||||
['searchnoresult'] = "No results for search",
|
||||
['searchshifttofav'] = "Hold L-Shift and press enter to set as favorite.",
|
||||
['searchcantsetfav'] = "Shared emotes cannot be set as favorites.",
|
||||
['invalidvariation'] = "Invalid texture variation. Valid selections are: %s",
|
||||
['firework'] = "Press ~y~G~w~ to use the firework",
|
||||
['poop'] = "Press ~y~G~w~ to poop",
|
||||
|
@ -91,7 +86,6 @@ Locales['en'] = {
|
|||
-- Key maps
|
||||
['register_cancel_emote'] = "Cancel current emote",
|
||||
['register_open_menu'] = "Open animation menu",
|
||||
['register_fav_anim'] = "Play your favorite emote",
|
||||
['register_handsup'] = "Raise hands up",
|
||||
['register_crouch'] = "Crouch",
|
||||
['register_crawl'] = "Crawl",
|
|
@ -4,12 +4,8 @@ Locales['es'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Bailes",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Emotes de animales",
|
||||
['propemotes'] = "~h~~p~ 📦 Objetos",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favoritos",
|
||||
['favoriteinfo'] = "Seleccione una animación aquí para configurarlo como su favorito.",
|
||||
['rfavorite'] = "Restablecer favoritos",
|
||||
['prop2info'] = "❓ Los Prop Emotes se pueden encontrar al final",
|
||||
['set'] = "Elegir (",
|
||||
['setboundemote'] = ") como tu animación favorita?",
|
||||
['newsetemote'] = "~w~ es ahora tu animación favorita, presiona ~g~[CapsLock]~w~ para usarla.",
|
||||
['cancelemote'] = "~h~~r~ Cancelar animación 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Cancela la animación actual.",
|
||||
|
@ -53,8 +49,6 @@ Locales['es'] = {
|
|||
['searchinputtitle'] = "Buscar:",
|
||||
['searchmenudesc'] = "resultado(s) para",
|
||||
['searchnoresult'] = "No se encontró nada con",
|
||||
['searchshifttofav'] = "Mantén L-Shift y presiona Enter para guardar como favorito.",
|
||||
['searchcantsetfav'] = "Las animaciones compartidas no pueden ser guardadas como favoritas.",
|
||||
['invalidvariation'] = "Variación de textura no válida. Las opciones válidas son: %s",
|
||||
['firework'] = "Presione ~y~G~w~ para usar los fuegos artificiales",
|
||||
['poop'] = "Presione ~y~G~w~ para hacer caca",
|
|
@ -4,12 +4,8 @@ Locales['fa'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 raghs Emotes",
|
||||
['animalemotes'] = "~h~~p~ 🐩 hevanat Emotes",
|
||||
['propemotes'] = "~h~~p~ 📦 tekye dadan Emotes",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 alaghemandiha",
|
||||
['favoriteinfo'] = "yek emote ra baray ezafe kardan be alaghe mandi ha entekhab konid.",
|
||||
['rfavorite'] = "bazneshani alaghe mandi ha",
|
||||
['prop2info'] = "❓ bad az tekye dadan be yek ja motavaghef mishavad",
|
||||
['set'] = "Set (",
|
||||
['setboundemote'] = ") che kelid baray dastressi sari entekhab shavad?",
|
||||
['newsetemote'] = "~w~ baray dastresi sari, press ~g~CapsLock~w~ baray ejra",
|
||||
['cancelemote'] = "~h~~r~ laghv emote🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ baray laghv emote ",
|
||||
|
@ -54,8 +50,6 @@ Locales['fa'] = {
|
|||
['searchinputtitle'] = "jostojo:",
|
||||
['searchmenudesc'] = "result(s) for",
|
||||
['searchnoresult'] = "No results for search",
|
||||
['searchshifttofav'] = "Hold L-Shift and press enter to set as favorite.",
|
||||
['searchcantsetfav'] = "Shared emotes cannot be set as favorites.",
|
||||
['invalidvariation'] = "Invalid texture variation. Valid selections are: %s",
|
||||
['firework'] = "Press ~y~G~w~ to use the firework",
|
||||
['poop'] = "Press ~y~G~w~ to poop",
|
|
@ -4,12 +4,8 @@ Locales['fi'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Tanssi Animaatiot",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Eläin Animaatiot",
|
||||
['propemotes'] = "~h~~p~ 📦 Esine Animaatiot",
|
||||
['favoriteemotes'] = "~h~~p~ 🌟 Suosikit",
|
||||
['favoriteinfo'] = "Valitse animaatio asettaaksesi sen suosikiksi.",
|
||||
['rfavorite'] = "Resetoi suosikit.",
|
||||
['prop2info'] = "❓ Esine animaatiot voivat sijaita lopussa",
|
||||
['set'] = "Aseta (",
|
||||
['setboundemote'] = ") bindatuksi animaatioksi?",
|
||||
['newsetemote'] = "~w~ on nyt bindattu animaatio, paina ~g~CapsLock~w~ käyttääksesi",
|
||||
['cancelemote'] = "~h~~r~ Peru animaatio 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Peruu tämän hetkisen animaation",
|
||||
|
@ -54,8 +50,6 @@ Locales['fi'] = {
|
|||
['searchinputtitle'] = "Etsi:",
|
||||
['searchmenudesc'] = "tulokset",
|
||||
['searchnoresult'] = "Ei tuloksia haulle",
|
||||
['searchshifttofav'] = "Pidä L-Shift painettuna ja aseta suosikiksi painamalla Enter.",
|
||||
['searchcantsetfav'] = "Jaettuja emoteja ei voi asettaa suosikeiksi.",
|
||||
['invalidvariation'] = "Virheellinen tekstuurimuunnelma. Kelvollisia valintoja ovat: %s",
|
||||
['firework'] = "Käytä ilotulitteita painamalla ~y~G~w~",
|
||||
['poop'] = "Paina ~y~G~w~ kakataksesi.",
|
|
@ -4,12 +4,8 @@ Locales['fr'] = {
|
|||
['danceemotes'] = "~p~ 🕺 Danses",
|
||||
['animalemotes'] = "~p~ 🐩 Emotes d'animaux",
|
||||
['propemotes'] = "~p~ 📦 Emotes objet",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favori",
|
||||
['favoriteinfo'] = "Définir une emote comme favori.",
|
||||
['rfavorite'] = "Réinitialiser le favori.",
|
||||
['prop2info'] = "❓ Les emotes d'objet peuvent être à la fin",
|
||||
['set'] = "Mettre (",
|
||||
['setboundemote'] = ") en emote favorite?",
|
||||
['newsetemote'] = "~w~ est maintenant votre emote favorite, appuyez sur ~g~CapsLock~w~ pour l'utiliser.",
|
||||
['cancelemote'] = "~r~ Annuler l'émote 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Annule l'emote en cours",
|
||||
|
@ -53,8 +49,6 @@ Locales['fr'] = {
|
|||
['searchinputtitle'] = "Recherche:",
|
||||
['searchmenudesc'] = "resultat(s) pour",
|
||||
['searchnoresult'] = "Aucun résultat pour la recherche : ",
|
||||
['searchshifttofav'] = "Maintenir L-Shift et appuyer sur entrer pour marquer comme favorie.",
|
||||
['searchcantsetfav'] = "Les emotes partagées ne peuvent pas être mise en favorie.",
|
||||
['invalidvariation'] = "Variation de texture invalide. Les sélections valides sont : %s",
|
||||
['firework'] = "Appuyez sur <b>G</b> pour utiliser les feux d'artifice",
|
||||
['poop'] = "Appuyez sur <b>G</b> pour faire caca.",
|
|
@ -4,12 +4,8 @@ Locales['hu'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Tánc Animációk",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Állatos Animációk",
|
||||
['propemotes'] = "~h~~p~ 📦 Tárgyas Animációk",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Kedvenc",
|
||||
['favoriteinfo'] = "Válassz ki itt egy animációt, hogy kedvenceddé tedd.",
|
||||
['rfavorite'] = "Kedvenc alaphelyzetbe állítása",
|
||||
['prop2info'] = "❓ A Prop Emote-ok a végén találhatók",
|
||||
['set'] = "Kiválasztod (",
|
||||
['setboundemote'] = ") hogy ez legyen a kedvenc animációd?",
|
||||
['newsetemote'] = "~w~ lett a kedvenc animációd, nyomj egy ~g~CapsLock~w~-ot a használatához.",
|
||||
['cancelemote'] = "~h~~r~ Animáció Befejezése 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Megszünteti az aktuálisan lejátszott animációt",
|
||||
|
@ -54,8 +50,6 @@ Locales['hu'] = {
|
|||
['searchinputtitle'] = "Keresés:",
|
||||
['searchmenudesc'] = "eredmény erre: ",
|
||||
['searchnoresult'] = "Nincs eredmény erre:",
|
||||
['searchshifttofav'] = "Tartsd lenyomva az L-Shift billentyűt, és nyomd meg az enter billentyűt a kedvencek beállításához.",
|
||||
['searchcantsetfav'] = "A megosztott animációkat nem lehet kedvencekként beállítani.",
|
||||
['invalidvariation'] = "Érvénytelen textúra variáció. Érvényes választások a következők: %s",
|
||||
['firework'] = "Nyomj ~y~G~w~ gombot a tűzijáték használatához",
|
||||
['poop'] = "Nyomj ~y~G~w~ gombot a kakiláshoz",
|
|
@ -4,12 +4,8 @@ Locales['id'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Emote Menari",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Emote Hewan",
|
||||
['propemotes'] = "~h~~p~ 📦 Prop Emotes",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favorit",
|
||||
['favoriteinfo'] = "Pilih emote di sini untuk menetapkannya sebagai favorit Anda.",
|
||||
['rfavorite'] = "Setel ulang favorit",
|
||||
['prop2info'] = "❓ Prop Emotes can be located at the end",
|
||||
['set'] = "Tetapkan (",
|
||||
['setboundemote'] = ") untuk menjadi emote terikat Anda?",
|
||||
['newsetemote'] = "~w~ sekarang menjadi emote terikat Anda, tekan ~g~CapsLock~w~ untuk menggunakannya.",
|
||||
['cancelemote'] = "~h~~r~ Batalkan Emote 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Batalkan emote yang sedang dimainkan",
|
||||
|
@ -54,8 +50,6 @@ Locales['id'] = {
|
|||
['searchinputtitle'] = "Cari:",
|
||||
['searchmenudesc'] = "hasil untuk",
|
||||
['searchnoresult'] = "Tidak ada hasil untuk pencarian",
|
||||
['searchshifttofav'] = "Tahan L-Shift dan tekan enter untuk menetapkan sebagai favorit.",
|
||||
['searchcantsetfav'] = "Emote yang dibagikan tidak dapat ditetapkan sebagai favorit.",
|
||||
['invalidvariation'] = "Variasi tekstur tidak valid. Pilihan yang valid adalah: %s",
|
||||
['firework'] = "Tekan ~y~G~w~ untuk menggunakan kembang api",
|
||||
['poop'] = "Tekan ~y~G~w~ untuk buang air besar",
|
|
@ -4,12 +4,8 @@ Locales['it'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Animazioni Di Danza",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Animazioni Di Animali",
|
||||
['propemotes'] = "~h~~p~ 📦 Animazioni Prop",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Emote preferite",
|
||||
['favoriteinfo'] = "Seleziona un'animazione per metterla nei preferiti.",
|
||||
['rfavorite'] = "Rimuovi preferito",
|
||||
['prop2info'] = "❓ Le animazioni Prop possono essere trovate in fondo.",
|
||||
['set'] = "Imposta (",
|
||||
['setboundemote'] = ") come tua animazione corrente?",
|
||||
['newsetemote'] = "~w~ è ora la tua animazione corrente, premi ~g~CapsLock~w~ per usarla.",
|
||||
['cancelemote'] = "~h~~r~ Annulla animazione 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Cancella l'animazione in corso.",
|
||||
|
@ -54,8 +50,6 @@ Locales['it'] = {
|
|||
['searchinputtitle'] = "Search:",
|
||||
['searchmenudesc'] = "result(s) for",
|
||||
['searchnoresult'] = "No results for search",
|
||||
['searchshifttofav'] = "Hold L-Shift and press enter to set as favorite.",
|
||||
['searchcantsetfav'] = "Shared emotes cannot be set as favorites.",
|
||||
['invalidvariation'] = "Opzioni colore non valide. scelte valide sono: %s",
|
||||
['firework'] = "Premere ~y~G~w~ per utilizzare il fuoco d'artificio",
|
||||
['poop'] = "Premere ~y~G w~ per fare la cacca",
|
|
@ -4,12 +4,8 @@ Locales['lk'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Natana Emotes",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Sattunge Emotes",
|
||||
['propemotes'] = "~h~~p~ 📦 Prop Emotes",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favorite Emotes",
|
||||
['favoriteinfo'] = "Methanin oyage favorite emote eka thoraganna.",
|
||||
['rfavorite'] = "Favorite emote eka reset karanna",
|
||||
['prop2info'] = "❓ Prop emotes tiyenne anthimata",
|
||||
['set'] = "Set karanna (",
|
||||
['setboundemote'] = ") favorite emote eka widiyata?",
|
||||
['newsetemote'] = "~w~ thamai oyage favorite emote eka, ~g~CapsLock~w~ eken use karanna.",
|
||||
['cancelemote'] = "~h~~r~ Emote Eka Nawattanna 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Wetila thiyana emote eka nawattanawa",
|
||||
|
@ -54,8 +50,6 @@ Locales['lk'] = {
|
|||
['searchinputtitle'] = "Search karanna:",
|
||||
['searchmenudesc'] = "result(s) for",
|
||||
['searchnoresult'] = "Mukut hambune na",
|
||||
['searchshifttofav'] = "L-Shift obagena Enter press karala, favorite karaganna.",
|
||||
['searchcantsetfav'] = "Shared emotes favorite karanna ba.",
|
||||
['invalidvariation'] = "Weradi texture variation ekak. Hari ewa thamai: %s",
|
||||
['firework'] = "Firework ekata ~y~G~w~ press karanna",
|
||||
['poop'] = "Kakki danna ~y~G~w~ press karanna",
|
|
@ -4,12 +4,8 @@ Locales['lt'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Sokiu animacijos",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Gyvunu animacijos",
|
||||
['propemotes'] = "~h~~p~ 📦 Daiktu animacijos",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Megstamiausi",
|
||||
['favoriteinfo'] = "Cia pasirinkite jaustuka, kad nustatytumete ji kaip megstamiausia.",
|
||||
['rfavorite'] = "Atstatyti megstamiausia",
|
||||
['prop2info'] = "❓ Daiktu animacijos gali buti pabaigoje",
|
||||
['set'] = "Rinkinys (",
|
||||
['setboundemote'] = ") buti tavo surista emocija?",
|
||||
['newsetemote'] = "~w~ dabar yra jusu susietas jaustukas, paspauskite ~g~CapsLock~w~, kad ji naudotumete.",
|
||||
['cancelemote'] = "~h~~r~ Atsaukti animacija 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Atsaukti dabar naudojama animacija",
|
||||
|
@ -63,8 +59,6 @@ Locales['lt'] = {
|
|||
['searchinputtitle'] = "Ieskoti:",
|
||||
['searchmenudesc'] = "rezultatas (-ai), skirtas",
|
||||
['searchnoresult'] = "Paieskos rezultatu nera",
|
||||
['searchshifttofav'] = "Laikykite nuspaude L-Shift ir paspauskite Enter, kad nustatytumete kaip megstamiausia.",
|
||||
['searchcantsetfav'] = "Bendrinamos animacijos negali buti nustatytos kaip megstamiausios.",
|
||||
['invalidvariation'] = "Netinkamas teksturos variantas. Galiojantys pasirinkimai yra: %s",
|
||||
['firework'] = "Paspauskite ~y~G~w~, kad galetumete naudoti fejerverka",
|
||||
['poop'] = "Paspauskite ~y~G~w~, kad istustumete",
|
||||
|
@ -93,7 +87,6 @@ Locales['lt'] = {
|
|||
['register_cancel_emote'] = "Atšaukti animaciją",
|
||||
['register_handsup'] = "Pakelti rankas",
|
||||
['register_open_menu'] = "Animacijų meniu",
|
||||
['register_fav_anim'] = "Paleisti mėgstamiausia animaciją",
|
||||
['register_crouch'] = "Pritūpti",
|
||||
['register_crawl'] = "Šliaužti",
|
||||
['register_pointing'] = "Rodyti pirštu",
|
|
@ -4,12 +4,8 @@ Locales['nl'] = {
|
|||
['danceemotes'] = "🕺 Dans Animaties",
|
||||
['animalemotes'] = "🐩 Dier Animaties",
|
||||
['propemotes'] = "📦 Voorwerp Animaties",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favoriete",
|
||||
['favoriteinfo'] = "Selecteer hier een animatie om deze als favoriete in te stellen.",
|
||||
['rfavorite'] = "Favoriete wissen",
|
||||
['prop2info'] = "❓ Voorwerp animaties aan het einde",
|
||||
['set'] = "Maak (",
|
||||
['setboundemote'] = ") je toegewezen animatie.",
|
||||
['newsetemote'] = "~w~ is nu je toegewezen animatie, druk op ~g~CapsLock~w~ om het te gebruiken.",
|
||||
['cancelemote'] = "Animatie Stoppen 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Stopt je huidige animatie.",
|
||||
|
@ -63,8 +59,6 @@ Locales['nl'] = {
|
|||
['searchinputtitle'] = "Zoeken:",
|
||||
['searchmenudesc'] = "resultaten voor",
|
||||
['searchnoresult'] = "Geen resultaten voor zoekopdracht",
|
||||
['searchshifttofav'] = "Houd ~y~L-Shift~w~ ingedrukt en druk op enter om als favoriet op te slaan.",
|
||||
['searchcantsetfav'] = "Gedeelde animaties kunnen niet als favoriet worden ingesteld",
|
||||
['invalidvariation'] = "Ongeldige texture variatie. Geldige selecties zijn: %s",
|
||||
['firework'] = "Druk op ~y~G~w~ om het vuurwerk te gebruiken",
|
||||
['poop'] = "Druk op ~y~G~w~ om te poepen",
|
||||
|
@ -91,7 +85,6 @@ Locales['nl'] = {
|
|||
-- Key maps
|
||||
['register_cancel_emote'] = "Huidige animatie stoppen",
|
||||
['register_open_menu'] = "Animatiemenu openen",
|
||||
['register_fav_anim'] = "Start je favoriete animatie",
|
||||
['register_handsup'] = "Handen omhoog",
|
||||
['register_crouch'] = "Hurken",
|
||||
['register_crawl'] = "Kruipen",
|
|
@ -4,12 +4,8 @@ Locales['no'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Danse Animasjoner",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Dyreanimasjoner",
|
||||
['propemotes'] = "~h~~p~ 📦 Rekvisitt Animasjoner",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favoritt",
|
||||
['favoriteinfo'] = "Her kan du velge en favoritt animasjon.",
|
||||
['rfavorite'] = "Reset favoritt",
|
||||
['prop2info'] = "❓ Rekvisitt Animasjoner er på bunnen",
|
||||
['set'] = "Vil du sette (",
|
||||
['setboundemote'] = ") som din favoritt?",
|
||||
['newsetemote'] = "~w~ er nå lagret som din favoritt, trykk ~g~CapsLock~w~ for å bruke den.",
|
||||
['cancelemote'] = "~h~~r~ Avbryt Animasjonen 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Avbryt den nåværende animasjonen",
|
||||
|
@ -54,8 +50,6 @@ Locales['no'] = {
|
|||
['searchinputtitle'] = "Søk:",
|
||||
['searchmenudesc'] = "resultat(er) for",
|
||||
['searchnoresult'] = "Ingen resultater for søk",
|
||||
['searchshifttofav'] = "Hold L-Shift og trykk Enter for å sette som favoritt.",
|
||||
['searchcantsetfav'] = "Du kan ikke sitte en Felles Animasjon som favoritt.",
|
||||
['invalidvariation'] = "Ugyldig tekstur variant. Gyldige varianter: %s",
|
||||
['firework'] = "Trykk ~y~G~w~ for å avfyre fyrverkeriet",
|
||||
['poop'] = "Hold ~y~G~w~ for å bæsje",
|
|
@ -4,12 +4,8 @@ Locales['pl'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Tańce",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Animacje zwierząt",
|
||||
['propemotes'] = "~h~~p~ 📦 Animacje z propami",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Ulubione",
|
||||
['favoriteinfo'] = "Wybierz animację i ustaw ją jako ulubioną.",
|
||||
['rfavorite'] = "Zresetuj ulubione animacje",
|
||||
['prop2info'] = "❓ Animacje z propami są zlokalizowane na samym końcu listy",
|
||||
['set'] = "Ustaw (",
|
||||
['setboundemote'] = ") jako Twoją przypisaną animację?",
|
||||
['newsetemote'] = "~w~ jest teraz Twoją przypisaną animacją, wciśnij ~g~CapsLock~w~ by jej użyć.",
|
||||
['cancelemote'] = "~h~~r~ Anuluj animację 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Anuluje aktualnie graną animację",
|
||||
|
@ -54,8 +50,6 @@ Locales['pl'] = {
|
|||
['searchinputtitle'] = "Szukaj:",
|
||||
['searchmenudesc'] = "wyników dla frazy",
|
||||
['searchnoresult'] = "Brak wyników dla frazy",
|
||||
['searchshifttofav'] = "Przytrzymaj L-Shift i naciśnij Enter by dodać do ulubionych.",
|
||||
['searchcantsetfav'] = "Współdzielona animacja nie może być dodana do ulubionych.",
|
||||
['invalidvariation'] = "Niepoprawny wariant tekstury. Dostępne tekstury to: %s",
|
||||
['firework'] = "Naciśnij ~y~G~w~ aby odpalić fajerwerki",
|
||||
['poop'] = "Naciśnij ~y~G~w~ by zrobić kupę",
|
|
@ -4,12 +4,8 @@ Locales['pt'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Emotes de Danças",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Emotes de Animais",
|
||||
['propemotes'] = "~h~~p~ 📦 Emotes com Props",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favoritos",
|
||||
['favoriteinfo'] = "Selecione um emote para colocá-lo nos seus favoritos",
|
||||
['rfavorite'] = "Limpar favoritos",
|
||||
['prop2info'] = "❓ Emotes de props podem ser localizados no fim",
|
||||
['set'] = "Set (",
|
||||
['setboundemote'] = ") para ser seu emote vinculado?",
|
||||
['newsetemote'] = "~w~ é o seu emote vinculado, pressione ~g~CapsLock~w~ para usá-lo",
|
||||
['cancelemote'] = "~h~~r~ Cancelar emote 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Cancela os emotes rodando atualmente",
|
||||
|
@ -54,8 +50,6 @@ Locales['pt'] = {
|
|||
['searchinputtitle'] = "Procurar:",
|
||||
['searchmenudesc'] = "resultado(s) para",
|
||||
['searchnoresult'] = "Nenhum resultado para a pesquisa",
|
||||
['searchshifttofav'] = "Segure Shift Esquerdo e pressione enter para setar como favorito.",
|
||||
['searchcantsetfav'] = "Emotes compartilhados não podem ser setados como favorito.",
|
||||
['invalidvariation'] = "Variação de textura inválida. As opções válidas são: %s",
|
||||
['firework'] = "Pressione ~y~G~w~ para usar o fogo de artifício",
|
||||
['poop'] = "Pressione ~y~G~w~ para fazer cocô", -- Translated using smodin.io
|
|
@ -4,12 +4,8 @@ Locales['ro'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Dansuri",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Emote-uri pentru animale",
|
||||
['propemotes'] = "~h~~p~ 📦 Prop Emote-uri",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favorite",
|
||||
['favoriteinfo'] = "Selecteaza un emote aici pentru a îl alege ca favorit.",
|
||||
['rfavorite'] = "Reseteaza emote-uri favorite",
|
||||
['prop2info'] = "❓ Prop Emote-urile pot fi gasite la final",
|
||||
['set'] = "Seteaza (",
|
||||
['setboundemote'] = ") sa fie emote-ul binduit?",
|
||||
['newsetemote'] = "~w~ este acum emote-ul tau binduit, apasa ~g~CapsLock~w~ pentru a folosi.",
|
||||
['cancelemote'] = "~h~~r~ Anuleaza animatia 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Anuleaza animatia curenta",
|
||||
|
@ -54,8 +50,6 @@ Locales['ro'] = {
|
|||
['searchinputtitle'] = "Cautare:",
|
||||
['searchmenudesc'] = "rezultat(e) pentru",
|
||||
['searchnoresult'] = "Fara rezultate pentru cautarea",
|
||||
['searchshifttofav'] = "Tine apasat L-Shift si apasa enter pentru a seta ca favorit.",
|
||||
['searchcantsetfav'] = "Emote-urile Shared nu pot fi setate ca favorite.",
|
||||
['invalidvariation'] = "Variație nevalidă a texturii. Selectările valide sunt: %s",
|
||||
['firework'] = "Apasa ~y~G~w~ pentru a folosi artificiile",
|
||||
['poop'] = "Apăsați pe ~y~G~w~ pentru a face caca", --Trannslated using smodin.io
|
|
@ -4,12 +4,8 @@ Locales['ru'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Танцевальные эмоции",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Эмоции животных",
|
||||
['propemotes'] = "~h~~p~ 📦 Эмоции с пропом",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Избранные",
|
||||
['favoriteinfo'] = "Выберите здесь эмоцию, чтобы сделать ее избранной.",
|
||||
['rfavorite'] = "Сбросить избранное",
|
||||
['prop2info'] = "❓ Эмоции с пропом могут быть расположены в конце",
|
||||
['set'] = "Установить (",
|
||||
['setboundemote'] = ") как привязанную эмоцию?",
|
||||
['newsetemote'] = "~w~ теперь привязанная эмоция, нажмите ~g~CapsLock~w~ для использования.",
|
||||
['cancelemote'] = "~h~~r~ Остановить эмоцию 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Отменяет воспроизводимую эмоцию",
|
||||
|
@ -62,8 +58,6 @@ Locales['ru'] = {
|
|||
['searchinputtitle'] = "Поиск:",
|
||||
['searchmenudesc'] = "результат(ы) для",
|
||||
['searchnoresult'] = "Нет результатов по поиску",
|
||||
['searchshifttofav'] = "Удерживайте L-Shift и нажмите Enter, чтобы установить в избранное.",
|
||||
['searchcantsetfav'] = "Парные эмоции не могут быть добавлены в избранное.",
|
||||
['invalidvariation'] = "Недопустимая вариация текстуры. Допустимые варианты: %s",
|
||||
['firework'] = "Нажмите ~y~G~w~, чтобы запустить фейерверк.",
|
||||
['poop'] = "Нажмите ~y~G~w~, чтобы какать",
|
||||
|
@ -91,7 +85,6 @@ Locales['ru'] = {
|
|||
-- Key maps
|
||||
['register_cancel_emote'] = "Отменить текущую эмоцию",
|
||||
['register_open_menu'] = "Открыть меню анимации",
|
||||
['register_fav_anim'] = "Воспроизведите свою любимую эмоцию",
|
||||
['register_handsup'] = "Поднимите руки вверх",
|
||||
['register_crouch'] = "В приседи",
|
||||
['register_crawl'] = "Ползти",
|
|
@ -4,12 +4,8 @@ Locales['sl'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Plesi",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Emote živali",
|
||||
['propemotes'] = "~h~~p~ 📦 Emote pripomočkov",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Priljubljeni",
|
||||
['favoriteinfo'] = "Izberite emote tukaj, da ga nastavite kot priljubljenega.",
|
||||
['rfavorite'] = "Ponastavi priljubljenega",
|
||||
['prop2info'] = "❓ Emote pripomočki se nahajajo na koncu",
|
||||
['set'] = "Nastavi (",
|
||||
['setboundemote'] = ") kot vaš vezan emote?",
|
||||
['newsetemote'] = "~w~ je sedaj vaš vezan emote, pritisnite ~g~CapsLock~w~, da ga uporabite.",
|
||||
['cancelemote'] = "~h~~r~ Prekliči Emote 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Prekliče trenutno predvajani emote",
|
||||
|
@ -54,8 +50,6 @@ Locales['sl'] = {
|
|||
['searchinputtitle'] = "Iskanje:",
|
||||
['searchmenudesc'] = "rezultat(ov) za",
|
||||
['searchnoresult'] = "Ni rezultatov za iskanje",
|
||||
['searchshifttofav'] = "Pritisnite in pridržite levi Shift ter pritisnite Enter, da ga nastavite kot priljubljenega.",
|
||||
['searchcantsetfav'] = "Deljeni emotes ni mogoče nastaviti kot priljubljene.",
|
||||
['invalidvariation'] = "Neveljavna teksturna variacija. Veljavne izbire so: %s",
|
||||
['firework'] = "Pritisnite ~y~G~w~, da uporabite ognjemet",
|
||||
['poop'] = "Pritisnite ~y~G~w~, da opravite veliko potrebo",
|
|
@ -4,12 +4,8 @@ Locales['sq'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Emotet e Kërcimit",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Emotet e Kafshëve",
|
||||
['propemotes'] = "~h~~p~ 📦 Emotet e Përparave",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Të preferuar",
|
||||
['favoriteinfo'] = "Zgjidh një emote këtu për ta caktuar si të preferuarin tënd.",
|
||||
['rfavorite'] = "Rivendos të preferuarin",
|
||||
['prop2info'] = "❓ Emotet e Përparave mund të gjenden në fund",
|
||||
['set'] = "Vendos (",
|
||||
['setboundemote'] = ") të jetë emote e lidhur?",
|
||||
['newsetemote'] = "~w~ është tani emota e lidhur, shtyp ~g~CapsLock~w~ për ta përdorur.",
|
||||
['cancelemote'] = "~h~~r~ Anulo Emoten 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Anulon emoten që është duke u luajtur momentalisht",
|
||||
|
@ -54,8 +50,6 @@ Locales['sq'] = {
|
|||
['searchinputtitle'] = "Kërko:",
|
||||
['searchmenudesc'] = "rezultat(e) për",
|
||||
['searchnoresult'] = "Asnjë rezultat për kërkimin",
|
||||
['searchshifttofav'] = "Mbaj Shift të majtë dhe shtyp enter për ta caktuar si të preferuar.",
|
||||
['searchcantsetfav'] = "Emotet e ndara nuk mund të caktohen si të preferuara.",
|
||||
['invalidvariation'] = "Variacioni i teksturës i pavlefshëm. Zgjedhjet e vlefshme janë: %s",
|
||||
['firework'] = "Shtyp ~y~G~w~ për të përdorur fenerin",
|
||||
['poop'] = "Shtyp ~y~G~w~ për të bërë që të defekosh",
|
|
@ -4,12 +4,8 @@ Locales['sr'] = {
|
|||
['danceemotes'] = "🕺 Plesovi",
|
||||
['animalemotes'] = "🐩 Životinjske Animacije",
|
||||
['propemotes'] = "📦 Animacije Sa Predmetima",
|
||||
['favoriteemotes'] = "🌟 Omiljeno",
|
||||
['favoriteinfo'] = "Izaberite animaciju ovdje da je stavite kao omiljenu",
|
||||
['rfavorite'] = "Resetuj omiljeno",
|
||||
['prop2info'] = "❓ Animacije sa predmetima se mogu naći na kraju",
|
||||
['set'] = "Postavi (",
|
||||
['setboundemote'] = ") da bude tvoji bound-ana animacija?",
|
||||
['newsetemote'] = "~w~ je sada tvoja bound-ana animacija, pritisni ~g~CapsLock~w~ da je uradiš.",
|
||||
['cancelemote'] = "Prekini Animaciju 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Prekine animaciju koju trenutno radiš",
|
||||
|
@ -53,8 +49,6 @@ Locales['sr'] = {
|
|||
['searchinputtitle'] = "Pretraži:",
|
||||
['searchmenudesc'] = "rezultat(a) za",
|
||||
['searchnoresult'] = "Nema rezultata za pretraživanje",
|
||||
['searchshifttofav'] = "Drži L-Shift i pritisni Enter da staviš kao tvoje omiljeno.",
|
||||
['searchcantsetfav'] = "Društvene Animacije ne mogu biti omiljene.",
|
||||
['invalidvariation'] = "Nevažeća varijacija teksture. Važeće selekcije su: %s",
|
||||
['firework'] = "Pritisni ~y~G~w~ da koristiš vatromet",
|
||||
['poop'] = "Pritisni ~y~G~w~ da kakiš",
|
|
@ -4,12 +4,8 @@ Locales['sv'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Dans Emotes",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Djur Emotes",
|
||||
['propemotes'] = "~h~~p~ 📦 Objekt Emotes",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favorit",
|
||||
['favoriteinfo'] = "Välj en emote för att ställa in den som din favorit.",
|
||||
['rfavorite'] = "Återställ favorit.",
|
||||
['prop2info'] = "❓ Objekt Emotes finns längst ner i listan.",
|
||||
['set'] = "Sätt (",
|
||||
['setboundemote'] = ") till din favorit emote?",
|
||||
['newsetemote'] = "~w~ är nu din favorit emote, tryck ~g~CapsLock~w~ för att använda den.",
|
||||
['cancelemote'] = "~h~~r~ Avbryt Emote 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ avbryter nuvarande spelande emote.",
|
||||
|
@ -54,8 +50,6 @@ Locales['sv'] = {
|
|||
['searchinputtitle'] = "Sök:",
|
||||
['searchmenudesc'] = "resultat på",
|
||||
['searchnoresult'] = "Inga resultat hittades på",
|
||||
['searchshifttofav'] = "Håll ned L-Shift och tryck på enter för att ställa in som favorit.",
|
||||
['searchcantsetfav'] = "Delade Emotes kan inte ställas in som favoriter.",
|
||||
['invalidvariation'] = "Ogiltig texturvariation. Giltiga val är: %s",
|
||||
['firework'] = "Tryck ~y~G~w~ för att avfyra dina fyrverkerier",
|
||||
['poop'] = "Tryck ~y~G~w~ för att bajsa", -- Translated using smodin.io
|
|
@ -4,12 +4,8 @@ Locales['tr'] = {
|
|||
['danceemotes'] = "🕺 Dans Animasyonları",
|
||||
['animalemotes'] = "🐩 Hayvan Animasyonları",
|
||||
['propemotes'] = "📦 Eşyaları Animasyonlar",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Favoriler",
|
||||
['favoriteinfo'] = "Favori olarak seçmek için buradan bir animasyon seçin",
|
||||
['rfavorite'] = "Favorileri sıfırla",
|
||||
['prop2info'] = "❓ Eşyalı animasyonlar sonda bulunur",
|
||||
['set'] = "Set (",
|
||||
['setboundemote'] = ") animasyonu bağlansın mı?",
|
||||
['newsetemote'] = "~w~ animasyonu bağlandı, kullanmak için ~g~CapsLock~w~ tuşuna basın",
|
||||
['cancelemote'] = "Animasyonu iptal et 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ Şu anki animasyonu iptal eder",
|
||||
|
@ -63,8 +59,6 @@ Locales['tr'] = {
|
|||
['searchinputtitle'] = "Ara:",
|
||||
['searchmenudesc'] = "sonuçlar:",
|
||||
['searchnoresult'] = "Animasyon bulunamadı",
|
||||
['searchshifttofav'] = "Animasyonu favori eklemek için LShift + Enter tuşlarına basın",
|
||||
['searchcantsetfav'] = "Ortak animasyonlar favori olarak eklenemez",
|
||||
['invalidvariation'] = "Geçersiz doku. Geçerli dokular: %s",
|
||||
['firework'] = "Havai fişeği kullanmak için ~y~G~w~ tuşuna basın",
|
||||
['poop'] = "Kaka yapmak için ~y~G~w~ tuşuna basın",
|
||||
|
@ -91,7 +85,6 @@ Locales['tr'] = {
|
|||
-- Key maps
|
||||
['register_cancel_emote'] = "Şu anki animasyonu iptal et",
|
||||
['register_open_menu'] = "Animasyon menüsünü aç",
|
||||
['register_fav_anim'] = "Favori animasyonuna gir",
|
||||
['register_handsup'] = "Ellerini kaldır",
|
||||
['register_crouch'] = "Eğil",
|
||||
['register_crawl'] = "Sürün",
|
|
@ -4,12 +4,8 @@ Locales['vi'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 Nhảy nhót",
|
||||
['animalemotes'] = "~h~~p~ 🐩 Thú cưng",
|
||||
['propemotes'] = "~h~~p~ 📦 Đồ vật",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 Ưa thích",
|
||||
['favoriteinfo'] = "Hãy chọn 1 hành động và đưa vào mục ưa thích.",
|
||||
['rfavorite'] = "Xóa toàn bộ Ưa thích",
|
||||
['prop2info'] = "❓ Hành động liên quan đến đồ vật sẽ ở cuối.",
|
||||
['set'] = "Đặt (",
|
||||
['setboundemote'] = ") Làm hành động ưa thích?",
|
||||
['newsetemote'] = "~w~ đã được đặt, Bấm ~g~CapsLock~w~ để sử dụng.",
|
||||
['cancelemote'] = "~h~~r~ Hủy hành động 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ để hủy hành động",
|
||||
|
@ -54,8 +50,6 @@ Locales['vi'] = {
|
|||
['searchinputtitle'] = "Tìm kiếm:",
|
||||
['searchmenudesc'] = "Kết quả cho",
|
||||
['searchnoresult'] = "Không có kết quả",
|
||||
['searchshifttofav'] = "Giữ l-shift và nhấn enter để đặt làm hành động yêu thích.",
|
||||
['searchcantsetfav'] = "ác biểu tượng được chia sẻ không thể được đặt làm mục yêu thích.",
|
||||
['invalidvariation'] = "Biến thể kết cấu không hợp lệ.Các lựa chọn hợp lệ là: %s",
|
||||
['firework'] = "Nhấn ~y~G~w~ Để sử dụng pháo hoa",
|
||||
['poop'] = "Nhấn ~y~G~w~ để ị", -- Translated using smodin.io
|
|
@ -4,12 +4,8 @@ Locales['zhcn'] = {
|
|||
['danceemotes'] = "🕺 舞蹈动作",
|
||||
['animalemotes'] = "🐩 动物动作",
|
||||
['propemotes'] = "📦 道具动作",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 收藏",
|
||||
['favoriteinfo'] = "在这里选择一个动作作为收藏。",
|
||||
['rfavorite'] = "重置收藏",
|
||||
['prop2info'] = "❓ 道具动作位于末尾",
|
||||
['set'] = "设置 (",
|
||||
['setboundemote'] = ") 为你的绑定动作?",
|
||||
['newsetemote'] = "~w~ 现在是你的绑定动作,按 ~g~CapsLock~w~ 使用它。",
|
||||
['cancelemote'] = "取消动作 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ 取消当前的动作",
|
||||
|
@ -63,8 +59,6 @@ Locales['zhcn'] = {
|
|||
['searchinputtitle'] = "搜索:",
|
||||
['searchmenudesc'] = "搜索结果",
|
||||
['searchnoresult'] = "没有搜索结果",
|
||||
['searchshifttofav'] = "按住 L-Shift 并按回车键设置为收藏。",
|
||||
['searchcantsetfav'] = "共享动作不能设置为收藏。",
|
||||
['invalidvariation'] = "无效的纹理变体。有效选择为: %s",
|
||||
['firework'] = "按 ~y~G~w~ 使用烟花",
|
||||
['poop'] = "按 ~y~G~w~ 大便",
|
||||
|
@ -91,7 +85,6 @@ Locales['zhcn'] = {
|
|||
-- 按键映射
|
||||
['register_cancel_emote'] = "取消当前动作",
|
||||
['register_open_menu'] = "打开动作菜单",
|
||||
['register_fav_anim'] = "使用你最喜欢的动作",
|
||||
['register_handsup'] = "举手",
|
||||
['register_crouch'] = "蹲下",
|
||||
['register_crawl'] = "爬行",
|
|
@ -4,12 +4,8 @@ Locales['zhtw'] = {
|
|||
['danceemotes'] = "~h~~p~ 🕺 舞蹈動作",
|
||||
['animalemotes'] = "~h~~p~ 🐩 動物動作",
|
||||
['propemotes'] = "~h~~p~ 📦 物品動作",
|
||||
['favoriteemotes'] = "~h~~y~ 🌟 收藏",
|
||||
['favoriteinfo'] = "在此處選擇壹個動作並將其設為收藏。",
|
||||
['rfavorite'] = "重置收藏",
|
||||
['prop2info'] = "❓ 物品動作在最後面",
|
||||
['set'] = "設置 (",
|
||||
['setboundemote'] = ") 為綁定動作?",
|
||||
['newsetemote'] = "~w~ 已設置為妳的綁定動作,按 ~g~CapsLock~w~ 使用。",
|
||||
['cancelemote'] = "~h~~r~ 取消動作 🚷",
|
||||
['cancelemoteinfo'] = "~r~X~w~ 取消當前動作",
|
||||
|
@ -54,8 +50,6 @@ Locales['zhtw'] = {
|
|||
['searchinputtitle'] = "搜索:",
|
||||
['searchmenudesc'] = " 有 %s 個結果:",
|
||||
['searchnoresult'] = " 沒有搜索結果。",
|
||||
['searchshifttofav'] = "按住 L-Shift 並按回車鍵設置為收藏。",
|
||||
['searchcantsetfav'] = "共享動作無法設置為收藏。",
|
||||
['invalidvariation'] = "紋理顏色無效。有效選擇為: %s",
|
||||
['firework'] = "按 ~y~G~w~ 放煙花",
|
||||
['poop'] = "按 ~y~G~w~ 排便",
|
Before Width: | Height: | Size: 4.1 MiB After Width: | Height: | Size: 4.1 MiB |
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
Before Width: | Height: | Size: 4 MiB After Width: | Height: | Size: 4 MiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 267 KiB After Width: | Height: | Size: 267 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 3.1 MiB After Width: | Height: | Size: 3.1 MiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.8 MiB |
Before Width: | Height: | Size: 3.4 MiB After Width: | Height: | Size: 3.4 MiB |
Before Width: | Height: | Size: 4.1 MiB After Width: | Height: | Size: 4.1 MiB |
Before Width: | Height: | Size: 3.3 MiB After Width: | Height: | Size: 3.3 MiB |
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 4.2 MiB |
Before Width: | Height: | Size: 4 MiB After Width: | Height: | Size: 4 MiB |
Before Width: | Height: | Size: 3.7 MiB After Width: | Height: | Size: 3.7 MiB |
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
164
resources/[standalone]/rpemotes-reborn/server/Server.lua
Normal file
|
@ -0,0 +1,164 @@
|
|||
RegisterNetEvent("rpemotes:server:requestEmote", function(target, emotename, etype)
|
||||
local source = source
|
||||
if not Player(source).state.canEmote then return end
|
||||
|
||||
if target == -1 then
|
||||
return
|
||||
end
|
||||
|
||||
local distance = #(GetEntityCoords(GetPlayerPed(source)) - GetEntityCoords(GetPlayerPed(target)))
|
||||
|
||||
if distance > 3 then
|
||||
return
|
||||
end
|
||||
|
||||
TriggerClientEvent("rpemotes:client:requestEmote", target, emotename, etype, source)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rpemotes:server:confirmEmote", function(target, requestedemote, otheremote)
|
||||
local source = source
|
||||
|
||||
if target == -1 then
|
||||
return
|
||||
end
|
||||
|
||||
local distance = #(GetEntityCoords(GetPlayerPed(source)) - GetEntityCoords(GetPlayerPed(target)))
|
||||
|
||||
if distance > 3 then
|
||||
return
|
||||
end
|
||||
|
||||
TriggerClientEvent("rpemotes:client:syncEmote", source, otheremote, target)
|
||||
TriggerClientEvent("rpemotes:client:syncEmoteSource", target, requestedemote, source)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rpemotes:server:cancelEmote", function(target)
|
||||
TriggerClientEvent("rpemotes:client:cancelEmote", target, source)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rpemotes:ptfx:sync", function(asset, name, offset, rot, bone, scale, color)
|
||||
assert(type(asset) == "string", "[rpemotes] ptfx:sync: invalid asset for source: " .. tostring(source))
|
||||
assert(type(name) == "string", "[rpemotes] ptfx:sync: invalid name for source: " .. tostring(source))
|
||||
assert(type(offset) == "vector3", "[rpemotes] ptfx:sync: invalid offset for source: " .. tostring(source))
|
||||
assert(type(rot) == "vector3", "[rpemotes] ptfx:sync: invalid rot for source: " .. tostring(source))
|
||||
|
||||
local state = Player(source).state
|
||||
|
||||
state:set("ptfxAsset", asset, true)
|
||||
state:set("ptfxName", name, true)
|
||||
state:set("ptfxOffset", offset, true)
|
||||
state:set("ptfxRot", rot, true)
|
||||
state:set("ptfxBone", bone, true)
|
||||
state:set("ptfxScale", scale, true)
|
||||
state:set("ptfxColor", color, true)
|
||||
state:set("ptfxPropNet", nil, true)
|
||||
state:set("ptfx", nil, true)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("rpemotes:ptfx:syncProp", function(propNet)
|
||||
local state = Player(source).state
|
||||
if propNet then
|
||||
local entity
|
||||
local maxAttempts = 100
|
||||
local attempt = 0
|
||||
|
||||
repeat
|
||||
entity = NetworkGetEntityFromNetworkId(propNet)
|
||||
if entity and DoesEntityExist(entity) then
|
||||
state:set("ptfxPropNet", propNet, true)
|
||||
return
|
||||
end
|
||||
attempt = attempt + 1
|
||||
Wait(10)
|
||||
until attempt >= maxAttempts
|
||||
|
||||
print(("[rpemotes] Warning: Failed to find entity for propNet %s after %d attempts (source: %s)"):format(tostring(propNet), maxAttempts, tostring(source)))
|
||||
end
|
||||
|
||||
state:set("ptfxPropNet", nil, true)
|
||||
end)
|
||||
|
||||
|
||||
local function ExtractEmoteProps(format)
|
||||
format = tonumber(format)
|
||||
local xt, c, total = '', '', 0
|
||||
if format == 1 then
|
||||
print("Selected format: ^2'prop_name',")
|
||||
xt = "'"; c = ","
|
||||
elseif format == 2 then
|
||||
print("Selected format: ^2\"prop_name\",")
|
||||
xt = "\""; c = ","
|
||||
elseif format == 3 then
|
||||
print("Selected format: ^2prop_name,")
|
||||
elseif format == 4 then
|
||||
print("Selected to calculate ^2total amount of emotes^0.")
|
||||
else
|
||||
print(
|
||||
"\n### RPEmotes - Props Extractor ###\n\n^3Select output format^0\nAvailable formats:\n^11^0 - ^2'prop_name',\n^12^0 - ^2\"prop_name\",\n^13^0 - ^2prop_name\n^14^0 - ^2calculate total emotes\n\n^0Command usage example: ^5emoteextract 1^0\n")
|
||||
return
|
||||
end
|
||||
|
||||
local animationFile = LoadResourceFile(GetCurrentResourceName(), "client/AnimationList.lua")
|
||||
if not animationFile then return nil end
|
||||
|
||||
local f, err = load(animationFile .. " return RP")
|
||||
if err then return nil end
|
||||
|
||||
local success, res = pcall(f)
|
||||
if not success then return nil end
|
||||
|
||||
if format == 4 then
|
||||
local emoteTypes = { "Shared", "Dances", "AnimalEmotes", "Emotes", "PropEmotes", "Expressions", "Walks" }
|
||||
local expressionAndWalkCount = 0
|
||||
local otherEmotesCount = 0
|
||||
|
||||
for _, emoteType in ipairs(emoteTypes) do
|
||||
local count = 0
|
||||
for _ in pairs(res[emoteType]) do
|
||||
count = count + 1
|
||||
end
|
||||
if emoteType == "Expressions" or emoteType == "Walks" then
|
||||
expressionAndWalkCount = expressionAndWalkCount + count
|
||||
else
|
||||
otherEmotesCount = otherEmotesCount + count
|
||||
end
|
||||
end
|
||||
|
||||
local totalEmotes = expressionAndWalkCount + otherEmotesCount
|
||||
|
||||
print("Total Expressions and Walks: ^3" .. expressionAndWalkCount .. "^0")
|
||||
print("Total Emotes without Expressions and Walks: ^3" .. otherEmotesCount .. "^0")
|
||||
print("Total Emotes: ^3" .. totalEmotes .. "^0")
|
||||
else
|
||||
local file = io.open(GetResourcePath(GetCurrentResourceName()) .. "/prop_list.lua", "w+")
|
||||
if not file then
|
||||
print("Failed to open file for writing.")
|
||||
return
|
||||
end
|
||||
|
||||
local uniqueProps = {}
|
||||
|
||||
for _, value in pairs(res.PropEmotes) do
|
||||
if type(value) == "table" and value.AnimationOptions then
|
||||
local prop = value.AnimationOptions.Prop
|
||||
local secondProp = value.AnimationOptions.SecondProp
|
||||
if prop then uniqueProps[prop] = true end
|
||||
if secondProp then uniqueProps[secondProp] = true end
|
||||
end
|
||||
end
|
||||
|
||||
-- Write all unique props to file
|
||||
for propName in pairs(uniqueProps) do
|
||||
file:write(xt .. propName .. xt .. c .. "\n")
|
||||
total = total + 1
|
||||
end
|
||||
|
||||
file:close()
|
||||
print("Exported " .. total .. " props to ^2prop_list.lua^0")
|
||||
end
|
||||
end
|
||||
|
||||
RegisterCommand("emoteextract", function(source, args)
|
||||
if source > 0 then return end
|
||||
ExtractEmoteProps(args[1])
|
||||
end, true)
|