mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-29 03:26:38 +00:00 
			
		
		
		
	Merge branch 'ghd' into 'master'
Great House Dagoth See merge request OpenMW/openmw!638
This commit is contained in:
		
						commit
						cda0c7ed44
					
				
					 19 changed files with 86 additions and 9 deletions
				
			
		|  | @ -3,6 +3,8 @@ | |||
| 
 | ||||
|     Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions) | ||||
|     Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes | ||||
|     Bug #3905: Great House Dagoth issues | ||||
|     Bug #5120: Scripted object spawning updates physics system | ||||
|     Bug #5379: Wandering NPCs falling through cantons | ||||
|     Bug #5453: Magic effect VFX are offset for creatures | ||||
|     Bug #5483: AutoCalc flag is not used to calculate spells cost | ||||
|  |  | |||
|  | @ -39,6 +39,11 @@ namespace MWClass | |||
|     } | ||||
| 
 | ||||
|     void Activator::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); | ||||
|     } | ||||
| 
 | ||||
|     void Activator::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         if(!model.empty()) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); | ||||
|  |  | |||
|  | @ -19,6 +19,8 @@ namespace MWClass | |||
| 
 | ||||
|             void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
| 
 | ||||
|             void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const override; | ||||
| 
 | ||||
|             std::string getName (const MWWorld::ConstPtr& ptr) const override; | ||||
|             ///< \return name or ID; can return an empty string.
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -107,6 +107,11 @@ namespace MWClass | |||
|     } | ||||
| 
 | ||||
|     void Container::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); | ||||
|     } | ||||
| 
 | ||||
|     void Container::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         if(!model.empty()) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ namespace MWClass | |||
|             ///< Add reference into a cell for rendering
 | ||||
| 
 | ||||
|             void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
|             void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
| 
 | ||||
|             std::string getName (const MWWorld::ConstPtr& ptr) const override; | ||||
|             ///< \return name or ID; can return an empty string.
 | ||||
|  |  | |||
|  | @ -57,8 +57,7 @@ namespace MWClass | |||
| 
 | ||||
|     void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         if(!model.empty()) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door, skipAnimated); | ||||
|         insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); | ||||
| 
 | ||||
|         // Resume the door's opening/closing animation if it wasn't finished
 | ||||
|         if (ptr.getRefData().getCustomData()) | ||||
|  | @ -71,6 +70,12 @@ namespace MWClass | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void Door::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         if(!model.empty()) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_Door, skipAnimated); | ||||
|     } | ||||
| 
 | ||||
|     bool Door::isDoor() const | ||||
|     { | ||||
|         return true; | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ namespace MWClass | |||
|             ///< Add reference into a cell for rendering
 | ||||
| 
 | ||||
|             void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
|             void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
| 
 | ||||
|             bool isDoor() const override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -39,9 +39,7 @@ namespace MWClass | |||
|             ptr.get<ESM::Light>(); | ||||
|         assert (ref->mBase != nullptr); | ||||
| 
 | ||||
|         // TODO: add option somewhere to enable collision for placeable objects
 | ||||
|         if (!model.empty() && (ref->mBase->mData.mFlags & ESM::Light::Carry) == 0) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); | ||||
|         insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); | ||||
| 
 | ||||
|         if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)) | ||||
|             MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, | ||||
|  | @ -49,6 +47,13 @@ namespace MWClass | |||
|                                                                       MWSound::PlayMode::Loop); | ||||
|     } | ||||
| 
 | ||||
|     void Light::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         // TODO: add option somewhere to enable collision for placeable objects
 | ||||
|         if (!model.empty() && (ptr.get<ESM::Light>()->mBase->mData.mFlags & ESM::Light::Carry) == 0) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); | ||||
|     } | ||||
| 
 | ||||
|     bool Light::useAnim() const | ||||
|     { | ||||
|         return true; | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ namespace MWClass | |||
|             ///< Add reference into a cell for rendering
 | ||||
| 
 | ||||
|             void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
|             void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
| 
 | ||||
|             bool useAnim() const override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,6 +24,11 @@ namespace MWClass | |||
|     } | ||||
| 
 | ||||
|     void Static::insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         insertObjectPhysics(ptr, model, rotation, physics, skipAnimated); | ||||
|     } | ||||
| 
 | ||||
