1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-29 18:32:36 +00:00

Add option "onGround=true/false" in Lua teleporting

This commit is contained in:
Petr Mikheev 2023-05-13 16:50:56 +02:00
parent e53f907a53
commit 2725a9d7f4
2 changed files with 35 additions and 12 deletions

View File

@ -66,7 +66,8 @@ namespace MWLua
return &wm->getCellByPosition(pos, cell);
}
void teleportPlayer(MWWorld::CellStore* destCell, const osg::Vec3f& pos, const osg::Vec3f& rot)
void teleportPlayer(
MWWorld::CellStore* destCell, const osg::Vec3f& pos, const osg::Vec3f& rot, bool placeOnGround)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
ESM::Position esmPos;
@ -78,11 +79,16 @@ namespace MWLua
stats.land(true);
stats.setTeleported(true);
world->getPlayer().setTeleported(true);
world->changeToCell(destCell->getCell()->getId(), esmPos, true);
world->changeToCell(destCell->getCell()->getId(), esmPos, false);
MWWorld::Ptr newPtr = world->getPlayerPtr();
world->moveObject(newPtr, pos);
world->rotateObject(newPtr, rot);
if (placeOnGround)
world->adjustPosition(newPtr, true);
}
void teleportNotPlayer(
const MWWorld::Ptr& ptr, MWWorld::CellStore* destCell, const osg::Vec3f& pos, const osg::Vec3f& rot)
void teleportNotPlayer(const MWWorld::Ptr& ptr, MWWorld::CellStore* destCell, const osg::Vec3f& pos,
const osg::Vec3f& rot, bool placeOnGround)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
const MWWorld::Class& cls = ptr.getClass();
@ -94,6 +100,8 @@ namespace MWLua
}
MWWorld::Ptr newPtr = world->moveObject(ptr, destCell, pos);
world->rotateObject(newPtr, rot, MWBase::RotationFlag_none);
if (placeOnGround)
world->adjustPosition(newPtr, true);
if (!newPtr.getRefData().isEnabled())
world->enable(newPtr);
}
@ -349,38 +357,47 @@ namespace MWLua
});
};
objectT["teleport"] = [removeFn, context](const GObject& object, const sol::object& cellOrName,
const osg::Vec3f& pos, const sol::optional<osg::Vec3f>& optRot) {
const osg::Vec3f& pos, const sol::object& options) {
MWWorld::CellStore* cell = findCell(cellOrName, pos);
MWWorld::Ptr ptr = object.ptr();
int count = ptr.getRefData().getCount();
if (count == 0)
throw std::runtime_error("Object is either removed or already in the process of teleporting");
osg::Vec3f rot = optRot ? *optRot : ptr.getRefData().getPosition().asRotationVec3();
osg::Vec3f rot = ptr.getRefData().getPosition().asRotationVec3();
bool placeOnGround = false;
if (options.is<osg::Vec3f>())
rot = options.as<osg::Vec3f>();
else if (options != sol::nil)
{
sol::table t = LuaUtil::cast<sol::table>(options);
rot = LuaUtil::getValueOrDefault(t["rotation"], rot);
placeOnGround = LuaUtil::getValueOrDefault(t["onGround"], placeOnGround);
}
if (ptr.getContainerStore())
{
DelayedRemovalFn delayedRemovalFn = *removeFn(ptr, count);
context.mLuaManager->addAction(
[object, cell, pos, rot, count, delayedRemovalFn] {
[object, cell, pos, rot, count, delayedRemovalFn, placeOnGround] {
MWWorld::Ptr oldPtr = object.ptr();
oldPtr.getRefData().setCount(count);
MWWorld::Ptr newPtr = oldPtr.getClass().moveToCell(oldPtr, *cell);
oldPtr.getRefData().setCount(0);
newPtr.getRefData().disable();
teleportNotPlayer(newPtr, cell, pos, rot);
teleportNotPlayer(newPtr, cell, pos, rot, placeOnGround);
delayedRemovalFn(oldPtr);
},
"TeleportFromContainerAction");
}
else if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
context.mLuaManager->addTeleportPlayerAction(
[cell, pos, rot] { teleportPlayer(cell, pos, rot); });
[cell, pos, rot, placeOnGround] { teleportPlayer(cell, pos, rot, placeOnGround); });
else
{
ptr.getRefData().setCount(0);
context.mLuaManager->addAction(
[object, cell, pos, rot, count] {
[object, cell, pos, rot, count, placeOnGround] {
object.ptr().getRefData().setCount(count);
teleportNotPlayer(object.ptr(), cell, pos, rot);
teleportNotPlayer(object.ptr(), cell, pos, rot, placeOnGround);
},
"TeleportAction");
}

View File

@ -177,7 +177,13 @@
-- @param #any cellOrName A cell to define the destination worldspace; can be either #Cell, or cell name, or an empty string (empty string means the default exterior worldspace).
-- If the worldspace has multiple cells (i.e. an exterior), the destination cell is calculated using `position`.
-- @param openmw.util#Vector3 position New position.
-- @param openmw.util#Vector3 rotation (optional) New rotation. If missing, then the current rotation is used.
-- @param #TeleportOptions options (optional) Either table @{#TeleportOptions} or @{openmw.util#Vector3} rotation.
---
-- Either table with options or @{openmw.util#Vector3} rotation.
-- @type TeleportOptions
-- @field openmw.util#Vector3 rotation New rotation; if missing, then the current rotation is used.
-- @field #boolean onGround If true, adjust destination position to the ground.
---
-- Moves object into a container or an inventory. Enables if was disabled.