164 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| 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)
 | 
