OSDN Git Service

[feature] *_info の std::vector 化
[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-hook/hook-checker.h"
8 #include "object-hook/hook-enchant.h"
9 #include "object/object-broken.h"
10 #include "object/object-flags.h"
11 #include "object/object-kind.h"
12 #include "object/object-value-calc.h"
13 #include "perception/object-perception.h"
14 #include "system/artifact-type-definition.h"
15 #include "util/bit-flags-calculator.h"
16
17 /*!
18  * @brief 未鑑定なベースアイテムの基本価格を返す /
19  * Return the "value" of an "unknown" item Make a guess at the value of non-aware items
20  * @param o_ptr 未鑑定価格を確認したいオブジェクトの構造体参照ポインタ
21  * @return オブジェクトの未鑑定価格
22  */
23 static PRICE object_value_base(object_type *o_ptr)
24 {
25     if (object_is_aware(o_ptr))
26         return (k_info[o_ptr->k_idx].cost);
27
28     switch (o_ptr->tval) {
29     case TV_FOOD:
30         return (5L);
31     case TV_POTION:
32         return (20L);
33     case TV_SCROLL:
34         return (20L);
35     case TV_STAFF:
36         return (70L);
37     case TV_WAND:
38         return (50L);
39     case TV_ROD:
40         return (90L);
41     case TV_RING:
42         return (45L);
43     case TV_AMULET:
44         return (45L);
45     case TV_FIGURINE: {
46         DEPTH level = r_info[o_ptr->pval].level;
47         if (level < 20)
48             return level * 50L;
49         else if (level < 30)
50             return 1000 + (level - 20) * 150L;
51         else if (level < 40)
52             return 2500 + (level - 30) * 350L;
53         else if (level < 50)
54             return 6000 + (level - 40) * 800L;
55         else
56             return 14000 + (level - 50) * 2000L;
57     }
58     case TV_CAPTURE:
59         if (!o_ptr->pval)
60             return 1000L;
61         else
62             return ((r_info[o_ptr->pval].level) * 50L + 1000);
63
64     default:
65         break;
66     }
67
68     return (0L);
69 }
70
71 /*!
72  * @brief オブジェクト価格算出のメインルーチン /
73  * Return the price of an item including plusses (and charges)
74  * @param o_ptr 判明している現価格を確認したいオブジェクトの構造体参照ポインタ
75  * @return オブジェクトの判明している現価格
76  * @details
77  * This function returns the "value" of the given item (qty one)\n
78  *\n
79  * Never notice "unknown" bonuses or properties, including "curses",\n
80  * since that would give the player information he did not have.\n
81  *\n
82  * Note that discounted items stay discounted forever, even if\n
83  * the discount is "forgotten" by the player via memory loss.\n
84  */
85 PRICE object_value(player_type *player_ptr, object_type *o_ptr)
86 {
87     PRICE value;
88
89     if (object_is_known(o_ptr)) {
90         if (object_is_broken(o_ptr))
91             return (0L);
92         if (object_is_cursed(o_ptr))
93             return (0L);
94
95         value = object_value_real(player_ptr, o_ptr);
96     } else {
97         if ((o_ptr->ident & (IDENT_SENSE)) && object_is_broken(o_ptr))
98             return (0L);
99         if ((o_ptr->ident & (IDENT_SENSE)) && object_is_cursed(o_ptr))
100             return (0L);
101
102         value = object_value_base(o_ptr);
103     }
104
105     if (o_ptr->discount)
106         value -= (value * o_ptr->discount / 100L);
107
108     return (value);
109 }
110
111 /*!
112  * @brief オブジェクトの真の価格を算出する /
113  * Return the value of the flags the object has...
114  * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
115  * @return オブジェクトの本価格
116  * @details
117  * Return the "real" price of a "known" item, not including discounts\n
118  *\n
119  * Wand and staffs get cost for each charge\n
120  *\n
121  * Armor is worth an extra 100 gold per bonus point to armor class.\n
122  *\n
123  * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
124  *\n
125  * Missiles are only worth 5 gold per bonus point, since they\n
126  * usually appear in groups of 20, and we want the player to get\n
127  * the same amount of cash for any "equivalent" item.  Note that\n
128  * missiles never have any of the "pval" flags, and in fact, they\n
129  * only have a few of the available flags, primarily of the "slay"\n
130  * and "brand" and "ignore" variety.\n
131  *\n
132  * Armor with a negative armor bonus is worthless.\n
133  * Weapons with negative hit+damage bonuses are worthless.\n
134  *\n
135  * Every wearable item with a "pval" bonus is worth extra (see below).\n
136  */
137 PRICE object_value_real(player_type *player_ptr, object_type *o_ptr)
138 {
139     BIT_FLAGS flgs[TR_FLAG_SIZE];
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     object_flags(player_ptr, o_ptr, flgs);
147     if (object_is_fixed_artifact(o_ptr)) {
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(player_ptr, o_ptr, o_ptr->pval);
154         return (value);
155     } else if (object_is_ego(o_ptr)) {
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(player_ptr, o_ptr, o_ptr->pval);
162     } else {
163         bool flag = FALSE;
164         for (int i = 0; i < TR_FLAG_SIZE; i++)
165             if (o_ptr->art_flags[i])
166                 flag = TRUE;
167
168         if (flag)
169             value += flag_cost(player_ptr, o_ptr, o_ptr->pval);
170     }
171
172     /* Analyze pval bonus for normal object */
173     switch (o_ptr->tval) {
174     case TV_SHOT:
175     case TV_ARROW:
176     case TV_BOLT:
177     case TV_BOW:
178     case TV_DIGGING:
179     case TV_HAFTED:
180     case TV_POLEARM:
181     case TV_SWORD:
182     case TV_BOOTS:
183     case TV_GLOVES:
184     case TV_HELM:
185     case TV_CROWN:
186     case TV_SHIELD:
187     case TV_CLOAK:
188     case TV_SOFT_ARMOR:
189     case TV_HARD_ARMOR:
190     case TV_DRAG_ARMOR:
191     case TV_LITE:
192     case TV_AMULET:
193     case TV_RING:
194         if (!o_ptr->pval)
195             break;
196         if (o_ptr->pval < 0)
197             return (0L);
198
199         if (has_flag(flgs, TR_STR))
200             value += (o_ptr->pval * 200L);
201         if (has_flag(flgs, TR_INT))
202             value += (o_ptr->pval * 200L);
203         if (has_flag(flgs, TR_WIS))
204             value += (o_ptr->pval * 200L);
205         if (has_flag(flgs, TR_DEX))
206             value += (o_ptr->pval * 200L);
207         if (has_flag(flgs, TR_CON))
208             value += (o_ptr->pval * 200L);
209         if (has_flag(flgs, TR_CHR))
210             value += (o_ptr->pval * 200L);
211         if (has_flag(flgs, TR_MAGIC_MASTERY))
212             value += (o_ptr->pval * 100);
213         if (has_flag(flgs, TR_STEALTH))
214             value += (o_ptr->pval * 100L);
215         if (has_flag(flgs, TR_SEARCH))
216             value += (o_ptr->pval * 100L);
217         if (has_flag(flgs, TR_INFRA))
218             value += (o_ptr->pval * 50L);
219         if (has_flag(flgs, TR_TUNNEL))
220             value += (o_ptr->pval * 50L);
221         if (has_flag(flgs, TR_BLOWS))
222             value += (o_ptr->pval * 5000L);
223         if (has_flag(flgs, TR_SPEED))
224             value += (o_ptr->pval * 10000L);
225         break;
226
227     default:
228         break;
229     }
230
231     switch (o_ptr->tval) {
232     case TV_WAND: {
233         /* Pay extra for charges, depending on standard number of
234          * charges.  Handle new-style wands correctly. -LM-
235          */
236         value += (value * o_ptr->pval / o_ptr->number / (k_ptr->pval * 2));
237         break;
238     }
239     case TV_STAFF: {
240         /* Pay extra for charges, depending on standard number of
241          * charges.  -LM-
242          */
243         value += (value * o_ptr->pval / (k_ptr->pval * 2));
244         break;
245     }
246     case TV_RING:
247     case TV_AMULET: {
248         if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0)
249             return (0L);
250
251         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
252         break;
253     }
254     case TV_BOOTS:
255     case TV_GLOVES:
256     case TV_CLOAK:
257     case TV_CROWN:
258     case TV_HELM:
259     case TV_SHIELD:
260     case TV_SOFT_ARMOR:
261     case TV_HARD_ARMOR:
262     case TV_DRAG_ARMOR: {
263         if (o_ptr->to_a < 0)
264             return (0L);
265
266         value += (((o_ptr->to_h - k_ptr->to_h) + (o_ptr->to_d - k_ptr->to_d)) * 200L + (o_ptr->to_a) * 100L);
267         break;
268     }
269     case TV_BOW:
270     case TV_DIGGING:
271     case TV_HAFTED:
272     case TV_SWORD:
273     case TV_POLEARM: {
274         if (o_ptr->to_h + o_ptr->to_d < 0)
275             return (0L);
276
277         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
278         value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 250L;
279         value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 250L;
280         break;
281     }
282     case TV_SHOT:
283     case TV_ARROW:
284     case TV_BOLT: {
285         if (o_ptr->to_h + o_ptr->to_d < 0)
286             return (0L);
287
288         value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
289         value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 5L;
290         value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 5L;
291         break;
292     }
293     case TV_FIGURINE: {
294         DEPTH level = r_info[o_ptr->pval].level;
295         if (level < 20)
296             value = level * 50L;
297         else if (level < 30)
298             value = 1000 + (level - 20) * 150L;
299         else if (level < 40)
300             value = 2500 + (level - 30) * 350L;
301         else if (level < 50)
302             value = 6000 + (level - 40) * 800L;
303         else
304             value = 14000 + (level - 50) * 2000L;
305         break;
306     }
307     case TV_CAPTURE: {
308         if (!o_ptr->pval)
309             value = 1000L;
310         else
311             value = ((r_info[o_ptr->pval].level) * 50L + 1000);
312         break;
313     }
314     case TV_CHEST: {
315         if (!o_ptr->pval)
316             value = 0L;
317         break;
318     }
319
320     default:
321         break;
322     }
323
324     if (value < 0)
325         return 0L;
326
327     return (value);
328 }