mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-01 01:45:36 +00:00
Add methods to disable an animation
And rename WeaponState to WeaponType
This commit is contained in:
parent
6605aa7dec
commit
6b8a687a79
5 changed files with 81 additions and 64 deletions
|
@ -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…
Reference in a new issue