OSDN Git Service

[Refactor] #2124 Changed struct object_type to class ObjectType
[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     switch (o_ptr->tval) {
30     case ItemKindType::FOOD:
31         return (5L);
32     case ItemKindType::POTION:
33         return (20L);
34     case ItemKindType::SCROLL:
35         return (20L);
36     case ItemKindType::STAFF:
37         return (70L);
38     case ItemKindType::WAND:
39         return (50L);
40     case ItemKindType::ROD:
41         return (90L);
42     case ItemKindType::RING:
43         return (45L);
44     case ItemKindType::AMULET:
45         return (45L);
46     case ItemKindType::FIGURINE: {
47         DEPTH level = r_info[o_ptr->pval].level;
48         if (level < 20)
49             return level * 50L;
50         else if (level < 30)
51             return 1000 + (level - 20) * 150L;
52         else if (level < 40)
53             return 2500 + (level - 30) * 350L;
54         else if (level < 50)
55             return 6000 + (level - 40) * 800L;
56         else
57             return 14000 + (level - 50) * 2000L;
58     }
59     case ItemKindType::CAPTURE:
60         if (!o_ptr->pval)
61             return 1000L;
62         else
63             return ((r_info[o_ptr->pval].level) * 50L + 1000);
64
65     default:
66         break;
67     }
68
69     return (0L);
70 }
71
72 /*!
73  * @brief オブジェクト価格算出のメインルーチン /
74  * Return the price of an item including plusses (and charges)
75  * @param o_ptr 判明している現価格を確認したいオブジェクトの構造体参照ポインタ
76  * @return オブジェクトの判明している現価格
77  * @details
78  * This function returns the "value" of the given item (qty one)\n
79  *\n
80  * Never notice "unknown" bonuses or properties, including "curses",\n
81  * since that would give the player information he did not have.\n
82  *\n
83  * Note that discounted items stay discounted forever, even if\n
84  * the discount is "forgotten" by the player via memory loss.\n
85  */
86 PRICE object_value(const ObjectType *o_ptr)
87 {
88     PRICE value;
89
90     if (o_ptr->is_known()) {
91         if (o_ptr->is_broken())
92             return (0L);
93         if (o_ptr->is_cursed())
94             return (0L);
95
96         value = object_value_real(o_ptr);
97     } else {
98         if ((o_ptr->ident & (IDENT_SENSE)) && o_ptr->is_broken())
99             return (0L);
100         if ((o_ptr->ident & (IDENT_SENSE)) && o_ptr->is_cursed())
101             return (0L);
102
103         value = object_value_base(o_ptr);
104     }
105
106     if (o_ptr->discount)
107         value -= (value * o_ptr->discount / 100L);
108
109     return (value);
110 }
111
112 /*!
113  * @brief オブジェクトの真の価格を算出する /
114  * Return the value of the flags the object has...
115  * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
116  * @return オブジェクトの本価格
117  * @details
118  * Return the "real" price of a "known" item, not including discounts\n
119  *\n
120  * Wand and staffs get cost for each charge\n
121  *\n
122  * Armor is worth an extra 100 gold per bonus point to armor class.\n
123  *\n
124  * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
125  *\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
132  *\n
133  * Armor with a negative armor bonus is worthless.\n
134  * Weapons with negative hit+damage bonuses are worthless.\n
135  *\n
136  * Every wearable item with a "pval" bonus is worth extra (see below).\n
137  */
138 PRICE object_value_real(const ObjectType *o_ptr)
139 {
140     object_kind *k_ptr = &k_info[o_ptr->k_idx];
141
142     if (!k_info[o_ptr->k_idx].cost)
143         return (0L);
144
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];
149         if (!a_ptr->cost)
150             return (0L);
151
152         value = a_ptr->cost;
153         value += flag_cost(o_ptr, o_ptr->pval);
154         return (value);
155     } else if (o_ptr->is_ego()) {
156         ego_item_type *e_ptr = &e_info[o_ptr->name2];
157         if (!e_ptr->cost)
158             return (0L);
159
160         value += e_ptr->cost;
161         value += flag_cost(o_ptr, o_ptr->pval);
162     } else {
163         if (o_ptr->art_flags.any())
164             value += flag_cost(o_ptr, o_ptr->pval);
165     }
166
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:
189         if (!o_ptr->pval)
190             break;
191         if (o_ptr->pval < 0)
192             return (0L);
193
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);
220         break;
221
222     default:
223         break;
224     }
225
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-
230          */
231         value += (value * o_ptr->pval / o_ptr->number / (k_ptr->pval * 2));
232         break;
233     }
234     case ItemKindType::STAFF: {
235         /* Pay extra for charges, depending on standard number of
236          * charges.  -LM-
237          */
238         value += (value * o_ptr->pval / (k_ptr->pval * 2));
239         break;
240     }
241     case ItemKindType::RING:
242     case ItemKindType::AMULET: {
243         if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0)
244             return (0L);
245
246         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
247         break;
248     }
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: {
258         if (o_ptr->to_a < 0)
259             return (0L);
260
261         value += (((o_ptr->to_h - k_ptr->to_h) + (o_ptr->to_d - k_ptr->to_d)) * 200L + (o_ptr->to_a) * 100L);
262         break;
263     }
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)
270             return (0L);
271
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;
275         break;
276     }
277     case ItemKindType::SHOT:
278     case ItemKindType::ARROW:
279     case ItemKindType::BOLT: {
280         if (o_ptr->to_h + o_ptr->to_d < 0)
281             return (0L);
282
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;
286         break;
287     }
288     case ItemKindType::FIGURINE: {
289         DEPTH level = r_info[o_ptr->pval].level;
290         if (level < 20)
291             value = level * 50L;
292         else if (level < 30)
293             value = 1000 + (level - 20) * 150L;
294         else if (level < 40)
295             value = 2500 + (level - 30) * 350L;
296         else if (level < 50)
297             value = 6000 + (level - 40) * 800L;
298         else
299             value = 14000 + (level - 50) * 2000L;
300         break;
301     }
302     case ItemKindType::CAPTURE: {
303         if (!o_ptr->pval)
304             value = 1000L;
305         else
306             value = ((r_info[o_ptr->pval].level) * 50L + 1000);
307         break;
308     }
309     case ItemKindType::CHEST: {
310         if (!o_ptr->pval)
311             value = 0L;
312         break;
313     }
314
315     default:
316         break;
317     }
318
319     if (value < 0)
320         return 0L;
321
322     return (value);
323 }