forked from teamnwah/openmw-tes3coop
Track death separately in the character controller
This commit is contained in:
parent
4ae65c20e6
commit
06e631f213
4 changed files with 66 additions and 36 deletions
|
@ -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…
Reference in a new issue