mirror of https://github.com/OpenMW/openmw.git
Merge branch 'lua_ai' into 'master'
Control AI packages from Lua See merge request OpenMW/openmw!1604C++20
commit
643c1d6aeb
@ -0,0 +1,145 @@
|
||||
Built-in AI packages
|
||||
====================
|
||||
|
||||
Combat
|
||||
------
|
||||
|
||||
Attack another actor.
|
||||
|
||||
**Arguments**
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 20 60
|
||||
|
||||
* - name
|
||||
- type
|
||||
- description
|
||||
* - target
|
||||
- `GameObject <openmw_core.html##(GameObject)>`_ [required]
|
||||
- the actor to attack
|
||||
|
||||
**Examples**
|
||||
|
||||
.. code-block:: Lua
|
||||
|
||||
-- from local script add package to self
|
||||
local AI = require('openmw.interfaces').AI
|
||||
AI.startPackage({type='Combat', target=anotherActor})
|
||||
|
||||
-- via event to any actor
|
||||
actor:sendEvent('StartAIPackage', {type='Combat', target=anotherActor})
|
||||
|
||||
Pursue
|
||||
------
|
||||
|
||||
Pursue another actor.
|
||||
|
||||
**Arguments**
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 20 60
|
||||
|
||||
* - name
|
||||
- type
|
||||
- description
|
||||
* - target
|
||||
- `GameObject <openmw_core.html##(GameObject)>`_ [required]
|
||||
- the actor to pursue
|
||||
|
||||
Follow
|
||||
------
|
||||
|
||||
Follow another actor.
|
||||
|
||||
**Arguments**
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 20 60
|
||||
|
||||
* - name
|
||||
- type
|
||||
- description
|
||||
* - target
|
||||
- `GameObject <openmw_core.html##(GameObject)>`_ [required]
|
||||
- the actor to follow
|
||||
|
||||
Escort
|
||||
------
|
||||
|
||||
Escort another actor to the given location.
|
||||
|
||||
**Arguments**
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 20 60
|
||||
|
||||
* - name
|
||||
- type
|
||||
- description
|
||||
* - target
|
||||
- `GameObject <openmw_core.html##(GameObject)>`_ [required]
|
||||
- the actor to follow
|
||||
* - destPosition
|
||||
- `3d vector <openmw_util.html##(Vector3)>`_ [required]
|
||||
- the destination point
|
||||
* - destCell
|
||||
- Cell [optional]
|
||||
- the destination cell
|
||||
* - duration
|
||||
- number [optional]
|
||||
- duration in game time (will be rounded up to the next hour)
|
||||
|
||||
**Example**
|
||||
|
||||
.. code-block:: Lua
|
||||
|
||||
actor:sendEvent('StartAIPackage', {
|
||||
type = 'Escort',
|
||||
target = object.self,
|
||||
destPosition = util.vector3(x, y, z),
|
||||
duration = 3 * time.hour,
|
||||
})
|
||||
|
||||
Wander
|
||||
------
|
||||
|
||||
Wander nearby current position.
|
||||
|
||||
**Arguments**
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 20 60
|
||||
|
||||
* - name
|
||||
- type
|
||||
- description
|
||||
* - distance
|
||||
- float [default=0]
|
||||
- the actor to follow
|
||||
* - duration
|
||||
- number [optional]
|
||||
- duration in game time (will be rounded up to the next hour)
|
||||
|
||||
Travel
|
||||
------
|
||||
|
||||
Go to given location.
|
||||
|
||||
**Arguments**
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:widths: 20 20 60
|
||||
|
||||
* - name
|
||||
- type
|
||||
- description
|
||||
* - destPosition
|
||||
- `3d vector <openmw_util.html##(Vector3)>`_ [required]
|
||||
- the point to travel to
|
||||
|
@ -0,0 +1,13 @@
|
||||
Built-in events
|
||||
===============
|
||||
|
||||
Any script can send to any actor (except player, for player will be ignored) events ``StartAIPackage`` and ``RemoveAIPackages``.
|
||||
The effect is equivalent to calling ``interfaces.AI.startPackage`` or ``interfaces.AI.removePackages`` in a local script on this actor.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: Lua
|
||||
|
||||
actor:sendEvent('StartAIPackage', {type='Combat', target=self.object})
|
||||
actor:sendEvent('RemoveAIPackages', 'Pursue')
|
||||
|
@ -0,0 +1,6 @@
|
||||
Interface AI
|
||||
============
|
||||
|
||||
.. raw:: html
|
||||
:file: generated_html/scripts_omw_ai.html
|
||||
|
@ -1 +1,2 @@
|
||||
PLAYER: scripts/omw/camera.lua
|
||||
NPC,CREATURE: scripts/omw/ai.lua
|
||||
|
@ -0,0 +1,116 @@
|
||||
local self = require('openmw.self')
|
||||
local interfaces = require('openmw.interfaces')
|
||||
|
||||
local function startPackage(args)
|
||||
if args.type == 'Combat' then
|
||||
if not args.target then error("target required") end
|
||||
self:_startAiCombat(args.target)
|
||||
elseif args.type == 'Pursue' then
|
||||
if not args.target then error("target required") end
|
||||
self:_startAiPursue(args.target)
|
||||
elseif args.type == 'Follow' then
|
||||
if not args.target then error("target required") end
|
||||
self:_startAiFollow(args.target)
|
||||
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)
|
||||
elseif args.type == 'Wander' then
|
||||
self:_startAiWander(args.distance or 0, args.duration or 0)
|
||||
elseif args.type == 'Travel' then
|
||||
if not args.destPosition then error("destPosition required") end
|
||||
self:_startAiTravel(args.destPosition)
|
||||
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 position Destination point of the AI package (can be nil).
|
||||
|
||||
--- 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,
|
||||
|
||||
--- 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,
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in New Issue