File: usehandlers.lua

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (98 lines) | stat: -rw-r--r-- 3,692 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
local types = require('openmw.types')
local world = require('openmw.world')

local handlersPerObject = {}
local handlersPerType = {}

local function useItem(obj, actor, force)
    local options = { force = force or false }
    local handlers = handlersPerObject[obj.id]
    if handlers then
        for i = #handlers, 1, -1 do
            if handlers[i](obj, actor, options) == false then
                return -- skip other handlers
            end
        end
    end
    handlers = handlersPerType[obj.type]
    if handlers then
        for i = #handlers, 1, -1 do
            if handlers[i](obj, actor, options) == false then
                return -- skip other handlers
            end
        end
    end
    world._runStandardUseAction(obj, actor, options.force)
end

return {
    interfaceName = 'ItemUsage',
    ---
    -- Allows to extend or override built-in item usage mechanics.
    -- Note: at the moment it can override item usage in inventory
    -- (dragging an item on the character's model), but
    --
    -- * can't intercept actions performed by mwscripts;
    -- * can't intercept actions performed by the AI (i.e. drinking a potion in combat);
    -- * can't intercept actions performed via quick keys menu.
    -- @module ItemUsage
    -- @usage local I = require('openmw.interfaces')
    --
    -- -- Override Use action (global script).
    -- -- Forbid equipping armor with weight > 5
    -- I.ItemUsage.addHandlerForType(types.Armor, function(armor, actor)
    --     if types.Armor.record(armor).weight > 5 then
    --         return false -- disable other handlers
    --     end
    -- end)
    --
    -- -- Call Use action (any script).
    -- core.sendGlobalEvent('UseItem', {object = armor, actor = player})
    interface = {
        --- Interface version
        -- @field [parent=#ItemUsage] #number version
        version = 0,

        --- Add new use action handler for a specific object.
        -- If `handler(object, actor, options)` returns false, other handlers for
        -- the same object (including type handlers) will be skipped.
        -- @function [parent=#ItemUsage] addHandlerForObject
        -- @param openmw.core#GameObject obj The object.
        -- @param #function handler The handler.
        addHandlerForObject = function(obj, handler)
            local handlers = handlersPerObject[obj.id]
            if handlers == nil then
                handlers = {}
                handlersPerObject[obj.id] = handlers
            end
            handlers[#handlers + 1] = handler
        end,

        --- Add new use action handler for a type of objects.
        -- If `handler(object, actor, options)` returns false, other handlers for
        -- the same object (including type handlers) will be skipped.
        -- @function [parent=#ItemUsage] addHandlerForType
        -- @param #any type A type from the `openmw.types` package.
        -- @param #function handler The handler.
        addHandlerForType = function(type, handler)
            local handlers = handlersPerType[type]
            if handlers == nil then
                handlers = {}
                handlersPerType[type] = handlers
            end
            handlers[#handlers + 1] = handler
        end,
    },
    engineHandlers = { _onUseItem = useItem },
    eventHandlers = {
        UseItem = function(data)
            if not data.object then
                error('UseItem: missing argument "object"')
            end
            if not data.actor or not types.Actor.objectIsInstance(data.actor) then
                error('UseItem: invalid argument "actor"')
            end
            useItem(data.object, data.actor, data.force)
        end
    }
}