|     void Static::insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     { | ||||
|         if(!model.empty()) | ||||
|             physics.addObject(ptr, model, rotation, MWPhysics::CollisionType_World, skipAnimated); | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ namespace MWClass | |||
|             ///< Add reference into a cell for rendering
 | ||||
| 
 | ||||
|             void insertObject(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
|             void insertObjectPhysics(const MWWorld::Ptr& ptr, const std::string& model, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const override; | ||||
| 
 | ||||
|             std::string getName (const MWWorld::ConstPtr& ptr) const override; | ||||
|             ///< \return name or ID; can return an empty string.
 | ||||
|  |  | |||
|  | @ -463,6 +463,8 @@ namespace MWPhysics | |||
| 
 | ||||
|     void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, osg::Quat rotation, int collisionType, bool skipAnimated) | ||||
|     { | ||||
|         if (ptr.mRef->mData.mPhysicsPostponed) | ||||
|             return; | ||||
|         osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->getInstance(mesh); | ||||
|         if (!shapeInstance || !shapeInstance->getCollisionShape()) | ||||
|             return; | ||||
|  |  | |||
|  | @ -168,6 +168,8 @@ namespace MWScript | |||
|                 void execute (Interpreter::Runtime& runtime) override | ||||
|                 { | ||||
|                     MWWorld::Ptr ptr = R()(runtime); | ||||
|                     if(!ptr.isEmpty() && !ptr.mRef->mData.isEnabled()) | ||||
|                         ptr.mRef->mData.mPhysicsPostponed = false; | ||||
|                     MWBase::Environment::get().getWorld()->enable (ptr); | ||||
|                 } | ||||
|         }; | ||||
|  |  | |||
|  | @ -42,10 +42,19 @@ namespace MWScript | |||
| 
 | ||||
|                 void execute (Interpreter::Runtime& runtime) override | ||||
|                 { | ||||
|                     MWWorld::Ptr from = R()(runtime); | ||||
|                     MWWorld::Ptr from = R()(runtime, !R::implicit); | ||||
|                     std::string name = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     if (from.isEmpty()) | ||||
|                     { | ||||
|                         std::string error = "Missing implicit ref"; | ||||
|                         runtime.getContext().report(error); | ||||
|                         Log(Debug::Error) << error; | ||||
|                         runtime.push(0.f); | ||||
|                         return; | ||||
|                     } | ||||
| 
 | ||||
|                     if (from.getContainerStore()) // is the object contained?
 | ||||
|                     { | ||||
|                         MWWorld::Ptr container = MWBase::Environment::get().getWorld()->findContainer(from); | ||||
|  | @ -501,6 +510,7 @@ namespace MWScript | |||
|                         pos.rot[0] = pos.rot[1] = 0; | ||||
|                         pos.rot[2] = osg::DegreesToRadians(zRotDegrees); | ||||
|                         MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); | ||||
|                         ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); | ||||
|                         ref.getPtr().getCellRef().setPosition(pos); | ||||
|                         MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos); | ||||
|                         placed.getClass().adjustPosition(placed, true); | ||||
|  | @ -548,6 +558,7 @@ namespace MWScript | |||
|                     pos.rot[0] = pos.rot[1] = 0; | ||||
|                     pos.rot[2] = osg::DegreesToRadians(zRotDegrees); | ||||
|                     MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); | ||||
|                     ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); | ||||
|                     ref.getPtr().getCellRef().setPosition(pos); | ||||
|                     MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(),store,pos); | ||||
|                     placed.getClass().adjustPosition(placed, true); | ||||
|  | @ -588,6 +599,7 @@ namespace MWScript | |||
|                     { | ||||
|                         // create item
 | ||||
|                         MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, 1); | ||||
|                         ref.getPtr().mRef->mData.mPhysicsPostponed = !ref.getPtr().getClass().isActor(); | ||||
| 
 | ||||
|                         MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), actor, actor.getCell(), direction, distance); | ||||
|                         MWBase::Environment::get().getWorld()->scaleObject(ptr, actor.getCellRef().getScale()); | ||||
|  |  | |||
|  | @ -35,6 +35,9 @@ namespace MWWorld | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     void Class::insertObjectPhysics(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated) const | ||||
|     {} | ||||
| 
 | ||||
