mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:56:42 +00:00 
			
		
		
		
	Implement magic item recharging via soulgem use
This commit is contained in:
		
							parent
							
								
									16e5477c60
								
							
						
					
					
						commit
						cab535dd69
					
				
					 10 changed files with 287 additions and 1 deletions
				
			
		|  | @ -36,6 +36,7 @@ add_openmw_dir (mwgui | |||
|     merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks | ||||
|     keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview | ||||
|     tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog | ||||
|     recharge | ||||
|     ) | ||||
| 
 | ||||
| add_openmw_dir (mwdialogue | ||||
|  |  | |||
|  | @ -265,6 +265,7 @@ namespace MWBase | |||
|             virtual void showCompanionWindow(MWWorld::Ptr actor) = 0; | ||||
|             virtual void startSpellMaking(MWWorld::Ptr actor) = 0; | ||||
|             virtual void startEnchanting(MWWorld::Ptr actor) = 0; | ||||
|             virtual void startRecharge(MWWorld::Ptr soulgem) = 0; | ||||
|             virtual void startSelfEnchanting(MWWorld::Ptr soulgem) = 0; | ||||
|             virtual void startTraining(MWWorld::Ptr actor) = 0; | ||||
|             virtual void startRepair(MWWorld::Ptr actor) = 0; | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ namespace MWGui | |||
|       GM_Travel, | ||||
|       GM_SpellCreation, | ||||
|       GM_Enchanting, | ||||
|       GM_Recharge, | ||||
|       GM_Training, | ||||
|       GM_MerchantRepair, | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										194
									
								
								apps/openmw/mwgui/recharge.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								apps/openmw/mwgui/recharge.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,194 @@ | |||
| #include "recharge.hpp" | ||||
| 
 | ||||
| #include <boost/lexical_cast.hpp> | ||||
| #include <boost/format.hpp> | ||||
| 
 | ||||
| #include "../mwbase/world.hpp" | ||||
| #include "../mwbase/environment.hpp" | ||||
| #include "../mwbase/windowmanager.hpp" | ||||
| 
 | ||||
| #include "../mwworld/player.hpp" | ||||
| #include "../mwworld/containerstore.hpp" | ||||
| #include "../mwworld/class.hpp" | ||||
| 
 | ||||
| #include "../mwmechanics/creaturestats.hpp" | ||||
| #include "../mwmechanics/npcstats.hpp" | ||||
| 
 | ||||
| #include "widgets.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
| 
 | ||||
| Recharge::Recharge() | ||||
|     : WindowBase("openmw_recharge_dialog.layout") | ||||
| { | ||||
|     getWidget(mBox, "Box"); | ||||
|     getWidget(mView, "View"); | ||||
|     getWidget(mGemBox, "GemBox"); | ||||
|     getWidget(mGemIcon, "GemIcon"); | ||||
|     getWidget(mChargeLabel, "ChargeLabel"); | ||||
|     getWidget(mCancelButton, "CancelButton"); | ||||
| 
 | ||||
|     mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onCancel); | ||||
| 
 | ||||
|     setVisible(false); | ||||
| } | ||||
| 
 | ||||
| void Recharge::open() | ||||
| { | ||||
|     center(); | ||||
| } | ||||
| 
 | ||||
| void Recharge::start (const MWWorld::Ptr &item) | ||||
| { | ||||
|     std::string path = std::string("icons\\"); | ||||
|     path += MWWorld::Class::get(item).getInventoryIcon(item); | ||||
|     int pos = path.rfind("."); | ||||
|     path.erase(pos); | ||||
|     path.append(".dds"); | ||||
|     mGemIcon->setImageTexture (path); | ||||
|     mGemIcon->setUserString("ToolTipType", "ItemPtr"); | ||||
|     mGemIcon->setUserData(item); | ||||
| 
 | ||||
|     updateView(); | ||||
| } | ||||
| 
 | ||||
