Use a common doors rotation code in the "lock" command handler

pull/2492/head
Andrei Kortunov 5 years ago
parent 043231737d
commit 786a6c6d42

@ -127,6 +127,7 @@
Bug #5112: Insufficient magicka for current spell not reflected on HUD icon
Bug #5123: Script won't run on respawn
Bug #5124: Arrow remains attached to actor if pulling animation was cancelled
Bug #5134: Doors rotation by "Lock" console command is inconsistent
Bug #5137: Textures with Clamp Mode set to Clamp instead of Wrap are too dark outside the boundaries
Feature #1774: Handle AvoidNode
Feature #2229: Improve pathfinding AI

@ -189,12 +189,6 @@ namespace MWScript
if (ptr.getTypeName() == typeid(ESM::Door).name() && !ptr.getCellRef().getTeleport())
{
MWBase::Environment::get().getWorld()->activateDoor(ptr, 0);
float xr = ptr.getCellRef().getPosition().rot[0];
float yr = ptr.getCellRef().getPosition().rot[1];
float zr = ptr.getCellRef().getPosition().rot[2];
MWBase::Environment::get().getWorld()->rotateObject(ptr, xr, yr, zr);
}
}
};

@ -1617,6 +1617,45 @@ namespace MWWorld
return result.mHit;
}
bool World::rotateDoor(const Ptr door, int state, float duration)
{
const ESM::Position& objPos = door.getRefData().getPosition();
float oldRot = objPos.rot[2];
float minRot = door.getCellRef().getPosition().rot[2];
float maxRot = minRot + osg::DegreesToRadians(90.f);
float diff = duration * osg::DegreesToRadians(90.f);
float targetRot = std::min(std::max(minRot, oldRot + diff * (state == 1 ? 1 : -1)), maxRot);
rotateObject(door, objPos.rot[0], objPos.rot[1], targetRot);
bool reached = (targetRot == maxRot && state) || targetRot == minRot;
/// \todo should use convexSweepTest here
std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
for (MWWorld::Ptr& ptr : collisions)
{
if (ptr.getClass().isActor())
{
// Collided with actor, ask actor to try to avoid door
if(ptr != getPlayerPtr() )
{
MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) //Only add it once
seq.stack(MWMechanics::AiAvoidDoor(door),ptr);
}
// we need to undo the rotation
rotateObject(door, objPos.rot[0], objPos.rot[1], oldRot);
reached = false;
}
}
// the rotation order we want to use
mWorldScene->updateObjectRotation(door, false);
return reached;
}
void World::processDoors(float duration)
{
std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin();
@ -1631,40 +1670,7 @@ namespace MWWorld
}
else
{
const ESM::Position& objPos = it->first.getRefData().getPosition();
float oldRot = objPos.rot[2];
float minRot = it->first.getCellRef().getPosition().rot[2];
float maxRot = minRot + osg::DegreesToRadians(90.f);
float diff = duration * osg::DegreesToRadians(90.f);
float targetRot = std::min(std::max(minRot, oldRot + diff * (it->second == 1 ? 1 : -1)), maxRot);
rotateObject(it->first, objPos.rot[0], objPos.rot[1], targetRot);
bool reached = (targetRot == maxRot && it->second) || targetRot == minRot;
/// \todo should use convexSweepTest here
std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(it->first, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
for (MWWorld::Ptr& ptr : collisions)
{
if (ptr.getClass().isActor())
{
// Collided with actor, ask actor to try to avoid door
if(ptr != getPlayerPtr() )
{
MWMechanics::AiSequence& seq = ptr.getClass().getCreatureStats(ptr).getAiSequence();
if(seq.getTypeId() != MWMechanics::AiPackage::TypeIdAvoidDoor) //Only add it once
seq.stack(MWMechanics::AiAvoidDoor(it->first),ptr);
}
// we need to undo the rotation
rotateObject(it->first, objPos.rot[0], objPos.rot[1], oldRot);
reached = false;
}
}
// the rotation order we want to use
mWorldScene->updateObjectRotation(it->first, false);
bool reached = rotateDoor(it->first, it->second, duration);
if (reached)
{
@ -2535,7 +2541,10 @@ namespace MWWorld
door.getClass().setDoorState(door, state);
mDoorStates[door] = state;
if (state == 0)
{
mDoorStates.erase(door);
rotateDoor(door, state, 1);
}
}
bool World::getPlayerStandingOn (const MWWorld::ConstPtr& object)

@ -146,6 +146,8 @@ namespace MWWorld
private:
void PCDropped (const Ptr& item);
bool rotateDoor(const Ptr door, int state, float duration);
void processDoors(float duration);
///< Run physics simulation and modify \a world accordingly.

Loading…
Cancel
Save