mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 04:26:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			145 lines
		
	
	
		
			No EOL
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			No EOL
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
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,
 | 
						|
    }
 | 
						|
} |