494 lines
18 KiB
Lua
494 lines
18 KiB
Lua
-- sequential animations are only supported for up to 3 animations
|
|
-- they need to be in the order of Start=>Loop=>Exit
|
|
local animationList = {
|
|
['rottweiler'] = {
|
|
['standing'] = {
|
|
['normal_bark'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_barking@idle_a',
|
|
animationName = 'idle_a'
|
|
},
|
|
['standing_bark'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_barking@idle_a',
|
|
animationName = 'idle_b'
|
|
},
|
|
['rotate_bark'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_barking@idle_a',
|
|
animationName = 'idle_c'
|
|
}
|
|
},
|
|
['siting'] = {
|
|
['self_itch'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_sitting@idle_a',
|
|
animationName = 'idle_a'
|
|
},
|
|
['look_around'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_sitting@idle_a',
|
|
animationName = 'idle_b',
|
|
skip = { 'A_C_Westy', 'A_C_Pug', 'A_C_Poodle', 'A_C_Cat_01', 'A_C_MtLion', 'A_C_Panther' }
|
|
},
|
|
['sit_Up'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_sitting@idle_a',
|
|
animationName = 'idle_c'
|
|
},
|
|
['sit'] = {
|
|
animDictionary = 'creatures@retriever@amb@world_dog_sitting@base',
|
|
animationName = 'base'
|
|
}
|
|
},
|
|
['misc'] = {
|
|
['indicate_ahead'] = {
|
|
animDictionary = 'creatures@rottweiler@indication@',
|
|
animationName = 'indicate_ahead'
|
|
},
|
|
['indicate_high'] = {
|
|
animDictionary = 'creatures@rottweiler@indication@',
|
|
animationName = 'indicate_high'
|
|
},
|
|
['indicate_low'] = {
|
|
animDictionary = 'creatures@rottweiler@indication@',
|
|
animationName = 'indicate_low'
|
|
},
|
|
['play_dead'] = {
|
|
animDictionary = 'creatures@rottweiler@move',
|
|
animationName = 'dying'
|
|
}
|
|
},
|
|
['tricks'] = {
|
|
['beg'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'beg_enter'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'beg_loop'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'beg_exit'
|
|
}
|
|
}
|
|
},
|
|
['paw'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'paw_right_enter'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'paw_right_loop'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'paw_right_exit'
|
|
}
|
|
}
|
|
},
|
|
['petting_chop'] = {
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'petting_chop'
|
|
},
|
|
['petting_franklin'] = { -- this is for human that is petting dog!
|
|
animDictionary = 'creatures@rottweiler@tricks@',
|
|
animationName = 'petting_franklin'
|
|
}
|
|
},
|
|
['hump'] = {
|
|
['hump_chop'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'creatures@rottweiler@amb@',
|
|
animationName = 'hump_enter_chop'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'creatures@rottweiler@amb@',
|
|
animationName = 'hump_loop_chop'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'creatures@rottweiler@amb@',
|
|
animationName = 'hump_exit_chop'
|
|
}
|
|
}
|
|
},
|
|
['hump_ladydog'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'creatures@rottweiler@amb@',
|
|
animationName = 'hump_enter_ladydog'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'creatures@rottweiler@amb@',
|
|
animationName = 'hump_loop_ladydog'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'creatures@rottweiler@amb@',
|
|
animationName = 'hump_exit_ladydog'
|
|
}
|
|
}
|
|
}
|
|
|
|
},
|
|
['sleep'] = {
|
|
['exit_kennel'] = {
|
|
animDictionary = 'creatures@rottweiler@amb@sleep_in_kennel@',
|
|
animationName = 'exit_kennel'
|
|
},
|
|
['sleep_in_kennel'] = {
|
|
animDictionary = 'creatures@rottweiler@amb@sleep_in_kennel@',
|
|
animationName = 'sleep_in_kennel'
|
|
}
|
|
},
|
|
['pickup'] = {
|
|
['fetch_drop'] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'fetch_drop'
|
|
},
|
|
['fetch_pickup'] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'fetch_pickup'
|
|
}
|
|
},
|
|
['dump'] = {
|
|
['dumpi'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'dump_enter'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'dump_loop'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'dump_exit'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
['pee'] = {
|
|
['pee'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'pee_left_enter'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'pee_left_idle'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'CREATURES@ROTTWEILER@MOVE',
|
|
animationName = 'pee_left_exit'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
['cat'] = {
|
|
['standing'] = {
|
|
['idle'] = {
|
|
animDictionary = 'creatures@cat@move',
|
|
animationName = 'idle'
|
|
},
|
|
['idle_dwn'] = {
|
|
animDictionary = 'creatures@cat@move',
|
|
animationName = 'idle_dwn'
|
|
},
|
|
['idle_upp'] = {
|
|
animDictionary = 'creatures@cat@move',
|
|
animationName = 'idle_upp'
|
|
}
|
|
},
|
|
['siting'] = {
|
|
['sitting'] = {
|
|
animDictionary = 'creatures@cat@amb@world_cat_sleeping_ledge@idle_a',
|
|
animationName = 'idle_a'
|
|
}
|
|
},
|
|
['misc'] = {},
|
|
['sleep'] = {
|
|
['enter_sleep'] = {
|
|
animDictionary = 'creatures@cat@amb@world_cat_sleeping_ground@enter',
|
|
animationName = 'enter'
|
|
},
|
|
['sleep'] = {
|
|
animDictionary = 'creatures@cat@amb@world_cat_sleeping_ground@base',
|
|
animationName = 'base'
|
|
},
|
|
['idle_sleep'] = {
|
|
animDictionary = 'creatures@cat@amb@world_cat_sleeping_ground@idle_a',
|
|
animationName = 'idle_a'
|
|
},
|
|
['exit_sleep'] = {
|
|
animDictionary = 'creatures@cat@amb@world_cat_sleeping_ground@exit',
|
|
animationName = 'base'
|
|
},
|
|
['exit2_sleep'] = {
|
|
animDictionary = 'creatures@cat@amb@peyote@enter',
|
|
animationName = 'enter'
|
|
},
|
|
['exit_panic_sleep'] = {
|
|
animDictionary = 'creatures@cat@amb@world_cat_sleeping_ground@exit',
|
|
animationName = 'idle_a'
|
|
}
|
|
}
|
|
},
|
|
['cougar'] = {
|
|
['standing'] = {
|
|
['idle'] = {
|
|
animDictionary = 'creatures@cat@move',
|
|
animationName = 'idle'
|
|
}
|
|
},
|
|
['siting'] = {
|
|
['sitting'] = {
|
|
animDictionary = 'creatures@cougar@amb@world_cougar_rest@idle_a',
|
|
animationName = 'idle_c'
|
|
}
|
|
},
|
|
['misc'] = {},
|
|
['sleep'] = {
|
|
['enter_sleep'] = {
|
|
animDictionary = 'creatures@cougar@amb@world_cougar_rest@idle_a',
|
|
animationName = 'idle_a'
|
|
}
|
|
|
|
}
|
|
},
|
|
['small'] = {
|
|
['standing'] = {
|
|
['barking'] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_barking@idle_a',
|
|
animationName = 'idle_a'
|
|
},
|
|
['barking_idle'] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_barking@idle_a',
|
|
animationName = 'idle_b'
|
|
},
|
|
['self_clean'] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_barking@idle_a',
|
|
animationName = 'idle_c'
|
|
}
|
|
},
|
|
['siting'] = {
|
|
['siting_1'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_sitting@enter',
|
|
animationName = 'enter'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_sitting@base',
|
|
animationName = 'base'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_sitting@exit',
|
|
animationName = 'exit'
|
|
}
|
|
}
|
|
},
|
|
['sitting_idle_a'] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_sitting@idle_a',
|
|
animationName = 'idle_a'
|
|
},
|
|
['look_around'] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_sitting@idle_a',
|
|
animationName = 'idle_b'
|
|
},
|
|
['sitting_idle_c'] = {
|
|
animDictionary = 'creatures@pug@amb@world_dog_sitting@idle_a',
|
|
animationName = 'idle_c'
|
|
}
|
|
},
|
|
['sleep'] = {}
|
|
},
|
|
['PLAYER'] = {
|
|
['revive'] = {
|
|
['tendtodead'] = {
|
|
sequential = true,
|
|
list = {
|
|
[1] = {
|
|
animDictionary = 'amb@medic@standing@tendtodead@enter',
|
|
animationName = 'enter'
|
|
},
|
|
[2] = {
|
|
animDictionary = 'amb@medic@standing@tendtodead@idle_a',
|
|
animationName = 'idle_c'
|
|
},
|
|
[3] = {
|
|
animDictionary = 'amb@medic@standing@tendtodead@exit',
|
|
animationName = 'exit'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
-- sort animations by ped model
|
|
local correctionList = {
|
|
['A_C_Husky'] = animationList.rottweiler,
|
|
['A_C_shepherd'] = animationList.rottweiler,
|
|
['A_C_Rottweiler'] = animationList.rottweiler,
|
|
['A_C_Retriever'] = animationList.rottweiler,
|
|
['A_C_Westy'] = animationList.small,
|
|
['A_C_Pug'] = animationList.small,
|
|
['A_C_Poodle'] = animationList.small,
|
|
['A_C_Panther'] = animationList.cougar,
|
|
['A_C_MtLion'] = animationList.cougar,
|
|
['A_C_Cat_01'] = animationList.cat,
|
|
['PLAYER'] = animationList.PLAYER
|
|
}
|
|
|
|
function Animator(pedHandle, pedModel, state, options)
|
|
if type(pedHandle) ~= 'number' then assert(pedHandle, 'pedhandle is not a number') return false end
|
|
if type(options) ~= 'table' then assert(table, 'Failed to load options table') return false end
|
|
|
|
-- find a random animaiton if animation is not defined by request
|
|
if options.animation == nil then
|
|
local tmp = {}
|
|
for key, value in pairs(correctionList[pedModel][state]) do
|
|
tmp[#tmp + 1] = key
|
|
end
|
|
options.animation = tmp[math.random(1, #tmp)]
|
|
while correctionList[pedModel][state][options.animation].sequential ~= nil do
|
|
options.animation = tmp[math.random(1, #tmp)]
|
|
end
|
|
end
|
|
|
|
if correctionList[pedModel] == nil or correctionList[pedModel][state] == nil or
|
|
correctionList[pedModel][state][options.animation] == nil then
|
|
return false
|
|
end
|
|
|
|
-- sequential animation logic
|
|
if correctionList[pedModel][state][options.animation].sequential ~= nil and
|
|
correctionList[pedModel][state][options.animation].sequential == true then
|
|
CreateThread(function()
|
|
local finish = false
|
|
local count = 1
|
|
local size = #correctionList[pedModel][state][options.animation].list
|
|
while finish == false do
|
|
local currentAnimation = options.animation
|
|
|
|
if count <= size then
|
|
currentAnimation = correctionList[pedModel][state][options.animation].list[count]
|
|
end
|
|
local c_animDictionary = currentAnimation.animDictionary
|
|
local c_animationName = currentAnimation.animationName
|
|
|
|
local timeout = 0
|
|
if options == nil then
|
|
options = {}
|
|
end
|
|
if options.sequentialTimings == nil then
|
|
options.sequentialTimings = {}
|
|
end
|
|
|
|
local tmpsequentialTimings = {
|
|
[1] = options.sequentialTimings[1] or 0, -- start animation Timeout ==> 1sec(6s-5s) to loop
|
|
[2] = options.sequentialTimings[2] or 0, -- loop animation Timeout ==> 6sec(6s-0s) to exit
|
|
[3] = options.sequentialTimings[3] or 0, -- exit animation Timeout ==> 4sec(6s-2s) to end
|
|
step = options.sequentialTimings['step'] or 1,
|
|
Timeout = options.sequentialTimings['Timeout'] or 5
|
|
}
|
|
if count == 1 then
|
|
timeout = timeout + tmpsequentialTimings[1]
|
|
excuteAnimation(pedHandle, c_animDictionary, c_animationName, 'STOP_LAST_FRAME')
|
|
elseif count == 2 then
|
|
timeout = timeout + tmpsequentialTimings[2]
|
|
excuteAnimation(pedHandle, c_animDictionary, c_animationName, 'REPEAT')
|
|
elseif count == 3 then
|
|
timeout = timeout + tmpsequentialTimings[3]
|
|
excuteAnimation(pedHandle, c_animDictionary, c_animationName)
|
|
end
|
|
|
|
local skip = false
|
|
Wait(75)
|
|
while IsEntityPlayingAnim(pedHandle, c_animDictionary, c_animationName, 3) == 1 and skip == false do
|
|
if tmpsequentialTimings['Timeout'] ~= 5 then
|
|
timeout = timeout + tmpsequentialTimings['step']
|
|
if timeout > tmpsequentialTimings['Timeout'] then
|
|
skip = true
|
|
end
|
|
else
|
|
timeout = timeout + 1
|
|
if timeout > 6 then
|
|
skip = true
|
|
end
|
|
end
|
|
Wait(1000)
|
|
end
|
|
count = count + 1
|
|
if count > size then
|
|
finish = true
|
|
end
|
|
end
|
|
end)
|
|
-- skip rest of functions when we have to play sequential
|
|
return
|
|
end
|
|
|
|
-- QBCore.Functions.Notify(Lang:t('menu.action_menu.error.pet_unable_to_do_that'), 'error', 1500)
|
|
|
|
-- QBCore.Functions.Notify(Lang:t('menu.general_menu_items.success'), 'success', 1500)
|
|
|
|
|
|
local c_animDictionary = correctionList[pedModel][state][options.animation].animDictionary
|
|
local c_animationName = correctionList[pedModel][state][options.animation].animationName
|
|
|
|
excuteAnimation(pedHandle, c_animDictionary, c_animationName, options.c_timings)
|
|
end
|
|
|
|
function excuteAnimation(pedHandle, c_animDictionary, c_animationName, c_timings)
|
|
local flag = 0
|
|
local slow = -1
|
|
|
|
if c_timings ~= nil then
|
|
if c_timings == 'REPEAT' then
|
|
flag = 1
|
|
elseif c_timings == 'STOP_LAST_FRAME' then
|
|
flag = 2
|
|
elseif c_timings == 'UPPERBODY' then
|
|
flag = 16
|
|
elseif c_timings == 'ENABLE_PLAYER_CONTROL' then
|
|
flag = 32
|
|
elseif c_timings == 'CANCELABLE' then
|
|
flag = 120
|
|
else
|
|
flag = -1
|
|
end
|
|
end
|
|
|
|
waitForAnimation(c_animDictionary)
|
|
TaskPlayAnim(pedHandle, c_animDictionary, c_animationName, 8.0, -8, slow, flag, 0, false, false, false)
|
|
end
|
|
|
|
-- missexile2 fra0_ig_14_chop_sniff_fwds
|
|
-- missexile2 taunt_01 taunt_02
|
|
-- missfra0_chop_find chop_bark_at_ballas
|
|
-- missfra0_chop_find fra0_ig_14_chop_sniff_fwds
|
|
|
|
-- 014704 random@nigel@1c take_collar_cam 3966
|
|
-- 014705 random@nigel@1c take_collar_dog 3966
|
|
-- 014706 random@nigel@1c take_collar_dogfacial 3966
|
|
-- 014707 random@nigel@1c take_collar_trevor 3966
|
|
|
|
--- missfra1leadinoutfra_1_int_trevor _trevor_leadin_loop_chop <<<< sleep with feared face!
|
|
--- misschop_vehicle@back_of_van chop_sit_loop chop_lean_back_loop chop_growl_to_sit chop_growl chop_bark
|
|
-- fix_agy_int1-1 a_c_chop_02_dual-1 <<<< sleep
|
|
-- options = {
|
|
-- animation = ?, -- if not icluded sciprt will pick one random animation inside list
|
|
-- c_timings = ?,
|
|
-- }
|