From 228254c890e6b90f1bcb2070b3e356c854efeeb1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 17 Jan 2014 16:31:27 +0100 Subject: [PATCH] Handle creature attack animations in character controller --- apps/openmw/mwmechanics/character.cpp | 46 +++++++++++++++++++++++++-- apps/openmw/mwmechanics/character.hpp | 3 +- apps/openmw/mwworld/worldimp.cpp | 3 +- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 755dbc093..fe650237a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -479,9 +479,47 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr) mPtr = ptr; } -bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak) +bool CharacterController::updateCreatureState() { - const MWWorld::Class &cls = MWWorld::Class::get(mPtr); + const MWWorld::Class &cls = mPtr.getClass(); + CreatureStats &stats = cls.getCreatureStats(mPtr); + + if(stats.getAttackingOrSpell()) + { + if(mUpperBodyState == UpperCharState_Nothing && mHitState == CharState_None) + { + MWBase::Environment::get().getWorld()->breakInvisibility(mPtr); + + switch (stats.getAttackType()) + { + case CreatureStats::AT_Chop: + mCurrentWeapon = "attack1"; + break; + case CreatureStats::AT_Thrust: + mCurrentWeapon = "attack2"; + break; + case CreatureStats::AT_Slash: + mCurrentWeapon = "attack3"; + break; + } + + mAnimation->play(mCurrentWeapon, Priority_Weapon, + MWRender::Animation::Group_UpperBody, true, + 1, "start", "stop", + 0.0f, 0); + mUpperBodyState = UpperCharState_StartToMinAttack; + } + } + + bool animPlaying = mAnimation->getInfo(mCurrentWeapon); + if (!animPlaying) + mUpperBodyState = UpperCharState_Nothing; + return false; +} + +bool CharacterController::updateNpcState(bool inwater, bool isrunning) +{ + const MWWorld::Class &cls = MWWorld::Class::get(mPtr); NpcStats &stats = cls.getNpcStats(mPtr); WeaponType weaptype = WeapType_None; MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); @@ -1091,7 +1129,9 @@ void CharacterController::update(float duration) } if(cls.isNpc()) - forcestateupdate = updateNpcState(onground, inwater, isrunning, sneak) || forcestateupdate; + forcestateupdate = updateNpcState(inwater, isrunning) || forcestateupdate; + else + forcestateupdate = updateCreatureState() || forcestateupdate; refreshCurrentAnims(idlestate, movestate, forcestateupdate); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 438f542f0..d3d4b4435 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -176,7 +176,8 @@ class CharacterController void clearAnimQueue(); - bool updateNpcState(bool onground, bool inwater, bool isrunning, bool sneak); + bool updateNpcState(bool inwater, bool isrunning); + bool updateCreatureState(); void updateVisibility(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index a40f20696..0d7802081 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2282,7 +2282,8 @@ namespace MWWorld void World::breakInvisibility(const Ptr &actor) { actor.getClass().getCreatureStats(actor).getActiveSpells().purgeEffect(ESM::MagicEffect::Invisibility); - actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility); + if (actor.getClass().isNpc()) + actor.getClass().getInventoryStore(actor).purgeEffect(ESM::MagicEffect::Invisibility); } bool World::isDark() const