Make coc and fixme console commands close to vanilla (bug #4292, bug #4217)

pull/541/head
Andrei Kortunov 6 years ago
parent 3761aaadfd
commit 01b3f92f7e

@ -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;
}
@ -2604,31 +2628,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…
Cancel
Save