OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[hengband/hengband.git] / src / object / object-value.c
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
65     return (0L);
66 }
67
68 /*!
69  * @brief オブジェクト価格算出のメインルーチン /
70  * Return the price of an item including plusses (and charges)
71  * @param o_ptr 判明している現価格を確認したいオブジェクトの構造体参照ポインタ
72  * @return オブジェクトの判明している現価格
73  * @details
74  * This function returns the "value" of the given item (qty one)\n
75  *\n
76  * Never notice "unknown" bonuses or properties, including "curses",\n
77  * since that would give the player information he did not have.\n
78  *\n
79  * Note that discounted items stay discounted forever, even if\n
80  * the discount is "forgotten" by the player via memory loss.\n
81  */
82 PRICE object_value(player_type *player_ptr, object_type *o_ptr)
83 {
84     PRICE value;
85
86     if (object_is_known(o_ptr)) {
87         if (object_is_broken(o_ptr))
88             return (0L);
89         if (object_is_cursed(o_ptr))
90             return (0L);
91
92         value = object_value_real(player_ptr, o_ptr);
93     } else {
94         if ((o_ptr->ident & (IDENT_SENSE)) && object_is_broken(o_ptr))
95             return (0L);
96         if ((o_ptr->ident & (IDENT_SENSE)) && object_is_cursed(o_ptr))
97             return (0L);
98
99         value = object_value_base(o_ptr);
100     }
101
102     if (o_ptr->discount)
103         value -= (value * o_ptr->discount / 100L);
104
105     return (value);
106 }
107
108 /*!
109  * @brief オブジェクトの真の価格を算出する /
110  * Return the value of the flags the object has...
111  * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
112  * @return オブジェクトの本価格
113  * @details
114  * Return the "real" price of a "known" item, not including discounts\n
115  *\n
116  * Wand and staffs get cost for each charge\n
117  *\n
118  * Armor is worth an extra 100 gold per bonus point to armor class.\n
119  *\n
120  * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
121  *\n
122  * Missiles are only worth 5 gold per bonus point, since they\n
123  * usually appear in groups of 20, and we want the player to get\n
124  * the same amount of cash for any "equivalent" item.  Note that\n
125  * missiles never have any of the "pval" flags, and in fact, they\n
126  * only have a few of the available flags, primarily of the "slay"\n
127  * and "brand" and "ignore" variety.\n
128  *\n
129  * Armor with a negative armor bonus is worthless.\n
130  * Weapons with negative hit+damage bonuses are worthless.\n
131  *\n
132  * Every wearable item with a "pval" bonus is worth extra (see below).\n
133  */
134 PRICE object_value_real(player_type *player_ptr, object_type *o_ptr)
135 {
136     BIT_FLAGS flgs[TR_FLAG_SIZE];
137     object_kind *k_ptr = &k_info[o_ptr->k_idx];
138
139     if (!k_info[o_ptr->k_idx].cost)
140         return (0L);
141
142     PRICE value = k_info[o_ptr->k_idx].cost;
143     object_flags(player_ptr, o_ptr, flgs);
144     if (object_is_fixed_artifact(o_ptr)) {
145         artifact_type *a_ptr = &a_info[o_ptr->name1];
146         if (!a_ptr->cost)
147             return (0L);
148
149         value = a_ptr->cost;
150         value += flag_cost(player_ptr, o_ptr, o_ptr->pval);
151         return (value);
152     } else if (object_is_ego(o_ptr)) {
153         ego_item_type *e_ptr = &e_info[o_ptr->name2];
154         if (!e_ptr->cost)
155             return (0L);
156
157         value += e_ptr->cost;
158         value += flag_cost(player_ptr, o_ptr, o_ptr->pval);
159     } else {
160         bool flag = FALSE;
161         for (int i = 0; i < TR_FLAG_SIZE; i++)
162             if (o_ptr->art_flags[i])
163                 flag = TRUE;
164
165         if (flag)
166             value += flag_cost(player_ptr, o_ptr, o_ptr->pval);
167     }
168
169     /* Analyze pval bonus for normal object */
170     switch (o_ptr->tval) {
171     case TV_SHOT:
172     case TV_ARROW:
173     case TV_BOLT:
174     case TV_BOW:
175     case TV_DIGGING:
176     case TV_HAFTED:
177     case TV_POLEARM:
178     case TV_SWORD:
179     case TV_BOOTS:
180     case TV_GLOVES:
181     case TV_HELM:
182     case TV_CROWN:
183     case TV_SHIELD:
184     case TV_CLOAK:
185     case TV_SOFT_ARMOR:
186     case TV_HARD_ARMOR:
187     case TV_DRAG_ARMOR:
188     case TV_LITE:
189     case TV_AMULET:
190     case TV_RING:
191         if (!o_ptr->pval)
192             break;
193         if (o_ptr->pval < 0)
194             return (0L);
195
196         if (have_flag(flgs, TR_STR))
197             value += (o_ptr->pval * 200L);
198         if (have_flag(flgs, TR_INT))
199             value += (o_ptr->pval * 200L);
200         if (have_flag(flgs, TR_WIS))
201             value += (o_ptr->pval * 200L);
202         if (have_flag(flgs, TR_DEX))
203             value += (o_ptr->pval * 200L);
204         if (have_flag(flgs, TR_CON))
205             value += (o_ptr->pval * 200L);
206         if (have_flag(flgs, TR_CHR))
207             value += (o_ptr->pval * 200L);
208         if (have_flag(flgs, TR_MAGIC_MASTERY))
209             value += (o_ptr->pval * 100);
210         if (have_flag(flgs, TR_STEALTH))
211             value += (o_ptr->pval * 100L);
212         if (have_flag(flgs, TR_SEARCH))
213             value += (o_ptr->pval * 100L);
214         if (have_flag(flgs, TR_INFRA))
215             value += (o_ptr->pval * 50L);
216         if (have_flag(flgs, TR_TUNNEL))
217             value += (o_ptr->pval * 50L);
218         if (have_flag(flgs, TR_BLOWS))
219             value += (o_ptr->pval * 5000L);
220         if (have_flag(flgs, TR_SPEED))
221             value += (o_ptr->pval * 10000L);
222         break;
223     }
224
225     switch (o_ptr->tval) {
226     case TV_WAND: {
227         /* Pay extra for charges, depending on standard number of
228          * charges.  Handle new-style wands correctly. -LM-
229          */
230         value += (value * o_ptr->pval / o_ptr->number / (k_ptr->pval * 2));
231         break;
232     }
233     case TV_STAFF: {
234         /* Pay extra for charges, depending on standard number of
235          * charges.  -LM-
236          */
237         value += (value * o_ptr->pval / (k_ptr->pval * 2));
238         break;
239     }
240     case TV_RING:
241     case TV_AMULET: {
242         if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0)
243             return (0L);
244
245         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
246         break;
247     }
248     case TV_BOOTS:
249     case TV_GLOVES:
250     case TV_CLOAK:
251     case TV_CROWN:
252     case TV_HELM:
253     case TV_SHIELD:
254     case TV_SOFT_ARMOR:
255     case TV_HARD_ARMOR:
256     case TV_DRAG_ARMOR: {
257         if (o_ptr->to_a < 0)
258             return (0L);
259
260         value += (((o_ptr->to_h - k_ptr->to_h) + (o_ptr->to_d - k_ptr->to_d)) * 200L + (o_ptr->to_a) * 100L);
261         break;
262     }
263     case TV_BOW:
264     case TV_DIGGING:
265     case TV_HAFTED:
266     case TV_SWORD:
267     case TV_POLEARM: {
268         if (o_ptr->to_h + o_ptr->to_d < 0)
269             return (0L);
270
271         value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
272         value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 250L;
273         value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 250L;
274         break;
275     }
276     case TV_SHOT:
277     case TV_ARROW:
278     case TV_BOLT: {
279         if (o_ptr->to_h + o_ptr->to_d < 0)
280             return (0L);
281
282         value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
283         value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 5L;
284         value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 5L;
285         break;
286     }
287     case TV_FIGURINE: {
288         DEPTH level = r_info[o_ptr->pval].level;
289         if (level < 20)
290             value = level * 50L;
291         else if (level < 30)
292             value = 1000 + (level - 20) * 150L;
293         else if (level < 40)
294             value = 2500 + (level - 30) * 350L;
295         else if (level < 50)
296             value = 6000 + (level - 40) * 800L;
297         else
298             value = 14000 + (level - 50) * 2000L;
299         break;
300     }
301     case TV_CAPTURE: {
302         if (!o_ptr->pval)
303             value = 1000L;
304         else
305             value = ((r_info[o_ptr->pval].level) * 50L + 1000);
306         break;
307     }
308     case TV_CHEST: {
309         if (!o_ptr->pval)
310             value = 0L;
311         break;
312     }
313     }
314
315     if (value < 0)
316         return 0L;
317
318     return (value);
319 }