mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-04-01 00:36:46 +00:00
Merge branch 'restore_caster' into 'master'
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
This commit is contained in:
parent
c9d3da498a
commit
2bfee281fd
8 changed files with 47 additions and 1 deletions
|
@ -539,6 +539,7 @@ namespace MWBase
|
||||||
virtual void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) = 0;
|
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,
|
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;
|
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;
|
virtual void applyLoopingParticles(const MWWorld::Ptr& ptr) = 0;
|
||||||
|
|
||||||
|
|
|
@ -604,7 +604,9 @@ namespace MWPhysics
|
||||||
return object->getCollisionObject();
|
return object->getCollisionObject();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}();
|
}();
|
||||||
assert(caster);
|
|
||||||
|
if (caster == nullptr)
|
||||||
|
Log(Debug::Warning) << "No caster for projectile " << projectileId;
|
||||||
|
|
||||||
ProjectileConvexCallback resultCallback(caster, btFrom, btTo, projectile);
|
ProjectileConvexCallback resultCallback(caster, btFrom, btTo, projectile);
|
||||||
resultCallback.m_collisionFilterMask = 0xff;
|
resultCallback.m_collisionFilterMask = 0xff;
|
||||||
|
@ -695,6 +697,15 @@ namespace MWPhysics
|
||||||
return mProjectileId;
|
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()
|
bool PhysicsSystem::toggleCollisionMode()
|
||||||
{
|
{
|
||||||
ActorMap::iterator found = mActors.find(MWMechanics::getPlayer());
|
ActorMap::iterator found = mActors.find(MWMechanics::getPlayer());
|
||||||
|
|
|
@ -125,6 +125,7 @@ namespace MWPhysics
|
||||||
void addActor (const MWWorld::Ptr& ptr, const std::string& mesh);
|
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);
|
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 updateProjectile(const int projectileId, const osg::Vec3f &position) const;
|
||||||
void removeProjectile(const int projectileId);
|
void removeProjectile(const int projectileId);
|
||||||
|
|
||||||
|
|
|
@ -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()->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,
|
// 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.
|
// but some mods may be using it as a reload detector.
|
||||||
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
MWBase::Environment::get().getScriptManager()->getGlobalScripts().addStartup();
|
||||||
|
|
|
@ -352,6 +352,29 @@ namespace MWWorld
|
||||||
mProjectiles.push_back(state);
|
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)
|
void ProjectileManager::update(float dt)
|
||||||
{
|
{
|
||||||
periodicCleanup(dt);
|
periodicCleanup(dt);
|
||||||
|
|
|
@ -54,6 +54,8 @@ namespace MWWorld
|
||||||
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
void launchProjectile (MWWorld::Ptr actor, MWWorld::ConstPtr projectile,
|
||||||
const osg::Vec3f& pos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength);
|
const osg::Vec3f& pos, const osg::Quat& orient, MWWorld::Ptr bow, float speed, float attackStrength);
|
||||||
|
|
||||||
|
void updateCasters();
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
void processHits();
|
void processHits();
|
||||||
|
|
|
@ -3186,6 +3186,11 @@ namespace MWWorld
|
||||||
mProjectileManager->launchMagicBolt(spellId, caster, fallbackDirection);
|
mProjectileManager->launchMagicBolt(spellId, caster, fallbackDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::updateProjectilesCasters()
|
||||||
|
{
|
||||||
|
mProjectileManager->updateCasters();
|
||||||
|
}
|
||||||
|
|
||||||
class ApplyLoopingParticlesVisitor : public MWMechanics::EffectSourceVisitor
|
class ApplyLoopingParticlesVisitor : public MWMechanics::EffectSourceVisitor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -644,6 +644,7 @@ namespace MWWorld
|
||||||
void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
void launchMagicBolt (const std::string& spellId, const MWWorld::Ptr& caster, const osg::Vec3f& fallbackDirection) override;
|
||||||
void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
void launchProjectile (MWWorld::Ptr& actor, MWWorld::Ptr& projectile,
|
||||||
const osg::Vec3f& worldPos, const osg::Quat& orient, MWWorld::Ptr& bow, float speed, float attackStrength) override;
|
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;
|
void applyLoopingParticles(const MWWorld::Ptr& ptr) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue