mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-16 02:09:42 +00:00
Treat teleportation out of the draft cell as object creation
This commit is contained in:
parent
38f56cfcdd
commit
641f34a3c9
9 changed files with 40 additions and 17 deletions
apps/openmw
mwclass
mwlua
mwworld
files/lua_api/openmw
|
@ -692,7 +692,7 @@ namespace MWClass
|
|||
if (newPtr.getRefData().getCustomData())
|
||||
{
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
newPtr.getContainerStore()->setPtr(newPtr);
|
||||
newPtr.getClass().getContainerStore(newPtr).setPtr(newPtr);
|
||||
}
|
||||
return newPtr;
|
||||
}
|
||||
|
|
|
@ -205,7 +205,8 @@ namespace MWClass
|
|||
newPtr = MWWorld::Ptr(cell.insert(ref), &cell);
|
||||
newPtr.getRefData().setCount(count);
|
||||
}
|
||||
newPtr.getCellRef().unsetRefNum();
|
||||
if (ptr.getCell() != &MWBase::Environment::get().getWorldModel()->getDraftCell())
|
||||
newPtr.getCellRef().unsetRefNum();
|
||||
newPtr.getRefData().setLuaScripts(nullptr);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
return newPtr;
|
||||
|
|
|
@ -1338,7 +1338,7 @@ namespace MWClass
|
|||
if (newPtr.getRefData().getCustomData())
|
||||
{
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
newPtr.getContainerStore()->setPtr(newPtr);
|
||||
newPtr.getClass().getContainerStore(newPtr).setPtr(newPtr);
|
||||
}
|
||||
return newPtr;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <components/esm3/loadcrea.hpp>
|
||||
#include <components/esm3/loaddoor.hpp>
|
||||
#include <components/esm3/loadingr.hpp>
|
||||
#include <components/esm3/loadlevlist.hpp>
|
||||
#include <components/esm3/loadligh.hpp>
|
||||
#include <components/esm3/loadlock.hpp>
|
||||
#include <components/esm3/loadmisc.hpp>
|
||||
|
@ -198,6 +199,9 @@ namespace MWLua
|
|||
case ESM::REC_STAT:
|
||||
cell.mStore->template forEachType<ESM::Static>(visitor);
|
||||
break;
|
||||
case ESM::REC_LEVC:
|
||||
cell.mStore->template forEachType<ESM::CreatureLevList>(visitor);
|
||||
break;
|
||||
|
||||
case ESM::REC_ACTI4:
|
||||
cell.mStore->template forEachType<ESM4::Activator>(visitor);
|
||||
|
|
|
@ -77,20 +77,25 @@ namespace MWLua
|
|||
return &wm->getExterior(ESM::positionToExteriorCellLocation(pos.x(), pos.y(), worldspace));
|
||||
}
|
||||
|
||||
void teleportPlayer(
|
||||
MWWorld::CellStore* destCell, const osg::Vec3f& pos, const osg::Vec3f& rot, bool placeOnGround)
|
||||
ESM::Position toPos(const osg::Vec3f& pos, const osg::Vec3f& rot)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
ESM::Position esmPos;
|
||||
static_assert(sizeof(esmPos) == sizeof(osg::Vec3f) * 2);
|
||||
std::memcpy(esmPos.pos, &pos, sizeof(osg::Vec3f));
|
||||
std::memcpy(esmPos.rot, &rot, sizeof(osg::Vec3f));
|
||||
return esmPos;
|
||||
}
|
||||
|
||||
void teleportPlayer(
|
||||
MWWorld::CellStore* destCell, const osg::Vec3f& pos, const osg::Vec3f& rot, bool placeOnGround)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
MWWorld::Ptr ptr = world->getPlayerPtr();
|
||||
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
stats.land(true);
|
||||
stats.setTeleported(true);
|
||||
world->getPlayer().setTeleported(true);
|
||||
world->changeToCell(destCell->getCell()->getId(), esmPos, false);
|
||||
world->changeToCell(destCell->getCell()->getId(), toPos(pos, rot), false);
|
||||
MWWorld::Ptr newPtr = world->getPlayerPtr();
|
||||
world->moveObject(newPtr, pos);
|
||||
world->rotateObject(newPtr, rot);
|
||||
|
@ -103,6 +108,7 @@ namespace MWLua
|
|||
const osg::Vec3f& rot, bool placeOnGround)
|
||||
{
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
MWWorld::WorldModel* wm = MWBase::Environment::get().getWorldModel();
|
||||
const MWWorld::Class& cls = ptr.getClass();
|
||||
if (cls.isActor())
|
||||
{
|
||||
|
@ -110,8 +116,19 @@ namespace MWLua
|
|||
stats.land(false);
|
||||
stats.setTeleported(true);
|
||||
}
|
||||
MWWorld::Ptr newPtr = world->moveObject(ptr, destCell, pos);
|
||||
world->rotateObject(newPtr, rot, MWBase::RotationFlag_none);
|
||||
MWWorld::Ptr newPtr;
|
||||
if (ptr.getCell() == &wm->getDraftCell())
|
||||
{
|
||||
newPtr = world->placeObject(ptr, destCell, toPos(pos, rot));
|
||||
ptr.getCellRef().unsetRefNum();
|
||||
ptr.getRefData().setLuaScripts(nullptr);
|
||||
ptr.getRefData().setCount(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPtr = world->moveObject(ptr, destCell, pos);
|
||||
world->rotateObject(newPtr, rot, MWBase::RotationFlag_none);
|
||||
}
|
||||
if (placeOnGround)
|
||||
world->adjustPosition(newPtr, true);
|
||||
if (cls.isDoor())
|
||||
|
|
|
@ -1235,13 +1235,12 @@ namespace MWWorld
|
|||
clearCorpse(ptr, mStore);
|
||||
ptr.getClass().respawn(ptr);
|
||||
}
|
||||
for (CellRefList<ESM::CreatureLevList>::List::iterator it(get<ESM::CreatureLevList>().mList.begin());
|
||||
it != get<ESM::CreatureLevList>().mList.end(); ++it)
|
||||
{
|
||||
Ptr ptr = getCurrentPtr(&*it);
|
||||
forEachType<ESM::CreatureLevList>([](Ptr ptr) {
|
||||
// no need to clearCorpse, handled as part of get<ESM::Creature>()
|
||||
ptr.getClass().respawn(ptr);
|
||||
}
|
||||
if (!ptr.getRefData().isDeleted())
|
||||
ptr.getClass().respawn(ptr);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ namespace MWWorld
|
|||
/// unintended behaviour. \attention This function also lists deleted (count 0) objects! \return Iteration
|
||||
/// completed?
|
||||
template <class T, class Visitor>
|
||||
bool forEachType(Visitor& visitor)
|
||||
bool forEachType(Visitor&& visitor)
|
||||
{
|
||||
if (mState != State_Loaded)
|
||||
return false;
|
||||
|
|
|
@ -372,7 +372,8 @@ namespace MWWorld
|
|||
MWWorld::Ptr Class::copyToCell(const ConstPtr& ptr, CellStore& cell, int count) const
|
||||
{
|
||||
Ptr newPtr = copyToCellImpl(ptr, cell);
|
||||
newPtr.getCellRef().unsetRefNum(); // This RefNum is only valid within the original cell of the reference
|
||||
if (ptr.getCell() != &MWBase::Environment::get().getWorldModel()->getDraftCell())
|
||||
newPtr.getCellRef().unsetRefNum(); // This RefNum is only valid within the original cell of the reference
|
||||
newPtr.getRefData().setCount(count);
|
||||
newPtr.getRefData().setLuaScripts(nullptr);
|
||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
---
|
||||
-- Create a new instance of the given record.
|
||||
-- After creation the object is in the disabled state. Use :teleport to place to the world or :moveInto to put it into a container or an inventory.
|
||||
-- Note that dynamically created creatures, NPCs, and container inventories will not respawn.
|
||||
-- @function [parent=#world] createObject
|
||||
-- @param #string recordId Record ID in lowercase
|
||||
-- @param #number count (optional, 1 by default) The number of objects in stack
|
||||
|
|
Loading…
Reference in a new issue