mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 21:59:55 +00:00
Merge branch 'lua_ai' into 'master'
Expose the argument `cancelOther` of `AiSequence::stack` to Lua Closes #7245 See merge request OpenMW/openmw!2865
This commit is contained in:
commit
7f3926db3f
3 changed files with 54 additions and 19 deletions
|
@ -154,23 +154,23 @@ namespace MWLua
|
||||||
return !keep;
|
return !keep;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
selfAPI["_startAiCombat"] = [](SelfObject& self, const LObject& target) {
|
selfAPI["_startAiCombat"] = [](SelfObject& self, const LObject& target, bool cancelOther) {
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
ai.stack(MWMechanics::AiCombat(target.ptr()), ptr);
|
ai.stack(MWMechanics::AiCombat(target.ptr()), ptr, cancelOther);
|
||||||
};
|
};
|
||||||
selfAPI["_startAiPursue"] = [](SelfObject& self, const LObject& target) {
|
selfAPI["_startAiPursue"] = [](SelfObject& self, const LObject& target, bool cancelOther) {
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
ai.stack(MWMechanics::AiPursue(target.ptr()), ptr);
|
ai.stack(MWMechanics::AiPursue(target.ptr()), ptr, cancelOther);
|
||||||
};
|
};
|
||||||
selfAPI["_startAiFollow"] = [](SelfObject& self, const LObject& target) {
|
selfAPI["_startAiFollow"] = [](SelfObject& self, const LObject& target, bool cancelOther) {
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
ai.stack(MWMechanics::AiFollow(target.ptr()), ptr);
|
ai.stack(MWMechanics::AiFollow(target.ptr()), ptr, cancelOther);
|
||||||
};
|
};
|
||||||
selfAPI["_startAiEscort"] = [](SelfObject& self, const LObject& target, LCell cell, float duration,
|
selfAPI["_startAiEscort"] = [](SelfObject& self, const LObject& target, LCell cell, float duration,
|
||||||
const osg::Vec3f& dest) {
|
const osg::Vec3f& dest, bool cancelOther) {
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
// TODO: change AiEscort implementation to accept ptr instead of a non-unique refId.
|
// TODO: change AiEscort implementation to accept ptr instead of a non-unique refId.
|
||||||
|
@ -178,22 +178,23 @@ namespace MWLua
|
||||||
int gameHoursDuration = static_cast<int>(std::ceil(duration / 3600.0));
|
int gameHoursDuration = static_cast<int>(std::ceil(duration / 3600.0));
|
||||||
auto* esmCell = cell.mStore->getCell();
|
auto* esmCell = cell.mStore->getCell();
|
||||||
if (esmCell->isExterior())
|
if (esmCell->isExterior())
|
||||||
ai.stack(MWMechanics::AiEscort(refId, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr);
|
ai.stack(MWMechanics::AiEscort(refId, gameHoursDuration, dest.x(), dest.y(), dest.z(), false), ptr,
|
||||||
|
cancelOther);
|
||||||
else
|
else
|
||||||
ai.stack(MWMechanics::AiEscort(
|
ai.stack(MWMechanics::AiEscort(
|
||||||
refId, esmCell->getNameId(), gameHoursDuration, dest.x(), dest.y(), dest.z(), false),
|
refId, esmCell->getNameId(), gameHoursDuration, dest.x(), dest.y(), dest.z(), false),
|
||||||
ptr);
|
ptr, cancelOther);
|
||||||
};
|
};
|
||||||
selfAPI["_startAiWander"] = [](SelfObject& self, int distance, float duration) {
|
selfAPI["_startAiWander"] = [](SelfObject& self, int distance, float duration, bool cancelOther) {
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
int gameHoursDuration = static_cast<int>(std::ceil(duration / 3600.0));
|
int gameHoursDuration = static_cast<int>(std::ceil(duration / 3600.0));
|
||||||
ai.stack(MWMechanics::AiWander(distance, gameHoursDuration, 0, {}, false), ptr);
|
ai.stack(MWMechanics::AiWander(distance, gameHoursDuration, 0, {}, false), ptr, cancelOther);
|
||||||
};
|
};
|
||||||
selfAPI["_startAiTravel"] = [](SelfObject& self, const osg::Vec3f& target) {
|
selfAPI["_startAiTravel"] = [](SelfObject& self, const osg::Vec3f& target, bool cancelOther) {
|
||||||
const MWWorld::Ptr& ptr = self.ptr();
|
const MWWorld::Ptr& ptr = self.ptr();
|
||||||
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
MWMechanics::AiSequence& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence();
|
||||||
ai.stack(MWMechanics::AiTravel(target.x(), target.y(), target.z(), false), ptr);
|
ai.stack(MWMechanics::AiTravel(target.x(), target.y(), target.z(), false), ptr, cancelOther);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,38 @@
|
||||||
Built-in AI packages
|
Built-in AI packages
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
Starting an AI package
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
There are two ways to start AI package:
|
||||||
|
|
||||||
|
.. code-block:: Lua
|
||||||
|
|
||||||
|
-- from local script add package to self
|
||||||
|
local AI = require('openmw.interfaces').AI
|
||||||
|
AI.startPackage(options)
|
||||||
|
|
||||||
|
-- via event to any actor
|
||||||
|
actor:sendEvent('StartAIPackage', options)
|
||||||
|
|
||||||
|
``options`` is Lua table with arguments of the AI package.
|
||||||
|
|
||||||
|
**Common arguments that can be used with any AI package**
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:header-rows: 1
|
||||||
|
:widths: 20 20 60
|
||||||
|
|
||||||
|
* - name
|
||||||
|
- type
|
||||||
|
- description
|
||||||
|
* - type
|
||||||
|
- string [required]
|
||||||
|
- the name of the package (see packages listed below)
|
||||||
|
* - cancelOther
|
||||||
|
- boolean [default=true]
|
||||||
|
- whether to cancel all other AI packages
|
||||||
|
|
||||||
Combat
|
Combat
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -2,24 +2,26 @@ local self = require('openmw.self')
|
||||||
local interfaces = require('openmw.interfaces')
|
local interfaces = require('openmw.interfaces')
|
||||||
|
|
||||||
local function startPackage(args)
|
local function startPackage(args)
|
||||||
|
local cancelOther = args.cancelOther
|
||||||
|
if cancelOther == nil then cancelOther = true end
|
||||||
if args.type == 'Combat' then
|
if args.type == 'Combat' then
|
||||||
if not args.target then error("target required") end
|
if not args.target then error("target required") end
|
||||||
self:_startAiCombat(args.target)
|
self:_startAiCombat(args.target, cancelOther)
|
||||||
elseif args.type == 'Pursue' then
|
elseif args.type == 'Pursue' then
|
||||||
if not args.target then error("target required") end
|
if not args.target then error("target required") end
|
||||||
self:_startAiPursue(args.target)
|
self:_startAiPursue(args.target, cancelOther)
|
||||||
elseif args.type == 'Follow' then
|
elseif args.type == 'Follow' then
|
||||||
if not args.target then error("target required") end
|
if not args.target then error("target required") end
|
||||||
self:_startAiFollow(args.target)
|
self:_startAiFollow(args.target, cancelOther)
|
||||||
elseif args.type == 'Escort' then
|
elseif args.type == 'Escort' then
|
||||||
if not args.target then error("target required") end
|
if not args.target then error("target required") end
|
||||||
if not args.destPosition then error("destPosition 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)
|
self:_startAiEscort(args.target, args.destCell or self.cell, args.duration or 0, args.destPosition, cancelOther)
|
||||||
elseif args.type == 'Wander' then
|
elseif args.type == 'Wander' then
|
||||||
self:_startAiWander(args.distance or 0, args.duration or 0)
|
self:_startAiWander(args.distance or 0, args.duration or 0, cancelOther)
|
||||||
elseif args.type == 'Travel' then
|
elseif args.type == 'Travel' then
|
||||||
if not args.destPosition then error("destPosition required") end
|
if not args.destPosition then error("destPosition required") end
|
||||||
self:_startAiTravel(args.destPosition)
|
self:_startAiTravel(args.destPosition, cancelOther)
|
||||||
else
|
else
|
||||||
error('Unsupported AI Package: ' .. args.type)
|
error('Unsupported AI Package: ' .. args.type)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue