1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-25 15:35:23 +00:00

The player can now barter with merchants

This commit is contained in:
gugus 2012-11-08 13:38:20 +01:00
parent bf98b95955
commit 0a883f4492
3 changed files with 74 additions and 7 deletions

View File

@ -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();
}

View File

@ -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; }

View File

@ -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();