mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-03 17:37:18 +00:00
150 lines
6.1 KiB
Lua
150 lines
6.1 KiB
Lua
local self = require('openmw.self')
|
|
local interfaces = require('openmw.interfaces')
|
|
local types = require('openmw.types')
|
|
local util = require('openmw.util')
|
|
|
|
local function startPackage(args)
|
|
local cancelOther = args.cancelOther
|
|
if cancelOther == nil then cancelOther = true end
|
|
if args.type == 'Combat' then
|
|
if not args.target then error("target required") end
|
|
self:_startAiCombat(args.target, cancelOther)
|
|
elseif args.type == 'Pursue' then
|
|
if not args.target then error("target required") end
|
|
if not types.Player.objectIsInstance(args.target) then error("target must be a player") end
|
|
self:_startAiPursue(args.target, cancelOther)
|
|
elseif args.type == 'Follow' then
|
|
if not args.target then error("target required") end
|
|
self:_startAiFollow(args.target, args.cellId, args.duration or 0, args.destPosition or util.vector3(0, 0, 0), args.isRepeat or false, cancelOther)
|
|
elseif args.type == 'Escort' then
|
|
if not args.target then error("target required") end
|
|
if not args.destPosition then error("destPosition required") end
|
|
self:_startAiEscort(args.target, args.destCell or self.cell, args.duration or 0, args.destPosition, cancelOther)
|
|
elseif args.type == 'Wander' then
|
|
local key = "idle"
|
|
local idle = {}
|
|
local duration = 0
|
|
if args.idle then
|
|
for i = 2, 9 do
|
|
local val = args.idle[key .. i]
|
|
if val == nil then
|
|
idle[i-1] = 0
|
|
else
|
|
local v = tonumber(val) or 0
|
|
if v < 0 or v > 100 then
|
|
error("idle values cannot exceed 100")
|
|
end
|
|
idle[i-1] = v
|
|
end
|
|
end
|
|
end
|
|
if args.duration then
|
|
duration = args.duration / 3600
|
|
end
|
|
self:_startAiWander(args.distance or 0, duration, idle, args.isRepeat or false, cancelOther)
|
|
elseif args.type == 'Travel' then
|
|
if not args.destPosition then error("destPosition required") end
|
|
self:_startAiTravel(args.destPosition, args.isRepeat or false, cancelOther)
|
|
else
|
|
error('Unsupported AI Package: ' .. args.type)
|
|
end
|
|
end
|
|
|
|
local function filterPackages(filter)
|
|
self:_iterateAndFilterAiSequence(filter)
|
|
end
|
|
|
|
return {
|
|
interfaceName = 'AI',
|
|
--- Basic AI interface
|
|
-- @module AI
|
|
-- @usage require('openmw.interfaces').AI
|
|
interface = {
|
|
--- Interface version
|
|
-- @field [parent=#AI] #number version
|
|
version = 0,
|
|
|
|
--- AI Package
|
|
-- @type Package
|
|
-- @field #string type Type of the AI package.
|
|
-- @field openmw.core#GameObject target Target (usually an actor) of the AI package (can be nil).
|
|
-- @field #boolean sideWithTarget Whether to help the target in combat (true or false).
|
|
-- @field openmw.util#Vector3 destPosition Destination point of the AI package.
|
|
-- @field #number distance Distance value (can be nil).
|
|
-- @field #number duration Duration value (can be nil).
|
|
-- @field #table idle Idle value (can be nil).
|
|
-- @field #boolean isRepeat Should this package be repeated (true or false).
|
|
|
|
--- Return the currently active AI package (or `nil` if there are no AI packages).
|
|
-- @function [parent=#AI] getActivePackage
|
|
-- @return #Package
|
|
getActivePackage = function() return self:_getActiveAiPackage() end,
|
|
|
|
--- Return whether the actor is fleeing.
|
|
-- @function [parent=#AI] isFleeing
|
|
-- @return #boolean
|
|
isFleeing = function() return self:_isFleeing() end,
|
|
|
|
--- Start new AI package.
|
|
-- @function [parent=#AI] startPackage
|
|
-- @param #table options See the "Built-in AI packages" page.
|
|
startPackage = startPackage,
|
|
|
|
--- Iterate over all packages starting from the active one and remove those where `filterCallback` returns false.
|
|
-- @function [parent=#AI] filterPackages
|
|
-- @param #function filterCallback
|
|
filterPackages = filterPackages,
|
|
|
|
--- Iterate over all packages and run `callback` for each starting from the active one.
|
|
-- The same as `filterPackage`, but without removal.
|
|
-- @function [parent=#AI] forEachPackage
|
|
-- @param #function callback
|
|
forEachPackage = function(callback)
|
|
local filter = function(p)
|
|
callback(p)
|
|
return true
|
|
end
|
|
filterPackages(filter)
|
|
end,
|
|
|
|
--- Remove packages of given type (remove all packages if the type is not specified).
|
|
-- @function [parent=#AI] removePackages
|
|
-- @param #string packageType (optional) The type of packages to remove.
|
|
removePackages = function(packageType)
|
|
filterPackages(function(p) return packageType and p.type ~= packageType end)
|
|
end,
|
|
|
|
--- Return the target of the active package if the package has given type
|
|
-- @function [parent=#AI] getActiveTarget
|
|
-- @param #string packageType The expected type of the active package
|
|
-- @return openmw.core#GameObject The target (can be nil if the package has no target or has another type)
|
|
getActiveTarget = function(packageType)
|
|
local p = self:_getActiveAiPackage()
|
|
if p and p.type == packageType then
|
|
return p.target
|
|
else
|
|
return nil
|
|
end
|
|
end,
|
|
|
|
--- Get list of targets of all packages of the given type.
|
|
-- @function [parent=#AI] getTargets
|
|
-- @param #string packageType
|
|
-- @return #list<openmw.core#GameObject>
|
|
getTargets = function(packageType)
|
|
local res = {}
|
|
filterPackages(function(p)
|
|
if p.type == packageType and p.target then
|
|
res[#res + 1] = p.target
|
|
end
|
|
return true
|
|
end)
|
|
return res
|
|
end,
|
|
},
|
|
eventHandlers = {
|
|
StartAIPackage = function(options) interfaces.AI.startPackage(options) end,
|
|
RemoveAIPackages = function(packageType) interfaces.AI.removePackages(packageType) end,
|
|
},
|
|
}
|