mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-28 12:09:46 +00:00
Merge pull request #2492 from akortunov/lock
Use a common doors rotation code in the "lock" command handler
This commit is contained in:
commit
38042bb49f
4 changed files with 46 additions and 40 deletions
|
@ -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…
Reference in a new issue