Add methods to disable an animation

And rename WeaponState to WeaponType
actorid
Chris Robinson 12 years ago
parent 6605aa7dec
commit 6b8a687a79

@ -92,21 +92,21 @@ static const struct {
static const size_t sStateListSize = sizeof(sStateList)/sizeof(sStateList[0]); static const size_t sStateListSize = sizeof(sStateList)/sizeof(sStateList[0]);
static const struct { static const struct {
WeaponState state; WeaponType type;
const char idlegroup[16]; const char idlegroup[16];
const char movementgroup[16]; const char movementgroup[16];
const char actiongroup[16]; const char actiongroup[16];
} sWeaponStateList[] = { } sWeaponTypeList[] = {
{ WeapState_HandToHand, "hh", "hh", "handtohand" }, { WeapType_HandToHand, "hh", "hh", "handtohand" },
{ WeapState_OneHand, "1h", "1h", "weapononehand" }, { WeapType_OneHand, "1h", "1h", "weapononehand" },
{ WeapState_TwoHand, "2c", "2c", "weapontwohand" }, { WeapType_TwoHand, "2c", "2c", "weapontwohand" },
{ WeapState_TwoWide, "2w", "2w", "weapontwowide" }, { WeapType_TwoWide, "2w", "2w", "weapontwowide" },
{ WeapState_BowAndArrow, "1h", "1h", "bowandarrow" }, { WeapType_BowAndArrow, "1h", "1h", "bowandarrow" },
{ WeapState_Crossbow, "crossbow", "2c", "crossbow" }, { WeapType_Crossbow, "crossbow", "2c", "crossbow" },
{ WeapState_ThowWeapon, "1h", "1h", "throwweapon" }, { WeapType_ThowWeapon, "1h", "1h", "throwweapon" },
{ WeapState_Spell, "spell", "", "spellcast" }, { WeapType_Spell, "spell", "", "spellcast" },
}; };
static const size_t sWeaponStateListSize = sizeof(sWeaponStateList)/sizeof(sWeaponStateList[0]); static const size_t sWeaponTypeListSize = sizeof(sWeaponTypeList)/sizeof(sWeaponTypeList[0]);
void CharacterController::getCurrentGroup(std::string &group) const void CharacterController::getCurrentGroup(std::string &group) const
@ -123,16 +123,16 @@ void CharacterController::getCurrentGroup(std::string &group) const
if(name.empty()) if(name.empty())
throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mCharState)); throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mCharState));
if(!(mCharState >= CharState_Death1) && mWeapState != WeapState_None) if(!(mCharState >= CharState_Death1) && mWeaponType != WeapType_None)
{ {
for(size_t i = 0;i < sWeaponStateListSize;i++) for(size_t i = 0;i < sWeaponTypeListSize;i++)
{ {
if(sWeaponStateList[i].state == mWeapState) if(sWeaponTypeList[i].type == mWeaponType)
{ {
if(mCharState == CharState_Idle) if(mCharState == CharState_Idle)
(group=name) += sWeaponStateList[i].idlegroup; (group=name) += sWeaponTypeList[i].idlegroup;
else else
(group=name) += sWeaponStateList[i].movementgroup; (group=name) += sWeaponTypeList[i].movementgroup;
break; break;
} }
} }
@ -147,7 +147,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
: mPtr(ptr) : mPtr(ptr)
, mAnimation(anim) , mAnimation(anim)
, mCharState(state) , mCharState(state)
, mWeapState(WeapState_None) , mWeaponType(WeapType_None)
, mSkipAnim(false) , mSkipAnim(false)
, mMovingAnim(false) , mMovingAnim(false)
, mSecondsOfRunning(0) , mSecondsOfRunning(0)
@ -172,7 +172,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
std::string group; std::string group;
getCurrentGroup(group); getCurrentGroup(group);
mMovingAnim = mAnimation->play(group, MWRender::Animation::Priority_Default, mMovingAnim = mAnimation->play(group, MWRender::Animation::Priority_Default,
MWRender::Animation::Group_All, MWRender::Animation::Group_All, false,
"start", "stop", 1.0f, loop ? (~(size_t)0) : 0); "start", "stop", 1.0f, loop ? (~(size_t)0) : 0);
} }
@ -229,21 +229,21 @@ void CharacterController::update(float duration, Movement &movement)
if(mPtr.getTypeName() == typeid(ESM::NPC).name()) if(mPtr.getTypeName() == typeid(ESM::NPC).name())
{ {
NpcStats &stats = cls.getNpcStats(mPtr); NpcStats &stats = cls.getNpcStats(mPtr);
WeaponState weapstate = WeapState_None; WeaponType weaptype = WeapType_None;
if(stats.getDrawState() == DrawState_Spell) if(stats.getDrawState() == DrawState_Spell)
weapstate = WeapState_Spell; weaptype = WeapType_Spell;
else if(stats.getDrawState() == MWMechanics::DrawState_Weapon) else if(stats.getDrawState() == MWMechanics::DrawState_Weapon)
{ {
MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr);
MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if(weapon == inv.end()) if(weapon == inv.end())
weapstate = WeapState_HandToHand; weaptype = WeapType_HandToHand;
else else
{ {
const std::string &type = weapon->getTypeName(); const std::string &type = weapon->getTypeName();
if(type == typeid(ESM::Lockpick).name() || type == typeid(ESM::Probe).name()) if(type == typeid(ESM::Lockpick).name() || type == typeid(ESM::Probe).name())
weapstate = WeapState_OneHand; weaptype = WeapType_OneHand;
else if(type == typeid(ESM::Weapon).name()) else if(type == typeid(ESM::Weapon).name())
{ {
MWWorld::LiveCellRef<ESM::Weapon> *ref = weapon->get<ESM::Weapon>(); MWWorld::LiveCellRef<ESM::Weapon> *ref = weapon->get<ESM::Weapon>();
@ -256,32 +256,36 @@ void CharacterController::update(float duration, Movement &movement)
case ESM::Weapon::AxeOneHand: case ESM::Weapon::AxeOneHand:
case ESM::Weapon::Arrow: case ESM::Weapon::Arrow:
case ESM::Weapon::Bolt: case ESM::Weapon::Bolt:
weapstate = WeapState_OneHand; weaptype = WeapType_OneHand;
break; break;
case ESM::Weapon::LongBladeTwoHand: case ESM::Weapon::LongBladeTwoHand:
case ESM::Weapon::BluntTwoClose: case ESM::Weapon::BluntTwoClose:
case ESM::Weapon::AxeTwoHand: case ESM::Weapon::AxeTwoHand:
weapstate = WeapState_TwoHand; weaptype = WeapType_TwoHand;
break; break;
case ESM::Weapon::BluntTwoWide: case ESM::Weapon::BluntTwoWide:
case ESM::Weapon::SpearTwoWide: case ESM::Weapon::SpearTwoWide:
weapstate = WeapState_TwoWide; weaptype = WeapType_TwoWide;
break; break;
case ESM::Weapon::MarksmanBow: case ESM::Weapon::MarksmanBow:
weapstate = WeapState_BowAndArrow; weaptype = WeapType_BowAndArrow;
break; break;
case ESM::Weapon::MarksmanCrossbow: case ESM::Weapon::MarksmanCrossbow:
weapstate = WeapState_Crossbow; weaptype = WeapType_Crossbow;
break; break;
case ESM::Weapon::MarksmanThrown: case ESM::Weapon::MarksmanThrown:
weapstate = WeapState_ThowWeapon; weaptype = WeapType_ThowWeapon;
break; break;
} }
} }
} }
} }
setWeaponState(weapstate); if(weaptype != mWeaponType)
{
mWeaponType = weaptype;
forceStateUpdate();
}
} }
/* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except
@ -349,7 +353,7 @@ void CharacterController::update(float duration, Movement &movement)
{ {
mMovingAnim = mAnimation->play(mAnimQueue.front().first, mMovingAnim = mAnimation->play(mAnimQueue.front().first,
MWRender::Animation::Priority_Default, MWRender::Animation::Priority_Default,
MWRender::Animation::Group_All, MWRender::Animation::Group_All, false,
"start", "stop", 0.0f, "start", "stop", 0.0f,
mAnimQueue.front().second); mAnimQueue.front().second);
mAnimQueue.pop_front(); mAnimQueue.pop_front();
@ -386,7 +390,7 @@ void CharacterController::playGroup(const std::string &groupname, int mode, int
mCharState = CharState_SpecialIdle; mCharState = CharState_SpecialIdle;
mLooping = false; mLooping = false;
mMovingAnim = mAnimation->play(groupname, MWRender::Animation::Priority_Default, mMovingAnim = mAnimation->play(groupname, MWRender::Animation::Priority_Default,
MWRender::Animation::Group_All, MWRender::Animation::Group_All, false,
((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1); ((mode==2) ? "loop start" : "start"), "stop", 0.0f, count-1);
} }
else if(mode == 0) else if(mode == 0)
@ -413,15 +417,6 @@ void CharacterController::setState(CharacterState state, bool loop)
forceStateUpdate(); forceStateUpdate();
} }
void CharacterController::setWeaponState(WeaponState state)
{
if(state == mWeapState)
return;
mWeapState = state;
forceStateUpdate();
}
void CharacterController::forceStateUpdate() void CharacterController::forceStateUpdate()
{ {
if(!mAnimation) if(!mAnimation)
@ -431,11 +426,11 @@ void CharacterController::forceStateUpdate()
std::string group; std::string group;
getCurrentGroup(group); getCurrentGroup(group);
mMovingAnim = mAnimation->play(group, MWRender::Animation::Priority_Default, mMovingAnim = mAnimation->play(group, MWRender::Animation::Priority_Default,
MWRender::Animation::Group_All, MWRender::Animation::Group_All, false,
"start", "stop", 0.0f, mLooping ? (~(size_t)0) : 0); "start", "stop", 0.0f, mLooping ? (~(size_t)0) : 0);
mAnimation->showWeapons(mWeapState != WeapState_None && mWeapState != WeapState_HandToHand && mAnimation->showWeapons(mWeaponType != WeapType_None && mWeaponType != WeapType_HandToHand &&
mWeapState != WeapState_Spell); mWeaponType != WeapType_Spell);
} }
} }

@ -67,18 +67,18 @@ enum CharacterState {
CharState_Death5 CharState_Death5
}; };
enum WeaponState { enum WeaponType {
WeapState_None, WeapType_None,
WeapState_HandToHand, WeapType_HandToHand,
WeapState_OneHand, WeapType_OneHand,
WeapState_TwoHand, WeapType_TwoHand,
WeapState_TwoWide, WeapType_TwoWide,
WeapState_BowAndArrow, WeapType_BowAndArrow,
WeapState_Crossbow, WeapType_Crossbow,
WeapState_ThowWeapon, WeapType_ThowWeapon,
WeapState_Spell WeapType_Spell
}; };
class CharacterController class CharacterController
@ -90,7 +90,7 @@ class CharacterController
AnimationQueue mAnimQueue; AnimationQueue mAnimQueue;
CharacterState mCharState; CharacterState mCharState;
WeaponState mWeapState; WeaponType mWeaponType;
bool mLooping; bool mLooping;
bool mSkipAnim; bool mSkipAnim;
@ -118,10 +118,6 @@ public:
CharacterState getState() const CharacterState getState() const
{ return mCharState; } { return mCharState; }
void setWeaponState(WeaponState state);
WeaponState getWeaponState() const
{ return mWeapState; }
void forceStateUpdate(); void forceStateUpdate();
}; };

@ -481,7 +481,7 @@ bool Animation::handleTextKey(AnimState &state, const std::string &groupname, co
} }
bool Animation::play(const std::string &groupname, Priority priority, int groups, const std::string &start, const std::string &stop, float startpoint, size_t loops) bool Animation::play(const std::string &groupname, Priority priority, int groups, bool autodisable, const std::string &start, const std::string &stop, float startpoint, size_t loops)
{ {
if(!mSkelBase) if(!mSkelBase)
return false; return false;
@ -517,6 +517,7 @@ bool Animation::play(const std::string &groupname, Priority priority, int groups
state.mPlaying = true; state.mPlaying = true;
state.mPriority = priority; state.mPriority = priority;
state.mGroups = groups; state.mGroups = groups;
state.mAutoDisable = autodisable;
mStates[groupname] = state; mStates[groupname] = state;
break; break;
@ -617,13 +618,22 @@ bool Animation::getInfo(const std::string &groupname, float *complete, std::stri
} }
bool Animation::disable(const std::string &groupname)
{
AnimStateMap::iterator iter = mStates.find(groupname);
if(iter != mStates.end())
mStates.erase(iter);
return resetActiveGroups();
}
Ogre::Vector3 Animation::runAnimation(float duration) Ogre::Vector3 Animation::runAnimation(float duration)
{ {
Ogre::Vector3 movement(0.0f); Ogre::Vector3 movement(0.0f);
duration *= mAnimSpeedMult; duration *= mAnimSpeedMult;
AnimStateMap::iterator stateiter = mStates.begin(); AnimStateMap::iterator stateiter = mStates.begin();
for(;stateiter != mStates.end();stateiter++) while(stateiter != mStates.end())
{ {
AnimState &state = stateiter->second; AnimState &state = stateiter->second;
float timepassed = duration; float timepassed = duration;
@ -649,6 +659,11 @@ Ogre::Vector3 Animation::runAnimation(float duration)
if(!handleTextKey(state, stateiter->first, key)) if(!handleTextKey(state, stateiter->first, key))
break; break;
} }
if(!state.mPlaying && state.mAutoDisable)
mStates.erase(stateiter++);
else
stateiter++;
} }
for(size_t i = 0;i < mObjectRoot.mControllers.size();i++) for(size_t i = 0;i < mObjectRoot.mControllers.size();i++)

@ -73,6 +73,7 @@ protected:
int mPriority; int mPriority;
int mGroups; int mGroups;
bool mAutoDisable;
AnimState() : mSource(NULL), mTime(0.0f), mPlaying(false), mLoopCount(0) AnimState() : mSource(NULL), mTime(0.0f), mPlaying(false), mLoopCount(0)
{ } { }
@ -162,6 +163,8 @@ public:
* bone groups that don't have another animation set of a * bone groups that don't have another animation set of a
* higher priority. * higher priority.
* \param groups Bone groups to play the animation on. * \param groups Bone groups to play the animation on.
* \param autodisable Automatically disable the animation when it stops
* playing.
* \param start Key marker from which to start. * \param start Key marker from which to start.
* \param stop Key marker to stop at. * \param stop Key marker to stop at.
* \param startpoint How far in between the two markers to start. 0 starts * \param startpoint How far in between the two markers to start. 0 starts
@ -172,7 +175,7 @@ public:
* \return Boolean specifying whether the animation will return movement * \return Boolean specifying whether the animation will return movement
* for the character at all. * for the character at all.
*/ */
bool play(const std::string &groupname, Priority priority, int groups, bool play(const std::string &groupname, Priority priority, int groups, bool autodisable,
const std::string &start, const std::string &stop, const std::string &start, const std::string &stop,
float startpoint, size_t loops); float startpoint, size_t loops);
@ -185,6 +188,13 @@ public:
*/ */
bool getInfo(const std::string &groupname, float *complete=NULL, std::string *start=NULL, std::string *stop=NULL) const; bool getInfo(const std::string &groupname, float *complete=NULL, std::string *start=NULL, std::string *stop=NULL) const;
/** Disables the specified animation group;
* \param groupname Animation group to disable.
* \return Boolean specifying whether the animation will continue to return
* movement for the character at all.
*/
bool disable(const std::string &groupname);
virtual Ogre::Vector3 runAnimation(float duration); virtual Ogre::Vector3 runAnimation(float duration);
virtual void showWeapons(bool showWeapon); virtual void showWeapons(bool showWeapon);

