bool Enchanting::create() { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); ESM::Enchantment enchantment; enchantment.mData.mCharge = getGemCharge(); mSoulGemPtr.getRefData().setCount (mSoulGemPtr.getRefData().getCount()-1); //Exception for Azura Star, new one will be added after enchanting if(boost::iequals(mSoulGemPtr.get<ESM::Miscellaneous>()->mBase->mId, "Misc_SoulGem_Azura")) { MWWorld::ManualRef azura (MWBase::Environment::get().getWorld()->getStore(), "Misc_SoulGem_Azura"); MWWorld::Class::get (player).getContainerStore (player).add (azura.getPtr()); } if(mSelfEnchanting) { if(getEnchantChance()<std::rand()/static_cast<double> (RAND_MAX)*100) return false; MWWorld::Class::get (mEnchanter).skillUsageSucceeded (mEnchanter, ESM::Skill::Enchant, 1); } if(mCastStyle==ESM::Enchantment::ConstantEffect) { enchantment.mData.mCharge=0; } enchantment.mData.mType = mCastStyle; enchantment.mData.mCost = getEnchantPoints(); enchantment.mEffects = mEffectList; const ESM::Enchantment *enchantmentPtr = MWBase::Environment::get().getWorld()->createRecord (enchantment); MWWorld::Class::get(mOldItemPtr).applyEnchantment(mOldItemPtr, enchantmentPtr->mId, getGemCharge(), mNewItemName); mOldItemPtr.getRefData().setCount(1); MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), mOldItemId); ref.getPtr().getRefData().setCount (mOldItemCount-1); MWWorld::Class::get (player).getContainerStore (player).add (ref.getPtr()); if(!mSelfEnchanting) payForEnchantment(); return true; }
virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); std::string creature = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); std::string gem = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), gem); ref.getPtr().getRefData().setCount (1); ref.getPtr().getCellRef().mSoul = creature; MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr()); }
virtual void execute (Interpreter::Runtime& runtime) { MWWorld::Ptr ptr = R()(runtime); std::string item = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); Interpreter::Type_Integer count = runtime[0].mInteger; runtime.pop(); if (count<0) throw std::runtime_error ("second argument for AddItem must be non-negative"); // no-op if (count == 0) return; MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item); ref.getPtr().getRefData().setCount (count); // Configure item's script variables std::string script = MWWorld::Class::get(ref.getPtr()).getScript(ref.getPtr()); if (script != "") { const ESM::Script *esmscript = MWBase::Environment::get().getWorld()->getStore().get<ESM::Script>().find (script); ref.getPtr().getRefData().setLocals(*esmscript); } MWWorld::Class::get (ptr).getContainerStore (ptr).add (ref.getPtr()); // Spawn a messagebox (only for items added to player's inventory) if (ptr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer()) { // The two GMST entries below expand to strings informing the player of what, and how many of it has been added to their inventory std::string msgBox; std::string itemName = MWWorld::Class::get(ref.getPtr()).getName(ref.getPtr()); if (count == 1) { msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage60}"); msgBox = boost::str(boost::format(msgBox) % itemName); } else { msgBox = MyGUI::LanguageManager::getInstance().replaceTags("#{sNotifyMessage61}"); msgBox = boost::str(boost::format(msgBox) % count % itemName); } MWBase::Environment::get().getWindowManager()->messageBox(msgBox); } }
/// @return ID of resulting item, or empty if none inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, unsigned char failChance=0) { const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList; const MWWorld::Ptr& player = getPlayer(); int playerLevel = player.getClass().getCreatureStats(player).getLevel(); failChance += levItem->mChanceNone; if (Misc::Rng::roll0to99() < failChance) return std::string(); std::vector<std::string> candidates; int highestLevel = 0; for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it) { if (it->mLevel > highestLevel && it->mLevel <= playerLevel) highestLevel = it->mLevel; } // For levelled creatures, the flags are swapped. This file format just makes so much sense. bool allLevels = (levItem->mFlags & ESM::ItemLevList::AllLevels) != 0; if (creature) allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels; std::pair<int, std::string> highest = std::make_pair(-1, ""); for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it) { if (playerLevel >= it->mLevel && (allLevels || it->mLevel == highestLevel)) { candidates.push_back(it->mId); if (it->mLevel >= highest.first) highest = std::make_pair(it->mLevel, it->mId); } } if (candidates.empty()) return std::string(); std::string item = candidates[Misc::Rng::rollDice(candidates.size())]; // Vanilla doesn't fail on nonexistent items in levelled lists if (!MWBase::Environment::get().getWorld()->getStore().find(Misc::StringUtils::lowerCase(item))) { std::cerr << "Warning: ignoring nonexistent item '" << item << "' in levelled list '" << levItem->mId << "'" << std::endl; return std::string(); } // Is this another levelled item or a real item? MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1); if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name() && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name()) { return item; } else { if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name()) return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, failChance); else return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, failChance); } }
/// @return ID of resulting item, or empty if none inline std::string getLevelledItem (const ESM::LeveledListBase* levItem, bool creature, unsigned char failChance=0) { const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList; const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr(); int playerLevel = player.getClass().getCreatureStats(player).getLevel(); failChance += levItem->mChanceNone; int random = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99] if (random < failChance) return std::string(); std::vector<std::string> candidates; int highestLevel = 0; for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it) { if (it->mLevel > highestLevel && it->mLevel <= playerLevel) highestLevel = it->mLevel; } // For levelled creatures, the flags are swapped. This file format just makes so much sense. bool allLevels = levItem->mFlags & ESM::ItemLevList::AllLevels; if (creature) allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels; std::pair<int, std::string> highest = std::make_pair(-1, ""); for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it) { if (playerLevel >= it->mLevel && (allLevels || it->mLevel == highestLevel)) { candidates.push_back(it->mId); if (it->mLevel >= highest.first) highest = std::make_pair(it->mLevel, it->mId); } } if (candidates.empty()) return std::string(); std::string item = candidates[std::rand()%candidates.size()]; // Is this another levelled item or a real item? try { MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1); if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name() && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name()) { return item; } else { if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name()) return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, failChance); else return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, failChance); } } catch (std::logic_error& e) { // Vanilla doesn't fail on nonexistent items in levelled lists std::cerr << "Warning: ignoring nonexistent item '" << item << "'" << std::endl; return std::string(); } }