155 lines
		
	
	
		
			No EOL
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			No EOL
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| Anim = Anim or {}
 | |
| Ids = Ids or Require("lib/utility/shared/ids.lua")
 | |
| Anim.Active = Anim.Active or {}
 | |
| Anim.isUpdateLoopRunning = Anim.isUpdateLoopRunning or false
 | |
| 
 | |
| --- This will request the animation dictionary.
 | |
| --- @param animDict string
 | |
| --- @return boolean
 | |
| function Anim.RequestDict(animDict)
 | |
|     if not animDict or type(animDict) ~= "string" then
 | |
|         return false
 | |
|     end
 | |
| 
 | |
|     if HasAnimDictLoaded(animDict) then
 | |
|         return true
 | |
|     end
 | |
| 
 | |
|     RequestAnimDict(animDict)
 | |
|     local timeout = GetGameTimer() + 2000
 | |
|     while not HasAnimDictLoaded(animDict) and GetGameTimer() < timeout do
 | |
|         Wait(50)
 | |
|     end
 | |
| 
 | |
|     return HasAnimDictLoaded(animDict)
 | |
| end
 | |
| 
 | |
| --- This will start the animation update loop.
 | |
| function Anim.Start()
 | |
|     if Anim.isUpdateLoopRunning then return end
 | |
|     Anim.isUpdateLoopRunning = true
 | |
|     CreateThread(function()
 | |
|         while Anim.isUpdateLoopRunning do
 | |
|             local idsToProcess = {}
 | |
|             for idKey, _ in pairs(Anim.Active) do
 | |
|                 table.insert(idsToProcess, idKey)
 | |
|             end
 | |
| 
 | |
|             if #idsToProcess == 0 then
 | |
|                 Wait(750)
 | |
|             else
 | |
|                 for _, id in ipairs(idsToProcess) do
 | |
|                     local animData = Anim.Active[id]
 | |
|                     if animData then
 | |
|                         local entity = animData.entity
 | |
|                         local onComplete = animData.onComplete
 | |
|                         if not DoesEntityExist(entity) then
 | |
|                             if onComplete then onComplete(false, "despawned") end
 | |
|                             Anim.Active[id] = nil
 | |
|                         elseif animData.status == "pending_task" then
 | |
|                             TaskPlayAnim(entity, animData.animDict, animData.animName, animData.blendIn, animData.blendOut, animData.duration, animData.flag, animData.playbackRate, false, false, false)
 | |
|                             animData.startTime = GetGameTimer()
 | |
|                             animData.animEndTime = animData.duration > 0 and (animData.startTime + animData.duration) or -1
 | |
|                             animData.status = "playing"
 | |
|                         elseif animData.status == "playing" then
 | |
|                             local animationCompletedNaturally = false
 | |
|                             if animData.duration == -1 then
 | |
|                                 if not IsEntityPlayingAnim(entity, animData.animDict, animData.animName, 3) and GetEntityAnimCurrentTime(entity, animData.animDict, animData.animName) > 0.8 then
 | |
|                                     animationCompletedNaturally = true
 | |
|                                 end
 | |
|                             elseif animData.animEndTime ~= -1 and GetGameTimer() >= animData.animEndTime then
 | |
|                                 animationCompletedNaturally = true
 | |
|                             end
 | |
|                             if animationCompletedNaturally then
 | |
|                                 if onComplete then onComplete(true, "completed") end
 | |
|                                 Anim.Active[id] = nil
 | |
|                             end
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|                 Wait(100)
 | |
|             end
 | |
|         end
 | |
|     end)
 | |
| end
 | |
| 
 | |
| --- This will play an animation on the specified ped.
 | |
| --- @param id string | nil
 | |
| --- @param entity number
 | |
| --- @param animDict string
 | |
| --- @param animName string
 | |
| --- @param blendIn number | nil
 | |
| --- @param blendOut number | nil
 | |
| --- @param duration number | nil
 | |
| --- @param flag number | nil
 | |
| --- @param playbackRate number | nil
 | |
| --- @param onComplete function | nil
 | |
| --- @return string | nil
 | |
| function Anim.Play(id, entity, animDict, animName, blendIn, blendOut, duration, flag, playbackRate, onComplete)
 | |
|     local newId = id or Ids.CreateUniqueId(Anim.Active)
 | |
|     if Anim.Active[newId] then
 | |
|         if onComplete then
 | |
|             onComplete(false, "id_in_use")
 | |
|         end
 | |
|         return newId
 | |
|     end
 | |
| 
 | |
|     if not entity or not DoesEntityExist(entity) or not IsEntityAPed(entity) then
 | |
|         if onComplete then
 | |
|             onComplete(false, "invalid_entity")
 | |
|         end
 | |
|         return nil
 | |
|     end
 | |
| 
 | |
|     if not Anim.RequestDict(animDict) then
 | |
|         if onComplete then
 | |
|             onComplete(false, "dict_load_failed")
 | |
|         end
 | |
|         return nil
 | |
|     end
 | |
| 
 | |
|     Anim.Active[newId] = {
 | |
|         entity = entity,
 | |
|         animDict = animDict,
 | |
|         animName = animName,
 | |
|         blendIn = blendIn or 8.0,
 | |
|         blendOut = blendOut or -8.0,
 | |
|         duration = duration or -1,
 | |
|         flag = flag or 1,
 | |
|         playbackRate = playbackRate or 0.0,
 | |
|         onComplete = onComplete,
 | |
|         status = "pending_task",
 | |
|         startTime = 0,
 | |
|         animEndTime = 0
 | |
|     }
 | |
| 
 | |
|     Anim.Start()
 | |
|     return newId
 | |
| end
 | |
| 
 | |
| function Anim.Stop(id)
 | |
|     if not id or not Anim.Active or not Anim.Active[id] then
 | |
|         return false
 | |
|     end
 | |
| 
 | |
|     local animData = Anim.Active[id]
 | |
| 
 | |
|     if animData.entity and DoesEntityExist(animData.entity) and IsEntityAPed(animData.entity) then
 | |
|         if animData.status == "playing" or animData.status == "pending_task" then
 | |
|              StopAnimTask(animData.entity, animData.animDict, animData.animName, 1.0)
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     if animData.onComplete then
 | |
|         animData.onComplete(false, "stopped_by_id")
 | |
|     end
 | |
| 
 | |
|     Anim.Active[id] = nil
 | |
|     local anyLeft = Anim.Active and next(Anim.Active) ~= nil
 | |
|     if not anyLeft then
 | |
|         Anim.isUpdateLoopRunning = false
 | |
|     end
 | |
|     return true
 | |
| end
 | |
| 
 | |
| return Anim | 
