diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e6e1e1892..c89822843 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -775,7 +775,7 @@ namespace MWClass } if(getCreatureStats(ptr).isDead()) return boost::shared_ptr(new MWWorld::ActionOpen(ptr, true)); - if(get(actor).getStance(actor, MWWorld::Class::Sneak)) + if(getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak)) return boost::shared_ptr(new MWWorld::ActionOpen(ptr)); // stealing if(get(ptr).getCreatureStats(ptr).isHostile()) return boost::shared_ptr(new MWWorld::FailedAction("#{sActorInCombat}")); @@ -806,66 +806,6 @@ namespace MWClass return ref->mBase->mScript; } - void Npc::setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const - { - MWMechanics::NpcStats& stats = getNpcStats (ptr); - - switch (stance) - { - case Run: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceRun, force); - break; - - case Sneak: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak, force); - break; - } - } - - void Npc::setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const - { - MWMechanics::NpcStats& stats = getNpcStats (ptr); - - switch (stance) - { - case Run: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_Run, set); - break; - - case Sneak: - - stats.setMovementFlag (MWMechanics::NpcStats::Flag_Sneak, set); - break; - } - } - - bool Npc::getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce) const - { - MWMechanics::NpcStats& stats = getNpcStats (ptr); - - switch (stance) - { - case Run: - - if (!ignoreForce && stats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)) - return true; - - return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Run); - - case Sneak: - - if (!ignoreForce && stats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)) - return true; - - return stats.getMovementFlag (MWMechanics::NpcStats::Flag_Sneak); - } - - return false; - } - float Npc::getSpeed(const MWWorld::Ptr& ptr) const { const MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -874,11 +814,14 @@ namespace MWClass const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr); + bool sneaking = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak); + bool running = ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run); + float walkSpeed = fMinWalkSpeed->getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()* (fMaxWalkSpeed->getFloat() - fMinWalkSpeed->getFloat()); walkSpeed *= 1.0f - fEncumberedMoveEffect->getFloat()*normalizedEncumbrance; walkSpeed = std::max(0.0f, walkSpeed); - if(Npc::getStance(ptr, Sneak, false)) + if(sneaking) walkSpeed *= fSneakSpeedMultiplier->getFloat(); float runSpeed = walkSpeed*(0.01f * npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified() * @@ -902,14 +845,14 @@ namespace MWClass else if(world->isSwimming(ptr)) { float swimSpeed = walkSpeed; - if(Npc::getStance(ptr, Run, false)) + if(running) swimSpeed = runSpeed; swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).mMagnitude; swimSpeed *= fSwimRunBase->getFloat() + 0.01f*npcdata->mNpcStats.getSkill(ESM::Skill::Athletics).getModified()* fSwimRunAthleticsMult->getFloat(); moveSpeed = swimSpeed; } - else if(Npc::getStance(ptr, Run, false) && !Npc::getStance(ptr, Sneak, false)) + else if(running && !sneaking) moveSpeed = runSpeed; else moveSpeed = walkSpeed; @@ -941,7 +884,7 @@ namespace MWClass x += mageffects.get(ESM::MagicEffect::Jump).mMagnitude * 64; x *= encumbranceTerm; - if(Npc::getStance(ptr, Run, false)) + if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)) x *= fJumpRunMultiplier->getFloat(); x *= npcdata->mNpcStats.getFatigueTerm(); x -= -627.2f;/*gravity constant*/ diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 22a9632e8..9977866cd 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -84,16 +84,6 @@ namespace MWClass virtual std::string getScript (const MWWorld::Ptr& ptr) const; ///< Return name of the script attached to ptr - virtual void setForceStance (const MWWorld::Ptr& ptr, Stance stance, bool force) const; - ///< Force or unforce a stance. - - virtual void setStance (const MWWorld::Ptr& ptr, Stance stance, bool set) const; - ///< Set or unset a stance. - - virtual bool getStance (const MWWorld::Ptr& ptr, Stance stance, bool ignoreForce = false) - const; - ///< Check if a stance is active or not. - virtual float getSpeed (const MWWorld::Ptr& ptr) const; ///< Return movement speed. diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 62158fb12..42b618143 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -40,13 +40,13 @@ namespace MWMechanics if(MWWorld::Class::get(actor).getCreatureStats(actor).getHealth().getCurrent() <= 0) return true; + actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true); + if(actor.getTypeName() == typeid(ESM::NPC).name()) { - MWWorld::Class::get(actor). - MWWorld::Class::get(actor).setStance(actor, MWWorld::Class::Run,true); - MWMechanics::DrawState_ state = MWWorld::Class::get(actor).getNpcStats(actor).getDrawState(); + MWMechanics::DrawState_ state = actor.getClass().getNpcStats(actor).getDrawState(); if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) - MWWorld::Class::get(actor).getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); + actor.getClass().getNpcStats(actor).setDrawState(MWMechanics::DrawState_Weapon); //MWWorld::Class::get(actor).getCreatureStats(actor).setAttackingOrSpell(true); } ESM::Position pos = actor.getRefData().getPosition(); diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 07859d57c..580b71731 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -859,8 +859,8 @@ void CharacterController::update(float duration) { bool onground = world->isOnGround(mPtr); bool inwater = world->isSwimming(mPtr); - bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run); - bool sneak = cls.getStance(mPtr, MWWorld::Class::Sneak); + bool isrunning = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run); + bool sneak = cls.getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool flying = world->isFlying(mPtr); Ogre::Vector3 vec = cls.getMovementVector(mPtr); vec.normalise(); diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index ba6f0ba04..8d37e34c8 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -15,7 +15,8 @@ namespace MWMechanics mAttacked (false), mHostile (false), mAttackingOrSpell(false), mAttackType(AT_Chop), mIsWerewolf(false), - mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false) + mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mHitRecovery(false), + mMovementFlags(0) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -425,4 +426,30 @@ namespace MWMechanics { return mHitRecovery; } + + bool CreatureStats::getMovementFlag (Flag flag) const + { + return mMovementFlags & flag; + } + + void CreatureStats::setMovementFlag (Flag flag, bool state) + { + if (state) + mMovementFlags |= flag; + else + mMovementFlags &= ~flag; + } + + bool CreatureStats::getStance(Stance flag) const + { + switch (flag) + { + case Stance_Run: + return getMovementFlag (Flag_Run) || getMovementFlag (Flag_ForceRun); + case Stance_Sneak: + return getMovementFlag (Flag_Sneak) || getMovementFlag (Flag_ForceSneak); + } + return false; // shut up, compiler + } + } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 1f82a9b5c..26856c966 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -37,6 +37,7 @@ namespace MWMechanics bool mAttackingOrSpell; bool mKnockdown; bool mHitRecovery; + unsigned int mMovementFlags; float mFallHeight; @@ -47,6 +48,7 @@ namespace MWMechanics // Do we need to recalculate stats derived from attributes or other factors? bool mRecalcDynamicStats; + std::map mUsedPowers; protected: bool mIsWerewolf; @@ -193,6 +195,24 @@ namespace MWMechanics void setHitRecovery(bool value); bool getHitRecovery() const; + enum Flag + { + Flag_ForceRun = 1, + Flag_ForceSneak = 2, + Flag_Run = 4, + Flag_Sneak = 8 + }; + enum Stance + { + Stance_Run, + Stance_Sneak + }; + + bool getMovementFlag (Flag flag) const; + void setMovementFlag (Flag flag, bool state); + /// Like getMovementFlag, but also takes into account if the flag is Forced + bool getStance (Stance flag) const; + void setLastHitObject(const std::string &objectid); const std::string &getLastHitObject() const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 79a038dff..4514c077c 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -896,7 +896,7 @@ namespace MWMechanics return false; float sneakTerm = 0; - if (ptr.getClass().getStance(ptr, MWWorld::Class::Sneak) + if (ptr.getClass().getCreatureStats(ptr).getStance(CreatureStats::Stance_Sneak) && !MWBase::Environment::get().getWorld()->isSwimming(ptr) && MWBase::Environment::get().getWorld()->isOnGround(ptr)) { diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index f77b04271..293b078da 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -22,8 +22,7 @@ #include "../mwbase/soundmanager.hpp" MWMechanics::NpcStats::NpcStats() -: mMovementFlags (0) -, mDrawState (DrawState_Nothing) +: mDrawState (DrawState_Nothing) , mBounty (0) , mLevelProgress(0) , mDisposition(0) @@ -34,9 +33,7 @@ MWMechanics::NpcStats::NpcStats() , mTimeToStartDrowning(20.0) , mLastDrowningHit(0) { - mSkillIncreases.resize (ESM::Attribute::Length); - for (int i=0; i=ESM::Skill::Length) diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 5fd358c85..b89a2b4b3 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -25,18 +25,6 @@ namespace MWMechanics class NpcStats : public CreatureStats { - public: - - enum Flag - { - Flag_ForceRun = 1, - Flag_ForceSneak = 2, - Flag_Run = 4, - Flag_Sneak = 8 - }; - - private: - /// NPCs other than the player can only have one faction. But for the sake of consistency /// we use the same data structure for the PC and the NPCs. /// \note the faction key must be in lowercase @@ -44,7 +32,6 @@ namespace MWMechanics DrawState_ mDrawState; int mDisposition; - unsigned int mMovementFlags; SkillValue mSkill[27]; SkillValue mWerewolfSkill[27]; int mBounty; @@ -89,10 +76,6 @@ namespace MWMechanics void setReputation(int reputation); - bool getMovementFlag (Flag flag) const; - - void setMovementFlag (Flag flag, bool state); - const SkillValue& getSkill (int index) const; SkillValue& getSkill (int index); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 0c5e053c9..47cf3ee41 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -347,7 +347,7 @@ void RenderingManager::update (float duration, bool paused) } // Sink the camera while sneaking - bool isSneaking = MWWorld::Class::get(player).getStance(player, MWWorld::Class::Sneak); + bool isSneaking = player.getClass().getCreatureStats(player).getStance(MWMechanics::CreatureStats::Stance_Sneak); bool isInAir = !world->isOnGround(player); bool isSwimming = world->isSwimming(player); diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index 7697ab619..d2e774859 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -76,34 +76,34 @@ namespace MWScript template class OpClearMovementFlag : public Interpreter::Opcode0 { - MWMechanics::NpcStats::Flag mFlag; + MWMechanics::CreatureStats::Flag mFlag; public: - OpClearMovementFlag (MWMechanics::NpcStats::Flag flag) : mFlag (flag) {} + OpClearMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWWorld::Class::get (ptr).getNpcStats (ptr).setMovementFlag (mFlag, false); + ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, false); } }; template class OpSetMovementFlag : public Interpreter::Opcode0 { - MWMechanics::NpcStats::Flag mFlag; + MWMechanics::CreatureStats::Flag mFlag; public: - OpSetMovementFlag (MWMechanics::NpcStats::Flag flag) : mFlag (flag) {} + OpSetMovementFlag (MWMechanics::CreatureStats::Flag flag) : mFlag (flag) {} virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); - MWWorld::Class::get (ptr).getNpcStats (ptr).setMovementFlag (mFlag, true); + ptr.getClass().getCreatureStats(ptr).setMovementFlag (mFlag, true); } }; @@ -116,9 +116,8 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWMechanics::NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats (ptr); - - runtime.push (npcStats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr); + runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); } }; @@ -131,9 +130,8 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - MWMechanics::NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats (ptr); - - runtime.push (npcStats.getMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); + runtime.push (stats.getMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); } }; @@ -144,7 +142,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Run)); + runtime.push (ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Run)); } }; @@ -155,7 +153,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - runtime.push (MWWorld::Class::get(ptr).getStance (ptr, MWWorld::Class::Sneak)); + runtime.push (ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak)); } }; @@ -172,22 +170,22 @@ namespace MWScript interpreter.installSegment5 (Compiler::Control::opcodeToggleCollision, new OpToggleCollision); interpreter.installSegment5 (Compiler::Control::opcodeClearForceRun, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeForceRun, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneak, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeForceSneak, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeClearForceRunExplicit, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeForceRunExplicit, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceRun)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceRun)); interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneakExplicit, - new OpClearMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpClearMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeForceSneakExplicit, - new OpSetMovementFlag (MWMechanics::NpcStats::Flag_ForceSneak)); + new OpSetMovementFlag (MWMechanics::CreatureStats::Flag_ForceSneak)); interpreter.installSegment5 (Compiler::Control::opcodeGetPcRunning, new OpGetPcRunning); interpreter.installSegment5 (Compiler::Control::opcodeGetPcSneaking, new OpGetPcSneaking); interpreter.installSegment5 (Compiler::Control::opcodeGetForceRun, new OpGetForceRun); diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index 934dae015..07bd90571 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -147,21 +147,6 @@ namespace MWWorld return ""; } - void Class::setForceStance (const Ptr& ptr, Stance stance, bool force) const - { - throw std::runtime_error ("stance not supported by class"); - } - - void Class::setStance (const Ptr& ptr, Stance stance, bool set) const - { - throw std::runtime_error ("stance not supported by class"); - } - - bool Class::getStance (const Ptr& ptr, Stance stance, bool ignoreForce) const - { - return false; - } - float Class::getSpeed (const Ptr& ptr) const { return 0; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index a752f76a7..5c1c063a3 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -168,15 +168,6 @@ namespace MWWorld ///< Return name of the script attached to ptr (default implementation: return an empty /// string). - virtual void setForceStance (const Ptr& ptr, Stance stance, bool force) const; - ///< Force or unforce a stance. - - virtual void setStance (const Ptr& ptr, Stance stance, bool set) const; - ///< Set or unset a stance. - - virtual bool getStance (const Ptr& ptr, Stance stance, bool ignoreForce = false) const; - ///< Check if a stance is active or not. - virtual float getSpeed (const Ptr& ptr) const; ///< Return movement speed. diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index c59445402..3ea6c62f8 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -114,14 +114,14 @@ namespace MWWorld void Player::setRunState(bool run) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get(ptr).setStance(ptr, MWWorld::Class::Run, run); + ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Run, run); } void Player::setSneak(bool sneak) { MWWorld::Ptr ptr = getPlayer(); - MWWorld::Class::get (ptr).setStance (ptr, MWWorld::Class::Sneak, sneak); + ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak); // TODO show sneak indicator only when the player is not detected by any actor MWBase::Environment::get().getWindowManager()->setSneakVisibility(sneak);