mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-21 10:23:52 +00:00
This commit is contained in:
parent
3761aaadfd
commit
01b3f92f7e
5 changed files with 71 additions and 27 deletions
|
@ -46,18 +46,19 @@ namespace MWScript
|
||||||
|
|
||||||
ESM::Position pos;
|
ESM::Position pos;
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
|
||||||
|
|
||||||
if (world->findExteriorPosition(cell, pos))
|
if (world->findExteriorPosition(cell, pos))
|
||||||
{
|
{
|
||||||
MWWorld::ActionTeleport("", pos, false).execute(world->getPlayerPtr());
|
MWWorld::ActionTeleport("", pos, false).execute(playerPtr);
|
||||||
world->fixPosition(world->getPlayerPtr());
|
world->adjustPosition(playerPtr, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Change to interior even if findInteriorPosition()
|
// Change to interior even if findInteriorPosition()
|
||||||
// yields false. In this case position will be zero-point.
|
// yields false. In this case position will be zero-point.
|
||||||
world->findInteriorPosition(cell, pos);
|
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;
|
ESM::Position pos;
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
|
||||||
|
|
||||||
world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true);
|
world->indexToPosition (x, y, pos.pos[0], pos.pos[1], true);
|
||||||
pos.pos[2] = 0;
|
pos.pos[2] = 0;
|
||||||
|
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
|
|
||||||
MWWorld::ActionTeleport("", pos, false).execute(world->getPlayerPtr());
|
MWWorld::ActionTeleport("", pos, false).execute(playerPtr);
|
||||||
world->fixPosition(world->getPlayerPtr());
|
world->adjustPosition(playerPtr, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -732,14 +732,13 @@ namespace MWScript
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class R>
|
|
||||||
class OpFixme : public Interpreter::Opcode0
|
class OpFixme : public Interpreter::Opcode0
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
const MWWorld::Ptr ptr = MWMechanics::getPlayer();
|
||||||
MWBase::Environment::get().getWorld()->fixPosition(ptr);
|
MWBase::Environment::get().getWorld()->fixPosition(ptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -784,8 +783,7 @@ namespace MWScript
|
||||||
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>);
|
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngle, new OpGetStartingAngle<ImplicitRef>);
|
||||||
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>);
|
interpreter.installSegment5(Compiler::Transformation::opcodeGetStartingAngleExplicit, new OpGetStartingAngle<ExplicitRef>);
|
||||||
interpreter.installSegment5(Compiler::Transformation::opcodeResetActors, new OpResetActors);
|
interpreter.installSegment5(Compiler::Transformation::opcodeResetActors, new OpResetActors);
|
||||||
interpreter.installSegment5(Compiler::Transformation::opcodeFixme, new OpFixme<ImplicitRef>);
|
interpreter.installSegment5(Compiler::Transformation::opcodeFixme, new OpFixme);
|
||||||
interpreter.installSegment5(Compiler::Transformation::opcodeFixmeExplicit, new OpFixme<ExplicitRef>);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -246,7 +246,7 @@ namespace MWWorld
|
||||||
if (findExteriorPosition (mStartCell, pos))
|
if (findExteriorPosition (mStartCell, pos))
|
||||||
{
|
{
|
||||||
changeToExteriorCell (pos, true);
|
changeToExteriorCell (pos, true);
|
||||||
fixPosition(getPlayerPtr());
|
adjustPosition(getPlayerPtr(), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1353,13 +1353,37 @@ namespace MWWorld
|
||||||
|
|
||||||
void World::fixPosition(const Ptr &actor)
|
void World::fixPosition(const Ptr &actor)
|
||||||
{
|
{
|
||||||
const float dist = 8000;
|
const float distance = 128.f;
|
||||||
osg::Vec3f pos (actor.getRefData().getPosition().asVec3());
|
ESM::Position esmPos = actor.getRefData().getPosition();
|
||||||
pos.z() += dist;
|
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)
|
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)
|
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];
|
ipos.rot[2] = referenceObject.getRefData().getPosition().rot[2];
|
||||||
|
|
||||||
MWWorld::Ptr placed = copyObjectToCell(ptr, referenceCell, ipos, ptr.getRefData().getCount(), false);
|
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;
|
return placed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2604,31 +2628,52 @@ namespace MWWorld
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<const MWWorld::CellRef *> sortedDoors;
|
||||||
const DoorList &doors = cellStore->getReadOnlyDoors().mList;
|
const DoorList &doors = cellStore->getReadOnlyDoors().mList;
|
||||||
for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) {
|
for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it)
|
||||||
if (!it->mRef.getTeleport()) {
|
{
|
||||||
|
if (!it->mRef.getTeleport())
|
||||||
|
{
|
||||||
continue;
|
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;
|
MWWorld::CellStore *source = 0;
|
||||||
|
|
||||||
// door to exterior
|
// door to exterior
|
||||||
if (it->mRef.getDestCell().empty()) {
|
if ((*it)->getDestCell().empty())
|
||||||
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
ESM::Position doorDest = it->mRef.getDoorDest();
|
ESM::Position doorDest = (*it)->getDoorDest();
|
||||||
positionToIndex(doorDest.pos[0], doorDest.pos[1], x, y);
|
positionToIndex(doorDest.pos[0], doorDest.pos[1], x, y);
|
||||||
source = getExterior(x, y);
|
source = getExterior(x, y);
|
||||||
}
|
}
|
||||||
// door to interior
|
// door to interior
|
||||||
else {
|
else
|
||||||
source = getInterior(it->mRef.getDestCell());
|
{
|
||||||
|
source = getInterior((*it)->getDestCell());
|
||||||
}
|
}
|
||||||
if (0 != source) {
|
if (0 != source)
|
||||||
|
{
|
||||||
// Find door leading to our current teleport door
|
// Find door leading to our current teleport door
|
||||||
// and use its destination to position inside cell.
|
// and use its destination to position inside cell.
|
||||||
const DoorList &destinationDoors = source->getReadOnlyDoors().mList;
|
const DoorList &destinationDoors = source->getReadOnlyDoors().mList;
|
||||||
for (DoorList::const_iterator jt = destinationDoors.begin(); jt != destinationDoors.end(); ++jt) {
|
for (DoorList::const_iterator jt = destinationDoors.begin(); jt != destinationDoors.end(); ++jt)
|
||||||
if (it->mRef.getTeleport() &&
|
{
|
||||||
|
if ((*it)->getTeleport() &&
|
||||||
Misc::StringUtils::ciEqual(name, jt->mRef.getDestCell()))
|
Misc::StringUtils::ciEqual(name, jt->mRef.getDestCell()))
|
||||||
{
|
{
|
||||||
/// \note Using _any_ door pointed to the interior,
|
/// \note Using _any_ door pointed to the interior,
|
||||||
|
|
|
@ -546,7 +546,7 @@ namespace Compiler
|
||||||
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
|
extensions.registerInstruction("moveworld","cf",opcodeMoveWorld,opcodeMoveWorldExplicit);
|
||||||
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
|
extensions.registerFunction("getstartingangle",'f',"c",opcodeGetStartingAngle,opcodeGetStartingAngleExplicit);
|
||||||
extensions.registerInstruction("resetactors","",opcodeResetActors);
|
extensions.registerInstruction("resetactors","",opcodeResetActors);
|
||||||
extensions.registerInstruction("fixme","",opcodeFixme, opcodeFixmeExplicit);
|
extensions.registerInstruction("fixme","",opcodeFixme);
|
||||||
extensions.registerInstruction("ra","",opcodeResetActors);
|
extensions.registerInstruction("ra","",opcodeResetActors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,7 +504,6 @@ namespace Compiler
|
||||||
const int opcodeMoveWorldExplicit = 0x2000209;
|
const int opcodeMoveWorldExplicit = 0x2000209;
|
||||||
const int opcodeResetActors = 0x20002f4;
|
const int opcodeResetActors = 0x20002f4;
|
||||||
const int opcodeFixme = 0x2000302;
|
const int opcodeFixme = 0x2000302;
|
||||||
const int opcodeFixmeExplicit = 0x2000303;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace User
|
namespace User
|
||||||
|
|
Loading…
Reference in a new issue