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; 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…
Cancel
Save