diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 690afab95..a0e9da26a 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -229,6 +229,8 @@ namespace MWBase /// Sets the NPC's Acrobatics skill to match the fWerewolfAcrobatics GMST. /// It only applies to the current form the NPC is in. virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor) = 0; + + virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId) = 0; }; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 23f2978e6..f627e62ae 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -688,9 +688,7 @@ namespace MWMechanics creatureStats.getActiveSpells().visitEffectSources(updateSummonedCreatures); if (ptr.getClass().hasInventoryStore(ptr)) ptr.getClass().getInventoryStore(ptr).visitEffectSources(updateSummonedCreatures); - std::set deleted = updateSummonedCreatures.process(); - for (std::set::const_iterator it = deleted.begin(); it != deleted.end(); ++it) - purgeSpellEffects(*it); + updateSummonedCreatures.process(); } void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr, float duration) @@ -1259,6 +1257,30 @@ namespace MWMechanics } } + void Actors::cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId) + { + MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(creatureActorId); + if (!ptr.isEmpty()) + { + MWBase::Environment::get().getWorld()->deleteObject(ptr); + + const ESM::Static* fx = MWBase::Environment::get().getWorld()->getStore().get() + .search("VFX_Summon_End"); + if (fx) + MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + fx->mModel, + "", ptr.getRefData().getPosition().asVec3()); + } + else if (creatureActorId != -1) + { + // We didn't find the creature. It's probably in an inactive cell. + // Add to graveyard so we can delete it when the cell becomes active. + std::vector& graveyard = casterStats.getSummonedCreatureGraveyard(); + graveyard.push_back(creatureActorId); + } + + purgeSpellEffects(creatureActorId); + } + void Actors::purgeSpellEffects(int casterActorId) { for (PtrActorMap::iterator iter(mActors.begin());iter != mActors.end();++iter) diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 2dae6b1fb..644864e7f 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -19,6 +19,7 @@ namespace MWWorld namespace MWMechanics { class Actor; + class CreatureStats; class Actors { @@ -113,6 +114,8 @@ namespace MWMechanics void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out); + void cleanupSummonedCreature (CreatureStats& casterStats, int creatureActorId); + ///Returns the list of actors which are siding with the given actor in fights /**ie AiFollow or AiEscort is active and the target is the actor **/ std::list getActorsSidingWith(const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 0e1869ff1..6dd14be11 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1700,4 +1700,9 @@ namespace MWMechanics stats.getSkill(ESM::Skill::Acrobatics).setBase(gmst.find("fWerewolfAcrobatics")->getInt()); } + void MechanicsManager::cleanupSummonedCreature(const MWWorld::Ptr &caster, int creatureActorId) + { + mActors.cleanupSummonedCreature(caster.getClass().getCreatureStats(caster), creatureActorId); + } + } diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 693f49c94..793a8158e 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -189,6 +189,8 @@ namespace MWMechanics virtual void setWerewolf(const MWWorld::Ptr& actor, bool werewolf); virtual void applyWerewolfAcrobatics(const MWWorld::Ptr& actor); + virtual void cleanupSummonedCreature(const MWWorld::Ptr& caster, int creatureActorId); + private: void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim, OffenseType type, int arg=0); diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 8882d14a8..842951362 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -26,7 +26,6 @@ #include "magiceffects.hpp" #include "npcstats.hpp" -#include "summoning.hpp" #include "actorutil.hpp" namespace @@ -510,7 +509,7 @@ namespace MWMechanics std::map::iterator found = targetStats.getSummonedCreatureMap().find(std::make_pair(effectIt->mEffectID, mId)); if (found != targetStats.getSummonedCreatureMap().end()) { - cleanupSummonedCreature(targetStats, found->second); + MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(target, found->second); targetStats.getSummonedCreatureMap().erase(found); } } diff --git a/apps/openmw/mwmechanics/summoning.cpp b/apps/openmw/mwmechanics/summoning.cpp index 5108e40ff..9b094ba32 100644 --- a/apps/openmw/mwmechanics/summoning.cpp +++ b/apps/openmw/mwmechanics/summoning.cpp @@ -4,6 +4,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwmechanics/spellcasting.hpp" @@ -21,28 +22,6 @@ namespace MWMechanics { - void cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId) - { - MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(creatureActorId); - if (!ptr.isEmpty()) - { - MWBase::Environment::get().getWorld()->deleteObject(ptr); - - const ESM::Static* fx = MWBase::Environment::get().getWorld()->getStore().get() - .search("VFX_Summon_End"); - if (fx) - MWBase::Environment::get().getWorld()->spawnEffect("meshes\\" + fx->mModel, - "", ptr.getRefData().getPosition().asVec3()); - } - else if (creatureActorId != -1) - { - // We didn't find the creature. It's probably in an inactive cell. - // Add to graveyard so we can delete it when the cell becomes active. - std::vector& graveyard = casterStats.getSummonedCreatureGraveyard(); - graveyard.push_back(creatureActorId); - } - } - UpdateSummonedCreatures::UpdateSummonedCreatures(const MWWorld::Ptr &actor) : mActor(actor) { @@ -61,10 +40,8 @@ namespace MWMechanics } } - std::set UpdateSummonedCreatures::process() + void UpdateSummonedCreatures::process() { - std::set deletedCreatures; - static std::map summonMap; if (summonMap.empty()) { @@ -102,8 +79,7 @@ namespace MWMechanics if (!found) { // Effect has ended - cleanupSummonedCreature(creatureStats, it->second); - deletedCreatures.insert(it->second); + MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mActor, it->second); creatureMap.erase(it++); continue; } @@ -165,7 +141,7 @@ namespace MWMechanics if (mActor.getClass().hasInventoryStore(ptr)) mActor.getClass().getInventoryStore(mActor).purgeEffect(it->first.first, it->first.second); - cleanupSummonedCreature(creatureStats, it->second); + MWBase::Environment::get().getMechanicsManager()->cleanupSummonedCreature(mActor, it->second); creatureMap.erase(it++); } else @@ -191,8 +167,6 @@ namespace MWMechanics else ++it; } - - return deletedCreatures; } } diff --git a/apps/openmw/mwmechanics/summoning.hpp b/apps/openmw/mwmechanics/summoning.hpp index 2e1c48856..3a60e2b68 100644 --- a/apps/openmw/mwmechanics/summoning.hpp +++ b/apps/openmw/mwmechanics/summoning.hpp @@ -21,8 +21,7 @@ namespace MWMechanics float magnitude, float remainingTime = -1, float totalTime = -1); /// To call after all effect sources have been visited - /// Returns list of actorIds for creatures that have been deleted due to the magic effect having expired - std::set process(); + void process(); private: MWWorld::Ptr mActor; @@ -30,8 +29,6 @@ namespace MWMechanics std::set > mActiveEffects; }; - void cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId); - } #endif