diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 1cd7164133..cc1d83d9fc 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -571,15 +571,9 @@ namespace MWInput MWMechanics::DrawState_ state = mPlayer.getDrawState(); if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing) - { mPlayer.setDrawState(MWMechanics::DrawState_Spell); - std::cout << "Player has now readied his hands for spellcasting!\n" << std::endl; - } else - { mPlayer.setDrawState(MWMechanics::DrawState_Nothing); - std::cout << "Player does not have any kind of attack ready now.\n" << std::endl; - } } void InputManager::toggleWeapon() @@ -588,15 +582,9 @@ namespace MWInput MWMechanics::DrawState_ state = mPlayer.getDrawState(); if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) - { mPlayer.setDrawState(MWMechanics::DrawState_Weapon); - std::cout << "Player is now drawing his weapon.\n" << std::endl; - } else - { mPlayer.setDrawState(MWMechanics::DrawState_Nothing); - std::cout << "Player does not have any kind of attack ready now.\n" << std::endl; - } } void InputManager::rest() diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 30751dfdea..5b31b04994 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -22,6 +22,7 @@ #include #include "movement.hpp" +#include "npcstats.hpp" #include "../mwrender/animation.hpp" @@ -30,6 +31,7 @@ #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" namespace MWMechanics @@ -89,21 +91,55 @@ static const struct { }; static const size_t sStateListSize = sizeof(sStateList)/sizeof(sStateList[0]); +static const struct { + WeaponState state; + const char idlegroup[16]; + const char movementgroup[16]; + const char actiongroup[16]; +} sWeaponStateList[] = { + { WeapState_HandToHand, "hh", "hh", "handtohand" }, + { WeapState_OneHand, "1h", "1h", "weapononehand" }, + { WeapState_TwoHand, "2c", "2c", "weapontwohand" }, + { WeapState_TwoWide, "2w", "2w", "weapontwowide" }, + { WeapState_BowAndArrow, "1h", "1h", "bowandarrow" }, + { WeapState_Crossbow, "crossbow", "2c", "crossbow" }, + { WeapState_ThowWeapon, "1h", "1h", "throwweapon" }, + { WeapState_Spell, "spell", "", "spellcast" }, +}; +static const size_t sWeaponStateListSize = sizeof(sWeaponStateList)/sizeof(sWeaponStateList[0]); + + void CharacterController::getCurrentGroup(std::string &group) const { + std::string name; for(size_t i = 0;i < sStateListSize;i++) { if(sStateList[i].state == mCharState) { - group = sStateList[i].groupname; + name = sStateList[i].groupname; break; } } - if(group.empty()) + if(name.empty()) throw std::runtime_error("Failed to find character state "+Ogre::StringConverter::toString(mCharState)); - if(!mAnimation->hasAnimation(group)) - group = std::string(); + if(!(mCharState >= CharState_Death1) && mWeapState != WeapState_None) + { + for(size_t i = 0;i < sWeaponStateListSize;i++) + { + if(sWeaponStateList[i].state == mWeapState) + { + if(mCharState == CharState_Idle) + (group=name) += sWeaponStateList[i].idlegroup; + else + (group=name) += sWeaponStateList[i].movementgroup; + break; + } + } + } + + if(group.empty() || !mAnimation->hasAnimation(group)) + group = (mAnimation->hasAnimation(name) ? name : std::string()); } @@ -187,6 +223,64 @@ void CharacterController::update(float duration, Movement &movement) } } + if(mPtr.getTypeName() == typeid(ESM::NPC).name()) + { + NpcStats &stats = cls.getNpcStats(mPtr); + WeaponState weapstate = WeapState_None; + + if(stats.getDrawState() == DrawState_Spell) + weapstate = WeapState_Spell; + else if(stats.getDrawState() == MWMechanics::DrawState_Weapon) + { + MWWorld::InventoryStore &inv = cls.getInventoryStore(mPtr); + MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + if(weapon == inv.end()) + weapstate = WeapState_HandToHand; + else + { + const std::string &type = weapon->getTypeName(); + if(type == typeid(ESM::Lockpick).name() || type == typeid(ESM::Probe).name()) + weapstate = WeapState_OneHand; + else if(type == typeid(ESM::Weapon).name()) + { + MWWorld::LiveCellRef *ref = weapon->get(); + ESM::Weapon::Type type = (ESM::Weapon::Type)ref->mBase->mData.mType; + switch(type) + { + case ESM::Weapon::ShortBladeOneHand: + case ESM::Weapon::LongBladeOneHand: + case ESM::Weapon::BluntOneHand: + case ESM::Weapon::AxeOneHand: + case ESM::Weapon::Arrow: + case ESM::Weapon::Bolt: + weapstate = WeapState_OneHand; + break; + case ESM::Weapon::LongBladeTwoHand: + case ESM::Weapon::BluntTwoClose: + case ESM::Weapon::AxeTwoHand: + weapstate = WeapState_TwoHand; + break; + case ESM::Weapon::BluntTwoWide: + case ESM::Weapon::SpearTwoWide: + weapstate = WeapState_TwoWide; + break; + case ESM::Weapon::MarksmanBow: + weapstate = WeapState_BowAndArrow; + break; + case ESM::Weapon::MarksmanCrossbow: + weapstate = WeapState_Crossbow; + break; + case ESM::Weapon::MarksmanThrown: + weapstate = WeapState_ThowWeapon; + break; + } + } + } + } + + setWeaponState(weapstate); + } + /* FIXME: The state should be set to Jump, and X/Y movement should be disallowed except * for the initial thrust (which would be carried by "physics" until landing). */ if(onground && vec.z > 0.0f) @@ -312,6 +406,15 @@ void CharacterController::setState(CharacterState state, bool loop) forceStateUpdate(); } +void CharacterController::setWeaponState(WeaponState state) +{ + if(state == mWeapState) + return; + mWeapState = state; + + forceStateUpdate(); +} + void CharacterController::forceStateUpdate() { if(!mAnimation) @@ -321,6 +424,9 @@ void CharacterController::forceStateUpdate() std::string group; getCurrentGroup(group); mMovingAnim = mAnimation->play(group, "start", "stop", 0.0f, mLooping ? (~(size_t)0) : 0); + + mAnimation->showWeapons(mWeapState != WeapState_None && mWeapState != WeapState_HandToHand && + mWeapState != WeapState_Spell); } } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 05dabbd92b..64e19e51fa 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -118,6 +118,10 @@ public: CharacterState getState() const { return mCharState; } + void setWeaponState(WeaponState state); + WeaponState getWeaponState() const + { return mWeapState; } + void forceStateUpdate(); };