1 #include "object/object-value.h"
2 #include "monster-race/monster-race.h"
3 #include "object/object-flags.h"
4 #include "object/object-value-calc.h"
5 #include "object/tval-types.h"
6 #include "system/artifact-type-definition.h"
7 #include "system/baseitem-info-definition.h"
8 #include "system/monster-race-definition.h"
9 #include "system/player-type-definition.h"
12 * @brief オブジェクトの真の価格を算出する /
13 * Return the value of the flags the object has...
14 * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
17 * Return the "real" price of a "known" item, not including discounts\n
19 * Wand and staffs get cost for each charge\n
21 * Armor is worth an extra 100 gold per bonus point to armor class.\n
23 * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
25 * Missiles are only worth 5 gold per bonus point, since they\n
26 * usually appear in groups of 20, and we want the player to get\n
27 * the same amount of cash for any "equivalent" item. Note that\n
28 * missiles never have any of the "pval" flags, and in fact, they\n
29 * only have a few of the available flags, primarily of the "slay"\n
30 * and "brand" and "ignore" variety.\n
32 * Armor with a negative armor bonus is worthless.\n
33 * Weapons with negative hit+damage bonuses are worthless.\n
35 * Every wearable item with a "pval" bonus is worth extra (see below).\n
37 PRICE object_value_real(const ObjectType *o_ptr)
39 auto *k_ptr = &k_info[o_ptr->k_idx];
41 if (!k_info[o_ptr->k_idx].cost) {
45 PRICE value = k_info[o_ptr->k_idx].cost;
46 auto flgs = object_flags(o_ptr);
47 if (o_ptr->is_fixed_artifact()) {
48 const auto &a_ref = a_info.at(o_ptr->fixed_artifact_idx);
54 value += flag_cost(o_ptr, o_ptr->pval);
56 } else if (o_ptr->is_ego()) {
57 const auto &e_ref = e_info[o_ptr->ego_idx];
63 value += flag_cost(o_ptr, o_ptr->pval);
65 if (o_ptr->art_flags.any()) {
66 value += flag_cost(o_ptr, o_ptr->pval);
70 /* Analyze pval bonus for normal object */
71 switch (o_ptr->tval) {
72 case ItemKindType::SHOT:
73 case ItemKindType::ARROW:
74 case ItemKindType::BOLT:
75 case ItemKindType::BOW:
76 case ItemKindType::DIGGING:
77 case ItemKindType::HAFTED:
78 case ItemKindType::POLEARM:
79 case ItemKindType::SWORD:
80 case ItemKindType::BOOTS:
81 case ItemKindType::GLOVES:
82 case ItemKindType::HELM:
83 case ItemKindType::CROWN:
84 case ItemKindType::SHIELD:
85 case ItemKindType::CLOAK:
86 case ItemKindType::SOFT_ARMOR:
87 case ItemKindType::HARD_ARMOR:
88 case ItemKindType::DRAG_ARMOR:
89 case ItemKindType::LITE:
90 case ItemKindType::AMULET:
91 case ItemKindType::RING:
95 if (o_ptr->pval < 0) {
99 if (flgs.has(TR_STR)) {
100 value += (o_ptr->pval * 200L);
102 if (flgs.has(TR_INT)) {
103 value += (o_ptr->pval * 200L);
105 if (flgs.has(TR_WIS)) {
106 value += (o_ptr->pval * 200L);
108 if (flgs.has(TR_DEX)) {
109 value += (o_ptr->pval * 200L);
111 if (flgs.has(TR_CON)) {
112 value += (o_ptr->pval * 200L);
114 if (flgs.has(TR_CHR)) {
115 value += (o_ptr->pval * 200L);
117 if (flgs.has(TR_MAGIC_MASTERY)) {
118 value += (o_ptr->pval * 100);
120 if (flgs.has(TR_STEALTH)) {
121 value += (o_ptr->pval * 100L);
123 if (flgs.has(TR_SEARCH)) {
124 value += (o_ptr->pval * 100L);
126 if (flgs.has(TR_INFRA)) {
127 value += (o_ptr->pval * 50L);
129 if (flgs.has(TR_TUNNEL)) {
130 value += (o_ptr->pval * 50L);
132 if (flgs.has(TR_BLOWS)) {
133 value += (o_ptr->pval * 5000L);
135 if (flgs.has(TR_SPEED)) {
136 value += (o_ptr->pval * 10000L);
144 switch (o_ptr->tval) {
145 case ItemKindType::WAND: {
146 /* Pay extra for charges, depending on standard number of
147 * charges. Handle new-style wands correctly. -LM-
149 value += (value * o_ptr->pval / o_ptr->number / (k_ptr->pval * 2));
152 case ItemKindType::STAFF: {
153 /* Pay extra for charges, depending on standard number of
156 value += (value * o_ptr->pval / (k_ptr->pval * 2));
159 case ItemKindType::RING:
160 case ItemKindType::AMULET: {
161 if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0) {
165 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
168 case ItemKindType::BOOTS:
169 case ItemKindType::GLOVES:
170 case ItemKindType::CLOAK:
171 case ItemKindType::CROWN:
172 case ItemKindType::HELM:
173 case ItemKindType::SHIELD:
174 case ItemKindType::SOFT_ARMOR:
175 case ItemKindType::HARD_ARMOR:
176 case ItemKindType::DRAG_ARMOR: {
177 if (o_ptr->to_a < 0) {
181 value += (((o_ptr->to_h - k_ptr->to_h) + (o_ptr->to_d - k_ptr->to_d)) * 200L + (o_ptr->to_a) * 100L);
184 case ItemKindType::BOW:
185 case ItemKindType::DIGGING:
186 case ItemKindType::HAFTED:
187 case ItemKindType::SWORD:
188 case ItemKindType::POLEARM: {
189 if (o_ptr->to_h + o_ptr->to_d < 0) {
193 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
194 value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 250L;
195 value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 250L;
198 case ItemKindType::SHOT:
199 case ItemKindType::ARROW:
200 case ItemKindType::BOLT: {
201 if (o_ptr->to_h + o_ptr->to_d < 0) {
205 value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
206 value += (o_ptr->dd - k_ptr->dd) * o_ptr->ds * 5L;
207 value += (o_ptr->ds - k_ptr->ds) * o_ptr->dd * 5L;
210 case ItemKindType::FIGURINE: {
211 auto figure_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
212 DEPTH level = r_info[figure_r_idx].level;
215 } else if (level < 30) {
216 value = 1000 + (level - 20) * 150L;
217 } else if (level < 40) {
218 value = 2500 + (level - 30) * 350L;
219 } else if (level < 50) {
220 value = 6000 + (level - 40) * 800L;
222 value = 14000 + (level - 50) * 2000L;
226 case ItemKindType::CAPTURE: {
227 auto capture_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
228 if (!MonsterRace(capture_r_idx).is_valid()) {
231 value = ((r_info[capture_r_idx].level) * 50L + 1000);
235 case ItemKindType::CHEST: {