mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 00:26:39 +00:00 
			
		
		
		
	The player can now barter with merchants
This commit is contained in:
		
							parent
							
								
									bf98b95955
								
							
						
					
					
						commit
						0a883f4492
					
				
					 3 changed files with 74 additions and 7 deletions
				
			
		| 
						 | 
				
			
			@ -11,6 +11,11 @@
 | 
			
		|||
#include "../mwworld/inventorystore.hpp"
 | 
			
		||||
#include "../mwworld/manualref.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../mwmechanics/creaturestats.hpp"
 | 
			
		||||
#include "../mwmechanics/npcstats.hpp"
 | 
			
		||||
 | 
			
		||||
#include "../mwworld/player.hpp"
 | 
			
		||||
 | 
			
		||||
#include "inventorywindow.hpp"
 | 
			
		||||
 | 
			
		||||
namespace MWGui
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +58,8 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
        mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onCancelButtonClicked);
 | 
			
		||||
        mOfferButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onOfferButtonClicked);
 | 
			
		||||
        mIncreaseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onIncreaseButtonClicked);
 | 
			
		||||
        mDecreaseButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TradeWindow::onDecreaseButtonClicked);
 | 
			
		||||
 | 
			
		||||
        setCoord(400, 0, 400, 300);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,6 +71,7 @@ namespace MWGui
 | 
			
		|||
        setTitle(MWWorld::Class::get(actor).getName(actor));
 | 
			
		||||
 | 
			
		||||
        mCurrentBalance = 0;
 | 
			
		||||
        mCurrentMerchantOffer = 0;
 | 
			
		||||
 | 
			
		||||
        mWindowManager.getInventoryWindow()->startTrade();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -175,6 +183,49 @@ namespace MWGui
 | 
			
		|||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(mCurrentBalance > mCurrentMerchantOffer)
 | 
			
		||||
        {
 | 
			
		||||
            /// \todo : if creature....
 | 
			
		||||
            //if npc is a creature: reject (no haggle)
 | 
			
		||||
 | 
			
		||||
            int a = abs(mCurrentMerchantOffer);
 | 
			
		||||
            int b = abs(mCurrentBalance);
 | 
			
		||||
            int d = 0;
 | 
			
		||||
            if (mCurrentMerchantOffer<0) d = int(100 * (a - b) / a);
 | 
			
		||||
            else d = int(100 * (b - a) / a);
 | 
			
		||||
 | 
			
		||||
            float clampedDisposition = std::max<int>(0,std::min<int>(int(MWBase::Environment::get().getMechanicsManager()->disposition(mPtr)),100));
 | 
			
		||||
 | 
			
		||||
            MWMechanics::NpcStats sellerSkill = MWWorld::Class::get(mPtr).getNpcStats(mPtr);
 | 
			
		||||
            MWMechanics::CreatureStats sellerStats = MWWorld::Class::get(mPtr).getCreatureStats(mPtr); 
 | 
			
		||||
            MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
 | 
			
		||||
            MWMechanics::NpcStats playerSkill = MWWorld::Class::get(playerPtr).getNpcStats(playerPtr);
 | 
			
		||||
            MWMechanics::CreatureStats playerStats = MWWorld::Class::get(playerPtr).getCreatureStats(playerPtr);
 | 
			
		||||
 | 
			
		||||
            float a1 = std::min<float>(playerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100);
 | 
			
		||||
            float b1 = std::min<float>(0.1 * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10);
 | 
			
		||||
            float c1 = std::min<float>(0.2 * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10);
 | 
			
		||||
            float d1 = std::min<float>(sellerSkill.getSkill(ESM::Skill::Mercantile).getModified(), 100);
 | 
			
		||||
            float e1 = std::min<float>(0.1 * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10);
 | 
			
		||||
            float f1 = std::min<float>(0.2 * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10);
 | 
			
		||||
 | 
			
		||||
            float pcTerm = (clampedDisposition - 50 + a1 + b1 + c1) * playerStats.getFatigueTerm();
 | 
			
		||||
            float npcTerm = (d1 + e1 + f1) * sellerStats.getFatigueTerm();
 | 
			
		||||
            float x = MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fBargainOfferMulti")->getFloat() * d + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fBargainOfferBase")->getFloat();
 | 
			
		||||
            if (mCurrentMerchantOffer<0) x += abs(int(pcTerm - npcTerm));
 | 
			
		||||
            else x += abs(int(npcTerm - pcTerm));
 | 
			
		||||
 | 
			
		||||
            int roll = std::rand()%100 + 1;
 | 
			
		||||
            if(roll > x) //trade refused
 | 
			
		||||
            {
 | 
			
		||||
                /// \todo adjust npc temporary disposition by iBarterSuccessDisposition or iBarterFailDisposition
 | 
			
		||||
                return ;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// \todo adjust npc temporary disposition by iBarterSuccessDisposition or iBarterFailDisposition
 | 
			
		||||
 | 
			
		||||
        // success! make the item transfer.
 | 
			
		||||
        transferBoughtItems();
 | 
			
		||||
        mWindowManager.getInventoryWindow()->transferBoughtItems();
 | 
			
		||||
| 
						 | 
				
			
			@ -199,6 +250,20 @@ namespace MWGui
 | 
			
		|||
        mWindowManager.removeGuiMode(GM_Barter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void TradeWindow::onIncreaseButtonClicked(MyGUI::Widget* _sender)
 | 
			
		||||
    {
 | 
			
		||||
        if(mCurrentBalance<=-1) mCurrentBalance -= 1;
 | 
			
		||||
        if(mCurrentBalance>=1) mCurrentBalance += 1;
 | 
			
		||||
        updateLabels();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void TradeWindow::onDecreaseButtonClicked(MyGUI::Widget* _sender)
 | 
			
		||||
    {
 | 
			
		||||
        if(mCurrentBalance<-1) mCurrentBalance += 1;
 | 
			
		||||
        if(mCurrentBalance>1) mCurrentBalance -= 1;
 | 
			
		||||
        updateLabels();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void TradeWindow::updateLabels()
 | 
			
		||||
    {
 | 
			
		||||
        mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(mWindowManager.getInventoryWindow()->getPlayerGold()));
 | 
			
		||||
| 
						 | 
				
			
			@ -317,20 +382,17 @@ namespace MWGui
 | 
			
		|||
 | 
			
		||||
    void TradeWindow::sellToNpc(MWWorld::Ptr item, int count)
 | 
			
		||||
    {
 | 
			
		||||
        /// \todo price adjustment depending on merchantile skill
 | 
			
		||||
 | 
			
		||||
        mCurrentBalance -= MWWorld::Class::get(item).getValue(item) * count
 | 
			
		||||
            + MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false);
 | 
			
		||||
 | 
			
		||||
        mCurrentBalance -= MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true);
 | 
			
		||||
        mCurrentMerchantOffer -= MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true);
 | 
			
		||||
        updateLabels();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void TradeWindow::buyFromNpc(MWWorld::Ptr item, int count)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        mCurrentBalance += MWWorld::Class::get(item).getValue(item) * count 
 | 
			
		||||
            -  MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,true);
 | 
			
		||||
 | 
			
		||||
        mCurrentBalance += MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false);
 | 
			
		||||
        mCurrentMerchantOffer += MWBase::Environment::get().getMechanicsManager()->barterOffer(mPtr, MWWorld::Class::get(item).getValue(item) * count,false);
 | 
			
		||||
        updateLabels();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,11 +55,14 @@ namespace MWGui
 | 
			
		|||
            MyGUI::TextBox* mMerchantGold;
 | 
			
		||||
 | 
			
		||||
            int mCurrentBalance;
 | 
			
		||||
            int mCurrentMerchantOffer;
 | 
			
		||||
 | 
			
		||||
            void onWindowResize(MyGUI::Window* _sender);
 | 
			
		||||
            void onFilterChanged(MyGUI::Widget* _sender);
 | 
			
		||||
            void onOfferButtonClicked(MyGUI::Widget* _sender);
 | 
			
		||||
            void onCancelButtonClicked(MyGUI::Widget* _sender);
 | 
			
		||||
            void onIncreaseButtonClicked(MyGUI::Widget* _sender);
 | 
			
		||||
            void onDecreaseButtonClicked(MyGUI::Widget* _sender);
 | 
			
		||||
 | 
			
		||||
            // don't show items that the NPC has equipped in his trade-window.
 | 
			
		||||
            virtual bool ignoreEquippedItems() { return true; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -384,6 +384,8 @@ namespace MWMechanics
 | 
			
		|||
        x += (MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionRankMult")->getFloat() * rank 
 | 
			
		||||
            + MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionRankBase")->getFloat()) 
 | 
			
		||||
            * MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispFactionMod")->getFloat() * reaction;
 | 
			
		||||
 | 
			
		||||
        /// \todo implement bounty and disease
 | 
			
		||||
        //x -= MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispCrimeMod") * pcBounty;
 | 
			
		||||
        //if (pc has a disease) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispDiseaseMod");
 | 
			
		||||
        if (playerSkill.getDrawState() == MWMechanics::DrawState_::DrawState_Weapon) x += MWBase::Environment::get().getWorld()->getStore().gameSettings.find("fDispWeaponDrawn")->getFloat();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue