mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 18:56:38 +00:00 
			
		
		
		
	Allow choosing different apparatus in alchemy window
This commit is contained in:
		
							parent
							
								
									edd69885ce
								
							
						
					
					
						commit
						6d0dceae34
					
				
					 7 changed files with 154 additions and 0 deletions
				
			
		|  | @ -7,6 +7,7 @@ | |||
| #include <MyGUI_EditBox.h> | ||||
| #include <MyGUI_Gui.h> | ||||
| 
 | ||||
| #include <components/esm3/loadappa.hpp> | ||||
| #include <components/esm3/loadingr.hpp> | ||||
| #include <components/esm3/loadmgef.hpp> | ||||
| 
 | ||||
|  | @ -77,6 +78,11 @@ namespace MWGui | |||
|         mIngredients[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||
|         mIngredients[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||
| 
 | ||||
|         mApparatus[0]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected); | ||||
|         mApparatus[1]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected); | ||||
|         mApparatus[2]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected); | ||||
|         mApparatus[3]->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onApparatusSelected); | ||||
| 
 | ||||
|         mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked); | ||||
|         mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked); | ||||
| 
 | ||||
|  | @ -293,6 +299,80 @@ namespace MWGui | |||
|         update(); | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::onItemSelected(MWWorld::Ptr item) | ||||
|     { | ||||
|         mItemSelectionDialog->setVisible(false); | ||||
| 
 | ||||
|         int32_t index = item.get<ESM::Apparatus>()->mBase->mData.mType; | ||||
|         const auto& widget = mApparatus[index]; | ||||
| 
 | ||||
|         widget->setItem(item); | ||||
| 
 | ||||
|         if (item.isEmpty()) | ||||
|         { | ||||
|             widget->clearUserStrings(); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         mAlchemy->addApparatus(item); | ||||
| 
 | ||||
|         widget->setUserString("ToolTipType", "ItemPtr"); | ||||
|         widget->setUserData(MWWorld::Ptr(item)); | ||||
| 
 | ||||
|         MWBase::Environment::get().getWindowManager()->playSound(item.getClass().getDownSoundId(item)); | ||||
|         update(); | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::onItemCancel() | ||||
|     { | ||||
|         mItemSelectionDialog->setVisible(false); | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::onApparatusSelected(MyGUI::Widget* _sender) | ||||
|     { | ||||
|         if (_sender->getUserData<MWWorld::Ptr>()->isEmpty()) // if this apparatus slot is empty
 | ||||
|         { | ||||
|             std::string title; | ||||
| 
 | ||||
|             size_t i = 0; | ||||
|             for (; i < mApparatus.size(); ++i) | ||||
|             { | ||||
|                 if (mApparatus[i] == _sender) | ||||
|                     break; | ||||
|             } | ||||
| 
 | ||||
|             switch (i) | ||||
|             { | ||||
|                 case ESM::Apparatus::AppaType::MortarPestle: | ||||
|                     title = "#{sMortar}"; | ||||
|                     break; | ||||
|                 case ESM::Apparatus::AppaType::Alembic: | ||||
|                     title = "#{sAlembic}"; | ||||
|                     break; | ||||
|                 case ESM::Apparatus::AppaType::Calcinator: | ||||
|                     title = "#{sCalcinator}"; | ||||
|                     break; | ||||
|                 case ESM::Apparatus::AppaType::Retort: | ||||
|                     title = "#{sRetort}"; | ||||
|                     break; | ||||
|                 default: | ||||
|                     title = "#{sApparatus}"; | ||||
|             } | ||||
| 
 | ||||
|             mItemSelectionDialog = std::make_unique<ItemSelectionDialog>(title); | ||||
|             mItemSelectionDialog->eventItemSelected += MyGUI::newDelegate(this, &AlchemyWindow::onItemSelected); | ||||
|             mItemSelectionDialog->eventDialogCanceled += MyGUI::newDelegate(this, &AlchemyWindow::onItemCancel); | ||||
|             mItemSelectionDialog->setVisible(true); | ||||
|             mItemSelectionDialog->openContainer(MWMechanics::getPlayer()); | ||||
|             mItemSelectionDialog->getSortModel()->setApparatusTypeFilter(i); | ||||
|             mItemSelectionDialog->setFilter(SortFilterItemModel::Filter_OnlyAlchemyTools); | ||||
|         } | ||||
|         else | ||||
|             removeApparatus(_sender); | ||||
| 
 | ||||
|         update(); | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::onSelectedItem(int index) | ||||
|     { | ||||
|         MWWorld::Ptr item = mSortModel->getItem(index).mBase; | ||||
|  | @ -395,6 +475,27 @@ namespace MWGui | |||
|         update(); | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::removeApparatus(MyGUI::Widget* apparatus) | ||||
|     { | ||||
|         for (size_t i = 0; i < mApparatus.size(); ++i) | ||||
|         { | ||||
|             const auto& widget = mApparatus[i]; | ||||
|             if (widget == apparatus) | ||||
|             { | ||||
|                 mAlchemy->removeApparatus(i); | ||||
| 
 | ||||
|                 if (widget->getChildCount()) | ||||
|                     MyGUI::Gui::getInstance().destroyWidget(widget->getChildAt(0)); | ||||
| 
 | ||||
|                 widget->clearUserStrings(); | ||||
| 
 | ||||
|                 widget->setItem(MWWorld::Ptr()); | ||||
| 
 | ||||
|                 widget->setUserData(MWWorld::Ptr()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::addRepeatController(MyGUI::Widget* widget) | ||||
|     { | ||||
|         MyGUI::ControllerItem* item | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include <components/widgets/box.hpp> | ||||
| #include <components/widgets/numericeditbox.hpp> | ||||
| 
 | ||||
| #include "itemselection.hpp" | ||||
| #include "windowbase.hpp" | ||||
| 
 | ||||
| #include "../mwmechanics/alchemy.hpp" | ||||
|  | @ -44,6 +45,8 @@ namespace MWGui | |||
|         }; | ||||
|         FilterType mCurrentFilter; | ||||
| 
 | ||||
|         std::unique_ptr<ItemSelectionDialog> mItemSelectionDialog; | ||||
| 
 | ||||
|         ItemView* mItemView; | ||||
|         InventoryItemModel* mModel; | ||||
|         SortFilterItemModel* mSortModel; | ||||
|  | @ -63,6 +66,7 @@ namespace MWGui | |||
|         void onCancelButtonClicked(MyGUI::Widget* _sender); | ||||
|         void onCreateButtonClicked(MyGUI::Widget* _sender); | ||||
|         void onIngredientSelected(MyGUI::Widget* _sender); | ||||
|         void onApparatusSelected(MyGUI::Widget* _sender); | ||||
|         void onAccept(MyGUI::EditBox*); | ||||
|         void onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); | ||||
|         void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); | ||||
|  | @ -85,6 +89,10 @@ namespace MWGui | |||
|         void onSelectedItem(int index); | ||||
| 
 | ||||
|         void removeIngredient(MyGUI::Widget* ingredient); | ||||
|         void removeApparatus(MyGUI::Widget* ingredient); | ||||
| 
 | ||||
|         void onItemSelected(MWWorld::Ptr item); | ||||
|         void onItemCancel(); | ||||
| 
 | ||||
|         void createPotions(int count); | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,6 +32,8 @@ namespace MWGui | |||
|         void setCategory(int category); | ||||
|         void setFilter(int filter); | ||||
| 
 | ||||
|         SortFilterItemModel* getSortModel() { return mSortModel; } | ||||
| 
 | ||||
|     private: | ||||
|         ItemView* mItemView; | ||||
|         SortFilterItemModel* mSortModel; | ||||
|  |  | |||
|  | @ -174,6 +174,7 @@ namespace MWGui | |||
|         : mCategory(Category_All) | ||||
|         , mFilter(0) | ||||
|         , mSortByType(true) | ||||
|         , mApparatusTypeFilter(-1) | ||||
|     { | ||||
|         mSourceModel = std::move(sourceModel); | ||||
|     } | ||||
|  | @ -311,6 +312,16 @@ namespace MWGui | |||
|                 return false; | ||||
|         } | ||||
| 
 | ||||
|         if ((mFilter & Filter_OnlyAlchemyTools)) | ||||
|         { | ||||
|             if (base.getType() != ESM::Apparatus::sRecordId) | ||||
|                 return false; | ||||
| 
 | ||||
|             int32_t apparatusType = base.get<ESM::Apparatus>()->mBase->mData.mType; | ||||
|             if (mApparatusTypeFilter >= 0 && apparatusType != mApparatusTypeFilter) | ||||
|                 return false; | ||||
|         } | ||||
| 
 | ||||
|         std::string compare = Utf8Stream::lowerCaseUtf8(item.mBase.getClass().getName(item.mBase)); | ||||
|         if (compare.find(mNameFilter) == std::string::npos) | ||||
|             return false; | ||||
|  | @ -352,6 +363,11 @@ namespace MWGui | |||
|         mEffectFilter = Utf8Stream::lowerCaseUtf8(filter); | ||||
|     } | ||||
| 
 | ||||
|     void SortFilterItemModel::setApparatusTypeFilter(const int32_t type) | ||||
|     { | ||||
|         mApparatusTypeFilter = type; | ||||
|     } | ||||
| 
 | ||||
|     void SortFilterItemModel::update() | ||||
|     { | ||||
|         mSourceModel->update(); | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ namespace MWGui | |||
|         void setFilter(int filter); | ||||
|         void setNameFilter(const std::string& filter); | ||||
|         void setEffectFilter(const std::string& filter); | ||||
|         void setApparatusTypeFilter(const int32_t type); | ||||
| 
 | ||||
|         /// Use ItemStack::Type for sorting?
 | ||||
|         void setSortByType(bool sort) { mSortByType = sort; } | ||||
|  | @ -49,6 +50,7 @@ namespace MWGui | |||
|         static constexpr int Filter_OnlyRepairable = (1 << 5); | ||||
|         static constexpr int Filter_OnlyRechargable = (1 << 6); | ||||
|         static constexpr int Filter_OnlyRepairTools = (1 << 7); | ||||
|         static constexpr int Filter_OnlyAlchemyTools = (1 << 8); | ||||
| 
 | ||||
|     private: | ||||
|         std::vector<ItemStack> mItems; | ||||
|  | @ -59,6 +61,7 @@ namespace MWGui | |||
|         int mFilter; | ||||
|         bool mSortByType; | ||||
| 
 | ||||
|         int32_t mApparatusTypeFilter; // filter by apparatus type
 | ||||
|         std::string mNameFilter; // filter by item name
 | ||||
|         std::string mEffectFilter; // filter by magic effect
 | ||||
|     }; | ||||
|  |  | |||
|  | @ -461,6 +461,24 @@ void MWMechanics::Alchemy::removeIngredient(int index) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void MWMechanics::Alchemy::addApparatus(const MWWorld::Ptr& apparatus) | ||||
| { | ||||
|     int32_t slot = apparatus.get<ESM::Apparatus>()->mBase->mData.mType; | ||||
| 
 | ||||
|     mTools[slot] = apparatus; | ||||
| 
 | ||||
|     updateEffects(); | ||||
| } | ||||
| 
 | ||||
| void MWMechanics::Alchemy::removeApparatus(int index) | ||||
| { | ||||
|     if (index >= 0 && index < static_cast<int>(mTools.size())) | ||||
|     { | ||||
|         mTools[index] = MWWorld::Ptr(); | ||||
|         updateEffects(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::beginEffects() const | ||||
| { | ||||
|     return mEffects.begin(); | ||||
|  |  | |||
|  | @ -119,9 +119,15 @@ namespace MWMechanics | |||
|         /// \return Slot index or -1, if adding failed because of no free slot or the ingredient type being
 | ||||
|         /// listed already.
 | ||||
| 
 | ||||
|         void addApparatus(const MWWorld::Ptr& apparatus); | ||||
|         ///< Add apparatus into the appropriate slot.
 | ||||
| 
 | ||||
|         void removeIngredient(int index); | ||||
|         ///< Remove ingredient from slot (calling this function on an empty slot is a no-op).
 | ||||
| 
 | ||||
|         void removeApparatus(int index); | ||||
|         ///< Remove apparatus from slot.
 | ||||
| 
 | ||||
|         std::string suggestPotionName(); | ||||
|         ///< Suggest a name for the potion, based on the current effects
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue