mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Merged pull request #1919
This commit is contained in:
commit
43880ca47b
5 changed files with 71 additions and 27 deletions
|
@ -46,18 +46,19 @@ namespace MWScript
|
|||
|
||||
ESM::Position pos;
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
|
||||
|
||||
if (world->findExteriorPosition(cell, pos))
|
||||
{
|
||||
MWWorld::ActionTeleport("", pos, false).execute(world->getPlayerPtr());
|
||||
world->fixPosition(world->getPlayerPtr());
|
||||
MWWorld::ActionTeleport("", pos, false).execute(playerPtr);
|
||||
world->adjustPosition(playerPtr, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change to interior even if findInteriorPosition()
|
||||
// yields false. In this case position will be zero-point.
|
||||
world->findInteriorPosition(cell, pos);
|
||||
MWWorld::ActionTeleport(cell, pos, false).execute(world->getPlayerPtr());
|
||||
MWWorld::ActionTeleport(cell, pos, false).execute(playerPtr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -76,14 +77,15 @@ namespace MWScript
|
|||
|
||||
ESM::Position pos;
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
|
||||
|
||||
world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true);
|
||||
pos.pos[2] = 0;
|
||||
|
||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||
|
||||
MWWorld::ActionTeleport("", pos, false).execute(world->getPlayerPtr());
|
||||
world->fixPosition(world->getPlayerPtr());
|
||||
MWWorld::ActionTeleport("", pos, false).execute(playerPtr);
|
||||
world->adjustPosition(playerPtr, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -732,14 +732,13 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
template <class R>
|
||||
class OpFixme : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
const MWWorld::Ptr ptr = MWMechanics::getPlayer();
|
||||
MWBase::Environment::get().getWorld()->fixPosition(ptr);
|
||||
}
|
||||
};
|
||||
|
@ -784,8 +783,7 @@ namespace MWScript
|
|||
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodeResetActors, new OpResetActors);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodeFixme, new OpFixme<ImplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodeFixmeExplicit, new OpFixme<ExplicitRef>);
|
||||
interpreter.installSegment5(Compiler::Transformation::opcodeFixme, new OpFixme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ namespace MWWorld
|
|||
if (findExteriorPosition (mStartCell, pos))
|
||||
{
|
||||
changeToExteriorCell (pos, true);
|
||||
fixPosition(getPlayerPtr());
|
||||
adjustPosition(getPlayerPtr(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1353,13 +1353,37 @@ namespace MWWorld
|
|||
|
||||
void World::fixPosition(const Ptr &actor)
|
||||
{
|
||||
const float dist = 8000;
|
||||
osg::Vec3f pos (actor.getRefData().getPosition().asVec3());
|
||||
pos.z() += dist;
|
||||
const float distance = 128.f;
|
||||
ESM::Position esmPos = actor.getRefData().getPosition();
|
||||
osg::Quat orientation(esmPos.rot[2], osg::Vec3f(0,0,-1));
|
||||
osg::Vec3f pos (esmPos.asVec3());
|
||||
|
||||
osg::Vec3f traced = mPhysics->traceDown(actor, pos, dist*1.1f);
|
||||
int direction = 0;
|
||||
int fallbackDirections[4] = {direction, (direction+3)%4, (direction+2)%4, (direction+1)%4};
|
||||
|
||||
osg::Vec3f targetPos = pos;
|
||||
for (int i=0; i<4; ++i)
|
||||
{
|
||||
direction = fallbackDirections[i];
|
||||
if (direction == 0) targetPos = pos + (orientation * osg::Vec3f(0,1,0)) * distance;
|
||||
else if(direction == 1) targetPos = pos - (orientation * osg::Vec3f(0,1,0)) * distance;
|
||||
else if(direction == 2) targetPos = pos - (orientation * osg::Vec3f(1,0,0)) * distance;
|
||||
else if(direction == 3) targetPos = pos + (orientation * osg::Vec3f(1,0,0)) * distance;
|
||||
|
||||
// destination is free
|
||||
if (!castRay(pos.x(), pos.y(), pos.z(), targetPos.x(), targetPos.y(), targetPos.z()))
|
||||
break;
|
||||
}
|
||||
|
||||
targetPos.z() += distance / 2.f; // move up a bit to get out from geometry, will snap down later
|
||||
osg::Vec3f traced = mPhysics->traceDown(actor, targetPos, Constants::CellSizeInUnits);
|
||||
if (traced != pos)
|
||||
moveObject(actor, actor.getCell(), traced.x(), traced.y(), traced.z());
|
||||
{
|
||||
esmPos.pos[0] = traced.x();
|
||||
esmPos.pos[1] = traced.y();
|
||||
esmPos.pos[2] = traced.z();
|
||||
MWWorld::ActionTeleport("", esmPos, false).execute(actor);
|
||||
}
|
||||
}
|
||||
|
||||
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
||||
|
@ -1429,7 +1453,7 @@ namespace MWWorld
|
|||
ipos.rot[2] = referenceObject.getRefData().getPosition().rot[2];
|
||||
|
||||
MWWorld::Ptr placed = copyObjectToCell(ptr, referenceCell, ipos, ptr.getRefData().getCount(), false);
|
||||
placed.getClass().adjustPosition(placed, true); // snap to ground
|
||||
adjustPosition(placed, true); // snap to ground
|
||||
return placed;
|
||||
}
|
||||
|
||||
|
@ -2607,31 +2631,52 @@ namespace MWWorld
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector<const MWWorld::CellRef *> sortedDoors;
|
||||
const DoorList &doors = cellStore->getReadOnlyDoors().mList;
|
||||
for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) {
|
||||
if (!it->mRef.getTeleport()) {
|
||||
for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it)
|
||||
{
|
||||
if (!it->mRef.getTeleport())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sortedDoors.push_back(&it->mRef);
|
||||
}
|
||||
|
||||
// Sort teleporting doors alphabetically, first by ID, then by destination cell to make search consistent
|
||||
std::sort(sortedDoors.begin(), sortedDoors.end(), [] (const MWWorld::CellRef *lhs, const MWWorld::CellRef *rhs)
|
||||
{
|
||||
if (lhs->getRefId() != rhs->getRefId())
|
||||
return lhs->getRefId() < rhs->getRefId();
|
||||
|
||||
return lhs->getDestCell() < rhs->getDestCell();
|
||||
});
|
||||
|
||||
for (std::vector<const MWWorld::CellRef *>::const_iterator it = sortedDoors.begin(); it != sortedDoors.end(); ++it)
|
||||
{
|
||||
MWWorld::CellStore *source = 0;
|
||||
|
||||
// door to exterior
|
||||
if (it->mRef.getDestCell().empty()) {
|
||||
if ((*it)->getDestCell().empty())
|
||||
{
|
||||
int x, y;
|
||||
ESM::Position doorDest = it->mRef.getDoorDest();
|
||||
ESM::Position doorDest = (*it)->getDoorDest();
|
||||
positionToIndex(doorDest.pos[0], doorDest.pos[1], x, y);
|
||||
source = getExterior(x, y);
|
||||
}
|
||||
// door to interior
|
||||
else {
|
||||
source = getInterior(it->mRef.getDestCell());
|
||||
else
|
||||
{
|
||||
source = getInterior((*it)->getDestCell());
|
||||
}
|
||||
if (0 != source) {
|
||||
if (0 != source)
|
||||
{
|
||||
// Find door leading to our current teleport door
|
||||
// and use its destination to position inside cell.
|
||||
const DoorList &destinationDoors = source->getReadOnlyDoors().mList;
|
||||
for (DoorList::const_iterator jt = destinationDoors.begin(); jt != destinationDoors.end(); ++jt) {
|
||||
if (it->mRef.getTeleport() &&
|
||||
for (DoorList::const_iterator jt = destinationDoors.begin(); jt != destinationDoors.end(); ++jt)
|
||||
{
|
||||
if ((*it)->getTeleport() &&
|
||||
Misc::StringUtils::ciEqual(name, jt->mRef.getDestCell()))
|
||||
{
|
||||
/// \note Using _any_ door pointed to the interior,
|
||||
|
|
|
@ -546,7 +546,7 @@ namespace Compiler
|
|||
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
|
||||
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
|
||||
extensions.registerInstruction("resetactors","",opcodeResetActors);
|
||||
extensions.registerInstruction("fixme","",opcodeFixme, opcodeFixmeExplicit);
|
||||
extensions.registerInstruction("fixme","",opcodeFixme);
|
||||
extensions.registerInstruction("ra","",opcodeResetActors);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -504,7 +504,6 @@ namespace Compiler
|
|||
const int opcodeMoveWorldExplicit = 0x2000209;
|
||||
const int opcodeResetActors = 0x20002f4;
|
||||
const int opcodeFixme = 0x2000302;
|
||||
const int opcodeFixmeExplicit = 0x2000303;
|
||||
}
|
||||
|
||||
namespace User
|
||||
|
|
Loading…
Reference in a new issue