| void Recharge::updateView() | ||||
| { | ||||
|     MWWorld::Ptr gem = *mGemIcon->getUserData<MWWorld::Ptr>(); | ||||
| 
 | ||||
|     std::string soul = gem.getCellRef().mSoul; | ||||
|     const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul); | ||||
| 
 | ||||
|     mChargeLabel->setCaptionWithReplacing("#{sCharges} " + boost::lexical_cast<std::string>(creature->mData.mSoul)); | ||||
| 
 | ||||
|     bool toolBoxVisible = (gem.getRefData().getCount() != 0); | ||||
|     mGemBox->setVisible(toolBoxVisible); | ||||
| 
 | ||||
|     bool toolBoxWasVisible = (mBox->getPosition().top != mGemBox->getPosition().top); | ||||
| 
 | ||||
|     if (toolBoxVisible && !toolBoxWasVisible) | ||||
|     { | ||||
|         // shrink
 | ||||
|         mBox->setPosition(mBox->getPosition() + MyGUI::IntPoint(0, mGemBox->getSize().height)); | ||||
|         mBox->setSize(mBox->getSize() - MyGUI::IntSize(0,mGemBox->getSize().height)); | ||||
|     } | ||||
|     else if (!toolBoxVisible && toolBoxWasVisible) | ||||
|     { | ||||
|         // expand
 | ||||
|         mBox->setPosition(MyGUI::IntPoint (mBox->getPosition().left, mGemBox->getPosition().top)); | ||||
|         mBox->setSize(mBox->getSize() + MyGUI::IntSize(0,mGemBox->getSize().height)); | ||||
|     } | ||||
| 
 | ||||
|     while (mView->getChildCount()) | ||||
|         MyGUI::Gui::getInstance().destroyWidget(mView->getChildAt(0)); | ||||
| 
 | ||||
|     int currentY = 0; | ||||
| 
 | ||||
|     MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||
|     MWWorld::ContainerStore& store = MWWorld::Class::get(player).getContainerStore(player); | ||||
|     for (MWWorld::ContainerStoreIterator iter (store.begin()); | ||||
|          iter!=store.end(); ++iter) | ||||
|     { | ||||
|         std::string enchantmentName = iter->getClass().getEnchantment(*iter); | ||||
|         if (enchantmentName.empty()) | ||||
|             continue; | ||||
|         const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantmentName); | ||||
|         if (iter->getCellRef().mEnchantmentCharge >= enchantment->mData.mCharge | ||||
|                 || iter->getCellRef().mEnchantmentCharge == -1) | ||||
|             continue; | ||||
| 
 | ||||
|         MyGUI::TextBox* text = mView->createWidget<MyGUI::TextBox> ( | ||||
|                     "SandText", MyGUI::IntCoord(8, currentY, mView->getWidth()-8, 18), MyGUI::Align::Default); | ||||
|         text->setCaption(MWWorld::Class::get(*iter).getName(*iter)); | ||||
|         text->setNeedMouseFocus(false); | ||||
|         currentY += 19; | ||||
| 
 | ||||
|         MyGUI::ImageBox* icon = mView->createWidget<MyGUI::ImageBox> ( | ||||
|                     "ImageBox", MyGUI::IntCoord(16, currentY, 32, 32), MyGUI::Align::Default); | ||||
|         std::string path = std::string("icons\\"); | ||||
|         path += MWWorld::Class::get(*iter).getInventoryIcon(*iter); | ||||
|         int pos = path.rfind("."); | ||||
|         path.erase(pos); | ||||
|         path.append(".dds"); | ||||
|         icon->setImageTexture (path); | ||||
|         icon->setUserString("ToolTipType", "ItemPtr"); | ||||
|         icon->setUserData(*iter); | ||||
|         icon->eventMouseButtonClick += MyGUI::newDelegate(this, &Recharge::onItemClicked); | ||||
|         icon->eventMouseWheel += MyGUI::newDelegate(this, &Recharge::onMouseWheel); | ||||
| 
 | ||||
