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)