add setRotation and setPosition

This commit is contained in:
SkyHasACat 2025-08-01 08:51:27 -07:00
parent 966f1f1b09
commit da8949e40a
2 changed files with 66 additions and 7 deletions

View File

@ -501,7 +501,7 @@ namespace MWLua
});
};
objectT["setTransform"] = [context](const GObject& object, const osg::Vec3f& newPos,
sol::object newRotObj, sol::optional<bool> terrainClampOpt) {
const sol::object& newRotObj, sol::optional<bool> terrainClampOpt) {
bool terrainClamp = terrainClampOpt.value_or(true);
MWWorld::Ptr ptr = object.ptr();
if (ptr.getCellRef().getCount() == 0 || !ptr.isInCell())
@ -522,11 +522,7 @@ namespace MWLua
finalPos.z() = terrainHeight;
}
osg::Vec3f rotVec = ptr.getRefData().getPosition().asRotationVec3();
if (newRotObj != sol::nil)
{
rotVec = toEulerRotation(newRotObj, ptr.getClass().isActor());
}
osg::Vec3f rotVec = toEulerRotation(newRotObj, ptr.getClass().isActor());
context.mLuaManager->addAction(
[object, finalPos, rotVec] {
@ -536,6 +532,50 @@ namespace MWLua
},
"SetTransformAction");
};
objectT["setPosition"]
= [context](const GObject& object, const osg::Vec3f& newPos, sol::optional<bool> terrainClampOpt) {
bool terrainClamp = terrainClampOpt.value_or(true);
MWWorld::Ptr ptr = object.ptr();
if (ptr.getCellRef().getCount() == 0 || !ptr.isInCell())
throw std::runtime_error("Object is either removed or in the process of teleporting");
osg::Vec3f finalPos = newPos;
if (terrainClamp && ptr.getClass().isActor())
{
float terrainHeight = -std::numeric_limits<float>::max();
if (ptr.getCell()->isExterior())
{
terrainHeight = MWBase::Environment::get().getWorld()->getTerrainHeightAt(
finalPos, ptr.getCell()->getCell()->getWorldSpace());
}
if (finalPos.z() < terrainHeight)
finalPos.z() = terrainHeight;
}
context.mLuaManager->addAction(
[object, finalPos] {
auto world = MWBase::Environment::get().getWorld();
world->moveObject(object.ptr(), finalPos, true, false);
},
"SetPositionAction");
};
objectT["setRotation"] = [context](const GObject& object, const sol::object& newRotObj) {
MWWorld::Ptr ptr = object.ptr();
if (ptr.getCellRef().getCount() == 0 || !ptr.isInCell())
throw std::runtime_error("Object is either removed or in the process of teleporting");
// newRotObj must always be valid
osg::Vec3f rotVec = toEulerRotation(newRotObj, ptr.getClass().isActor());
context.mLuaManager->addAction(
[object, rotVec] {
auto world = MWBase::Environment::get().getWorld();
world->rotateObject(object.ptr(), rotVec, MWBase::RotationFlag_none);
},
"SetRotationAction");
};
objectT["teleport"] = [removeFn, context](const GObject& object, const sol::object& cellOrName,
const osg::Vec3f& pos, const sol::object& options) {
MWWorld::CellStore* cell = findCell(cellOrName, pos);

View File

@ -242,9 +242,28 @@
-- @function [parent=#GameObject] setTransform
-- @param self
-- @param openmw.util#Vector3 position New position.
-- @param openmw.util#Transform rotation New rotation; if missing, then the current rotation is used.
-- @param openmw.util#Transform rotation New rotation.
-- @param #boolean terrainClamp (optional, true by default) If true, actors will be restricted to positions above the terrain.
---
-- Moves an object to a given position.
-- Can be called only from a global script.
-- The effect is not immediate: the position will be updated only in the next frame.
-- If both rotation and position need to be updated, use setTransform.
-- @function [parent=#GameObject] setPosition
-- @param self
-- @param openmw.util#Vector3 position New position.
-- @param #boolean terrainClamp (optional, true by default) If true, actors will be restricted to positions above the terrain.
---
-- Rotates an object to a given rotation.
-- Can be called only from a global script.
-- The effect is not immediate: the rotation will be updated only in the next frame.
-- If both rotation and position need to be updated, use setTransform.
-- @function [parent=#GameObject] setRotation
-- @param self
-- @param openmw.util#Transform rotation New rotation.
---
-- Moves object to given cell and position.
-- Can be called only from a global script.