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)
|
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
// erase previous death events since we are currently only tracking them while in an active cell
|
// 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);
|
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)));
|
||||||
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)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
||||||
|
@ -228,8 +225,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
|
if(!MWWorld::Class::get(iter->first).getCreatureStats(iter->first).isDead())
|
||||||
{
|
{
|
||||||
if(iter->second->getState() >= CharState_Death1)
|
if(iter->second->isDead())
|
||||||
iter->second->setState(CharState_Idle);
|
iter->second->resurrect();
|
||||||
|
|
||||||
updateActor(iter->first, totalDuration);
|
updateActor(iter->first, totalDuration);
|
||||||
if(iter->first.getTypeName() == typeid(ESM::NPC).name())
|
if(iter->first.getTypeName() == typeid(ESM::NPC).name())
|
||||||
|
@ -256,10 +253,10 @@ namespace MWMechanics
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(iter->second->getState() >= CharState_Death1)
|
if(iter->second->isDead())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
iter->second->setState(CharState_Death1);
|
iter->second->kill();
|
||||||
|
|
||||||
++mDeathCount[MWWorld::Class::get(iter->first).getId(iter->first)];
|
++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)
|
: mPtr(ptr)
|
||||||
, mAnimation(anim)
|
, mAnimation(anim)
|
||||||
, mIdleState(CharState_Idle)
|
, mIdleState(CharState_Idle)
|
||||||
, mMovementState(CharState_None)
|
, mMovementState(CharState_None)
|
||||||
, mCharState(state)
|
, mDeathState(CharState_None)
|
||||||
, mWeaponType(WeapType_None)
|
, mWeaponType(WeapType_None)
|
||||||
, mSkipAnim(false)
|
, mSkipAnim(false)
|
||||||
, mSecondsOfRunning(0)
|
, 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
|
/* Accumulate along X/Y only for now, until we can figure out how we should
|
||||||
* handle knockout and death which moves the character down. */
|
* handle knockout and death which moves the character down. */
|
||||||
mAnimation->setAccumulation(Ogre::Vector3(1.0f, 1.0f, 0.0f));
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -249,13 +255,14 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshCurrentAnims(mIdleState, mMovementState, true);
|
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)
|
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);
|
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()
|
void CharacterController::forceStateUpdate()
|
||||||
{
|
{
|
||||||
if(!mAnimation)
|
if(!mAnimation)
|
||||||
|
@ -624,16 +622,49 @@ void CharacterController::forceStateUpdate()
|
||||||
clearAnimQueue();
|
clearAnimQueue();
|
||||||
|
|
||||||
refreshCurrentAnims(mIdleState, mMovementState, true);
|
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)
|
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))
|
mCurrentDeath = state->groupname;
|
||||||
mAnimation->play(state->groupname, Priority_Death, MWRender::Animation::Group_All,
|
if(!mAnimation->getInfo(mCurrentDeath))
|
||||||
|
mAnimation->play(mCurrentDeath, Priority_Death, MWRender::Animation::Group_All,
|
||||||
false, "start", "stop", 0.0f, 0);
|
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;
|
CharacterState mMovementState;
|
||||||
std::string mCurrentMovement;
|
std::string mCurrentMovement;
|
||||||
|
|
||||||
CharacterState mCharState;
|
CharacterState mDeathState;
|
||||||
|
std::string mCurrentDeath;
|
||||||
|
|
||||||
WeaponType mWeaponType;
|
WeaponType mWeaponType;
|
||||||
bool mSkipAnim;
|
bool mSkipAnim;
|
||||||
|
|
||||||
|
@ -126,7 +128,7 @@ class CharacterController
|
||||||
void clearAnimQueue();
|
void clearAnimQueue();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim, CharacterState state);
|
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
|
||||||
virtual ~CharacterController();
|
virtual ~CharacterController();
|
||||||
|
|
||||||
void updatePtr(const MWWorld::Ptr &ptr);
|
void updatePtr(const MWWorld::Ptr &ptr);
|
||||||
|
@ -137,9 +139,10 @@ public:
|
||||||
void skipAnim();
|
void skipAnim();
|
||||||
bool isAnimPlaying(const std::string &groupName);
|
bool isAnimPlaying(const std::string &groupName);
|
||||||
|
|
||||||
void setState(CharacterState state);
|
void kill();
|
||||||
CharacterState getState() const
|
void resurrect();
|
||||||
{ return mCharState; }
|
bool isDead() const
|
||||||
|
{ return mDeathState != CharState_None; }
|
||||||
|
|
||||||
void forceStateUpdate();
|
void forceStateUpdate();
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,8 +17,7 @@ Objects::Objects()
|
||||||
void Objects::addObject(const MWWorld::Ptr& ptr)
|
void Objects::addObject(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
|
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
|
||||||
if(anim != NULL)
|
if(anim) mObjects.insert(std::make_pair(ptr, CharacterController(ptr, anim)));
|
||||||
mObjects.insert(std::make_pair(ptr, CharacterController(ptr, anim, CharState_Idle)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::removeObject(const MWWorld::Ptr& ptr)
|
void Objects::removeObject(const MWWorld::Ptr& ptr)
|
||||||
|
|
Loading…
Reference in a new issue