mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 20:56:39 +00:00 
			
		
		
		
	auto-select the alchemy tools with highest quality
This commit is contained in:
		
							parent
							
								
									3ba24aee0d
								
							
						
					
					
						commit
						6eb15f7680
					
				
					 9 changed files with 218 additions and 9 deletions
				
			
		|  | @ -1,15 +1,46 @@ | |||
| #include "alchemywindow.hpp" | ||||
| 
 | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwworld/world.hpp" | ||||
| #include "../mwworld/player.hpp" | ||||
| #include "../mwworld/containerstore.hpp" | ||||
| 
 | ||||
| #include "window_manager.hpp" | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
|     std::string getIconPath(MWWorld::Ptr ptr) | ||||
|     { | ||||
|         std::string path = std::string("icons\\"); | ||||
|         path += MWWorld::Class::get(ptr).getInventoryIcon(ptr); | ||||
|         int pos = path.rfind("."); | ||||
|         path.erase(pos); | ||||
|         path.append(".dds"); | ||||
|         return path; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
|     AlchemyWindow::AlchemyWindow(WindowManager& parWindowManager) | ||||
|         : WindowBase("openmw_alchemy_window_layout.xml", parWindowManager) | ||||
|         , ContainerBase(0) | ||||
|     { | ||||
|         getWidget(mCreateButton, "CreateButton"); | ||||
|         getWidget(mCancelButton, "CancelButton"); | ||||
|         getWidget(mIngredient1, "Ingredient1"); | ||||
|         getWidget(mIngredient2, "Ingredient2"); | ||||
|         getWidget(mIngredient3, "Ingredient3"); | ||||
|         getWidget(mIngredient4, "Ingredient4"); | ||||
|         getWidget(mApparatus1, "Apparatus1"); | ||||
|         getWidget(mApparatus2, "Apparatus2"); | ||||
|         getWidget(mApparatus3, "Apparatus3"); | ||||
|         getWidget(mApparatus4, "Apparatus4"); | ||||
| 
 | ||||
|         mIngredient1->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||
|         mIngredient2->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||
|         mIngredient3->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||
|         mIngredient4->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onIngredientSelected); | ||||
| 
 | ||||
|         MyGUI::Widget* buttonBox = mCancelButton->getParent(); | ||||
|         int cancelButtonWidth = mCancelButton->getTextSize().width + 24; | ||||
|  | @ -22,6 +53,12 @@ namespace MWGui | |||
|         mCreateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCreateButtonClicked); | ||||
|         mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &AlchemyWindow::onCancelButtonClicked); | ||||
| 
 | ||||
|         MyGUI::ScrollView* itemView; | ||||
|         MyGUI::Widget* containerWidget; | ||||
|         getWidget(containerWidget, "Items"); | ||||
|         getWidget(itemView, "ItemView"); | ||||
|         setWidgets(containerWidget, itemView); | ||||
| 
 | ||||
