virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Float x = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float y = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float z = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float zRot = runtime[0].mFloat; runtime.pop(); int cx,cy; MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy); MWBase::Environment::get().getWorld()->moveObject(ptr, *MWBase::Environment::get().getWorld()->getExterior(cx,cy),x,y,z); float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees(); float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); if(ptr.getTypeName() == typeid(ESM::NPC).name())//some morrowind oddity { ax = ax/60.; ay = ay/60.; zRot = zRot/60.; } MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot); }
void InventoryWindow::pickUpObject (MWWorld::Ptr object) { /// \todo scripts // make sure the object is of a type that can be picked up std::string type = object.getTypeName(); if ( (type != typeid(ESM::Apparatus).name()) && (type != typeid(ESM::Armor).name()) && (type != typeid(ESM::Book).name()) && (type != typeid(ESM::Clothing).name()) && (type != typeid(ESM::Ingredient).name()) && (type != typeid(ESM::Light).name()) && (type != typeid(ESM::Miscellaneous).name()) && (type != typeid(ESM::Tool).name()) && (type != typeid(ESM::Probe).name()) && (type != typeid(ESM::Repair).name()) && (type != typeid(ESM::Weapon).name()) && (type != typeid(ESM::Potion).name())) return; // sound std::string sound = MWWorld::Class::get(object).getUpSoundId(object); MWBase::Environment::get().getSoundManager()->playSound(sound, 1, 1); int count = object.getRefData().getCount(); // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::Ptr newObject = *MWWorld::Class::get (player).getContainerStore (player).add (object); // remove from world MWBase::Environment::get().getWorld()->deleteObject (object); mDragAndDrop->mIsOnDragAndDrop = true; mDragAndDrop->mDraggedCount = count; std::string path = std::string("icons\\"); path += MWWorld::Class::get(newObject).getInventoryIcon(newObject); MyGUI::ImageBox* baseWidget = mContainerWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default); baseWidget->detachFromWidget(); baseWidget->attachToWidget(mDragAndDrop->mDragAndDropWidget); baseWidget->setUserData(newObject); mDragAndDrop->mDraggedWidget = baseWidget; ImageBox* image = baseWidget->createWidget<ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default); int pos = path.rfind("."); path.erase(pos); path.append(".dds"); image->setImageTexture(path); image->setNeedMouseFocus(false); // text widget that shows item count MyGUI::TextBox* text = image->createWidget<MyGUI::TextBox>("SandBrightText", MyGUI::IntCoord(0, 14, 32, 18), MyGUI::Align::Default, std::string("Label")); text->setTextAlign(MyGUI::Align::Right); text->setNeedMouseFocus(false); text->setTextShadow(true); text->setTextShadowColour(MyGUI::Colour(0,0,0)); text->setCaption(getCountString(count)); mDragAndDrop->mDraggedFrom = this; }
float ratePotion (const MWWorld::Ptr &item, const MWWorld::Ptr& actor) { if (item.getTypeName() != typeid(ESM::Potion).name()) return 0.f; const ESM::Potion* potion = item.get<ESM::Potion>()->mBase; return rateEffects(potion->mEffects, actor, MWWorld::Ptr()); }
bool CreatureStats::getCreatureTargetted() const { MWWorld::Ptr targetPtr; if (mAiSequence.getCombatTarget(targetPtr)) { return targetPtr.getTypeName() == typeid(ESM::Creature).name(); } return false; }
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 Player::use() { MWWorld::InventoryStore& store = MWWorld::Class::get(getPlayer()).getInventoryStore(getPlayer()); MWWorld::ContainerStoreIterator equipped = store.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); if (getDrawState() == MWMechanics::DrawState_Weapon) { if (equipped != store.end()) { MWWorld::Ptr item = *equipped; MWRender::Animation* anim = MWBase::Environment::get().getWorld()->getAnimation(getPlayer()); MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject(); if (anim->isPriorityActive(MWMechanics::Priority_Weapon)) return; std::string resultMessage, resultSound; if (item.getTypeName() == typeid(ESM::Lockpick).name()) { if (!target.isEmpty()) MWMechanics::Security(getPlayer()).pickLock(target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0); } else if (item.getTypeName() == typeid(ESM::Probe).name()) { if (!target.isEmpty()) MWMechanics::Security(getPlayer()).probeTrap(target, item, resultMessage, resultSound); anim->play("pickprobe", MWMechanics::Priority_Weapon, MWRender::Animation::Group_UpperBody, true, 1.0f, "start", "stop", 0.0, 0); } if (!resultMessage.empty()) MWBase::Environment::get().getWindowManager()->messageBox(resultMessage); if (!resultSound.empty()) MWBase::Environment::get().getSoundManager()->playSound(resultSound,1,1); // tool used up? if (!item.getRefData().getCount()) MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon(); else MWBase::Environment::get().getWindowManager()->setSelectedWeapon(item); } } }
bool CreatureStats::getCreatureTargetted() const { std::string target; if (mAiSequence.getCombatTarget(target)) { MWWorld::Ptr targetPtr; targetPtr = MWBase::Environment::get().getWorld()->getPtr(target, true); return targetPtr.getTypeName() == typeid(ESM::Creature).name(); } return false; }
bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) { PtrControllerMap::iterator iter = mObjects.find(ptr); if(iter != mObjects.end()) { return iter->second->playGroup(groupName, mode, number); } else { std::cerr<< "Error in Objects::playAnimationGroup: Unable to find " << ptr.getTypeName() << std::endl; return false; } }
void InventoryWindow::pickUpObject (MWWorld::Ptr object) { // If the inventory is not yet enabled, don't pick anything up if (!MWBase::Environment::get().getWindowManager()->isAllowed(GW_Inventory)) return; // make sure the object is of a type that can be picked up std::string type = object.getTypeName(); if ( (type != typeid(ESM::Apparatus).name()) && (type != typeid(ESM::Armor).name()) && (type != typeid(ESM::Book).name()) && (type != typeid(ESM::Clothing).name()) && (type != typeid(ESM::Ingredient).name()) && (type != typeid(ESM::Light).name()) && (type != typeid(ESM::Miscellaneous).name()) && (type != typeid(ESM::Lockpick).name()) && (type != typeid(ESM::Probe).name()) && (type != typeid(ESM::Repair).name()) && (type != typeid(ESM::Weapon).name()) && (type != typeid(ESM::Potion).name())) return; if (object.getClass().getName(object) == "") // objects without name presented to user can never be picked up return; int count = object.getRefData().getCount(); MWWorld::Ptr player = MWMechanics::getPlayer(); MWBase::Environment::get().getWorld()->breakInvisibility(player); MWBase::Environment::get().getMechanicsManager()->itemTaken(player, object, MWWorld::Ptr(), count); // add to player inventory // can't use ActionTake here because we need an MWWorld::Ptr to the newly inserted object MWWorld::Ptr newObject = *player.getClass().getContainerStore (player).add (object, object.getRefData().getCount(), player); // remove from world MWBase::Environment::get().getWorld()->deleteObject (object); // get ModelIndex to the item mTradeModel->update(); size_t i=0; for (; i<mTradeModel->getItemCount(); ++i) { if (mTradeModel->getItem(i).mBase == newObject) break; } if (i == mTradeModel->getItemCount()) throw std::runtime_error("Added item not found"); mDragAndDrop->startDrag(i, mSortModel, mTradeModel, mItemView, count); MWBase::Environment::get().getWindowManager()->updateSpellWindow(); }
virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); Interpreter::Type_Float x = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float y = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float z = runtime[0].mFloat; runtime.pop(); Interpreter::Type_Float zRot = runtime[0].mFloat; runtime.pop(); std::string cellID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); MWWorld::CellStore* store = 0; try { store = MWBase::Environment::get().getWorld()->getInterior(cellID); } catch(std::exception &e) { const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getExterior(cellID); if(cell) { int cx,cy; MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy); store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); } } if(store) { MWBase::Environment::get().getWorld()->moveObject(ptr,*store,x,y,z); float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees(); float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); if(ptr.getTypeName() == typeid(ESM::NPC).name())//some morrowind oddity { ax = ax/60.; ay = ay/60.; zRot = zRot/60.; } MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot); } else { throw std::runtime_error ("unknown cell"); } }
ObjectAnimation::ObjectAnimation(const MWWorld::Ptr& ptr, const std::string &model) : Animation(ptr, ptr.getRefData().getBaseNode()) { setObjectRoot(model, false); Ogre::Vector3 extents = getWorldBounds().getSize(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if(ptr.getTypeName().find("Door") != std::string::npos) small = false; float dist = small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0.0f; Ogre::Vector3 col = getEnchantmentColor(ptr); setRenderProperties(mObjectRoot, (mPtr.getTypeName() == typeid(ESM::Static).name()) ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc, RQG_Main, RQG_Alpha, dist, !ptr.getClass().getEnchantment(ptr).empty(), &col); }
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature) { CreatureStats& creatureStats = MWWorld::Class::get (creature).getCreatureStats (creature); MagicEffects now = creatureStats.mSpells.getMagicEffects(); if (creature.getTypeName()==typeid (ESM::NPC).name()) { MWWorld::InventoryStore& store = MWWorld::Class::get (creature).getInventoryStore (creature); now += store.getMagicEffects(); } now += creatureStats.mActiveSpells.getMagicEffects(); MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now); creatureStats.mMagicEffects = now; // TODO apply diff to other stats }
bool SortFilterItemModel::filterAccepts (const ItemStack& item) { MWWorld::Ptr base = item.mBase; int category = 0; if (base.getTypeName() == typeid(ESM::Armor).name() || base.getTypeName() == typeid(ESM::Clothing).name()) category = Category_Apparel; else if (base.getTypeName() == typeid(ESM::Weapon).name()) category = Category_Weapon; else if (base.getTypeName() == typeid(ESM::Ingredient).name() || base.getTypeName() == typeid(ESM::Potion).name()) category = Category_Magic; else if (base.getTypeName() == typeid(ESM::Miscellaneous).name() || base.getTypeName() == typeid(ESM::Ingredient).name() || base.getTypeName() == typeid(ESM::Repair).name() || base.getTypeName() == typeid(ESM::Lockpick).name() || base.getTypeName() == typeid(ESM::Light).name() || base.getTypeName() == typeid(ESM::Apparatus).name() || base.getTypeName() == typeid(ESM::Book).name() || base.getTypeName() == typeid(ESM::Probe).name()) category = Category_Misc; if (item.mFlags & ItemStack::Flag_Enchanted) category |= Category_Magic; if (!(category & mCategory)) return false; if ((mFilter & Filter_OnlyIngredients) && base.getTypeName() != typeid(ESM::Ingredient).name()) return false; if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted)) return false; if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name() || base.getCellRef().getSoul() == "")) return false; if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted || (base.getTypeName() != typeid(ESM::Armor).name() && base.getTypeName() != typeid(ESM::Clothing).name() && base.getTypeName() != typeid(ESM::Weapon).name() && base.getTypeName() != typeid(ESM::Book).name()))) return false; if ((mFilter & Filter_OnlyEnchantable) && base.getTypeName() == typeid(ESM::Book).name() && !base.get<ESM::Book>()->mBase->mData.mIsScroll) return false; if ((mFilter & Filter_OnlyUsableItems) && base.getClass().getScript(base).empty()) { boost::shared_ptr<MWWorld::Action> actionOnUse = base.getClass().use(base); if (!actionOnUse || actionOnUse->isNullAction()) return false; } if ((mFilter & Filter_OnlyRepairable) && ( !base.getClass().hasItemHealth(base) || (base.getClass().getItemHealth(base) == base.getClass().getItemMaxHealth(base)) || (base.getTypeName() != typeid(ESM::Weapon).name() && base.getTypeName() != typeid(ESM::Armor).name()))) return false; if (mFilter & Filter_OnlyRechargable) { if (!(item.mFlags & ItemStack::Flag_Enchanted)) return false; std::string enchId = base.getClass().getEnchantment(base); const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().search(enchId); if (!ench) { std::cerr << "Warning: Can't find enchantment '" << enchId << "' on item " << base.getCellRef().getRefId() << std::endl; return false; } if (base.getCellRef().getEnchantmentCharge() >= ench->mData.mCharge || base.getCellRef().getEnchantmentCharge() == -1) return false; } return true; }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh, bool light) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::ObjectList objects = NifOgre::Loader::createObjects(insert, mesh); for(size_t i = 0;i < objects.mEntities.size();i++) bounds.merge(objects.mEntities[i]->getWorldBoundingBox(true)); Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool anyTransparency = false; for(size_t i = 0;!anyTransparency && i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0;!anyTransparency && i < ent->getNumSubEntities(); ++i) { anyTransparency = ent->getSubEntity(i)->getMaterial()->isTransparent(); } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || anyTransparency || objects.mParticles.size() > 0) { for(size_t i = 0;i < objects.mEntities.size();i++) { Ogre::Entity *ent = objects.mEntities[i]; for(unsigned int i=0; i < ent->getNumSubEntities(); ++i) { Ogre::SubEntity* subEnt = ent->getSubEntity(i); subEnt->setRenderQueueGroup(subEnt->getMaterial()->isTransparent() ? RQG_Alpha : RQG_Main); } ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } for(size_t i = 0;i < objects.mParticles.size();i++) { Ogre::ParticleSystem *part = objects.mParticles[i]; // TODO: Check the particle system's material for actual transparency part->setRenderQueueGroup(RQG_Alpha); part->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); part->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(RQG_Main); std::vector<Ogre::Entity*>::reverse_iterator iter = objects.mEntities.rbegin(); while(iter != objects.mEntities.rend()) { Ogre::Node *node = (*iter)->getParentNode(); sg->addEntity(*iter, node->_getDerivedPosition(), node->_getDerivedOrientation(), node->_getDerivedScale()); (*iter)->detachFromParent(); mRenderer.getScene()->destroyEntity(*iter); iter++; } } if (light) { insertLight(ptr, objects.mSkelBase, bounds.getCenter() - insert->_getDerivedPosition()); } }
void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh) { Ogre::SceneNode* insert = ptr.getRefData().getBaseNode(); assert(insert); Ogre::AxisAlignedBox bounds = Ogre::AxisAlignedBox::BOX_NULL; NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(insert, NULL, mesh); for(size_t i = 0;i < entities.mEntities.size();i++) { const Ogre::AxisAlignedBox &tmp = entities.mEntities[i]->getBoundingBox(); bounds.merge(Ogre::AxisAlignedBox(insert->_getDerivedPosition() + tmp.getMinimum(), insert->_getDerivedPosition() + tmp.getMaximum()) ); } Ogre::Vector3 extents = bounds.getSize(); extents *= insert->getScale(); float size = std::max(std::max(extents.x, extents.y), extents.z); bool small = (size < Settings::Manager::getInt("small object size", "Viewing distance")) && Settings::Manager::getBool("limit small object distance", "Viewing distance"); // do not fade out doors. that will cause holes and look stupid if (ptr.getTypeName().find("Door") != std::string::npos) small = false; if (mBounds.find(ptr.getCell()) == mBounds.end()) mBounds[ptr.getCell()] = Ogre::AxisAlignedBox::BOX_NULL; mBounds[ptr.getCell()].merge(bounds); bool transparent = false; for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; for (unsigned int i=0; i<ent->getNumSubEntities(); ++i) { Ogre::MaterialPtr mat = ent->getSubEntity(i)->getMaterial(); Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator(); while (techIt.hasMoreElements()) { Ogre::Technique* tech = techIt.getNext(); Ogre::Technique::PassIterator passIt = tech->getPassIterator(); while (passIt.hasMoreElements()) { Ogre::Pass* pass = passIt.getNext(); if (pass->getDepthWriteEnabled() == false) transparent = true; } } } } if(!mIsStatic || !Settings::Manager::getBool("use static geometry", "Objects") || transparent) { for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; ent->setRenderingDistance(small ? Settings::Manager::getInt("small object distance", "Viewing distance") : 0); ent->setVisibilityFlags(mIsStatic ? (small ? RV_StaticsSmall : RV_Statics) : RV_Misc); ent->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); } } else { Ogre::StaticGeometry* sg = 0; if (small) { if( mStaticGeometrySmall.find(ptr.getCell()) == mStaticGeometrySmall.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometrySmall[ptr.getCell()] = sg; sg->setRenderingDistance(Settings::Manager::getInt("small object distance", "Viewing distance")); } else sg = mStaticGeometrySmall[ptr.getCell()]; } else { if( mStaticGeometry.find(ptr.getCell()) == mStaticGeometry.end()) { uniqueID = uniqueID +1; sg = mRenderer.getScene()->createStaticGeometry( "sg" + Ogre::StringConverter::toString(uniqueID)); mStaticGeometry[ptr.getCell()] = sg; } else sg = mStaticGeometry[ptr.getCell()]; } // This specifies the size of a single batch region. // If it is set too high: // - there will be problems choosing the correct lights // - the culling will be more inefficient // If it is set too low: // - there will be too many batches. sg->setRegionDimensions(Ogre::Vector3(2500,2500,2500)); sg->setVisibilityFlags(small ? RV_StaticsSmall : RV_Statics); sg->setCastShadows(true); sg->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); for(size_t i = 0;i < entities.mEntities.size();i++) { Ogre::Entity *ent = entities.mEntities[i]; insert->detachObject(ent); sg->addEntity(ent,insert->_getDerivedPosition(),insert->_getDerivedOrientation(),insert->_getDerivedScale()); mRenderer.getScene()->destroyEntity(ent); } } }
float rateWeapon (const MWWorld::Ptr &item, const MWWorld::Ptr& actor, const MWWorld::Ptr& target, int type, float arrowRating, float boltRating) { if (item.getTypeName() != typeid(ESM::Weapon).name()) return 0.f; const ESM::Weapon* weapon = item.get<ESM::Weapon>()->mBase; if (type != -1 && weapon->mData.mType != type) return 0.f; float rating=0.f; if (weapon->mData.mType >= ESM::Weapon::MarksmanBow) { rating = (weapon->mData.mChop[0] + weapon->mData.mChop[1]) / 2.f; } else { for (int i=0; i<2; ++i) { rating += weapon->mData.mSlash[i]; rating += weapon->mData.mThrust[i]; rating += weapon->mData.mChop[i]; } rating /= 6.f; } if (item.getClass().hasItemHealth(item)) { if (item.getClass().getItemHealth(item) == 0) return 0.f; rating *= item.getClass().getItemHealth(item) / float(item.getClass().getItemMaxHealth(item)); } if (weapon->mData.mType == ESM::Weapon::MarksmanBow) { if (arrowRating <= 0.f) rating = 0.f; else rating += arrowRating; } else if (weapon->mData.mType == ESM::Weapon::MarksmanCrossbow) { if (boltRating <= 0.f) rating = 0.f; else rating += boltRating; } if (!weapon->mEnchant.empty()) { const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(weapon->mEnchant); if (enchantment->mData.mType == ESM::Enchantment::WhenStrikes && (item.getCellRef().getEnchantmentCharge() == -1 || item.getCellRef().getEnchantmentCharge() >= enchantment->mData.mCost)) rating += rateEffects(enchantment->mEffects, actor, target); } int skill = item.getClass().getEquipmentSkill(item); if (skill != -1) rating *= actor.getClass().getSkill(actor, skill) / 100.f; return rating; }
bool SortFilterItemModel::filterAccepts (const ItemStack& item) { MWWorld::Ptr base = item.mBase; if (item.mType == ItemStack::Type_Equipped && !mShowEquipped) return false; int category = 0; if (base.getTypeName() == typeid(ESM::Armor).name() || base.getTypeName() == typeid(ESM::Clothing).name()) category = Category_Apparel; else if (base.getTypeName() == typeid(ESM::Weapon).name()) category = Category_Weapon; else if (base.getTypeName() == typeid(ESM::Ingredient).name() || base.getTypeName() == typeid(ESM::Potion).name()) category = Category_Magic; else if (base.getTypeName() == typeid(ESM::Miscellaneous).name() || base.getTypeName() == typeid(ESM::Ingredient).name() || base.getTypeName() == typeid(ESM::Repair).name() || base.getTypeName() == typeid(ESM::Lockpick).name() || base.getTypeName() == typeid(ESM::Light).name() || base.getTypeName() == typeid(ESM::Apparatus).name() || base.getTypeName() == typeid(ESM::Book).name() || base.getTypeName() == typeid(ESM::Probe).name()) category = Category_Misc; if (item.mFlags & ItemStack::Flag_Enchanted) category |= Category_Magic; if (!(category & mCategory)) return false; if ((mFilter & Filter_OnlyIngredients) && base.getTypeName() != typeid(ESM::Ingredient).name()) return false; if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted)) return false; if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name() || base.getCellRef().getSoul() == "")) return false; if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted || (base.getTypeName() != typeid(ESM::Armor).name() && base.getTypeName() != typeid(ESM::Clothing).name() && base.getTypeName() != typeid(ESM::Weapon).name() && base.getTypeName() != typeid(ESM::Book).name()))) return false; if ((mFilter & Filter_OnlyEnchantable) && base.getTypeName() == typeid(ESM::Book).name() && !base.get<ESM::Book>()->mBase->mData.mIsScroll) return false; if ((mFilter & Filter_OnlyUsableItems) && typeid(*base.getClass().use(base)) == typeid(MWWorld::NullAction) && base.getClass().getScript(base).empty()) return false; return true; }
int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const { MWWorld::Ptr player = MWMechanics::getPlayer(); switch (select.getFunction()) { case SelectWrapper::Function_Journal: return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); case SelectWrapper::Function_Item: { MWWorld::ContainerStore& store = player.getClass().getContainerStore (player); return store.count(select.getName()); } case SelectWrapper::Function_Dead: return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); case SelectWrapper::Function_Choice: return mChoice; case SelectWrapper::Function_AiSetting: return mActor.getClass().getCreatureStats (mActor).getAiSetting ( (MWMechanics::CreatureStats::AiSetting)select.getArgument()).getModified(); case SelectWrapper::Function_PcAttribute: return player.getClass().getCreatureStats (player). getAttribute (select.getArgument()).getModified(); case SelectWrapper::Function_PcSkill: return static_cast<int> (player.getClass(). getNpcStats (player).getSkill (select.getArgument()).getModified()); case SelectWrapper::Function_FriendlyHit: { int hits = mActor.getClass().getCreatureStats (mActor).getFriendlyHits(); return hits>4 ? 4 : hits; } case SelectWrapper::Function_PcLevel: return player.getClass().getCreatureStats (player).getLevel(); case SelectWrapper::Function_PcGender: return player.get<ESM::NPC>()->mBase->isMale() ? 0 : 1; case SelectWrapper::Function_PcClothingModifier: { MWWorld::InventoryStore& store = player.getClass().getInventoryStore (player); int value = 0; for (int i=0; i<=15; ++i) // everything except things held in hands and ammunition { MWWorld::ContainerStoreIterator slot = store.getSlot (i); if (slot!=store.end()) value += slot->getClass().getValue (*slot); } return value; } case SelectWrapper::Function_PcCrimeLevel: return player.getClass().getNpcStats (player).getBounty(); case SelectWrapper::Function_RankRequirement: { std::string faction = mActor.getClass().getPrimaryFaction(mActor); if (faction.empty()) return 0; int rank = getFactionRank (player, faction); if (rank>=9) return 0; // max rank int result = 0; if (hasFactionRankSkillRequirements (player, faction, rank+1)) result += 1; if (hasFactionRankReputationRequirements (player, faction, rank+1)) result += 2; return result; } case SelectWrapper::Function_Level: return mActor.getClass().getCreatureStats (mActor).getLevel(); case SelectWrapper::Function_PCReputation: return player.getClass().getNpcStats (player).getReputation(); case SelectWrapper::Function_Weather: return MWBase::Environment::get().getWorld()->getCurrentWeather(); case SelectWrapper::Function_Reputation: return mActor.getClass().getNpcStats (mActor).getReputation(); case SelectWrapper::Function_FactionRankDiff: { std::string faction = mActor.getClass().getPrimaryFaction(mActor); if (faction.empty()) return 0; int rank = getFactionRank (player, faction); int npcRank = mActor.getClass().getPrimaryFactionRank(mActor); return rank-npcRank; } case SelectWrapper::Function_WerewolfKills: return player.getClass().getNpcStats (player).getWerewolfKills(); case SelectWrapper::Function_RankLow: case SelectWrapper::Function_RankHigh: { bool low = select.getFunction()==SelectWrapper::Function_RankLow; std::string factionId = mActor.getClass().getPrimaryFaction(mActor); if (factionId.empty()) return 0; int value = 0; MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats (player); std::map<std::string, int>::const_iterator playerFactionIt = playerStats.getFactionRanks().begin(); for (; playerFactionIt != playerStats.getFactionRanks().end(); ++playerFactionIt) { int reaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(factionId, playerFactionIt->first); if (low ? reaction < value : reaction > value) value = reaction; } return value; } case SelectWrapper::Function_CreatureTargetted: { MWWorld::Ptr target; mActor.getClass().getCreatureStats(mActor).getAiSequence().getCombatTarget(target); if (target) { if (target.getClass().isNpc() && target.getClass().getNpcStats(target).isWerewolf()) return 2; if (target.getTypeName() == typeid(ESM::Creature).name()) return 1; } } return 0; default: throw std::runtime_error ("unknown integer select function"); } }
bool TradeWindow::npcAcceptsItem(MWWorld::Ptr item) { int services = 0; if (mPtr.getTypeName() == typeid(ESM::NPC).name()) { MWWorld::LiveCellRef<ESM::NPC>* ref = mPtr.get<ESM::NPC>(); if (ref->mBase->mHasAI) services = ref->mBase->mAiData.mServices; } else if (mPtr.getTypeName() == typeid(ESM::Creature).name()) { MWWorld::LiveCellRef<ESM::Creature>* ref = mPtr.get<ESM::Creature>(); if (ref->mBase->mHasAI) services = ref->mBase->mAiData.mServices; } /// \todo what about potions, there doesn't seem to be a flag for them?? if (item.getTypeName() == typeid(ESM::Weapon).name()) return services & ESM::NPC::Weapon; else if (item.getTypeName() == typeid(ESM::Armor).name()) return services & ESM::NPC::Armor; else if (item.getTypeName() == typeid(ESM::Clothing).name()) return services & ESM::NPC::Clothing; else if (item.getTypeName() == typeid(ESM::Book).name()) return services & ESM::NPC::Books; else if (item.getTypeName() == typeid(ESM::Ingredient).name()) return services & ESM::NPC::Ingredients; else if (item.getTypeName() == typeid(ESM::Tool).name()) return services & ESM::NPC::Picks; else if (item.getTypeName() == typeid(ESM::Probe).name()) return services & ESM::NPC::Probes; else if (item.getTypeName() == typeid(ESM::Light).name()) return services & ESM::NPC::Lights; else if (item.getTypeName() == typeid(ESM::Apparatus).name()) return services & ESM::NPC::Apparatus; else if (item.getTypeName() == typeid(ESM::Repair).name()) return services & ESM::NPC::RepairItem; else if (item.getTypeName() == typeid(ESM::Miscellaneous).name()) return services & ESM::NPC::Misc; return false; }