Divergent/mods/Outfit Animations/gamedata/scripts/lam.script

397 lines
12 KiB
Plaintext
Raw Normal View History

--TODO:
--remove dependency on fdda. Ether move all funcs to patches or add more checks
--move instant unequip code from outfit_animations.script into this script
----------------------------------------
-- action example
----------------------------------------
-- function get_action()
-- local action = {
-- sec = "", --section with animation info
-- anm = "", --animation name from animation section, if empty "anm_use" will be used by default
-- cam = "", --camera motion name from animation section, if empty "cam" will be used by default
-- snd = "", --sound path name from animation section, if empty "snd" will be used by default
-- params = {
-- delay = 0, --delay before animation will be played
-- length = 0, --set custom action length independant of animation length. Example: play idle animation while some audio plays
-- can_walk = true, --self explanatory
-- hud_fov = 0.6, --self explanatory
-- },
-- fnc = {
-- [1] = "",
-- [2] = "",
-- }
-- }
-- return action
-- end
----------------------------------------
-- moneky patches
----------------------------------------
--makes that you can't open backpack while animation palys
if zzz_ea_addon_backpack then
local originalBMO = zzz_ea_addon_backpack.backpack_m_open
zzz_ea_addon_backpack.backpack_m_open = function(name)
if lam.is_playing() then return end
originalBMO(name)
end
end
--makes that you can't pick up items while animation plays. Was causeing crash to desktop
if take_item_anim then
local originalAOIBP = take_item_anim.actor_on_item_before_pickup
function take_item_anim.actor_on_item_before_pickup(item, flags)
if is_playing() then
flags.ret_value = false
return
end
originalAOIBP(item, flags)
end
end
----------------------------------------
-- action list
----------------------------------------
local actions_first = 0
local actions_last = -1
local actions = {}
local snd_obj = nil
local current_action = nil
function add_action(action)
actions_last = actions_last + 1
actions[actions_last] = action
-- printf("first %s | last %s | length %s", actions_first, actions_last, actions_count())
on_action_added()
end
function get_next_action()
if actions_first > actions_last then return nil end --if list of action is empty
local val = actions[actions_first]
actions[actions_first] = nil
actions_first = actions_first + 1
return val
end
function actions_count()
local count = 0
for i, v in pairs(actions) do
count = count + 1
end
return count
end
----------------------------------------
-- public functions (sorta api i guess)
----------------------------------------
local _is_enabled = false
local _is_playing = false
function is_enabled()
return _is_enabled
end
function stop_current_action()
if is_playing() then
game.stop_hud_motion()
level.remove_cam_effector(2190)
if snd_obj then snd_obj:stop() end
if current_action then
local fnc = current_action.fnc
if fnc then
for i,v in pairs(fnc) do
RemoveTimeEvent("liz_animation_manager", "play_action_func_" .. i .. "_te")
end
end
RemoveTimeEvent("liz_animation_manager", "play_action_end_te")
if current_action.params.can_walk then
game.only_allow_movekeys(false)
else
level.enable_input()
end
if current_action.params.hud_fov then
lam_fov_manager.restore_fov()
end
end
current_action = nil
snd_obj = nil
on_action_end()
end
end
function stop_all_actions()
if is_playing() then
--clear action list
actions = {}
actions_first = 0
actions_last = -1
stop_current_action()
end
end
function is_playing()
return _is_playing
end
function is_able_to_play()
--all safety checks go here
if not _is_enabled then return false end --script is disabled
if not db.actor:alive() then return end --player is dead
if has_alife_info("BAR_ARENA_FIGHT") then return end --is fighting on arena
if enhanced_animations and enhanced_animations.used_item then return end --possible compatibility issues?
return true
end
--add action to play queue if nothing other plays
function try_play_action(action)
if not is_enabled() then return false end
if is_playing() then return false end
add_action(action)
return true
end
--add action to paly queue no matter if something already palys
function add_action_to_queue(action)
if not is_enabled() then return end
add_action(action)
end
----------------------------------------
-- callbacks
----------------------------------------
function on_game_start()
RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
-- RegisterScriptCallback("on_before_key_press", on_before_key_press)
end
function actor_on_first_update()
CreateTimeEvent("liz_animation_manager", "initialize_te", 3, function ()
_is_enabled = true
return true
end)
end
-- function on_before_key_press(dik, bind, dis, flags)
-- if is_playing() then
-- if dik == DIK_keys.DIK_K then
-- stop_current_action()
-- elseif dik == DIK_keys.DIK_L then
-- stop_all_actions()
-- end
-- if _lock_keys_allow_movement then
-- if
-- dik ~= DIK_keys.DIK_W
-- and dik ~= DIK_keys.DIK_A
-- and dik ~= DIK_keys.DIK_S
-- and dik ~= DIK_keys.DIK_D
-- then
-- flags.ret_value = false
-- return
-- end
-- elseif _lock_keys_all then
-- flags.ret_value = false
-- return
-- end
-- end
-- end
function on_action_added()
if is_playing() then return end
process_next_action()
end
function on_action_end()
process_next_action()
end
----------------------------------------
-- main
----------------------------------------
local cur_slot
local det_active
function process_next_action()
--out of actions show weapon set playing flag to false
if actions_count() == 0 then
show_weapons()
_is_playing = false
return
end
--semething else don't allow to play action, then skip it
if not is_able_to_play() then
get_next_action()
process_next_action()
return
end
if not is_playing() then
_is_playing = true
hide_weapons()
CreateTimeEvent("liz_animation_manager", "wait_for_free_hands_te", 0, function()
if
db.actor:active_slot() == 0
and not db.actor:active_detector()
and (not enhanced_animations or not enhanced_animations.used_item)
then
-- play_action()
CreateTimeEvent("liz_animation_manager", "wait_for_free_hands_delay_te", 0, function () --"fix" for 1.5.1 why it works I do not know ¯\(°_o)/¯
play_action()
return true
end)
return true
end
return false
end)
return
end
CreateTimeEvent("liz_animation_manager", "play_next_action_te", 0.01, function()
play_action()
return true
end)
end
function hide_weapons()
--fdda compatibility
if enhanced_animations and (zzz_ea_addon_backpack and zzz_ea_addon_backpack.anim_enabled and zzz_ea_addon_backpack.backpack_open_flag) then
cur_slot = zzz_ea_addon_backpack.active_slot
det_active = zzz_ea_addon_backpack.det_active
zzz_ea_addon_backpack.active_slot = nil
zzz_ea_addon_backpack.det_active = nil
else
cur_slot = db.actor:active_slot()
det_active = db.actor:active_detector() or nil
if det_active then det_active:switch_state(2) end
end
hide_hud_inventory()
db.actor:activate_slot(0)
end
function show_weapons()
db.actor:activate_slot(cur_slot or 0)
if det_active then det_active:switch_state(1) end
end
-- local ae = actor_effects --sortcut cuz i'm lazy to type full script name every time
function play_action()
local action = get_next_action()
current_action = action
local params = action.params or {}
local length = params.length or game.get_motion_length(action.sec, action.anm or "anm_use", 1) / 1000
local delay = params.delay or 0
--handle params start
if params.can_walk then
game.only_allow_movekeys(true)
else
level.disable_input()
end
if params.hud_fov then
lam_fov_manager.set_fov(0.6)
end
--handle params end
--play animation
CreateTimeEvent("liz_animation_manager", "play_action_te", delay, function()
game.play_hud_motion(2, action.sec, action.anm or "anm_use", false, 1)
local cam = ini_sys:r_string_ex(action.sec, action.cam or "cam")
if cam then
level.add_cam_effector(cam, 2190, false, "")
end
local snd = ini_sys:r_string_ex(action.sec, action.snd or "snd")
if snd then
-- xr_effects.play_snd(db.actor, nil, { [1] = snd })
snd_obj = sound_object(snd)
snd_obj:play(db.actor, 0, sound_object.s2d)
end
return true
end)
--create time events for all additional actions
local last_fnc = 0
local animation_end = delay + length
local fnc = action.fnc
if fnc then
for i,v in pairs(fnc) do
if i > last_fnc then
last_fnc = i
end
CreateTimeEvent("liz_animation_manager", "play_action_func_" .. i .. "_te", i/1000, function ()
assert(loadstring(v))() --this bound to blowup in my face at some point
return true
end)
end
end
last_fnc = last_fnc / 1000
local action_end = animation_end > last_fnc and animation_end or last_fnc
--callback after action ends
CreateTimeEvent("liz_animation_manager", "play_action_end_te", action_end, function ()
--handle params start
if params.can_walk then
game.only_allow_movekeys(false)
else
level.enable_input()
end
if params.hud_fov then
lam_fov_manager.restore_fov()
end
--handle params end
current_action = nil
snd_obj = nil
on_action_end()
return true
end)
-- is it good idea to piggyback on actor_effects code?
-- if (time_global() > ae.time_disabled) then
-- local tg = tostring(time_global())
-- local te = (delay + length) * 1000
-- ae.item_not_in_use = false
-- ae.item_in_use[tg] = action.fnc or {} -- should actually find last object in array. if it fiers after animation then add callback after it
-- if params.can_walk then
-- ae.item_in_use[tg][te] = "game.only_allow_movekeys(false)"
-- else
-- ae.item_in_use[tg][te] = "level.disable_input()"
-- end
-- ae.item_in_use[tg][te + 1] = "liz_anim_manager.on_action_end()"
-- for i,v in pairs(ae.item_in_use[tg]) do
-- printf("%s = %s", i, v)
-- end
-- end
end
-- local _lock_keys_allow_movement = false
-- local _lock_keys_all = false