1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-06 00:55:50 +00:00
OpenMW/apps/openmw/mwworld/actionteleport.cpp
scrawl 53f4b92426 AiEscort do not follow target through doors
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.
2015-12-19 15:15:44 +01:00

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]);
}
}
}