mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-06 00:55:50 +00:00
53f4b92426
Testing revealed a problem where the guard on the prison ship would incorrectly follow the player outside. Upon further investigation in vanilla MW, it appears that with AiEscort the actor only follows the target through doors once the AiEscort package has completed, *and* no new AI package is running yet.
86 lines
2.7 KiB
C++
86 lines
2.7 KiB
C++
#include "actionteleport.hpp"
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
#include "../mwbase/world.hpp"
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
#include "player.hpp"
|
|
|
|
namespace
|
|
{
|
|
|
|
void getFollowers (const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out)
|
|
{
|
|
std::list<MWWorld::Ptr> followers = MWBase::Environment::get().getMechanicsManager()->getActorsFollowing(actor);
|
|
for(std::list<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
|
{
|
|
if (out.insert(*it).second)
|
|
{
|
|
getFollowers(*it, out);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
namespace MWWorld
|
|
{
|
|
ActionTeleport::ActionTeleport (const std::string& cellName,
|
|
const ESM::Position& position, bool teleportFollowers)
|
|
: Action (true), mCellName (cellName), mPosition (position), mTeleportFollowers(teleportFollowers)
|
|
{
|
|
}
|
|
|
|
void ActionTeleport::executeImp (const Ptr& actor)
|
|
{
|
|
if (mTeleportFollowers)
|
|
{
|
|
//find any NPC that is following the actor and teleport him too
|
|
std::set<MWWorld::Ptr> followers;
|
|
getFollowers(actor, followers);
|
|
for(std::set<MWWorld::Ptr>::iterator it = followers.begin();it != followers.end();++it)
|
|
{
|
|
MWWorld::Ptr follower = *it;
|
|
|
|
std::string script = follower.getClass().getScript(follower);
|
|
if (!script.empty() && follower.getRefData().getLocals().getIntVar(script, "stayoutside") == 1)
|
|
continue;
|
|
|
|
if ((follower.getRefData().getPosition().asVec3() - actor.getRefData().getPosition().asVec3()).length2()
|
|
<= 800*800)
|
|
teleport(*it);
|
|
}
|
|
}
|
|
|
|
teleport(actor);
|
|
}
|
|
|
|
void ActionTeleport::teleport(const Ptr &actor)
|
|
{
|
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
if(actor == world->getPlayerPtr())
|
|
{
|
|
world->getPlayer().setTeleported(true);
|
|
if (mCellName.empty())
|
|
world->changeToExteriorCell (mPosition);
|
|
else
|
|
world->changeToInteriorCell (mCellName, mPosition);
|
|
}
|
|
else
|
|
{
|
|
if (mCellName.empty())
|
|
{
|
|
int cellX;
|
|
int cellY;
|
|
world->positionToIndex(mPosition.pos[0],mPosition.pos[1],cellX,cellY);
|
|
world->moveObject(actor,world->getExterior(cellX,cellY),
|
|
mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
|
}
|
|
else
|
|
world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
|
}
|
|
}
|
|
}
|