summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederic Chardon <chardon.frederic@gmail.com>2021-03-05 21:05:54 +0000
committerFrederic Chardon <chardon.frederic@gmail.com>2021-03-05 21:05:54 +0000
commitd64406a9e39350d5c5a2c35b22b9285c31dcc4ab (patch)
treeda338c863811a31645891ad5fedde734622fba46
parentc9d3da498a766fe06d883fcb671f74c03d8516a3 (diff)
Merge branch 'restore_caster' into 'master'cherry-pick-d595c7ad
Restore projectile caster from savegame (#5860) See merge request OpenMW/openmw!616 (cherry picked from commit d595c7adb0fb45eafed6d3d0403ad640a91411ed) c5426bec In the savegame, projectile caster is identified by its actor id. When
-rw-r--r--apps/openmw/mwbase/world.hpp1
-rw-r--r--apps/openmw/mwphysics/physicssystem.cpp13
-rw-r--r--apps/openmw/mwphysics/physicssystem.hpp1
-rw-r--r--apps/openmw/mwstate/statemanagerimp.cpp2
-rw-r--r--apps/openmw/mwworld/projectilemanager.cpp23
-rw-r--r--apps/openmw/mwworld/projectilemanager.hpp2
-rw-r--r--apps/openmw/mwworld/worldimp.cpp5
-rw-r--r--apps/openmw/mwworld/worldimp.hpp1
8 files changed, 47 insertions, 1 deletions
diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp
index 194e8f6956..27980f0705 100644
--- a/apps/openmw/mwbase/world.hpp
+++ b/apps/openmw/mwbase/world.hpp
@@ -539,6 +539,7 @@ namespace MWBase
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
virtual void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) = 0;
+ virtual void updateProjectilesCasters() = 0;
virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 0;
diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp
index 382b348b93..b2decde2f0 100644
--- a/apps/openmw/mwphysics/physicssystem.cpp
+++ b/apps/openmw/mwphysics/physicssystem.cpp
@@ -604,7 +604,9 @@ namespace MWPhysics
return object->getCollisionObject();
return nullptr;
}();
- assert(caster);
+
+ if (caster == nullptr)
+ Log(Debug::Warning) << "No caster for projectile " << projectileId;
ProjectileConvexCallback resultCallback(caster, btFrom, btTo, projectile);
resultCallback.m_collisionFilterMask = 0xff;
@@ -695,6 +697,15 @@ namespace MWPhysics
return mProjectileId;
}
+ void PhysicsSystem::setCaster(int projectileId, const MWWorld::Ptr& caster)
+ {
+ const auto foundProjectile = mProjectiles.find(projectileId);
+ assert(foundProjectile != mProjectiles.end());
+ auto* projectile = foundProjectile->second.get();
+
+ projectile->setCaster(caster);
+ }
+
bool PhysicsSystem::toggleCollisionMode()
{
ActorMap::iterator found = mActors.find(MWMechanics::getPlayer());
diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp
index 57ebbadbb3..80b2d98bcf 100644
--- a/apps/openmw/mwphysics/physicssystem.hpp
+++ b/apps/openmw/mwphysics/physicssystem.hpp
@@ -125,6 +125,7 @@ namespace MWPhysics
void addActor (const MWWorld::Ptr& ptr, const std::string& mesh);
int addProjectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius, bool canTraverseWater);
+ void setCaster(int projectileId, const MWWorld::Ptr& caster);
void updateProjectile(const int projectileId, const osg::Vec3f &position) const;
void removeProjectile(const int projectileId);
diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp
index 72e4b1ae02..f605344bf7 100644
--- a/apps/openmw/mwstate/statemanagerimp.cpp
+++ b/apps/openmw/mwstate/statemanagerimp.cpp
@@ -539,6 +539,8 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
MWBase::Environment::get().getWorld()->changeToCell(cell->getCell()->getCellId(), pos, true, false);
}
+ MWBase::Environment::get().getWorld()->updateProjectilesCasters();
+
// Vanilla MW will restart startup scripts when a save game is loaded. This is unintuitive,
// but some mods may be using it as a reload detector.
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
diff --git a/apps/openmw/mwworld/projectilemanager.cpp b/apps/openmw/mwworld/projectilemanager.cpp
index 3ffc7bb953..f483905ddf 100644
--- a/apps/openmw/mwworld/projectilemanager.cpp
+++ b/apps/openmw/mwworld/projectilemanager.cpp
@@ -352,6 +352,29 @@ namespace MWWorld
mProjectiles.push_back(state);
}
+ void ProjectileManager::updateCasters()
+ {
+ for (auto& state : mProjectiles)
+ mPhysics->setCaster(state.mProjectileId, state.getCaster());
+
+ for (auto& state : mMagicBolts)
+ {
+ // casters are identified by actor id in the savegame. objects doesn't have one so they can't be identified back.
+ // TODO: should object-type caster be restored from savegame?
+ if (state.mActorId == -1)
+ continue;
+
+ auto caster = state.getCaster();
+ if (caster.isEmpty())
+ {
+ Log(Debug::Error) << "Couldn't find caster with ID " << state.mActorId;
+ cleanupMagicBolt(state);
+ continue;
+ }
+ mPhysics->setCaster(state.mProjectileId, caster);
+ }
+ }
+
void ProjectileManager::update(float dt)
{
periodicCleanup(dt);
diff --git a/apps/openmw/mwworld/projectilemanager.hpp b/apps/openmw/mwworld/projectilemanager.hpp
index c047d90ddf..e4bcae1ae4 100644
--- a/apps/openmw/mwworld/projectilemanager.hpp
+++ b/apps/openmw/mwworld/projectilemanager.hpp
@@ -54,6 +54,8 @@ namespace MWWorld
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
const osg::Vec3f& pos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength);
+ void updateCasters();
+
void update(float dt);
void processHits();
diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp
index b609f325c9..01b90e9078 100644
--- a/apps/openmw/mwworld/worldimp.cpp
+++ b/apps/openmw/mwworld/worldimp.cpp
@@ -3186,6 +3186,11 @@ namespace MWWorld
mProjectileManager->launchMagicBolt(spellId, caster, fallbackDirection);
}
+ void World::updateProjectilesCasters()
+ {
+ mProjectileManager->updateCasters();
+ }
+
class ApplyLoopingParticlesVisitor : public MWMechanics::EffectSourceVisitor
{
private:
diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp
index bc2baafd8a..23153a31c4 100644
--- a/apps/openmw/mwworld/worldimp.hpp
+++ b/apps/openmw/mwworld/worldimp.hpp
@@ -644,6 +644,7 @@ namespace MWWorld
void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) override;
+ void updateProjectilesCasters() override;
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;