Track death separately in the character controller

actorid
Chris Robinson 12 years ago
parent 4ae65c20e6
commit 06e631f213

@ -168,13 +168,10 @@ namespace MWMechanics
void Actors::addActor (const MWWorld::Ptr& ptr)
{
// erase previous death events since we are currently only tracking them while in an active cell
MWWorld::Class::get (ptr).getCreatureStats (ptr).clearHasDied();
MWWorld::Class::get(ptr).getCreatureStats(ptr).clearHasDied();
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if(!MWWorld::Class::get(ptr).getCreatureStats(ptr).isDead())
mActors.insert(std::make_pair(ptr, new CharacterController(ptr, anim, CharState_Idle)));
else
mActors.insert(std::make_pair(ptr, new CharacterController(ptr, anim, CharState_Death1)));
mActors.insert(std::make_pair(ptr, new CharacterController(ptr, anim)));
}
void Actors::removeActor (const MWWorld::Ptr& ptr)
@ -228,8 +225,8 @@ namespace MWMechanics
{
if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
{
if(iter->second->getState() >= CharState_Death1)
iter->second->setState(CharState_Idle);
if(iter->second->isDead())
iter->second->resurrect();
updateActor(iter->first, totalDuration);
if(iter->first.getTypeName() == typeid(ESM::NPC).name())
@ -256,10 +253,10 @@ namespace MWMechanics
continue;
}
if(iter->second->getState() >= CharState_Death1)
if(iter->second->isDead())
continue;
iter->second->setState(CharState_Death1);
iter->second->kill();
++mDeathCount[MWWorld::Class::get(iter->first).getId(iter->first)];

@ -221,12 +221,12 @@ void CharacterController::getWeaponGroup(WeaponType weaptype, std::string &group
}
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state)
CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim)
: mPtr(ptr)
, mAnimation(anim)
, mIdleState(CharState_Idle)
, mMovementState(CharState_None)
, mCharState(state)
, mDeathState(CharState_None)
, mWeaponType(WeapType_None)
, mSkipAnim(false)
, mSecondsOfRunning(0)
@ -241,6 +241,12 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
/* Accumulate along X/Y only for now, until we can figure out how we should
* handle knockout and death which moves the character down. */
mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f));
if(MWWorld::Class::get(mPtr).getCreatureStats(mPtr).isDead())
{
/* FIXME: Get the actual death state used. */
mDeathState = CharState_Death1;
}
}
else
{
@ -249,13 +255,14 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
}
refreshCurrentAnims(mIdleState, mMovementState, true);
if(mCharState >= CharState_Death1)
if(mDeathState != CharState_None)
{
const StateInfo *state = std::find_if(sStateList, sStateListEnd, FindCharState(mCharState));
const StateInfo *state = std::find_if(sStateList, sStateListEnd, FindCharState(mDeathState));
if(state == sStateListEnd)
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(mDeathState));
mAnimation->play(state->groupname, Priority_Death, MWRender::Animation::Group_All,
mCurrentDeath = state->groupname;
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All,
false, "start", "stop", 1.0f, 0);
}
}
@ -608,15 +615,6 @@ void CharacterController::clearAnimQueue()
}
void CharacterController::setState(CharacterState state)
{
if(mCharState == state)
return;
mCharState = state;
forceStateUpdate();
}
void CharacterController::forceStateUpdate()
{
if(!mAnimation)
@ -624,16 +622,49 @@ void CharacterController::forceStateUpdate()
clearAnimQueue();
refreshCurrentAnims(mIdleState, mMovementState, true);
if(mCharState >= CharState_Death1)
if(mDeathState != CharState_None)
{
const StateInfo *state = std::find_if(sStateList, sStateListEnd, FindCharState(mCharState));
const StateInfo *state = std::find_if(sStateList, sStateListEnd, FindCharState(mDeathState));
if(state == sStateListEnd)
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(mDeathState));
if(!mAnimation->getInfo(state->groupname))
mAnimation->play(state->groupname, Priority_Death, MWRender::Animation::Group_All,
mCurrentDeath = state->groupname;
if(!mAnimation->getInfo(mCurrentDeath))
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All,
false, "start", "stop", 0.0f, 0);
}
}
void CharacterController::kill()
{
static const CharacterState deathstates[] = {
CharState_Death1, CharState_Death2, CharState_Death3, CharState_Death4, CharState_Death5
};
if(mDeathState != CharState_None)
return;
mDeathState = deathstates[(int)(rand()/((double)RAND_MAX+1.0)*5.0)];
const StateInfo *state = std::find_if(sStateList, sStateListEnd, FindCharState(mDeathState));
if(state == sStateListEnd)
throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mDeathState));
mCurrentDeath = state->groupname;
if(mAnimation && !mAnimation->getInfo(mCurrentDeath))
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All,
false, "start", "stop", 0.0f, 0);
}
void CharacterController::resurrect()
{
if(mDeathState == CharState_None)
return;
if(mAnimation)
mAnimation->disable(mCurrentDeath);
mCurrentDeath.empty();
mDeathState = CharState_None;
}
}

@ -108,7 +108,9 @@ class CharacterController
CharacterState mMovementState;
std::string mCurrentMovement;
CharacterState mCharState;
CharacterState mDeathState;
std::string mCurrentDeath;
WeaponType mWeaponType;
bool mSkipAnim;
@ -126,7 +128,7 @@ class CharacterController
void clearAnimQueue();
public:
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state);
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
virtual ~CharacterController();
void updatePtr(const MWWorld::Ptr &ptr);
@ -137,9 +139,10 @@ public:
void skipAnim();
bool isAnimPlaying(const std::string &groupName);
void setState(CharacterState state);
CharacterState getState() const
{ return mCharState; }
void kill();
void resurrect();
bool isDead() const
{ return mDeathState != CharState_None; }
void forceStateUpdate();
};

@ -17,8 +17,7 @@ Objects::Objects()
void Objects::addObject(const MWWorld::Ptr& ptr)
{
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if(anim != NULL)
mObjects.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle)));
if(anim) mObjects.insert(std::make_pair(ptr, CharacterController(ptr, anim)));
}
void Objects::removeObject(const MWWorld::Ptr& ptr)

Loading…
Cancel
Save