|     bool Class::apply (const MWWorld::Ptr& ptr, const std::string& id,  const MWWorld::Ptr& actor) const | ||||
|     { | ||||
|         return false; | ||||
|  |  | |||
|  | @ -80,6 +80,7 @@ namespace MWWorld | |||
|             virtual void insertObjectRendering (const Ptr& ptr, const std::string& mesh, MWRender::RenderingInterface& renderingInterface) const; | ||||
|             virtual void insertObject(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const; | ||||
|             ///< Add reference into a cell for rendering (default implementation: don't render anything).
 | ||||
|             virtual void insertObjectPhysics(const Ptr& ptr, const std::string& mesh, osg::Quat rotation, MWPhysics::PhysicsSystem& physics, bool skipAnimated = false) const; | ||||
| 
 | ||||
|             virtual std::string getName (const ConstPtr& ptr) const = 0; | ||||
|             ///< \return name or ID; can return an empty string.
 | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ namespace MWWorld | |||
|         mChanged = refData.mChanged; | ||||
|         mDeletedByContentFile = refData.mDeletedByContentFile; | ||||
|         mFlags = refData.mFlags; | ||||
|         mPhysicsPostponed = refData.mPhysicsPostponed; | ||||
| 
 | ||||
|         mAnimationState = refData.mAnimationState; | ||||
| 
 | ||||
|  | @ -44,7 +45,7 @@ namespace MWWorld | |||
|     } | ||||
| 
 | ||||
|     RefData::RefData() | ||||
|     : mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mCount (1), mCustomData (nullptr), mChanged(false), mFlags(0) | ||||
|     : mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mCount (1), mCustomData (nullptr), mChanged(false), mFlags(0), mPhysicsPostponed(false) | ||||
|     { | ||||
|         for (int i=0; i<3; ++i) | ||||
|         { | ||||
|  | @ -57,7 +58,7 @@ namespace MWWorld | |||
|     : mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), | ||||
|       mCount (1), mPosition (cellRef.mPos), | ||||
|       mCustomData (nullptr), | ||||
|       mChanged(false), mFlags(0) // Loading from ESM/ESP files -> assume unchanged
 | ||||
|       mChanged(false), mFlags(0), mPhysicsPostponed(false) // Loading from ESM/ESP files -> assume unchanged
 | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|  | @ -68,7 +69,7 @@ namespace MWWorld | |||
|       mPosition (objectState.mPosition), | ||||
|       mAnimationState(objectState.mAnimationState), | ||||
|       mCustomData (nullptr), | ||||
|       mChanged(true), mFlags(objectState.mFlags) // Loading from a savegame -> assume changed
 | ||||
|       mChanged(true), mFlags(objectState.mFlags), mPhysicsPostponed(false) // Loading from a savegame -> assume changed
 | ||||
|     { | ||||
|         // "Note that the ActivationFlag_UseEnabled is saved to the reference,
 | ||||
|         // which will result in permanently suppressed activation if the reference script is removed.
 | ||||
|  |  | |||
|  | @ -58,6 +58,8 @@ namespace MWWorld | |||
| 
 | ||||
|         public: | ||||
| 
 | ||||
|             bool mPhysicsPostponed; | ||||
| 
 | ||||
|             RefData(); | ||||
| 
 | ||||
|             /// @param cellRef Used to copy constant data such as position into this class where it can
 | ||||
|  |  | |||
|  | @ -343,7 +343,10 @@ namespace MWWorld | |||
| 
 | ||||
|         cell->forEach(visitor); | ||||
|         for (const auto& ptr : visitor.mObjects) | ||||
|         { | ||||
|             mPhysics->remove(ptr); | ||||
|             ptr.mRef->mData.mPhysicsPostponed = false; | ||||
|         } | ||||
| 
 | ||||
|         if (cell->getCell()->isExterior()) | ||||
|         { | ||||
|  | @ -626,6 +629,24 @@ namespace MWWorld | |||
|             } | ||||
|             return cellsPositionsToLoad; | ||||
|         }; | ||||
| 
 | ||||
|         for(const auto& cell : mActiveCells) | ||||
|         { | ||||
|             cell->forEach([&](const MWWorld::Ptr& ptr) | ||||
|             { | ||||
|                 if(ptr.mRef->mData.mPhysicsPostponed) | ||||
|                 { | ||||
|                     ptr.mRef->mData.mPhysicsPostponed = false; | ||||
|                     if(ptr.mRef->mData.isEnabled() && ptr.mRef->mData.getCount() > 0) { | ||||
|                         std::string model = getModel(ptr, MWBase::Environment::get().getResourceSystem()->getVFS()); | ||||
|                         const auto rotation = makeNodeRotation(ptr, RotationOrder::direct); | ||||
|                         ptr.getClass().insertObjectPhysics(ptr, model, rotation, *mPhysics); | ||||
|                     } | ||||
|                 } | ||||
|                 return true; | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         auto cellsPositionsToLoad = cellsToLoad(mActiveCells,mHalfGridSize); | ||||
|         auto cellsPositionsToLoadInactive = cellsToLoad(mInactiveCells,mHalfGridSize+1); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue