1 #include "object/object-value.h"
2 #include "monster-race/monster-race.h"
3 #include "object-enchant/object-curse.h"
4 #include "object-enchant/object-ego.h"
5 #include "object-enchant/special-object-flags.h"
6 #include "object-enchant/tr-types.h"
7 #include "object/object-broken.h"
8 #include "object/object-flags.h"
9 #include "object/object-kind.h"
10 #include "object/object-value-calc.h"
11 #include "perception/object-perception.h"
12 #include "system/artifact-type-definition.h"
13 #include "system/monster-race-definition.h"
14 #include "system/object-type-definition.h"
15 #include "system/player-type-definition.h"
16 #include "util/bit-flags-calculator.h"
19 * @brief 未鑑定なベースアイテムの基本価格を返す /
20 * Return the "value" of an "unknown" item Make a guess at the value of non-aware items
21 * @param o_ptr 未鑑定価格を確認したいオブジェクトの構造体参照ポインタ
22 * @return オブジェクトの未鑑定価格
24 static PRICE object_value_base(const object_type *o_ptr)
26 if (o_ptr->is_aware())
27 return (k_info[o_ptr->k_idx].cost);
29 switch (o_ptr->tval) {
30 case ItemKindType::FOOD:
32 case ItemKindType::POTION:
34 case ItemKindType::SCROLL:
36 case ItemKindType::STAFF:
38 case ItemKindType::WAND:
40 case ItemKindType::ROD:
42 case ItemKindType::RING:
44 case ItemKindType::AMULET:
46 case ItemKindType::FIGURINE: {
47 DEPTH level = r_info[o_ptr->pval].level;
51 return 1000 + (level - 20) * 150L;
53 return 2500 + (level - 30) * 350L;
55 return 6000 + (level - 40) * 800L;
57 return 14000 + (level - 50) * 2000L;
59 case ItemKindType::CAPTURE:
63 return ((r_info[o_ptr->pval].level) * 50L + 1000);
73 * @brief オブジェクト価格算出のメインルーチン /
74 * Return the price of an item including plusses (and charges)
75 * @param o_ptr 判明している現価格を確認したいオブジェクトの構造体参照ポインタ
76 * @return オブジェクトの判明している現価格
78 * This function returns the "value" of the given item (qty one)\n
80 * Never notice "unknown" bonuses or properties, including "curses",\n
81 * since that would give the player information he did not have.\n
83 * Note that discounted items stay discounted forever, even if\n
84 * the discount is "forgotten" by the player via memory loss.\n
86 PRICE object_value(const object_type *o_ptr)
90 if (o_ptr->is_known()) {
91 if (o_ptr->is_broken())
93 if (o_ptr->is_cursed())
96 value = object_value_real(o_ptr);
98 if ((o_ptr->ident & (IDENT_SENSE)) && o_ptr->is_broken())
100 if ((o_ptr->ident & (IDENT_SENSE)) && o_ptr->is_cursed())
103 value = object_value_base(o_ptr);
107 value -= (value * o_ptr->discount / 100L);
113 * @brief オブジェクトの真の価格を算出する /
114 * Return the value of the flags the object has...
115 * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
118 * Return the "real" price of a "known" item, not including discounts\n
120 * Wand and staffs get cost for each charge\n
122 * Armor is worth an extra 100 gold per bonus point to armor class.\n
124 * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
126 * Missiles are only worth 5 gold per bonus point, since they\n
127 * usually appear in groups of 20, and we want the player to get\n
128 * the same amount of cash for any "equivalent" item. Note that\n
129 * missiles never have any of the "pval" flags, and in fact, they\n
130 * only have a few of the available flags, primarily of the "slay"\n
131 * and "brand" and "ignore" variety.\n
133 * Armor with a negative armor bonus is worthless.\n
134 * Weapons with negative hit+damage bonuses are worthless.\n
136 * Every wearable item with a "pval" bonus is worth extra (see below).\n
138 PRICE object_value_real(const object_type *o_ptr)
140 object_kind *k_ptr = &k_info[o_ptr->k_idx];
142 if (!k_info[o_ptr->k_idx].cost)
145 PRICE value = k_info[o_ptr->k_idx].cost;
146 auto flgs = object_flags(o_ptr);
147 if (o_ptr->is_fixed_artifact()) {
148 artifact_type *a_ptr = &a_info[o_ptr->name1];
153 value += flag_cost(o_ptr, o_ptr->pval);
155 } else if (o_ptr->is_ego()) {
156 ego_item_type *e_ptr = &e_info[o_ptr->name2];
160 value += e_ptr->cost;
161 value += flag_cost(o_ptr, o_ptr->pval);
163 if (o_ptr->art_flags.any())
164 value += flag_cost(o_ptr, o_ptr->pval);
167 /* Analyze pval bonus for normal object */
168 switch (o_ptr->tval) {
169 case ItemKindType::SHOT:
170 case ItemKindType::ARROW:
171 case ItemKindType::BOLT:
172 case ItemKindType::BOW:
173 case ItemKindType::DIGGING:
174 case ItemKindType::HAFTED:
175 case ItemKindType::POLEARM:
176 case ItemKindType::SWORD:
177 case ItemKindType::BOOTS:
178 case ItemKindType::GLOVES:
179 case ItemKindType::HELM:
180 case ItemKindType::CROWN:
181 case ItemKindType::SHIELD:
182 case ItemKindType::CLOAK:
183 case ItemKindType::SOFT_ARMOR:
184 case ItemKindType::HARD_ARMOR:
185 case ItemKindType::DRAG_ARMOR:
186 case ItemKindType::LITE:
187 case ItemKindType::AMULET:
188 case ItemKindType::RING:
194 if (flgs.has(TR_STR))
195 value += (o_ptr->pval * 200L);
196 if (flgs.has(TR_INT))
197 value += (o_ptr->pval * 200L);
198 if (flgs.has(TR_WIS))
199 value += (o_ptr->pval * 200L);
200 if (flgs.has(TR_DEX))
201 value += (o_ptr->pval * 200L);
202 if (flgs.has(TR_CON))
203 value += (o_ptr->pval * 200L);
204 if (flgs.has(TR_CHR))
205 value += (o_ptr->pval * 200L);
206 if (flgs.has(TR_MAGIC_MASTERY))
207 value += (o_ptr->pval * 100);
208 if (flgs.has(TR_STEALTH))
209 value += (o_ptr->pval * 100L);
210 if (flgs.has(TR_SEARCH))
211 value += (o_ptr->pval * 100L);
212 if (flgs.has(TR_INFRA))
213 value += (o_ptr->pval * 50L);
214 if (flgs.has(TR_TUNNEL))
215 value += (o_ptr->pval * 50L);
216 if (flgs.has(TR_BLOWS))
217 value += (o_ptr->pval * 5000L);
218 if (flgs.has(TR_SPEED))
219 value += (o_ptr->pval * 10000L);
226 switch (o_ptr->tval) {
227 case ItemKindType::WAND: {
228 /* Pay extra for charges, depending on standard number of
229 * charges. Handle new-style wands correctly. -LM-
231 value += (value * o_ptr->pval / o_ptr->number / (k_ptr->pval * 2));
234 case ItemKindType::STAFF: {
235 /* Pay extra for charges, depending on standard number of
238 value += (value * o_ptr->pval / (k_ptr->pval * 2));
241 case ItemKindType::RING:
242 case ItemKindType::AMULET: {
243 if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0)
246 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
249 case ItemKindType::BOOTS:
250 case ItemKindType::GLOVES:
251 case ItemKindType::CLOAK:
252 case ItemKindType::CROWN:
253 case ItemKindType::HELM:
254 case ItemKindType::SHIELD:
255 case ItemKindType::SOFT_ARMOR:
256 case ItemKindType::HARD_ARMOR:
257 case ItemKindType::DRAG_ARMOR: {
261 value += (((o_ptr->to_h - k_ptr->to_h) + (o_ptr->to_d - k_ptr->to_d)) * 200L + (o_ptr->to_a) * 100L);
264 case ItemKindType::BOW:
265 case ItemKindType::DIGGING:
266 case ItemKindType::HAFTED:
267 case ItemKindType::SWORD:
268 case ItemKindType::POLEARM: {
269 if (o_ptr->to_h + o_ptr->to_d < 0)
272 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
273 value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 250L;
274 value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 250L;
277 case ItemKindType::SHOT:
278 case ItemKindType::ARROW:
279 case ItemKindType::BOLT: {
280 if (o_ptr->to_h + o_ptr->to_d < 0)
283 value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
284 value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 5L;
285 value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 5L;
288 case ItemKindType::FIGURINE: {
289 DEPTH level = r_info[o_ptr->pval].level;
293 value = 1000 + (level - 20) * 150L;
295 value = 2500 + (level - 30) * 350L;
297 value = 6000 + (level - 40) * 800L;
299 value = 14000 + (level - 50) * 2000L;
302 case ItemKindType::CAPTURE: {
306 value = ((r_info[o_ptr->pval].level) * 50L + 1000);
309 case ItemKindType::CHEST: {