mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 16:56:42 +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