mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Merge branch 'haggleraven' into 'master'
Remove superfluous Trading class See merge request OpenMW/openmw!3996
This commit is contained in:
commit
3380b806de
5 changed files with 72 additions and 112 deletions
|
@ -103,7 +103,7 @@ add_openmw_dir (mwmechanics
|
|||
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow aiavoiddoor aibreathe
|
||||
aicast aiescort aiface aiactivate aicombat recharge repair enchanting pathfinding pathgrid security spellcasting spellresistance
|
||||
disease pickpocket levelledlist combat steering obstacle autocalcspell difficultyscaling aicombataction summoning
|
||||
character actors objects aistate trading weaponpriority spellpriority weapontype spellutil
|
||||
character actors objects aistate weaponpriority spellpriority weapontype spellutil
|
||||
spelleffects
|
||||
)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <MyGUI_ControllerRepeatClick.h>
|
||||
#include <MyGUI_InputManager.h>
|
||||
|
||||
#include <components/misc/rng.hpp>
|
||||
#include <components/misc/strings/format.hpp>
|
||||
#include <components/widgets/numericeditbox.hpp>
|
||||
|
||||
|
@ -42,6 +43,75 @@ namespace
|
|||
return static_cast<int>(price * count);
|
||||
}
|
||||
|
||||
bool haggle(const MWWorld::Ptr& player, const MWWorld::Ptr& merchant, int playerOffer, int merchantOffer)
|
||||
{
|
||||
// accept if merchant offer is better than player offer
|
||||
if (playerOffer <= merchantOffer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// reject if npc is a creature
|
||||
if (merchant.getType() != ESM::NPC::sRecordId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst
|
||||
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
||||
|
||||
// Is the player buying?
|
||||
bool buying = (merchantOffer < 0);
|
||||
int a = std::abs(merchantOffer);
|
||||
int b = std::abs(playerOffer);
|
||||
int d = (buying) ? int(100 * (a - b) / a) : int(100 * (b - a) / b);
|
||||
|
||||
int clampedDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(merchant);
|
||||
|
||||
const MWMechanics::CreatureStats& merchantStats = merchant.getClass().getCreatureStats(merchant);
|
||||
const MWMechanics::CreatureStats& playerStats = player.getClass().getCreatureStats(player);
|
||||
|
||||
float a1 = static_cast<float>(player.getClass().getSkill(player, ESM::Skill::Mercantile));
|
||||
float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float c1 = 0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified();
|
||||
float d1 = static_cast<float>(merchant.getClass().getSkill(merchant, ESM::Skill::Mercantile));
|
||||
float e1 = 0.1f * merchantStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float f1 = 0.2f * merchantStats.getAttribute(ESM::Attribute::Personality).getModified();
|
||||
|
||||
float dispositionTerm = gmst.find("fDispositionMod")->mValue.getFloat() * (clampedDisposition - 50);
|
||||
float pcTerm = (dispositionTerm + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
||||
float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm();
|
||||
float x = gmst.find("fBargainOfferMulti")->mValue.getFloat() * d
|
||||
+ gmst.find("fBargainOfferBase")->mValue.getFloat() + int(pcTerm - npcTerm);
|
||||
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
int roll = Misc::Rng::rollDice(100, prng) + 1;
|
||||
|
||||
// reject if roll fails
|
||||
// (or if player tries to buy things and get money)
|
||||
if (roll > x || (merchantOffer < 0 && 0 < playerOffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// apply skill gain on successful barter
|
||||
float skillGain = 0.f;
|
||||
int finalPrice = std::abs(playerOffer);
|
||||
int initialMerchantOffer = std::abs(merchantOffer);
|
||||
|
||||
if (!buying && (finalPrice > initialMerchantOffer))
|
||||
{
|
||||
skillGain = std::floor(100.f * (finalPrice - initialMerchantOffer) / finalPrice);
|
||||
}
|
||||
else if (buying && (finalPrice < initialMerchantOffer))
|
||||
{
|
||||
skillGain = std::floor(100.f * (initialMerchantOffer - finalPrice) / initialMerchantOffer);
|
||||
}
|
||||
player.getClass().skillUsageSucceeded(
|
||||
player, ESM::Skill::Mercantile, ESM::Skill::Mercantile_Success, skillGain);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
|
@ -328,7 +398,7 @@ namespace MWGui
|
|||
}
|
||||
}
|
||||
|
||||
bool offerAccepted = mTrading.haggle(player, mPtr, mCurrentBalance, mCurrentMerchantOffer);
|
||||
bool offerAccepted = haggle(player, mPtr, mCurrentBalance, mCurrentMerchantOffer);
|
||||
|
||||
// apply disposition change if merchant is NPC
|
||||
if (mPtr.getClass().isNpc())
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef MWGUI_TRADEWINDOW_H
|
||||
#define MWGUI_TRADEWINDOW_H
|
||||
|
||||
#include "../mwmechanics/trading.hpp"
|
||||
|
||||
#include "referenceinterface.hpp"
|
||||
#include "windowbase.hpp"
|
||||
|
||||
|
@ -53,7 +51,6 @@ namespace MWGui
|
|||
ItemView* mItemView;
|
||||
SortFilterItemModel* mSortModel;
|
||||
TradeItemModel* mTradeModel;
|
||||
MWMechanics::Trading mTrading;
|
||||
|
||||
static const float sBalanceChangeInitialPause; // in seconds
|
||||
static const float sBalanceChangeInterval; // in seconds
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
#include "trading.hpp"
|
||||
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
|
||||
#include "creaturestats.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
Trading::Trading() {}
|
||||
|
||||
bool Trading::haggle(const MWWorld::Ptr& player, const MWWorld::Ptr& merchant, int playerOffer, int merchantOffer)
|
||||
{
|
||||
// accept if merchant offer is better than player offer
|
||||
if (playerOffer <= merchantOffer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// reject if npc is a creature
|
||||
if (merchant.getType() != ESM::NPC::sRecordId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst
|
||||
= MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>();
|
||||
|
||||
// Is the player buying?
|
||||
bool buying = (merchantOffer < 0);
|
||||
int a = std::abs(merchantOffer);
|
||||
int b = std::abs(playerOffer);
|
||||
int d = (buying) ? int(100 * (a - b) / a) : int(100 * (b - a) / b);
|
||||
|
||||
int clampedDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(merchant);
|
||||
|
||||
const MWMechanics::CreatureStats& merchantStats = merchant.getClass().getCreatureStats(merchant);
|
||||
const MWMechanics::CreatureStats& playerStats = player.getClass().getCreatureStats(player);
|
||||
|
||||
float a1 = static_cast<float>(player.getClass().getSkill(player, ESM::Skill::Mercantile));
|
||||
float b1 = 0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float c1 = 0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified();
|
||||
float d1 = static_cast<float>(merchant.getClass().getSkill(merchant, ESM::Skill::Mercantile));
|
||||
float e1 = 0.1f * merchantStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float f1 = 0.2f * merchantStats.getAttribute(ESM::Attribute::Personality).getModified();
|
||||
|
||||
float dispositionTerm = gmst.find("fDispositionMod")->mValue.getFloat() * (clampedDisposition - 50);
|
||||
float pcTerm = (dispositionTerm + a1 + b1 + c1) * playerStats.getFatigueTerm();
|
||||
float npcTerm = (d1 + e1 + f1) * merchantStats.getFatigueTerm();
|
||||
float x = gmst.find("fBargainOfferMulti")->mValue.getFloat() * d
|
||||
+ gmst.find("fBargainOfferBase")->mValue.getFloat() + int(pcTerm - npcTerm);
|
||||
|
||||
auto& prng = MWBase::Environment::get().getWorld()->getPrng();
|
||||
int roll = Misc::Rng::rollDice(100, prng) + 1;
|
||||
|
||||
// reject if roll fails
|
||||
// (or if player tries to buy things and get money)
|
||||
if (roll > x || (merchantOffer < 0 && 0 < playerOffer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// apply skill gain on successful barter
|
||||
float skillGain = 0.f;
|
||||
int finalPrice = std::abs(playerOffer);
|
||||
int initialMerchantOffer = std::abs(merchantOffer);
|
||||
|
||||
if (!buying && (finalPrice > initialMerchantOffer))
|
||||
{
|
||||
skillGain = std::floor(100.f * (finalPrice - initialMerchantOffer) / finalPrice);
|
||||
}
|
||||
else if (buying && (finalPrice < initialMerchantOffer))
|
||||
{
|
||||
skillGain = std::floor(100.f * (initialMerchantOffer - finalPrice) / initialMerchantOffer);
|
||||
}
|
||||
player.getClass().skillUsageSucceeded(
|
||||
player, ESM::Skill::Mercantile, ESM::Skill::Mercantile_Success, skillGain);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#ifndef OPENMW_MECHANICS_TRADING_H
|
||||
#define OPENMW_MECHANICS_TRADING_H
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Ptr;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
class Trading
|
||||
{
|
||||
public:
|
||||
Trading();
|
||||
|
||||
bool haggle(const MWWorld::Ptr& player, const MWWorld::Ptr& merchant, int playerOffer, int merchantOffer);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue