void CreatureWeaponAnimation::updatePart(PartHolderPtr& scene, int slot) { if (!mObjectRoot) return; MWWorld::InventoryStore& inv = mPtr.getClass().getInventoryStore(mPtr); MWWorld::ContainerStoreIterator it = inv.getSlot(slot); if (it == inv.end()) { scene.reset(); return; } MWWorld::Ptr item = *it; std::string bonename; if (slot == MWWorld::InventoryStore::Slot_CarriedRight) bonename = "Weapon Bone"; else bonename = "Shield Bone"; osg::ref_ptr<osg::Node> node = mResourceSystem->getSceneManager()->getInstance(item.getClass().getModel(item)); osg::ref_ptr<osg::Node> attached = SceneUtil::attach(node, mObjectRoot, bonename, bonename); mResourceSystem->getSceneManager()->notifyAttached(attached); if (mSkeleton) mSkeleton->markDirty(); scene.reset(new PartHolder(attached)); if (!item.getClass().getEnchantment(item).empty()) addGlow(attached, getEnchantmentColor(item)); // Crossbows start out with a bolt attached // FIXME: code duplicated from NpcAnimation if (slot == MWWorld::InventoryStore::Slot_CarriedRight && item.getTypeName() == typeid(ESM::Weapon).name() && item.get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::MarksmanCrossbow) { MWWorld::ContainerStoreIterator ammo = inv.getSlot(MWWorld::InventoryStore::Slot_Ammunition); if (ammo != inv.end() && ammo->get<ESM::Weapon>()->mBase->mData.mType == ESM::Weapon::Bolt) attachArrow(); else mAmmunition.reset(); } else mAmmunition.reset(); boost::shared_ptr<SceneUtil::ControllerSource> source; if (slot == MWWorld::InventoryStore::Slot_CarriedRight) source = mWeaponAnimationTime; else source.reset(new NullAnimationTime); SceneUtil::AssignControllerSourcesVisitor assignVisitor(source); attached->accept(assignVisitor); }
void Animation::handleTextKey(AnimState &state, const std::string &groupname, const NifOgre::TextKeyMap::const_iterator &key) { //float time = key->first; const std::string &evt = key->second; if(evt.compare(0, 7, "sound: ") == 0) { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); sndMgr->playSound3D(mPtr, evt.substr(7), 1.0f, 1.0f); return; } if(evt.compare(0, 10, "soundgen: ") == 0) { std::string soundgen = evt.substr(10); // The event can optionally contain volume and pitch modifiers float volume=1.f, pitch=1.f; if (soundgen.find(" ") != std::string::npos) { std::vector<std::string> tokens; split(soundgen, ' ', tokens); soundgen = tokens[0]; if (tokens.size() >= 2) volume = Ogre::StringConverter::parseReal(tokens[1]); if (tokens.size() >= 3) pitch = Ogre::StringConverter::parseReal(tokens[2]); } std::string sound = mPtr.getClass().getSoundIdFromSndGen(mPtr, soundgen); if(!sound.empty()) { MWBase::SoundManager *sndMgr = MWBase::Environment::get().getSoundManager(); MWBase::SoundManager::PlayType type = MWBase::SoundManager::Play_TypeSfx; if(evt.compare(10, evt.size()-10, "left") == 0 || evt.compare(10, evt.size()-10, "right") == 0) type = MWBase::SoundManager::Play_TypeFoot; sndMgr->playSound3D(mPtr, sound, volume, pitch, type); } return; } if(evt.compare(0, groupname.size(), groupname) != 0 || evt.compare(groupname.size(), 2, ": ") != 0) { // Not ours, skip it return; } size_t off = groupname.size()+2; size_t len = evt.size() - off; if(evt.compare(off, len, "loop start") == 0) state.mLoopStartTime = key->first; else if(evt.compare(off, len, "loop stop") == 0) state.mLoopStopTime = key->first; else if(evt.compare(off, len, "equip attach") == 0) showWeapons(true); else if(evt.compare(off, len, "unequip detach") == 0) showWeapons(false); else if(evt.compare(off, len, "chop hit") == 0) mPtr.getClass().hit(mPtr, ESM::Weapon::AT_Chop); else if(evt.compare(off, len, "slash hit") == 0) mPtr.getClass().hit(mPtr, ESM::Weapon::AT_Slash); else if(evt.compare(off, len, "thrust hit") == 0) mPtr.getClass().hit(mPtr, ESM::Weapon::AT_Thrust); else if(evt.compare(off, len, "hit") == 0) { if (groupname == "attack1") mPtr.getClass().hit(mPtr, ESM::Weapon::AT_Chop); else if (groupname == "attack2") mPtr.getClass().hit(mPtr, ESM::Weapon::AT_Slash); else if (groupname == "attack3") mPtr.getClass().hit(mPtr, ESM::Weapon::AT_Thrust); else mPtr.getClass().hit(mPtr); } else if (evt.compare(off, len, "shoot attach") == 0) attachArrow(); else if (evt.compare(off, len, "shoot release") == 0) releaseArrow(); else if (evt.compare(off, len, "shoot follow attach") == 0) attachArrow(); else if (groupname == "spellcast" && evt.substr(evt.size()-7, 7) == "release") MWBase::Environment::get().getWorld()->castSpell(mPtr); else if (groupname == "shield" && evt.compare(off, len, "block hit") == 0) mPtr.getClass().block(mPtr); }