|         Widgets::MWDynamicStatPtr chargeWidget = mView->createWidget<Widgets::MWDynamicStat> | ||||
|                 ("MW_ChargeBar", MyGUI::IntCoord(72, currentY+2, 199, 20), MyGUI::Align::Default); | ||||
|         chargeWidget->setValue(iter->getCellRef().mEnchantmentCharge, enchantment->mData.mCharge); | ||||
|         chargeWidget->setNeedMouseFocus(false); | ||||
| 
 | ||||
|         currentY += 32 + 4; | ||||
|     } | ||||
|     mView->setCanvasSize (MyGUI::IntSize(mView->getWidth(), std::max(mView->getHeight(), currentY))); | ||||
| } | ||||
| 
 | ||||
| void Recharge::onCancel(MyGUI::Widget *sender) | ||||
| { | ||||
|     MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Recharge); | ||||
| } | ||||
| 
 | ||||
| void Recharge::onItemClicked(MyGUI::Widget *sender) | ||||
| { | ||||
|     MWWorld::Ptr gem = *mGemIcon->getUserData<MWWorld::Ptr>(); | ||||
| 
 | ||||
|     if (!gem.getRefData().getCount()) | ||||
|         return; | ||||
| 
 | ||||
|     MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>(); | ||||
| 
 | ||||
|     MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); | ||||
|     MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); | ||||
|     MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player); | ||||
| 
 | ||||
|     float luckTerm = 0.1 * stats.getAttribute(ESM::Attribute::Luck).getModified(); | ||||
|     if (luckTerm < 1|| luckTerm > 10) | ||||
|         luckTerm = 1; | ||||
| 
 | ||||
|     float intelligenceTerm = 0.2 * stats.getAttribute(ESM::Attribute::Intelligence).getModified(); | ||||
| 
 | ||||
|     if (intelligenceTerm > 20) | ||||
|         intelligenceTerm = 20; | ||||
|     if (intelligenceTerm < 1) | ||||
|         intelligenceTerm = 1; | ||||
| 
 | ||||
|     float x = (npcStats.getSkill(ESM::Skill::Enchant).getModified() + intelligenceTerm + luckTerm) * stats.getFatigueTerm(); | ||||
|     int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
 | ||||
|     if (roll < x) | ||||
|     { | ||||
|         std::string soul = gem.getCellRef().mSoul; | ||||
|         const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul); | ||||
| 
 | ||||
|         float restored = creature->mData.mSoul * (roll / x); | ||||
| 
 | ||||
|         const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find( | ||||
|                     item.getClass().getEnchantment(item)); | ||||
|         item.getCellRef().mEnchantmentCharge = | ||||
|             std::min(item.getCellRef().mEnchantmentCharge + restored, static_cast<float>(enchantment->mData.mCharge)); | ||||
|     } | ||||
| 
 | ||||
|     gem.getContainerStore()->remove(gem, 1, player); | ||||
| 
 | ||||
|     if (gem.getRefData().getCount() == 0) | ||||
|     { | ||||
|         std::string message = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage51")->getString(); | ||||
|         message = boost::str(boost::format(message) % gem.getClass().getName(gem)); | ||||
|         MWBase::Environment::get().getWindowManager()->messageBox(message); | ||||
|     } | ||||
| 
 | ||||
|     updateView(); | ||||
| } | ||||
| 
 | ||||
| void Recharge::onMouseWheel(MyGUI::Widget* _sender, int _rel) | ||||
| { | ||||
|     if (mView->getViewOffset().top + _rel*0.3 > 0) | ||||
|         mView->setViewOffset(MyGUI::IntPoint(0, 0)); | ||||
|     else | ||||
|         mView->setViewOffset(MyGUI::IntPoint(0, mView->getViewOffset().top + _rel*0.3)); | ||||
| } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										42
									
								
								apps/openmw/mwgui/recharge.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								apps/openmw/mwgui/recharge.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| #ifndef OPENMW_MWGUI_RECHARGE_H | ||||
