1
0
Fork 0
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:
Alexei Kotov 2024-04-03 18:21:02 +00:00
commit 3380b806de
5 changed files with 72 additions and 112 deletions

View file

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

View file

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

View file

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

View file

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

View file

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