OSDN Git Service

[Style] clang-format をすべてのヘッダファイルにも適用する
[hengbandforosx/hengbandosx.git] / src / object / object-value.cpp
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"
17
18 /*!
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 オブジェクトの未鑑定価格
23  */
24 static PRICE object_value_base(const ObjectType *o_ptr)
25 {
26     if (o_ptr->is_aware()) {
27         return k_info[o_ptr->k_idx].cost;
28     }
29
30     switch (o_ptr->tval) {
31     case ItemKindType::FOOD:
32         return 5;
33     case ItemKindType::POTION:
34         return 20;
35     case ItemKindType::SCROLL:
36         return 20;
37     case ItemKindType::STAFF:
38         return 70;
39     case ItemKindType::WAND:
40         return 50;
41     case ItemKindType::ROD:
42         return 90;
43     case ItemKindType::RING:
44         return 45;
45     case ItemKindType::AMULET:
46         return 45;
47     case ItemKindType::FIGURINE: {
48         DEPTH level = r_info[o_ptr->pval].level;
49         if (level < 20) {
50             return level * 50L;
51         } else if (level < 30) {
52             return 1000 + (level - 20) * 150;
53         } else if (level < 40) {
54             return 2500 + (level - 30) * 350;
55         } else if (level < 50) {
56             return 6000 + (level - 40) * 800;
57         } else {
58             return 14000 + (level - 50) * 2000;
59         }
60     }
61     case ItemKindType::CAPTURE:
62         if (!o_ptr->pval) {
63             return 1000;
64         } else {
65             return (r_info[o_ptr->pval].level) * 50 + 1000;
66         }
67
68     default:
69         break;
70     }
71
72     return 0;
73 }
74
75 /*!
76  * @brief オブジェクト価格算出のメインルーチン /
77  * Return the price of an item including plusses (and charges)
78  * @param o_ptr 判明している現価格を確認したいオブジェクトの構造体参照ポインタ
79  * @return オブジェクトの判明している現価格
80  * @details
81  * This function returns the "value" of the given item (qty one)\n
82  *\n
83  * Never notice "unknown" bonuses or properties, including "curses",\n
84  * since that would give the player information he did not have.\n
85  *\n
86  * Note that discounted items stay discounted forever, even if\n
87  * the discount is "forgotten" by the player via memory loss.\n
88  */
89 PRICE object_value(const ObjectType *o_ptr)
90 {
91     PRICE value;
92
93     if (o_ptr->is_known()) {
94         if (o_ptr->is_broken()) {
95             return 0;
96         }
97         if (o_ptr->is_cursed()) {
98             return 0;
99         }
100
101         value = object_value_real(o_ptr);
102     } else {
103         if ((o_ptr->ident & (IDENT_SENSE)) && o_ptr->is_broken()) {
104             return 0;
105         }
106         if ((o_ptr->ident & (IDENT_SENSE)) && o_ptr->is_cursed()) {
107             return 0;
108         }
109
110         value = object_value_base(o_ptr);
111     }
112
113     if (o_ptr->discount) {
114         value -= (value * o_ptr->discount / 100L);
115     }
116
117     return value;
118 }
119
120 /*!
121  * @brief オブジェクトの真の価格を算出する /
122  * Return the value of the flags the object has...
123  * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
124  * @return オブジェクトの本価格
125  * @details
126  * Return the "real" price of a "known" item, not including discounts\n
127  *\n
128  * Wand and staffs get cost for each charge\n
129  *\n
130  * Armor is worth an extra 100 gold per bonus point to armor class.\n
131  *\n
132  * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
133  *\n
134  * Missiles are only worth 5 gold per bonus point, since they\n
135  * usually appear in groups of 20, and we want the player to get\n
136  * the same amount of cash for any "equivalent" item.  Note that\n
137  * missiles never have any of the "pval" flags, and in fact, they\n
138  * only have a few of the available flags, primarily of the "slay"\n
139  * and "brand" and "ignore" variety.\n
140  *\n
141  * Armor with a negative armor bonus is worthless.\n
142  * Weapons with negative hit+damage bonuses are worthless.\n
143  *\n
144  * Every wearable item with a "pval" bonus is worth extra (see below).\n
145  */
146 PRICE object_value_real(const ObjectType *o_ptr)
147 {
148     auto *k_ptr = &k_info[o_ptr->k_idx];
149
150     if (!k_info[o_ptr->k_idx].cost) {
151         return 0;
152     }
153
154     PRICE value = k_info[o_ptr->k_idx].cost;
155     auto flgs = object_flags(o_ptr);
156     if (o_ptr->is_fixed_artifact()) {
157         auto *a_ptr = &a_info[o_ptr->fixed_artifact_idx];
158         if (!a_ptr->cost) {
159             return 0;
160         }
161
162         value = a_ptr->cost;
163         value += flag_cost(o_ptr, o_ptr->pval);
164         return value;
165     } else if (o_ptr->is_ego()) {
166         auto *e_ptr = &e_info[o_ptr->ego_idx];
167         if (!e_ptr->cost) {
168             return 0;
169         }
170
171         value += e_ptr->cost;
172         value += flag_cost(o_ptr, o_ptr->pval);
173     } else {
174         if (o_ptr->art_flags.any()) {
175             value += flag_cost(o_ptr, o_ptr->pval);
176         }
177     }
178
179     /* Analyze pval bonus for normal object */
180     switch (o_ptr->tval) {
181     case ItemKindType::SHOT:
182     case ItemKindType::ARROW:
183     case ItemKindType::BOLT:
184     case ItemKindType::BOW:
185     case ItemKindType::DIGGING:
186     case ItemKindType::HAFTED:
187     case ItemKindType::POLEARM:
188     case ItemKindType::SWORD:
189     case ItemKindType::BOOTS:
190     case ItemKindType::GLOVES:
191     case ItemKindType::HELM:
192     case ItemKindType::CROWN:
193     case ItemKindType::SHIELD:
194     case ItemKindType::CLOAK:
195     case ItemKindType::SOFT_ARMOR:
196     case ItemKindType::HARD_ARMOR:
197     case ItemKindType::DRAG_ARMOR:
198     case ItemKindType::LITE:
199     case ItemKindType::AMULET:
200     case ItemKindType::RING:
201         if (!o_ptr->pval) {
202             break;
203         }
204         if (o_ptr->pval < 0) {
205             return 0;
206         }
207
208         if (flgs.has(TR_STR)) {
209             value += (o_ptr->pval * 200L);
210         }
211         if (flgs.has(TR_INT)) {
212             value += (o_ptr->pval * 200L);
213         }
214         if (flgs.has(TR_WIS)) {
215             value += (o_ptr->pval * 200L);
216         }
217         if (flgs.has(TR_DEX)) {
218             value += (o_ptr->pval * 200L);
219         }
220         if (flgs.has(TR_CON)) {
221             value += (o_ptr->pval * 200L);
222         }
223         if (flgs.has(TR_CHR)) {
224             value += (o_ptr->pval * 200L);
225         }
226         if (flgs.has(TR_MAGIC_MASTERY)) {
227             value += (o_ptr->pval * 100);
228         }
229         if (flgs.has(TR_STEALTH)) {
230             value += (o_ptr->pval * 100L);
231         }
232         if (flgs.has(TR_SEARCH)) {
233             value += (o_ptr->pval * 100L);
234         }
235         if (flgs.has(TR_INFRA)) {
236             value += (o_ptr->pval * 50L);
237         }
238         if (flgs.has(TR_TUNNEL)) {
239             value += (o_ptr->pval * 50L);
240         }
241         if (flgs.has(TR_BLOWS)) {
242             value += (o_ptr->pval * 5000L);
243         }
244         if (flgs.has(TR_SPEED)) {
245             value += (o_ptr->pval * 10000L);
246         }
247         break;
248
249     default:
250         break;
251     }
252
253     switch (o_ptr->tval) {
254     case ItemKindType::WAND: {
255         /* Pay extra for charges, depending on standard number of
256          * charges.  Handle new-style wands correctly. -LM-
257          */
258         value += (value * o_ptr->pval / o_ptr->number / (k_ptr->pval * 2));
259         break;
260     }
261     case ItemKindType::STAFF: {
262         /* Pay extra for charges, depending on standard number of
263          * charges.  -LM-
264          */
265         value += (value * o_ptr->pval / (k_ptr->pval * 2));
266         break;
267     }
268     case ItemKindType::RING:
269     case ItemKindType::AMULET: {
270         if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0) {
271             return 0;
272         }
273
274         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
275         break;
276     }
277     case ItemKindType::BOOTS:
278     case ItemKindType::GLOVES:
279     case ItemKindType::CLOAK:
280     case ItemKindType::CROWN:
281     case ItemKindType::HELM:
282     case ItemKindType::SHIELD:
283     case ItemKindType::SOFT_ARMOR:
284     case ItemKindType::HARD_ARMOR:
285     case ItemKindType::DRAG_ARMOR: {
286         if (o_ptr->to_a < 0) {
287             return 0;
288         }
289
290         value += (((o_ptr->to_h - k_ptr->to_h) + (o_ptr->to_d - k_ptr->to_d)) * 200L + (o_ptr->to_a) * 100L);
291         break;
292     }
293     case ItemKindType::BOW:
294     case ItemKindType::DIGGING:
295     case ItemKindType::HAFTED:
296     case ItemKindType::SWORD:
297     case ItemKindType::POLEARM: {
298         if (o_ptr->to_h + o_ptr->to_d < 0) {
299             return 0;
300         }
301
302         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
303         value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 250L;
304         value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 250L;
305         break;
306     }
307     case ItemKindType::SHOT:
308     case ItemKindType::ARROW:
309     case ItemKindType::BOLT: {
310         if (o_ptr->to_h + o_ptr->to_d < 0) {
311             return 0;
312         }
313
314         value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
315         value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 5L;
316         value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 5L;
317         break;
318     }
319     case ItemKindType::FIGURINE: {
320         DEPTH level = r_info[o_ptr->pval].level;
321         if (level < 20) {
322             value = level * 50L;
323         } else if (level < 30) {
324             value = 1000 + (level - 20) * 150L;
325         } else if (level < 40) {
326             value = 2500 + (level - 30) * 350L;
327         } else if (level < 50) {
328             value = 6000 + (level - 40) * 800L;
329         } else {
330             value = 14000 + (level - 50) * 2000L;
331         }
332         break;
333     }
334     case ItemKindType::CAPTURE: {
335         if (!o_ptr->pval) {
336             value = 1000L;
337         } else {
338             value = ((r_info[o_ptr->pval].level) * 50L + 1000);
339         }
340         break;
341     }
342     case ItemKindType::CHEST: {
343         if (!o_ptr->pval) {
344             value = 0L;
345         }
346         break;
347     }
348
349     default:
350         break;
351     }
352
353     if (value < 0) {
354         return 0L;
355     }
356
357     return value;
358 }