diff --git a/apps/openmw/mwmechanics/actor.hpp b/apps/openmw/mwmechanics/actor.hpp index 3a3b0baa67..1e257f613d 100644 --- a/apps/openmw/mwmechanics/actor.hpp +++ b/apps/openmw/mwmechanics/actor.hpp @@ -37,6 +37,7 @@ namespace MWMechanics void updatePtr(const MWWorld::Ptr& newPtr) { mCharacterController.updatePtr(newPtr); } CharacterController& getCharacterController() { return mCharacterController; } + const CharacterController& getCharacterController() const { return mCharacterController; } int getGreetingTimer() const { return mGreetingTimer; } void setGreetingTimer(int timer) { mGreetingTimer = timer; } diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 0a9546baa5..99256d1395 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -108,7 +108,7 @@ std::pair getRestorationPerHourOfSleep(const MWWorld::Ptr& ptr) } template -void forEachFollowingPackage(std::list& actors, const MWWorld::Ptr& actorPtr, const MWWorld::Ptr& player, T&& func) +void forEachFollowingPackage(const std::list& actors, const MWWorld::Ptr& actorPtr, const MWWorld::Ptr& player, T&& func) { for (const MWMechanics::Actor& actor : actors) { @@ -357,7 +357,7 @@ namespace MWMechanics } } - void Actors::updateActor (const MWWorld::Ptr& ptr, float duration) + void Actors::updateActor(const MWWorld::Ptr& ptr, float duration) const { // magic effects adjustMagicEffects (ptr, duration); @@ -366,7 +366,7 @@ namespace MWMechanics calculateRestoration(ptr, duration); } - void Actors::playIdleDialogue(const MWWorld::Ptr& actor) + void Actors::playIdleDialogue(const MWWorld::Ptr& actor) const { if (!actor.getClass().isActor() || actor == getPlayer() || MWBase::Environment::get().getSoundManager()->sayActive(actor)) return; @@ -393,7 +393,7 @@ namespace MWMechanics MWBase::Environment::get().getDialogueManager()->say(actor, "idle"); } - void Actors::updateMovementSpeed(const MWWorld::Ptr& actor) + void Actors::updateMovementSpeed(const MWWorld::Ptr& actor) const { if (mSmoothMovement) return; @@ -510,7 +510,7 @@ namespace MWMechanics actorState.setGreetingState(greetingState); } - void Actors::turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir) + void Actors::turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir) const { auto& movementSettings = actor.getClass().getMovementSettings(actor); movementSettings.mPosition[1] = 0; @@ -528,7 +528,7 @@ namespace MWMechanics } } - void Actors::stopCombat(const MWWorld::Ptr& ptr) + void Actors::stopCombat(const MWWorld::Ptr& ptr) const { auto& ai = ptr.getClass().getCreatureStats(ptr).getAiSequence(); std::vector targets; @@ -545,7 +545,8 @@ namespace MWMechanics } } - void Actors::engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, std::map >& cachedAllies, bool againstPlayer) + void Actors::engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, + std::map>& cachedAllies, bool againstPlayer) const { // No combat for totally static creatures if (!actor1.getClass().isMobile(actor1)) @@ -698,7 +699,7 @@ namespace MWMechanics } } - void Actors::adjustMagicEffects (const MWWorld::Ptr& creature, float duration) + void Actors::adjustMagicEffects(const MWWorld::Ptr& creature, float duration) const { CreatureStats& creatureStats = creature.getClass().getCreatureStats (creature); const bool wasDead = creatureStats.isDead(); @@ -754,7 +755,7 @@ namespace MWMechanics updateSummons(creature, mTimerDisposeSummonsCorpses == 0.f); } - void Actors::restoreDynamicStats (const MWWorld::Ptr& ptr, double hours, bool sleep) + void Actors::restoreDynamicStats(const MWWorld::Ptr& ptr, double hours, bool sleep) const { MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); if (stats.isDead()) @@ -822,7 +823,7 @@ namespace MWMechanics stats.setFatigue (fatigue); } - void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration) + void Actors::calculateRestoration(const MWWorld::Ptr& ptr, float duration) const { if (ptr.getClass().getCreatureStats(ptr).isDead()) return; @@ -847,7 +848,7 @@ namespace MWMechanics stats.setFatigue (fatigue); } - bool Actors::isAttackPreparing(const MWWorld::Ptr& ptr) + bool Actors::isAttackPreparing(const MWWorld::Ptr& ptr) const { const auto it = mIndex.find(ptr.mRef); if (it == mIndex.end()) @@ -855,7 +856,7 @@ namespace MWMechanics return it->second->getCharacterController().isAttackPreparing(); } - bool Actors::isRunning(const MWWorld::Ptr& ptr) + bool Actors::isRunning(const MWWorld::Ptr& ptr) const { const auto it = mIndex.find(ptr.mRef); if (it == mIndex.end()) @@ -863,7 +864,7 @@ namespace MWMechanics return it->second->getCharacterController().isRunning(); } - bool Actors::isSneaking(const MWWorld::Ptr& ptr) + bool Actors::isSneaking(const MWWorld::Ptr& ptr) const { const auto it = mIndex.find(ptr.mRef); if (it == mIndex.end()) @@ -1027,7 +1028,7 @@ namespace MWMechanics } } - void Actors::updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) + void Actors::updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) const { const MWWorld::Ptr player = getPlayer(); if (ptr == player) @@ -1139,7 +1140,7 @@ namespace MWMechanics updateVisibility(ptr, it->getCharacterController()); } - void Actors::updateVisibility (const MWWorld::Ptr& ptr, CharacterController& ctrl) + void Actors::updateVisibility(const MWWorld::Ptr& ptr, CharacterController& ctrl) const { MWWorld::Ptr player = MWMechanics::getPlayer(); if (ptr == player) @@ -1179,14 +1180,14 @@ namespace MWMechanics } } - void Actors::castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell) + void Actors::castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell) const { const auto iter = mIndex.find(ptr.mRef); if (iter != mIndex.end()) iter->second->getCharacterController().castSpell(spellId, manualSpell); } - bool Actors::isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) + bool Actors::isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) const { if (!actor.getClass().isActor()) return false; @@ -1218,7 +1219,7 @@ namespace MWMechanics return false; } - void Actors::updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) + void Actors::updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) const { const auto iter = mIndex.find(old.mRef); if (iter != mIndex.end()) @@ -1282,7 +1283,7 @@ namespace MWMechanics } - void Actors::predictAndAvoidCollisions(float duration) + void Actors::predictAndAvoidCollisions(float duration) const { if (!MWBase::Environment::get().getMechanicsManager()->isAIActive()) return; @@ -1675,7 +1676,7 @@ namespace MWMechanics ++mDeathCount[Misc::StringUtils::lowerCase(actor.getCellRef().getRefId())]; } - void Actors::resurrect(const MWWorld::Ptr &ptr) + void Actors::resurrect(const MWWorld::Ptr &ptr) const { const auto iter = mIndex.find(ptr.mRef); if (iter != mIndex.end()) @@ -1745,7 +1746,7 @@ namespace MWMechanics } } - void Actors::cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId) + void Actors::cleanupSummonedCreature(MWMechanics::CreatureStats& casterStats, int creatureActorId) const { const MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(creatureActorId); if (!ptr.isEmpty()) @@ -1780,7 +1781,7 @@ namespace MWMechanics purgeSpellEffects(creatureActorId); } - void Actors::purgeSpellEffects(int casterActorId) + void Actors::purgeSpellEffects(int casterActorId) const { for (const Actor& actor : mActors) { @@ -1789,7 +1790,7 @@ namespace MWMechanics } } - void Actors::rest(double hours, bool sleep) + void Actors::rest(double hours, bool sleep) const { float duration = hours * 3600.f; const float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); @@ -1928,14 +1929,14 @@ namespace MWMechanics return 0; } - void Actors::forceStateUpdate(const MWWorld::Ptr & ptr) + void Actors::forceStateUpdate(const MWWorld::Ptr& ptr) const { const auto iter = mIndex.find(ptr.mRef); if (iter != mIndex.end()) iter->second->getCharacterController().forceStateUpdate(); } - bool Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) + bool Actors::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) const { const auto iter = mIndex.find(ptr.mRef); if(iter != mIndex.end()) @@ -1948,14 +1949,14 @@ namespace MWMechanics return false; } } - void Actors::skipAnimation(const MWWorld::Ptr& ptr) + void Actors::skipAnimation(const MWWorld::Ptr& ptr) const { const auto iter = mIndex.find(ptr.mRef); if (iter != mIndex.end()) iter->second->getCharacterController().skipAnim(); } - bool Actors::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) + bool Actors::checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) const { const auto iter = mIndex.find(ptr.mRef); if(iter != mIndex.end()) @@ -1963,13 +1964,13 @@ namespace MWMechanics return false; } - void Actors::persistAnimationStates() + void Actors::persistAnimationStates() const { - for (Actor& actor : mActors) + for (const Actor& actor : mActors) actor.getCharacterController().persistAnimationState(); } - void Actors::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) + void Actors::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const { for (const Actor& actor : mActors) { @@ -1978,7 +1979,7 @@ namespace MWMechanics } } - bool Actors::isAnyObjectInRange(const osg::Vec3f& position, float radius) + bool Actors::isAnyObjectInRange(const osg::Vec3f& position, float radius) const { for (const Actor& actor : mActors) { @@ -1989,7 +1990,7 @@ namespace MWMechanics return false; } - std::vector Actors::getActorsSidingWith(const MWWorld::Ptr& actorPtr, bool excludeInfighting) + std::vector Actors::getActorsSidingWith(const MWWorld::Ptr& actorPtr, bool excludeInfighting) const { std::vector list; for (const Actor& actor : mActors) @@ -2037,7 +2038,7 @@ namespace MWMechanics return list; } - std::vector Actors::getActorsFollowing(const MWWorld::Ptr& actorPtr) + std::vector Actors::getActorsFollowing(const MWWorld::Ptr& actorPtr) const { std::vector list; forEachFollowingPackage(mActors, actorPtr, getPlayer(), [&] (const Actor& actor, const std::shared_ptr& package) @@ -2051,21 +2052,25 @@ namespace MWMechanics return list; } - void Actors::getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) { + void Actors::getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) const + { auto followers = getActorsFollowing(actor); for(const MWWorld::Ptr &follower : followers) if (out.insert(follower).second) getActorsFollowing(follower, out); } - void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, bool excludeInfighting) { + void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, bool excludeInfighting) const + { auto followers = getActorsSidingWith(actor, excludeInfighting); for(const MWWorld::Ptr &follower : followers) if (out.insert(follower).second) getActorsSidingWith(follower, out, excludeInfighting); } - void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, std::map >& cachedAllies) { + void Actors::getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, + std::map>& cachedAllies) const + { // If we have already found actor's allies, use the cache std::map >::const_iterator search = cachedAllies.find(actor); if (search != cachedAllies.end()) @@ -2087,7 +2092,7 @@ namespace MWMechanics } } - std::vector Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor) + std::vector Actors::getActorsFollowingIndices(const MWWorld::Ptr &actor) const { std::vector list; forEachFollowingPackage(mActors, actor, getPlayer(), [&] (const Actor&, const std::shared_ptr& package) @@ -2104,7 +2109,7 @@ namespace MWMechanics return list; } - std::map Actors::getActorsFollowingByIndex(const MWWorld::Ptr &actor) + std::map Actors::getActorsFollowingByIndex(const MWWorld::Ptr &actor) const { std::map map; forEachFollowingPackage(mActors, actor, getPlayer(), [&] (const Actor& otherActor, const std::shared_ptr& package) @@ -2122,7 +2127,8 @@ namespace MWMechanics return map; } - std::vector Actors::getActorsFighting(const MWWorld::Ptr& actor) { + std::vector Actors::getActorsFighting(const MWWorld::Ptr& actor) const + { std::vector list; std::vector neighbors; const osg::Vec3f position(actor.getRefData().getPosition().asVec3()); @@ -2142,7 +2148,7 @@ namespace MWMechanics return list; } - std::vector Actors::getEnemiesNearby(const MWWorld::Ptr& actor) + std::vector Actors::getEnemiesNearby(const MWWorld::Ptr& actor) const { std::vector list; std::vector neighbors; @@ -2200,7 +2206,7 @@ namespace MWMechanics mDeathCount.clear(); } - void Actors::updateMagicEffects(const MWWorld::Ptr &ptr) + void Actors::updateMagicEffects(const MWWorld::Ptr &ptr) const { adjustMagicEffects(ptr, 0.f); } @@ -2268,7 +2274,7 @@ namespace MWMechanics return it->second->isTurningToPlayer(); } - void Actors::fastForwardAi() + void Actors::fastForwardAi() const { if (!MWBase::Environment::get().getMechanicsManager()->isAIActive()) return; diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index aa4e7b4cb1..071e2e5d84 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -51,11 +51,11 @@ namespace MWMechanics /// Check if the target actor was detected by an observer /// If the observer is a non-NPC, check all actors in AI processing distance as observers - bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer); + bool isActorDetected(const MWWorld::Ptr& actor, const MWWorld::Ptr& observer) const; /// Update magic effects for an actor. Usually done automatically once per frame, but if we're currently /// paused we may want to do it manually (after equipping permanent enchantment) - void updateMagicEffects (const MWWorld::Ptr& ptr); + void updateMagicEffects(const MWWorld::Ptr& ptr) const; void updateProcessingRange(); float getProcessingRange() const; @@ -70,11 +70,11 @@ namespace MWMechanics /// /// \note Ignored, if \a ptr is not a registered actor. - void resurrect (const MWWorld::Ptr& ptr); + void resurrect(const MWWorld::Ptr& ptr) const; - void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell=false); + void castSpell(const MWWorld::Ptr& ptr, const std::string& spellId, bool manualSpell = false) const; - void updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr); + void updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr) const; ///< Updates an actor with a new Ptr void dropActors (const MWWorld::CellStore *cellStore, const MWWorld::Ptr& ignore); @@ -86,72 +86,75 @@ namespace MWMechanics void update (float duration, bool paused); ///< Update actor stats and store desired velocity vectors in \a movement - void updateActor (const MWWorld::Ptr& ptr, float duration); + void updateActor(const MWWorld::Ptr& ptr, float duration) const; ///< This function is normally called automatically during the update process, but it can /// also be called explicitly at any time to force an update. /// Removes an actor from combat and makes all of their allies stop fighting the actor's targets - void stopCombat(const MWWorld::Ptr& ptr); + void stopCombat(const MWWorld::Ptr& ptr) const; - void playIdleDialogue(const MWWorld::Ptr& actor); - void updateMovementSpeed(const MWWorld::Ptr& actor); + void playIdleDialogue(const MWWorld::Ptr& actor) const; + void updateMovementSpeed(const MWWorld::Ptr& actor) const; void updateGreetingState(const MWWorld::Ptr& actor, Actor& actorState, bool turnOnly); - void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir); + void turnActorToFacePlayer(const MWWorld::Ptr& actor, Actor& actorState, const osg::Vec3f& dir) const; - void rest(double hours, bool sleep); + void rest(double hours, bool sleep) const; ///< Update actors while the player is waiting or sleeping. void updateSneaking(CharacterController* ctrl, float duration); ///< Update the sneaking indicator state according to the given player character controller. - void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep); + void restoreDynamicStats(const MWWorld::Ptr& actor, double hours, bool sleep) const; int getHoursToRest(const MWWorld::Ptr& ptr) const; ///< Calculate how many hours the given actor needs to rest in order to be fully healed - void fastForwardAi(); + void fastForwardAi() const; ///< Simulate the passing of time int countDeaths (const std::string& id) const; ///< Return the number of deaths for actors with the given ID. - bool isAttackPreparing(const MWWorld::Ptr& ptr); - bool isRunning(const MWWorld::Ptr& ptr); - bool isSneaking(const MWWorld::Ptr& ptr); + bool isAttackPreparing(const MWWorld::Ptr& ptr) const; + bool isRunning(const MWWorld::Ptr& ptr) const; + bool isSneaking(const MWWorld::Ptr& ptr) const; - void forceStateUpdate(const MWWorld::Ptr &ptr); + void forceStateUpdate(const MWWorld::Ptr &ptr) const; - bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist=false); - void skipAnimation(const MWWorld::Ptr& ptr); - bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName); - void persistAnimationStates(); + bool playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, + int number, bool persist = false) const; + void skipAnimation(const MWWorld::Ptr& ptr) const; + bool checkAnimationPlaying(const MWWorld::Ptr& ptr, const std::string& groupName) const; + void persistAnimationStates() const; - void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out); + void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector& out) const; - bool isAnyObjectInRange(const osg::Vec3f& position, float radius); + bool isAnyObjectInRange(const osg::Vec3f& position, float radius) const; - void cleanupSummonedCreature (CreatureStats& casterStats, int creatureActorId); + void cleanupSummonedCreature(CreatureStats& casterStats, int creatureActorId) const; ///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::vector getActorsSidingWith(const MWWorld::Ptr& actor, bool excludeInfighting = false); - std::vector getActorsFollowing(const MWWorld::Ptr& actor); + std::vector getActorsSidingWith(const MWWorld::Ptr& actor, + bool excludeInfighting = false) const; + std::vector getActorsFollowing(const MWWorld::Ptr& actor) const; /// Recursive version of getActorsFollowing - void getActorsFollowing(const MWWorld::Ptr &actor, std::set& out); + void getActorsFollowing(const MWWorld::Ptr &actor, std::set& out) const; /// Recursive version of getActorsSidingWith - void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, bool excludeInfighting = false); + void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, + bool excludeInfighting = false) const; /// Get the list of AiFollow::mFollowIndex for all actors following this target - std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor); - std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor); + std::vector getActorsFollowingIndices(const MWWorld::Ptr& actor) const; + std::map getActorsFollowingByIndex(const MWWorld::Ptr& actor) const; ///Returns the list of actors which are fighting the given actor /**ie AiCombat is active and the target is the actor **/ - std::vector getActorsFighting(const MWWorld::Ptr& actor); + std::vector getActorsFighting(const MWWorld::Ptr& actor) const; /// Unlike getActorsFighting, also returns actors that *would* fight the given actor if they saw him. - std::vector getEnemiesNearby(const MWWorld::Ptr& actor); + std::vector getEnemiesNearby(const MWWorld::Ptr& actor) const; void write (ESM::ESMWriter& writer, Loading::Listener& listener) const; @@ -189,28 +192,31 @@ namespace MWMechanics bool mSmoothMovement; MusicType mCurrentMusic = MusicType::Title; - void updateVisibility (const MWWorld::Ptr& ptr, CharacterController& ctrl); + void updateVisibility(const MWWorld::Ptr& ptr, CharacterController& ctrl) const; - void adjustMagicEffects (const MWWorld::Ptr& creature, float duration); + void adjustMagicEffects(const MWWorld::Ptr& creature, float duration) const; - void calculateRestoration (const MWWorld::Ptr& ptr, float duration); + void calculateRestoration(const MWWorld::Ptr& ptr, float duration) const; - void updateCrimePursuit (const MWWorld::Ptr& ptr, float duration); + void updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) const; void killDeadActors (); - void purgeSpellEffects (int casterActorId); + void purgeSpellEffects(int casterActorId) const; - void predictAndAvoidCollisions(float duration); + void predictAndAvoidCollisions(float duration) const; /** Start combat between two actors @Notes: If againstPlayer = true then actor2 should be the Player. If one of the combatants is creature it should be actor1. */ - void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, std::map >& cachedAllies, bool againstPlayer); + void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, + std::map>& cachedAllies, bool againstPlayer) const; - /// Recursive version of getActorsSidingWith that takes, adds to and returns a cache of actors mapped to their allies. Excludes infighting - void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, std::map >& cachedAllies); + /// Recursive version of getActorsSidingWith that takes, adds to and returns a cache of + /// actors mapped to their allies. Excludes infighting + void getActorsSidingWith(const MWWorld::Ptr &actor, std::set& out, + std::map>& cachedAllies) const; }; }