mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-29 22:20:33 +00:00
Merge branch 'draft' into 'master'
Treat teleportation out of the draft cell as object creation Closes #7588 and #7453 See merge request OpenMW/openmw!3455
This commit is contained in:
commit
6c39e3f817
@ -678,7 +678,7 @@ namespace MWClass
|
|||||||
if (newPtr.getRefData().getCustomData())
|
if (newPtr.getRefData().getCustomData())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||||
newPtr.getContainerStore()->setPtr(newPtr);
|
newPtr.getClass().getContainerStore(newPtr).setPtr(newPtr);
|
||||||
}
|
}
|
||||||
return newPtr;
|
return newPtr;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ namespace MWClass
|
|||||||
manualRef.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition());
|
manualRef.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition());
|
||||||
manualRef.getPtr().getCellRef().setScale(ptr.getCellRef().getScale());
|
manualRef.getPtr().getCellRef().setScale(ptr.getCellRef().getScale());
|
||||||
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(
|
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(
|
||||||
manualRef.getPtr(), ptr.getCell(), ptr.getCellRef().getPosition());
|
manualRef.getPtr(), ptr.getCell(), ptr.getRefData().getPosition());
|
||||||
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
|
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
|
||||||
customData.mSpawn = false;
|
customData.mSpawn = false;
|
||||||
}
|
}
|
||||||
|
@ -1323,7 +1323,7 @@ namespace MWClass
|
|||||||
if (newPtr.getRefData().getCustomData())
|
if (newPtr.getRefData().getCustomData())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
MWBase::Environment::get().getWorldModel()->registerPtr(newPtr);
|
||||||
newPtr.getContainerStore()->setPtr(newPtr);
|
newPtr.getClass().getContainerStore(newPtr).setPtr(newPtr);
|
||||||
}
|
}
|
||||||
return newPtr;
|
return newPtr;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <components/esm3/loadcrea.hpp>
|
#include <components/esm3/loadcrea.hpp>
|
||||||
#include <components/esm3/loaddoor.hpp>
|
#include <components/esm3/loaddoor.hpp>
|
||||||
#include <components/esm3/loadingr.hpp>
|
#include <components/esm3/loadingr.hpp>
|
||||||
|
#include <components/esm3/loadlevlist.hpp>
|
||||||
#include <components/esm3/loadligh.hpp>
|
#include <components/esm3/loadligh.hpp>
|
||||||
#include <components/esm3/loadlock.hpp>
|
#include <components/esm3/loadlock.hpp>
|
||||||
#include <components/esm3/loadmisc.hpp>
|
#include <components/esm3/loadmisc.hpp>
|
||||||
@ -199,6 +200,9 @@ namespace MWLua
|
|||||||
case ESM::REC_STAT:
|
case ESM::REC_STAT:
|
||||||
cell.mStore->template forEachType<ESM::Static>(visitor);
|
cell.mStore->template forEachType<ESM::Static>(visitor);
|
||||||
break;
|
break;
|
||||||
|
case ESM::REC_LEVC:
|
||||||
|
cell.mStore->template forEachType<ESM::CreatureLevList>(visitor);
|
||||||
|
break;
|
||||||
|
|
||||||
case ESM::REC_ACTI4:
|
case ESM::REC_ACTI4:
|
||||||
cell.mStore->template forEachType<ESM4::Activator>(visitor);
|
cell.mStore->template forEachType<ESM4::Activator>(visitor);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/containerstore.hpp"
|
#include "../mwworld/containerstore.hpp"
|
||||||
|
#include "../mwworld/localscripts.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
#include "../mwworld/scene.hpp"
|
#include "../mwworld/scene.hpp"
|
||||||
#include "../mwworld/worldmodel.hpp"
|
#include "../mwworld/worldmodel.hpp"
|
||||||
@ -77,20 +78,25 @@ namespace MWLua
|
|||||||
return &wm->getExterior(ESM::positionToExteriorCellLocation(pos.x(), pos.y(), worldspace));
|
return &wm->getExterior(ESM::positionToExteriorCellLocation(pos.x(), pos.y(), worldspace));
|
||||||
}
|
}
|
||||||
|
|
||||||
void teleportPlayer(
|
ESM::Position toPos(const osg::Vec3f& pos, const osg::Vec3f& rot)
|
||||||
MWWorld::CellStore* destCell, const osg::Vec3f& pos, const osg::Vec3f& rot, bool placeOnGround)
|
|
||||||
{
|
{
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
||||||
ESM::Position esmPos;
|
ESM::Position esmPos;
|
||||||
static_assert(sizeof(esmPos) == sizeof(osg::Vec3f) * 2);
|
static_assert(sizeof(esmPos) == sizeof(osg::Vec3f) * 2);
|
||||||
std::memcpy(esmPos.pos, &pos, sizeof(osg::Vec3f));
|
std::memcpy(esmPos.pos, &pos, sizeof(osg::Vec3f));
|
||||||
std::memcpy(esmPos.rot, &rot, 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();
|
MWWorld::Ptr ptr = world->getPlayerPtr();
|
||||||
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
stats.land(true);
|
stats.land(true);
|
||||||
stats.setTeleported(true);
|
stats.setTeleported(true);
|
||||||
world->getPlayer().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();
|
MWWorld::Ptr newPtr = world->getPlayerPtr();
|
||||||
world->moveObject(newPtr, pos);
|
world->moveObject(newPtr, pos);
|
||||||
world->rotateObject(newPtr, rot);
|
world->rotateObject(newPtr, rot);
|
||||||
@ -103,15 +109,38 @@ namespace MWLua
|
|||||||
const osg::Vec3f& rot, bool placeOnGround)
|
const osg::Vec3f& rot, bool placeOnGround)
|
||||||
{
|
{
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
|
MWWorld::WorldModel* wm = MWBase::Environment::get().getWorldModel();
|
||||||
const MWWorld::Class& cls = ptr.getClass();
|
const MWWorld::Class& cls = ptr.getClass();
|
||||||
if (cls.isActor())
|
if (cls.isActor())
|
||||||
{
|
{
|
||||||
auto& stats = ptr.getClass().getCreatureStats(ptr);
|
auto& stats = cls.getCreatureStats(ptr);
|
||||||
stats.land(false);
|
stats.land(false);
|
||||||
stats.setTeleported(true);
|
stats.setTeleported(true);
|
||||||
}
|
}
|
||||||
MWWorld::Ptr newPtr = world->moveObject(ptr, destCell, pos);
|
const MWWorld::CellStore* srcCell = ptr.getCell();
|
||||||
world->rotateObject(newPtr, rot, MWBase::RotationFlag_none);
|
MWWorld::Ptr newPtr;
|
||||||
|
if (srcCell == &wm->getDraftCell())
|
||||||
|
{
|
||||||
|
newPtr = cls.moveToCell(ptr, *destCell, toPos(pos, rot));
|
||||||
|
ptr.getCellRef().unsetRefNum();
|
||||||
|
ptr.getRefData().setLuaScripts(nullptr);
|
||||||
|
ptr.getRefData().setCount(0);
|
||||||
|
ESM::RefId script = cls.getScript(newPtr);
|
||||||
|
if (!script.empty())
|
||||||
|
world->getLocalScripts().add(script, newPtr);
|
||||||
|
world->addContainerScripts(newPtr, newPtr.getCell());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newPtr = world->moveObject(ptr, destCell, pos);
|
||||||
|
if (srcCell == destCell)
|
||||||
|
{
|
||||||
|
ESM::RefId script = cls.getScript(newPtr);
|
||||||
|
if (!script.empty())
|
||||||
|
world->getLocalScripts().add(script, newPtr);
|
||||||
|
}
|
||||||
|
world->rotateObject(newPtr, rot, MWBase::RotationFlag_none);
|
||||||
|
}
|
||||||
if (placeOnGround)
|
if (placeOnGround)
|
||||||
world->adjustPosition(newPtr, true);
|
world->adjustPosition(newPtr, true);
|
||||||
if (cls.isDoor())
|
if (cls.isDoor())
|
||||||
|
@ -1236,13 +1236,12 @@ namespace MWWorld
|
|||||||
clearCorpse(ptr, mStore);
|
clearCorpse(ptr, mStore);
|
||||||
ptr.getClass().respawn(ptr);
|
ptr.getClass().respawn(ptr);
|
||||||
}
|
}
|
||||||
for (CellRefList<ESM::CreatureLevList>::List::iterator it(get<ESM::CreatureLevList>().mList.begin());
|
forEachType<ESM::CreatureLevList>([](Ptr ptr) {
|
||||||
it != get<ESM::CreatureLevList>().mList.end(); ++it)
|
|
||||||
{
|
|
||||||
Ptr ptr = getCurrentPtr(&*it);
|
|
||||||
// no need to clearCorpse, handled as part of get<ESM::Creature>()
|
// no need to clearCorpse, handled as part of get<ESM::Creature>()
|
||||||
ptr.getClass().respawn(ptr);
|
if (!ptr.getRefData().isDeleted())
|
||||||
}
|
ptr.getClass().respawn(ptr);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ namespace MWWorld
|
|||||||
/// unintended behaviour. \attention This function also lists deleted (count 0) objects! \return Iteration
|
/// unintended behaviour. \attention This function also lists deleted (count 0) objects! \return Iteration
|
||||||
/// completed?
|
/// completed?
|
||||||
template <class T, class Visitor>
|
template <class T, class Visitor>
|
||||||
bool forEachType(Visitor& visitor)
|
bool forEachType(Visitor&& visitor)
|
||||||
{
|
{
|
||||||
if (mState != State_Loaded)
|
if (mState != State_Loaded)
|
||||||
return false;
|
return false;
|
||||||
|
@ -134,6 +134,7 @@
|
|||||||
---
|
---
|
||||||
-- Create a new instance of the given record.
|
-- 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.
|
-- 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
|
-- @function [parent=#world] createObject
|
||||||
-- @param #string recordId Record ID in lowercase
|
-- @param #string recordId Record ID in lowercase
|
||||||
-- @param #number count (optional, 1 by default) The number of objects in stack
|
-- @param #number count (optional, 1 by default) The number of objects in stack
|
||||||
|
Loading…
x
Reference in New Issue
Block a user