@ -173,7 +173,7 @@ namespace MWRender
{ {
mCurrentAnimGroup = groupname; mCurrentAnimGroup = groupname;
mAnimation->play(mCurrentAnimGroup, Animation::Priority_Default, mAnimation->play(mCurrentAnimGroup, Animation::Priority_Default,
Animation::Group_All, "start", "stop", 0.0f, 0); Animation::Group_All, false, "start", "stop", 0.0f, 0);
} }
mAnimation->forceUpdate(); mAnimation->forceUpdate();
@ -201,7 +201,7 @@ namespace MWRender
mCurrentAnimGroup = "inventoryhandtohand"; mCurrentAnimGroup = "inventoryhandtohand";
mAnimation->play(mCurrentAnimGroup, Animation::Priority_Default, mAnimation->play(mCurrentAnimGroup, Animation::Priority_Default,
Animation::Group_All, "start", "stop", 0.0f, 0); Animation::Group_All, false, "start", "stop", 0.0f, 0);
} }
// -------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------
@ -235,7 +235,8 @@ namespace MWRender
void RaceSelectionPreview::onSetup () void RaceSelectionPreview::onSetup ()
{ {
mAnimation->play("idle", Animation::Priority_Default, Animation::Group_All, "start", "stop", 0.0f, 0); mAnimation->play("idle", Animation::Priority_Default, Animation::Group_All,
false, "start", "stop", 0.0f, 0);
updateCamera(); updateCamera();
} }

Loading…
Cancel
Save