2024-01-26 21:39:33 +00:00
local anim = require ( ' openmw.animation ' )
local self = require ( ' openmw.self ' )
local playBlendedHandlers = { }
local function onPlayBlendedAnimation ( groupname , options )
for i = # playBlendedHandlers , 1 , - 1 do
if playBlendedHandlers [ i ] ( groupname , options ) == false then
return
end
end
end
local function playBlendedAnimation ( groupname , options )
onPlayBlendedAnimation ( groupname , options )
if options.skip then
return
end
anim.playBlended ( self , groupname , options )
end
local textKeyHandlers = { }
local function onAnimationTextKey ( groupname , key )
local handlers = textKeyHandlers [ groupname ]
if handlers then
for i = # handlers , 1 , - 1 do
if handlers [ i ] ( groupname , key ) == false then
return
end
end
end
handlers = textKeyHandlers [ ' ' ]
if handlers then
for i = # handlers , 1 , - 1 do
if handlers [ i ] ( groupname , key ) == false then
return
end
end
end
end
local initialized = false
local function onUpdate ( dt )
-- The script is loaded before the actor's CharacterController object is initialized, therefore
-- we have to delay this initialization step or the call won't have any effect.
if not initialized then
self : _enableLuaAnimations ( true )
initialized = true
end
end
return {
engineHandlers = {
_onPlayAnimation = playBlendedAnimation ,
_onAnimationTextKey = onAnimationTextKey ,
onUpdate = onUpdate ,
} ,
interfaceName = ' AnimationController ' ,
---
-- Animation controller interface
-- @module AnimationController
-- @usage local anim = require('openmw.animation')
-- local I = require('openmw.interfaces')
--
-- -- play spellcast animation
-- I.AnimationController.playBlendedAnimation('spellcast', { startkey = 'self start', stopkey = 'self stop', priority = {
-- [anim.BONE_GROUP.RightArm] = anim.PRIORITY.Weapon,
-- [anim.BONE_GROUP.LeftArm] = anim.PRIORITY.Weapon,
-- [anim.BONE_GROUP.Torso] = anim.PRIORITY.Weapon,
-- [anim.BONE_GROUP.LowerBody] = anim.PRIORITY.WeaponLowerBody
-- } })
--
-- @usage -- react to the spellcast release textkey
-- I.AnimationController.addTextKeyHandler('spellcast', function(groupname, key)
-- -- Note, Lua is 1-indexed so have to subtract 1 less than the length of 'release'
-- if key.sub(key, #key - 6) == 'release' then
-- print('Abra kadabra!')
-- end
-- end)
--
-- @usage -- Add a text key handler that will react to all keys
-- I.AnimationController.addTextKeyHandler('', function(groupname, key)
-- if key.sub(key, #key - 2) == 'hit' and not key.sub(key, #key - 7) == ' min hit' then
-- print('Hit!')
-- end
-- end)
--
-- @usage -- Make a handler that changes player attack speed based on current fatigue
-- I.AnimationController.addPlayBlendedAnimationHandler(function (groupname, options)
-- local stop = options.stopkey
-- if #stop > 10 and stop.sub(stop, #stop - 10) == ' max attack' then
-- -- This is an attack wind up animation, scale its speed by attack
-- local fatigue = Actor.stats.dynamic.fatigue(self)
-- local factor = 1 - fatigue.current / fatigue.base
-- speed = 1 - factor * 0.8
-- options.speed = speed
-- end
-- end)
--
interface = {
--- Interface version
-- @field [parent=#AnimationController] #number version
version = 0 ,
--- AnimationController Package
-- @type Package
--- Make this actor play an animation. Makes a call to @{openmw.animation#playBlended}, after invoking handlers added through addPlayBlendedAnimationHandler
-- @function [parent=#AnimationController] playBlendedAnimation
-- @param #string groupname The animation group to be played
-- @param #table options The table of play options that will be passed to @{openmw.animation#playBlended}
playBlendedAnimation = playBlendedAnimation ,
--- Add new playBlendedAnimation handler for this actor
-- If `handler(groupname, options)` returns false, other handlers for
-- the call will be skipped.
-- @function [parent=#AnimationController] addPlayBlendedAnimationHandler
-- @param #function handler The handler.
addPlayBlendedAnimationHandler = function ( handler )
playBlendedHandlers [ # playBlendedHandlers + 1 ] = handler
end ,
--- Add new text key handler for this actor
-- While playing, some animations emit text key events. Register a handle to listen for all
-- text key events associated with this actor's animations.
-- If `handler(groupname, key)` returns false, other handlers for
-- the call will be skipped.
-- @function [parent=#AnimationController] addTextKeyHandler
-- @param #string groupname Name of the animation group to listen to keys for. If the empty string or nil, all keys will be received
-- @param #function handler The handler.
addTextKeyHandler = function ( groupname , handler )
if not groupname then
groupname = " "
end
local handlers = textKeyHandlers [ groupname ]
if handlers == nil then
handlers = { }
textKeyHandlers [ groupname ] = handlers
end
handlers [ # handlers + 1 ] = handler
end ,
2024-08-10 12:52:41 +00:00
} ,
eventHandlers = {
AddVfx = function ( data )
anim.addVfx ( self , data.model , data.options )
end ,
2024-01-26 21:39:33 +00:00
}
2024-08-10 12:52:41 +00:00
}