|         center(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -34,4 +71,140 @@ namespace MWGui | |||
|     void AlchemyWindow::onCreateButtonClicked(MyGUI::Widget* _sender) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::open() | ||||
|     { | ||||
|         openContainer(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); | ||||
|         setFilter(ContainerBase::Filter_Ingredients); | ||||
| 
 | ||||
|         // pick the best available apparatus
 | ||||
|         MWWorld::ContainerStore& store = MWWorld::Class::get(mContainer).getContainerStore(mContainer); | ||||
| 
 | ||||
|         MWWorld::Ptr bestAlbemic; | ||||
|         MWWorld::Ptr bestMortarPestle; | ||||
|         MWWorld::Ptr bestCalcinator; | ||||
|         MWWorld::Ptr bestRetort; | ||||
| 
 | ||||
|         for (MWWorld::ContainerStoreIterator it(store.begin(MWWorld::ContainerStore::Type_Apparatus)); | ||||
|             it != store.end(); ++it) | ||||
|         { | ||||
|             ESMS::LiveCellRef<ESM::Apparatus, MWWorld::RefData>* ref = it->get<ESM::Apparatus>(); | ||||
|             if (ref->base->data.type == ESM::Apparatus::Albemic | ||||
|             && (bestAlbemic.isEmpty() || ref->base->data.quality > bestAlbemic.get<ESM::Apparatus>()->base->data.quality)) | ||||
|                 bestAlbemic = *it; | ||||
|             else if (ref->base->data.type == ESM::Apparatus::MortarPestle | ||||
|             && (bestMortarPestle.isEmpty() || ref->base->data.quality > bestMortarPestle.get<ESM::Apparatus>()->base->data.quality)) | ||||
|                 bestMortarPestle = *it; | ||||
|             else if (ref->base->data.type == ESM::Apparatus::Calcinator | ||||
|             && (bestCalcinator.isEmpty() || ref->base->data.quality > bestCalcinator.get<ESM::Apparatus>()->base->data.quality)) | ||||
|                 bestCalcinator = *it; | ||||
|             else if (ref->base->data.type == ESM::Apparatus::Retort | ||||
|             && (bestRetort.isEmpty() || ref->base->data.quality > bestRetort.get<ESM::Apparatus>()->base->data.quality)) | ||||
|                 bestRetort = *it; | ||||
|         } | ||||
| 
 | ||||
|         if (!bestMortarPestle.isEmpty()) | ||||
|         { | ||||
|             mApparatus1->setUserString("ToolTipType", "ItemPtr"); | ||||
|             mApparatus1->setUserData(bestMortarPestle); | ||||
|             mApparatus1->setImageTexture(getIconPath(bestMortarPestle)); | ||||
|         } | ||||
|         if (!bestAlbemic.isEmpty()) | ||||
|         { | ||||
|             mApparatus2->setUserString("ToolTipType", "ItemPtr"); | ||||
|             mApparatus2->setUserData(bestAlbemic); | ||||
|             mApparatus2->setImageTexture(getIconPath(bestAlbemic)); | ||||
|         } | ||||
|         if (!bestCalcinator.isEmpty()) | ||||
|         { | ||||
|             mApparatus3->setUserString("ToolTipType", "ItemPtr"); | ||||
|             mApparatus3->setUserData(bestCalcinator); | ||||
|             mApparatus3->setImageTexture(getIconPath(bestCalcinator)); | ||||
|         } | ||||
|         if (!bestRetort.isEmpty()) | ||||
|         { | ||||
|             mApparatus4->setUserString("ToolTipType", "ItemPtr"); | ||||
|             mApparatus4->setUserData(bestRetort); | ||||
|             mApparatus4->setImageTexture(getIconPath(bestRetort)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::onIngredientSelected(MyGUI::Widget* _sender) | ||||
|     { | ||||
|         _sender->clearUserStrings(); | ||||
|         static_cast<MyGUI::ImageBox*>(_sender)->setImageTexture(""); | ||||
|         if (_sender->getChildCount()) | ||||
|             MyGUI::Gui::getInstance().destroyWidget(_sender->getChildAt(0)); | ||||
|         drawItems(); | ||||
|         update(); | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::onSelectedItemImpl(MWWorld::Ptr item) | ||||
|     { | ||||
|         MyGUI::ImageBox* add = NULL; | ||||
| 
 | ||||
|         if (!mIngredient1->isUserString("ToolTipType")) | ||||
|             add = mIngredient1; | ||||
|         if (add == NULL  && !mIngredient2->isUserString("ToolTipType")) | ||||
|             add = mIngredient2; | ||||
|         if (add == NULL  && !mIngredient3->isUserString("ToolTipType")) | ||||
|             add = mIngredient3; | ||||
|         if (add == NULL  && !mIngredient4->isUserString("ToolTipType")) | ||||
|             add = mIngredient4; | ||||
| 
 | ||||
|         if (add != NULL) | ||||
|         { | ||||
|             add->setUserString("ToolTipType", "ItemPtr"); | ||||
|             add->setUserData(item); | ||||
|             add->setImageTexture(getIconPath(item)); | ||||
|             drawItems(); | ||||
|             update(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     std::vector<MWWorld::Ptr> AlchemyWindow::itemsToIgnore() | ||||
|     { | ||||
|         std::vector<MWWorld::Ptr> ignore; | ||||
|         // don't show ingredients that are currently selected in the "available ingredients" box.
 | ||||
|         if (mIngredient1->isUserString("ToolTipType")) | ||||
|             ignore.push_back(*mIngredient1->getUserData<MWWorld::Ptr>()); | ||||
|         if (mIngredient2->isUserString("ToolTipType")) | ||||
|             ignore.push_back(*mIngredient2->getUserData<MWWorld::Ptr>()); | ||||
|         if (mIngredient3->isUserString("ToolTipType")) | ||||
|             ignore.push_back(*mIngredient3->getUserData<MWWorld::Ptr>()); | ||||
|         if (mIngredient4->isUserString("ToolTipType")) | ||||
|             ignore.push_back(*mIngredient4->getUserData<MWWorld::Ptr>()); | ||||
| 
 | ||||
|         return ignore; | ||||
|     } | ||||
| 
 | ||||
|     void AlchemyWindow::update() | ||||
|     { | ||||
|         // update ingredient count labels
 | ||||
|         for (int i=0; i<4; ++i) | ||||
|         { | ||||
|             MyGUI::ImageBox* ingredient; | ||||
|             if (i==0) | ||||
|                 ingredient = mIngredient1; | ||||
|             else if (i==1) | ||||
|                 ingredient = mIngredient2; | ||||
|             else if (i==2) | ||||
|                 ingredient = mIngredient3; | ||||
|             else if (i==3) | ||||
|                 ingredient = mIngredient4; | ||||
| 
 | ||||
|             if (!ingredient->isUserString("ToolTipType")) | ||||
|                 continue; | ||||
| 
 | ||||
|             if (ingredient->getChildCount()) | ||||
|                 MyGUI::Gui::getInstance().destroyWidget(ingredient->getChildAt(0)); | ||||
| 
 | ||||
|             MyGUI::TextBox* text = ingredient->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(ingredient->getUserData<MWWorld::Ptr>()->getRefData().getCount())); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -2,20 +2,39 @@ | |||
| #define MWGUI_ALCHEMY_H | ||||
| 
 | ||||
| #include "window_base.hpp" | ||||
| #include "container.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
|     class AlchemyWindow : public WindowBase | ||||
|     class AlchemyWindow : public WindowBase, public ContainerBase | ||||
|     { | ||||
|     public: | ||||
|         AlchemyWindow(WindowManager& parWindowManager); | ||||
| 
 | ||||
|         virtual void open(); | ||||
| 
 | ||||
|     protected: | ||||
|         MyGUI::Button* mCreateButton; | ||||
|         MyGUI::Button* mCancelButton; | ||||
| 
 | ||||
|         MyGUI::ImageBox* mIngredient1; | ||||
|         MyGUI::ImageBox* mIngredient2; | ||||
|         MyGUI::ImageBox* mIngredient3; | ||||
|         MyGUI::ImageBox* mIngredient4; | ||||
| 
 | ||||
|         MyGUI::ImageBox* mApparatus1; | ||||
|         MyGUI::ImageBox* mApparatus2; | ||||
|         MyGUI::ImageBox* mApparatus3; | ||||
|         MyGUI::ImageBox* mApparatus4; | ||||
| 
 | ||||
|         void onCancelButtonClicked(MyGUI::Widget* _sender); | ||||
|         void onCreateButtonClicked(MyGUI::Widget* _sender); | ||||
|         void onIngredientSelected(MyGUI::Widget* _sender); | ||||
| 
 | ||||
|         virtual void onSelectedItemImpl(MWWorld::Ptr item); | ||||
|         virtual std::vector<MWWorld::Ptr> itemsToIgnore(); | ||||
| 
 | ||||
|         void update(); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -119,7 +119,7 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) | |||
|         else | ||||
|             onContainerClicked(mContainerWidget); | ||||
|     } | ||||
|     else | ||||
|     else if (isTrading()) | ||||
|     { | ||||
|         MWWorld::Ptr object = (*_sender->getUserData<MWWorld::Ptr>()); | ||||
|         int count = object.getRefData().getCount(); | ||||
|  | @ -179,6 +179,10 @@ void ContainerBase::onSelectedItem(MyGUI::Widget* _sender) | |||
|             } | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         onSelectedItemImpl(*_sender->getUserData<MWWorld::Ptr>()); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ContainerBase::sellAlreadyBoughtItem(MyGUI::Widget* _sender, int count) | ||||
|  | @ -383,6 +387,8 @@ void ContainerBase::drawItems() | |||
|                     + MWWorld::ContainerStore::Type_Lockpick + MWWorld::ContainerStore::Type_Light | ||||
|                     + MWWorld::ContainerStore::Type_Apparatus; | ||||
|     } | ||||
|     else if (mFilter == Filter_Ingredients) | ||||
|         categories = MWWorld::ContainerStore::Type_Ingredient; | ||||
| 
 | ||||
|     /// \todo performance improvement: don't create/destroy all the widgets everytime the container window changes size, only reposition them
 | ||||
| 
 | ||||
|  | @ -514,6 +520,7 @@ void ContainerBase::drawItems() | |||
|             text->setNeedMouseFocus(false); | ||||
|             text->setTextShadow(true); | ||||
|             text->setTextShadowColour(MyGUI::Colour(0,0,0)); | ||||
|             text->setCaption(getCountString(displayCount)); | ||||
| 
 | ||||
|             y += 42; | ||||
|             if (y > maxHeight) | ||||
|  | @ -522,7 +529,6 @@ void ContainerBase::drawItems() | |||
|                 y = 0; | ||||
|             } | ||||
| 
 | ||||
|             text->setCaption(getCountString(displayCount)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -55,7 +55,9 @@ namespace MWGui | |||
|             Filter_Weapon = 0x02, | ||||
|             Filter_Apparel = 0x03, | ||||
|             Filter_Magic = 0x04, | ||||
|             Filter_Misc = 0x05 | ||||
|             Filter_Misc = 0x05, | ||||
| 
 | ||||
|             Filter_Ingredients = 0x06 | ||||
|         }; | ||||
| 
 | ||||
|         enum ItemState | ||||
|  | @ -116,6 +118,8 @@ namespace MWGui | |||
| 
 | ||||
|         virtual bool isTrading() { return false; } | ||||
| 
 | ||||
|         virtual void onSelectedItemImpl(MWWorld::Ptr item) { ; } | ||||
| 
 | ||||
|         virtual bool ignoreEquippedItems() { return false; } | ||||
|         virtual std::vector<MWWorld::Ptr> itemsToIgnore() { return std::vector<MWWorld::Ptr>(); } | ||||
|     }; | ||||
|  |  | |||
|  | @ -97,7 +97,7 @@ namespace MWGui | |||
|         openContainer(player); | ||||
|     } | ||||
| 
 | ||||
|     void InventoryWindow::openInventory() | ||||
|     void InventoryWindow::open() | ||||
|     { | ||||
|         updateEncumbranceBar(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ namespace MWGui | |||
|         public: | ||||
|             InventoryWindow(WindowManager& parWindowManager,DragAndDrop* dragAndDrop); | ||||
| 
 | ||||
|             void openInventory(); | ||||
|             virtual void open(); | ||||
| 
 | ||||
|             /// start trading, disables item drag&drop
 | ||||
|             void startTrade(); | ||||
|  |  | |||
|  | @ -13,6 +13,15 @@ void WindowBase::open() | |||
| { | ||||
| } | ||||
| 
 | ||||
| void WindowBase::setVisible(bool visible) | ||||
| { | ||||
|     bool wasVisible = mMainWidget->getVisible(); | ||||
|     mMainWidget->setVisible(visible); | ||||
| 
 | ||||
|     if (!wasVisible && visible) | ||||
|         open(); | ||||
| } | ||||
| 
 | ||||
| void WindowBase::center() | ||||
| { | ||||
|     // Centre dialog
 | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ namespace MWGui | |||
|         typedef MyGUI::delegates::CMultiDelegate1<WindowBase*> EventHandle_WindowBase; | ||||
| 
 | ||||
|         virtual void open(); | ||||
|         virtual void setVisible(bool visible); // calls open() if visible is true and was false before
 | ||||
|         void center(); | ||||
| 
 | ||||
|         /** Event : Dialog finished, OK button clicked.\n
 | ||||
|  |  | |||
|  | @ -269,20 +269,17 @@ void WindowManager::updateVisible() | |||
|             map   -> setVisible( (eff & GW_Map) != 0 ); | ||||
|             mStatsWindow -> setVisible( (eff & GW_Stats) != 0 ); | ||||
|             mInventoryWindow->setVisible(true); | ||||
|             mInventoryWindow->openInventory(); | ||||
|             break; | ||||
|         } | ||||
|         case GM_Container: | ||||
|             mContainerWindow->setVisible(true); | ||||
|             mInventoryWindow->setVisible(true); | ||||
|             mInventoryWindow->openInventory(); | ||||
|             break; | ||||
|         case GM_Dialogue: | ||||
|             mDialogueWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_Barter: | ||||
|             mInventoryWindow->setVisible(true); | ||||
|             mInventoryWindow->openInventory(); | ||||
|             mTradeWindow->setVisible(true); | ||||
|             break; | ||||
|         case GM_InterMessageBox: | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue