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.h"
8 #include "system/item-entity.h"
9 #include "system/monster-race-info.h"
10 #include "system/player-type-definition.h"
13 * @brief オブジェクトの真の価格を算出する /
14 * Return the value of the flags the object has...
15 * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
18 * Return the "real" price of a "known" item, not including discounts\n
20 * Wand and staffs get cost for each charge\n
22 * Armor is worth an extra 100 gold per bonus point to armor class.\n
24 * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
26 * Missiles are only worth 5 gold per bonus point, since they\n
27 * usually appear in groups of 20, and we want the player to get\n
28 * the same amount of cash for any "equivalent" item. Note that\n
29 * missiles never have any of the "pval" flags, and in fact, they\n
30 * only have a few of the available flags, primarily of the "slay"\n
31 * and "brand" and "ignore" variety.\n
33 * Armor with a negative armor bonus is worthless.\n
34 * Weapons with negative hit+damage bonuses are worthless.\n
36 * Every wearable item with a "pval" bonus is worth extra (see below).\n
38 PRICE object_value_real(const ItemEntity *o_ptr)
40 const auto &baseitem = o_ptr->get_baseitem();
46 PRICE value = baseitem.cost;
47 auto flags = object_flags(o_ptr);
48 if (o_ptr->is_fixed_artifact()) {
49 const auto &artifact = ArtifactsInfo::get_instance().get_artifact(o_ptr->fixed_artifact_idx);
54 value = artifact.cost;
55 value += flag_cost(o_ptr, o_ptr->pval);
57 } else if (o_ptr->is_ego()) {
58 const auto &ego = o_ptr->get_ego();
64 value += flag_cost(o_ptr, o_ptr->pval);
66 if (o_ptr->art_flags.any()) {
67 value += flag_cost(o_ptr, o_ptr->pval);
71 /* Analyze pval bonus for normal object */
72 switch (o_ptr->bi_key.tval()) {
73 case ItemKindType::SHOT:
74 case ItemKindType::ARROW:
75 case ItemKindType::BOLT:
76 case ItemKindType::BOW:
77 case ItemKindType::DIGGING:
78 case ItemKindType::HAFTED:
79 case ItemKindType::POLEARM:
80 case ItemKindType::SWORD:
81 case ItemKindType::BOOTS:
82 case ItemKindType::GLOVES:
83 case ItemKindType::HELM:
84 case ItemKindType::CROWN:
85 case ItemKindType::SHIELD:
86 case ItemKindType::CLOAK:
87 case ItemKindType::SOFT_ARMOR:
88 case ItemKindType::HARD_ARMOR:
89 case ItemKindType::DRAG_ARMOR:
90 case ItemKindType::LITE:
91 case ItemKindType::AMULET:
92 case ItemKindType::RING:
96 if (o_ptr->pval < 0) {
100 if (flags.has(TR_STR)) {
101 value += (o_ptr->pval * 200L);
103 if (flags.has(TR_INT)) {
104 value += (o_ptr->pval * 200L);
106 if (flags.has(TR_WIS)) {
107 value += (o_ptr->pval * 200L);
109 if (flags.has(TR_DEX)) {
110 value += (o_ptr->pval * 200L);
112 if (flags.has(TR_CON)) {
113 value += (o_ptr->pval * 200L);
115 if (flags.has(TR_CHR)) {
116 value += (o_ptr->pval * 200L);
118 if (flags.has(TR_MAGIC_MASTERY)) {
119 value += (o_ptr->pval * 100);
121 if (flags.has(TR_STEALTH)) {
122 value += (o_ptr->pval * 100L);
124 if (flags.has(TR_SEARCH)) {
125 value += (o_ptr->pval * 100L);
127 if (flags.has(TR_INFRA)) {
128 value += (o_ptr->pval * 50L);
130 if (flags.has(TR_TUNNEL)) {
131 value += (o_ptr->pval * 50L);
133 if (flags.has(TR_BLOWS)) {
134 value += (o_ptr->pval * 5000L);
136 if (flags.has(TR_SPEED)) {
137 value += (o_ptr->pval * 10000L);
145 switch (o_ptr->bi_key.tval()) {
146 case ItemKindType::WAND: {
147 /* Pay extra for charges, depending on standard number of
148 * charges. Handle new-style wands correctly. -LM-
150 value += (value * o_ptr->pval / o_ptr->number / (baseitem.pval * 2));
153 case ItemKindType::STAFF: {
154 /* Pay extra for charges, depending on standard number of
157 value += (value * o_ptr->pval / (baseitem.pval * 2));
160 case ItemKindType::RING:
161 case ItemKindType::AMULET: {
162 if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0) {
166 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
169 case ItemKindType::BOOTS:
170 case ItemKindType::GLOVES:
171 case ItemKindType::CLOAK:
172 case ItemKindType::CROWN:
173 case ItemKindType::HELM:
174 case ItemKindType::SHIELD:
175 case ItemKindType::SOFT_ARMOR:
176 case ItemKindType::HARD_ARMOR:
177 case ItemKindType::DRAG_ARMOR: {
178 if (o_ptr->to_a < 0) {
182 value += (((o_ptr->to_h - baseitem.to_h) + (o_ptr->to_d - baseitem.to_d)) * 200L + (o_ptr->to_a) * 100L);
185 case ItemKindType::BOW:
186 case ItemKindType::DIGGING:
187 case ItemKindType::HAFTED:
188 case ItemKindType::SWORD:
189 case ItemKindType::POLEARM: {
190 if (o_ptr->to_h + o_ptr->to_d < 0) {
194 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
195 value += (o_ptr->dd - baseitem.dd) * o_ptr->ds * 250L;
196 value += (o_ptr->ds - baseitem.ds) * o_ptr->dd * 250L;
199 case ItemKindType::SHOT:
200 case ItemKindType::ARROW:
201 case ItemKindType::BOLT: {
202 if (o_ptr->to_h + o_ptr->to_d < 0) {
206 value += ((o_ptr->to_h + o_ptr->to_d) * 5L);
207 value += (o_ptr->dd - baseitem.dd) * o_ptr->ds * 5L;
208 value += (o_ptr->ds - baseitem.ds) * o_ptr->dd * 5L;
211 case ItemKindType::FIGURINE: {
212 auto figure_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
213 DEPTH level = monraces_info[figure_r_idx].level;
216 } else if (level < 30) {
217 value = 1000 + (level - 20) * 150L;
218 } else if (level < 40) {
219 value = 2500 + (level - 30) * 350L;
220 } else if (level < 50) {
221 value = 6000 + (level - 40) * 800L;
223 value = 14000 + (level - 50) * 2000L;
227 case ItemKindType::CAPTURE: {
228 auto capture_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
229 if (!MonsterRace(capture_r_idx).is_valid()) {
232 value = ((monraces_info[capture_r_idx].level) * 50L + 1000);
236 case ItemKindType::CHEST: {