Closes #1106: Move stance to CreatureStats, since creatures also have separate run/walk animations.

actorid
scrawl 11 years ago
parent 0a8c61a7fe
commit da3295d69c

@ -775,7 +775,7 @@ namespace MWClass
}
if(getCreatureStats(ptr).isDead())
return boost::shared_ptr<MWWorld::Action>(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<MWWorld::Action>(new MWWorld::ActionOpen(ptr)); // stealing
if(get(ptr).getCreatureStats(ptr).isHostile())
return boost::shared_ptr<MWWorld::Action>(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*/

@ -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.

@ -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();

@ -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();

@ -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
}
}

@ -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<std::string, MWWorld::TimeStamp> 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;

@ -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))
{

@ -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::Attribute::Length; ++i)
mSkillIncreases[i] = 0;
mSkillIncreases.resize (ESM::Attribute::Length, 0);
}
MWMechanics::DrawState_ MWMechanics::NpcStats::getDrawState() const
@ -69,19 +66,6 @@ void MWMechanics::NpcStats::setBaseDisposition(int disposition)
mDisposition = disposition;
}
bool MWMechanics::NpcStats::getMovementFlag (Flag flag) const
{
return mMovementFlags & flag;
}
void MWMechanics::NpcStats::setMovementFlag (Flag flag, bool state)
{
if (state)
mMovementFlags |= flag;
else
mMovementFlags &= ~flag;
}
const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index) const
{
if (index<0 || index>=ESM::Skill::Length)

@ -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);

@ -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);

@ -76,34 +76,34 @@ namespace MWScript
template<class R>
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 R>
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<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
new OpClearMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
interpreter.installSegment5 (Compiler::Control::opcodeForceRun,
new OpSetMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
new OpSetMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneak,
new OpClearMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
new OpClearMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
interpreter.installSegment5 (Compiler::Control::opcodeForceSneak,
new OpSetMovementFlag<ImplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
new OpSetMovementFlag<ImplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
interpreter.installSegment5 (Compiler::Control::opcodeClearForceRunExplicit,
new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
new OpClearMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
interpreter.installSegment5 (Compiler::Control::opcodeForceRunExplicit,
new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceRun));
new OpSetMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceRun));
interpreter.installSegment5 (Compiler::Control::opcodeClearForceSneakExplicit,
new OpClearMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
new OpClearMovementFlag<ExplicitRef> (MWMechanics::CreatureStats::Flag_ForceSneak));
interpreter.installSegment5 (Compiler::Control::opcodeForceSneakExplicit,
new OpSetMovementFlag<ExplicitRef> (MWMechanics::NpcStats::Flag_ForceSneak));
new OpSetMovementFlag<ExplicitRef> (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<ImplicitRef>);

@ -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;

@ -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.

@ -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);

Loading…
Cancel
Save