mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 13:15:32 +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 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;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -3186,6 +3186,11 @@ namespace MWWorld
|
|||
mProjectileManager->launchMagicBolt(spellId, caster, fallbackDirection);
|
||||
}
|
||||
|
||||
void World::updateProjectilesCasters()
|
||||
{
|
||||
mProjectileManager->updateCasters();
|
||||
}
|
||||
|
||||
class ApplyLoopingParticlesVisitor : public MWMechanics::EffectSourceVisitor
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue