1 #include "object/object-value.h"
2 #include "object/object-value-calc.h"
3 #include "object/tval-types.h"
4 #include "system/artifact-type-definition.h"
5 #include "system/baseitem-info.h"
6 #include "system/item-entity.h"
7 #include "system/monster-race-info.h"
8 #include "system/player-type-definition.h"
11 * @brief オブジェクトの真の価格を算出する /
12 * Return the value of the flags the object has...
13 * @param o_ptr 本価格を確認したいオブジェクトの構造体参照ポインタ
16 * Return the "real" price of a "known" item, not including discounts\n
18 * Wand and staffs get cost for each charge\n
20 * Armor is worth an extra 100 gold per bonus point to armor class.\n
22 * Weapons are worth an extra 100 gold per bonus point (AC,TH,TD).\n
24 * Missiles are only worth 5 gold per bonus point, since they\n
25 * usually appear in groups of 20, and we want the player to get\n
26 * the same amount of cash for any "equivalent" item. Note that\n
27 * missiles never have any of the "pval" flags, and in fact, they\n
28 * only have a few of the available flags, primarily of the "slay"\n
29 * and "brand" and "ignore" variety.\n
31 * Armor with a negative armor bonus is worthless.\n
32 * Weapons with negative hit+damage bonuses are worthless.\n
34 * Every wearable item with a "pval" bonus is worth extra (see below).\n
36 PRICE object_value_real(const ItemEntity *o_ptr)
38 const auto &baseitem = o_ptr->get_baseitem();
44 PRICE value = baseitem.cost;
45 const auto flags = o_ptr->get_flags();
46 if (o_ptr->is_fixed_artifact()) {
47 const auto &artifact = o_ptr->get_fixed_artifact();
52 value = artifact.cost;
53 value += flag_cost(o_ptr, o_ptr->pval);
55 } else if (o_ptr->is_ego()) {
56 const auto &ego = o_ptr->get_ego();
62 value += flag_cost(o_ptr, o_ptr->pval);
64 if (o_ptr->art_flags.any()) {
65 value += flag_cost(o_ptr, o_ptr->pval);
69 /* Analyze pval bonus for normal object */
70 switch (o_ptr->bi_key.tval()) {
71 case ItemKindType::SHOT:
72 case ItemKindType::ARROW:
73 case ItemKindType::BOLT:
74 case ItemKindType::BOW:
75 case ItemKindType::DIGGING:
76 case ItemKindType::HAFTED:
77 case ItemKindType::POLEARM:
78 case ItemKindType::SWORD:
79 case ItemKindType::BOOTS:
80 case ItemKindType::GLOVES:
81 case ItemKindType::HELM:
82 case ItemKindType::CROWN:
83 case ItemKindType::SHIELD:
84 case ItemKindType::CLOAK:
85 case ItemKindType::SOFT_ARMOR:
86 case ItemKindType::HARD_ARMOR:
87 case ItemKindType::DRAG_ARMOR:
88 case ItemKindType::LITE:
89 case ItemKindType::AMULET:
90 case ItemKindType::RING:
94 if (o_ptr->pval < 0) {
98 if (flags.has(TR_STR)) {
99 value += (o_ptr->pval * 200L);
101 if (flags.has(TR_INT)) {
102 value += (o_ptr->pval * 200L);
104 if (flags.has(TR_WIS)) {
105 value += (o_ptr->pval * 200L);
107 if (flags.has(TR_DEX)) {
108 value += (o_ptr->pval * 200L);
110 if (flags.has(TR_CON)) {
111 value += (o_ptr->pval * 200L);
113 if (flags.has(TR_CHR)) {
114 value += (o_ptr->pval * 200L);
116 if (flags.has(TR_MAGIC_MASTERY)) {
117 value += (o_ptr->pval * 100);
119 if (flags.has(TR_STEALTH)) {
120 value += (o_ptr->pval * 100L);
122 if (flags.has(TR_SEARCH)) {
123 value += (o_ptr->pval * 100L);
125 if (flags.has(TR_INFRA)) {
126 value += (o_ptr->pval * 50L);
128 if (flags.has(TR_TUNNEL)) {
129 value += (o_ptr->pval * 50L);
131 if (flags.has(TR_BLOWS)) {
132 value += (o_ptr->pval * 5000L);
134 if (flags.has(TR_SPEED)) {
135 value += (o_ptr->pval * 10000L);
143 switch (o_ptr->bi_key.tval()) {
144 case ItemKindType::WAND: {
145 /* Pay extra for charges, depending on standard number of
146 * charges. Handle new-style wands correctly. -LM-
148 value += (value * o_ptr->pval / o_ptr->number / (baseitem.pval * 2));
151 case ItemKindType::STAFF: {
152 /* Pay extra for charges, depending on standard number of
155 value += (value * o_ptr->pval / (baseitem.pval * 2));
158 case ItemKindType::RING:
159 case ItemKindType::AMULET: {
160 if (o_ptr->to_h + o_ptr->to_d + o_ptr->to_a < 0) {
164 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 200L);
167 case ItemKindType::BOOTS:
168 case ItemKindType::GLOVES:
169 case ItemKindType::CLOAK:
170 case ItemKindType::CROWN:
171 case ItemKindType::HELM:
172 case ItemKindType::SHIELD:
173 case ItemKindType::SOFT_ARMOR:
174 case ItemKindType::HARD_ARMOR:
175 case ItemKindType::DRAG_ARMOR: {
176 if (o_ptr->to_a < 0) {
180 value += (((o_ptr->to_h - baseitem.to_h) + (o_ptr->to_d - baseitem.to_d)) * 200L + (o_ptr->to_a) * 100L);
183 case ItemKindType::BOW:
184 case ItemKindType::DIGGING:
185 case ItemKindType::HAFTED:
186 case ItemKindType::SWORD:
187 case ItemKindType::POLEARM: {
188 if (o_ptr->to_h + o_ptr->to_d < 0) {
192 value += ((o_ptr->to_h + o_ptr->to_d + o_ptr->to_a) * 100L);
193 const auto &dice = o_ptr->damage_dice;
194 value += (dice.num - baseitem.damage_dice.num) * dice.sides * 250L;
195 value += (dice.sides - baseitem.damage_dice.sides) * dice.num * 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 const auto &dice = o_ptr->damage_dice;
207 value += (dice.num - baseitem.damage_dice.num) * dice.sides * 5L;
208 value += (dice.sides - baseitem.damage_dice.sides) * dice.num * 5L;
211 case ItemKindType::FIGURINE: {
212 const auto level = o_ptr->get_monrace().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 const auto &monrace = o_ptr->get_monrace();
228 if (!monrace.is_valid()) {
231 value = monrace.level * 50 + 1000;
235 case ItemKindType::CHEST: {