|
|
|
@ -1617,34 +1617,22 @@ namespace MWWorld
|
|
|
|
|
return result.mHit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::processDoors(float duration)
|
|
|
|
|
{
|
|
|
|
|
std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin();
|
|
|
|
|
while (it != mDoorStates.end())
|
|
|
|
|
{
|
|
|
|
|
if (!mWorldScene->isCellActive(*it->first.getCell()) || !it->first.getRefData().getBaseNode())
|
|
|
|
|
{
|
|
|
|
|
// The door is no longer in an active cell, or it was disabled.
|
|
|
|
|
// Erase from mDoorStates, since we no longer need to move it.
|
|
|
|
|
// Once we load the door's cell again (or re-enable the door), Door::insertObject will reinsert to mDoorStates.
|
|
|
|
|
mDoorStates.erase(it++);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
bool World::rotateDoor(const Ptr door, int state, float duration)
|
|
|
|
|
{
|
|
|
|
|
const ESM::Position& objPos = it->first.getRefData().getPosition();
|
|
|
|
|
const ESM::Position& objPos = door.getRefData().getPosition();
|
|
|
|
|
float oldRot = objPos.rot[2];
|
|
|
|
|
|
|
|
|
|
float minRot = it->first.getCellRef().getPosition().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 * (it->second == 1 ? 1 : -1)), maxRot);
|
|
|
|
|
rotateObject(it->first, objPos.rot[0], objPos.rot[1], targetRot);
|
|
|
|
|
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 && it->second) || targetRot == minRot;
|
|
|
|
|
bool reached = (targetRot == maxRot && state) || targetRot == minRot;
|
|
|
|
|
|
|
|
|
|
/// \todo should use convexSweepTest here
|
|
|
|
|
std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(it->first, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
|
|
|
|
|
std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(door, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
|
|
|
|
|
for (MWWorld::Ptr& ptr : collisions)
|
|
|
|
|
{
|
|
|
|
|
if (ptr.getClass().isActor())
|
|
|
|
@ -1654,17 +1642,35 @@ namespace MWWorld
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
seq.stack(MWMechanics::AiAvoidDoor(door),ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// we need to undo the rotation
|
|
|
|
|
rotateObject(it->first, objPos.rot[0], objPos.rot[1], oldRot);
|
|
|
|
|
rotateObject(door, objPos.rot[0], objPos.rot[1], oldRot);
|
|
|
|
|
reached = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the rotation order we want to use
|
|
|
|
|
mWorldScene->updateObjectRotation(it->first, false);
|
|
|
|
|
mWorldScene->updateObjectRotation(door, false);
|
|
|
|
|
return reached;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void World::processDoors(float duration)
|
|
|
|
|
{
|
|
|
|
|
std::map<MWWorld::Ptr, int>::iterator it = mDoorStates.begin();
|
|
|
|
|
while (it != mDoorStates.end())
|
|
|
|
|
{
|
|
|
|
|
if (!mWorldScene->isCellActive(*it->first.getCell()) || !it->first.getRefData().getBaseNode())
|
|
|
|
|
{
|
|
|
|
|
// The door is no longer in an active cell, or it was disabled.
|
|
|
|
|
// Erase from mDoorStates, since we no longer need to move it.
|
|
|
|
|
// Once we load the door's cell again (or re-enable the door), Door::insertObject will reinsert to mDoorStates.
|
|
|
|
|
mDoorStates.erase(it++);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|