| #define OPENMW_MWGUI_RECHARGE_H | ||||
| 
 | ||||
| #include "windowbase.hpp" | ||||
| 
 | ||||
| #include "../mwworld/ptr.hpp" | ||||
| 
 | ||||
| namespace MWGui | ||||
| { | ||||
| 
 | ||||
| class Recharge : public WindowBase | ||||
| { | ||||
| public: | ||||
|     Recharge(); | ||||
| 
 | ||||
|     virtual void open(); | ||||
| 
 | ||||
|     void start (const MWWorld::Ptr& gem); | ||||
| 
 | ||||
| protected: | ||||
|     MyGUI::Widget* mBox; | ||||
|     MyGUI::ScrollView* mView; | ||||
| 
 | ||||
|     MyGUI::Widget* mGemBox; | ||||
| 
 | ||||
|     MyGUI::ImageBox* mGemIcon; | ||||
| 
 | ||||
|     MyGUI::TextBox* mChargeLabel; | ||||
| 
 | ||||
|     MyGUI::Button* mCancelButton; | ||||
| 
 | ||||
|     void updateView(); | ||||
| 
 | ||||
|     void onItemClicked (MyGUI::Widget* sender); | ||||
|     void onCancel (MyGUI::Widget* sender); | ||||
|     void onMouseWheel(MyGUI::Widget* _sender, int _rel); | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  | @ -21,7 +21,8 @@ namespace MWGui | |||
|     { | ||||
|         if (button == 0) | ||||
|         { | ||||
|             /// \todo show recharge enchanted item dialog here
 | ||||
|             MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Recharge); | ||||
|             MWBase::Environment::get().getWindowManager()->startRecharge(mSoulgem); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ | |||
| #include "waitdialog.hpp" | ||||
| #include "enchantingdialog.hpp" | ||||
| #include "trainingwindow.hpp" | ||||
| #include "recharge.hpp" | ||||
| #include "exposedwindow.hpp" | ||||
| #include "cursor.hpp" | ||||
| #include "merchantrepair.hpp" | ||||
|  | @ -95,6 +96,7 @@ namespace MWGui | |||
|       , mTrainingWindow(NULL) | ||||
|       , mMerchantRepair(NULL) | ||||
|       , mSoulgemDialog(NULL) | ||||
|       , mRecharge(NULL) | ||||
|       , mRepair(NULL) | ||||
|       , mCompanionWindow(NULL) | ||||
|       , mTranslationDataStorage (translationDataStorage) | ||||
|  | @ -197,6 +199,7 @@ namespace MWGui | |||
|         mDragAndDrop->mDraggedWidget = 0; | ||||
|         mDragAndDrop->mDragAndDropWidget = dragAndDropWidget; | ||||
| 
 | ||||
|         mRecharge = new Recharge(); | ||||
|         mMenu = new MainMenu(w,h); | ||||
|         mMap = new MapWindow(""); | ||||
|         mStatsWindow = new StatsWindow(); | ||||
|  | @ -312,6 +315,7 @@ namespace MWGui | |||
|         delete mSoulgemDialog; | ||||
|         delete mSoftwareCursor; | ||||
|         delete mCursorManager; | ||||
|         delete mRecharge; | ||||
| 
 | ||||
|         cleanupGarbage(); | ||||
| 
 | ||||
|  | @ -375,6 +379,7 @@ namespace MWGui | |||
|         mRepair->setVisible(false); | ||||
|         mCompanionWindow->setVisible(false); | ||||
|         mInventoryWindow->setTrading(false); | ||||
|         mRecharge->setVisible(false); | ||||
| 
 | ||||
|         mHud->setVisible(mHudEnabled); | ||||
| 
 | ||||
|  | @ -492,6 +497,9 @@ namespace MWGui | |||
|             case GM_SpellCreation: | ||||
|                 mSpellCreationDialog->setVisible(true); | ||||
|                 break; | ||||
|             case GM_Recharge: | ||||
|                 mRecharge->setVisible(true); | ||||
|                 break; | ||||
|             case GM_Enchanting: | ||||
|                 mEnchantingDialog->setVisible(true); | ||||
|                 break; | ||||
|  | @ -1363,4 +1371,9 @@ namespace MWGui | |||
|         return mLoadingScreen; | ||||
|     } | ||||
| 
 | ||||
|     void WindowManager::startRecharge(MWWorld::Ptr soulgem) | ||||
|     { | ||||
|         mRecharge->start(soulgem); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -77,6 +77,7 @@ namespace MWGui | |||
|   class MerchantRepair; | ||||
|   class Repair; | ||||
|   class SoulgemDialog; | ||||
|   class Recharge; | ||||
|   class CompanionWindow; | ||||
| 
 | ||||
|   class WindowManager : public MWBase::WindowManager | ||||
|  | @ -263,6 +264,7 @@ namespace MWGui | |||
|     virtual void startTraining(MWWorld::Ptr actor); | ||||
|     virtual void startRepair(MWWorld::Ptr actor); | ||||
|     virtual void startRepairItem(MWWorld::Ptr item); | ||||
|     virtual void startRecharge(MWWorld::Ptr soulgem); | ||||
| 
 | ||||
|     virtual void frameStarted(float dt); | ||||
| 
 | ||||
|  | @ -313,6 +315,7 @@ namespace MWGui | |||
|     MerchantRepair* mMerchantRepair; | ||||
|     SoulgemDialog* mSoulgemDialog; | ||||
|     Repair* mRepair; | ||||
|     Recharge* mRecharge; | ||||
|     CompanionWindow* mCompanionWindow; | ||||
| 
 | ||||
|     Translation::Storage& mTranslationDataStorage; | ||||
|  |  | |||
|  | @ -81,6 +81,7 @@ set(MYGUI_FILES | |||
|     openmw_repair.layout | ||||
|     openmw_companion_window.layout | ||||
|     openmw_savegame_dialog.layout | ||||
|     openmw_recharge_dialog.layout | ||||
|     smallbars.png | ||||
|     DejaVuLGCSansMono.ttf | ||||
|     markers.png | ||||
|  |  | |||
							
								
								
									
										29
									
								
								files/mygui/openmw_recharge_dialog.layout
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								files/mygui/openmw_recharge_dialog.layout
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| 
 | ||||
| <MyGUI type="Layout"> | ||||
|     <Widget type="Window" skin="MW_Dialog" layer="Windows" position="0 0 329 253" name="_Main"> | ||||
| 
 | ||||
|         <Widget type="Widget" skin="" position="4 4 321 42" name="GemBox"> | ||||
|             <Widget type="ImageBox" skin="ImageBox" position="5 6 32 32" name="GemIcon"/> | ||||
| 
 | ||||
|             <Widget type="TextBox" skin="SandText" position="55 13 250 18" name="ChargeLabel"> | ||||
|                 <Property key="Caption" value="#{sQuality}"/> | ||||
|                 <Property key="TextAlign" value="Right"/> | ||||
|             </Widget> | ||||
| 
 | ||||
|         </Widget> | ||||
| 
 | ||||
|         <Widget type="Widget" skin="MW_Box" position="6 46 309 160" align="Left Stretch" name="Box"> | ||||
|             <Widget type="ScrollView" skin="MW_ScrollView" position="4 4 301 152" align="Left Top Stretch" name="View"> | ||||
|                 <Property key="CanvasAlign" value="Left"/> | ||||
|             </Widget> | ||||
|         </Widget> | ||||
| 
 | ||||
|         <Widget type="AutoSizedButton" skin="MW_Button" position="239 214 75 24" name="CancelButton"> | ||||
|             <Property key="ExpandDirection" value="Left"/> | ||||
|             <Property key="Caption" value="#{sCancel}"/> | ||||
|         </Widget> | ||||
| 
 | ||||
|     </Widget> | ||||
| 
 | ||||
| </MyGUI> | ||||
		Loading…
	
		Reference in a new issue