1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 09:35:28 +00:00

Merge branch 'ghd' into 'master'

Great House Dagoth

See merge request OpenMW/openmw!638
This commit is contained in:
psi29a 2021-07-06 07:22:29 +00:00
commit cda0c7ed44
19 changed files with 86 additions and 9 deletions

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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;

View File

@ -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);
}
};

View File

@ -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());

View File

@ -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;

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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);