OSDN Git Service

Merge pull request #3561 from Hourier/Change-Signature-Terms
[hengbandforosx/hengbandosx.git] / src / store / pricing.cpp
1 #include "store/pricing.h"
2 #include "object/object-value.h"
3 #include "player/player-status-table.h"
4 #include "store/gold-magnification-table.h"
5 #include "store/store-owners.h"
6 #include "store/store-util.h"
7 #include "store/store.h"
8 #include "system/item-entity.h"
9 #include "system/player-type-definition.h"
10 #include "util/enum-converter.h"
11
12 /*!
13  * @brief 店舗価格を決定する. 無料にはならない /
14  * Determine the price of an item (qty one) in a store.
15  * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
16  * @param greed 店主の強欲度
17  * @param flip TRUEならば店主にとっての買取価格、FALSEなら売出価格を計算
18  * @return アイテムの店舗価格
19  * @details
20  * <pre>
21  * This function takes into account the player's charisma, and the
22  * shop-keepers friendliness, and the shop-keeper's base greed, but
23  * never lets a shop-keeper lose money in a transaction.
24  * The "greed" value should exceed 100 when the player is "buying" the
25  * item, and should be less than 100 when the player is "selling" it.
26  * Hack -- the black market always charges twice as much as it should.
27  * Charisma adjustment runs from 80 to 130
28  * Racial adjustment runs from 95 to 130
29  * Since greed/charisma/racial adjustments are centered at 100, we need
30  * to adjust (by 200) to extract a usable multiplier.  Note that the
31  * "greed" value is always something (?).
32  * </pre>
33  */
34 PRICE price_item(PlayerType *player_ptr, ItemEntity *o_ptr, int greed, bool flip, StoreSaleType store_num)
35 {
36     auto price = o_ptr->get_price();
37     if (price <= 0) {
38         return 0L;
39     }
40
41     int factor = rgold_adj[enum2i(ot_ptr->owner_race)][enum2i(player_ptr->prace)];
42     factor += adj_chr_gold[player_ptr->stat_index[A_CHR]];
43     int adjust;
44     if (flip) {
45         adjust = 100 + (300 - (greed + factor));
46         if (adjust > 100) {
47             adjust = 100;
48         }
49
50         if (store_num == StoreSaleType::BLACK) {
51             price = price / 2;
52         }
53
54         price = (price * adjust + 50L) / 100L;
55     } else {
56         adjust = 100 + ((greed + factor) - 300);
57         if (adjust < 100) {
58             adjust = 100;
59         }
60
61         if (store_num == StoreSaleType::BLACK) {
62             price = price * 2;
63         }
64
65         price = (int32_t)(((uint32_t)price * (uint32_t)adjust + 50UL) / 100UL);
66     }
67
68     if (price <= 0L) {
69         return 1L;
70     }
71
72     if (price >= LOW_PRICE_THRESHOLD) {
73         price += (flip ? -1 : 1) * price / 10;
74     }
75
76     return price;
77 }