1 #include "store/service-checker.h"
2 #include "monster-race/monster-race.h"
3 #include "monster-race/race-flags3.h"
4 #include "object-enchant/tr-types.h"
5 #include "object/object-flags.h"
6 #include "object/object-value.h"
7 #include "object/tval-types.h"
8 #include "store/store-util.h"
9 #include "sv-definition/sv-potion-types.h"
10 #include "sv-definition/sv-rod-types.h"
11 #include "sv-definition/sv-scroll-types.h"
12 #include "sv-definition/sv-weapon-types.h"
13 #include "system/monster-race-definition.h"
14 #include "system/object-type-definition.h"
15 #include "system/player-type-definition.h"
16 #include "util/bit-flags-calculator.h"
17 #include "util/string-processor.h"
20 * @brief オブジェクトが祝福されているかの判定を返す /
21 * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
22 * @return アイテムが祝福されたアイテムならばTRUEを返す
24 static bool is_blessed_item(const ObjectType *o_ptr)
26 auto flgs = object_flags(o_ptr);
27 return flgs.has(TR_BLESSED);
30 static bool check_store_general(const ObjectType *o_ptr)
32 switch (o_ptr->tval) {
33 case ItemKindType::ROD:
34 return (o_ptr->sval == SV_ROD_PESTICIDE);
35 case ItemKindType::POTION:
36 return (o_ptr->sval == SV_POTION_WATER);
37 case ItemKindType::WHISTLE:
38 case ItemKindType::FOOD:
39 case ItemKindType::LITE:
40 case ItemKindType::FLASK:
41 case ItemKindType::SPIKE:
42 case ItemKindType::SHOT:
43 case ItemKindType::ARROW:
44 case ItemKindType::BOLT:
45 case ItemKindType::DIGGING:
46 case ItemKindType::CLOAK:
47 case ItemKindType::BOTTLE:
48 case ItemKindType::FIGURINE:
49 case ItemKindType::STATUE:
50 case ItemKindType::CAPTURE:
51 case ItemKindType::CARD:
58 static bool check_store_armoury(const ObjectType *o_ptr)
60 switch (o_ptr->tval) {
61 case ItemKindType::BOOTS:
62 case ItemKindType::GLOVES:
63 case ItemKindType::CROWN:
64 case ItemKindType::HELM:
65 case ItemKindType::SHIELD:
66 case ItemKindType::CLOAK:
67 case ItemKindType::SOFT_ARMOR:
68 case ItemKindType::HARD_ARMOR:
69 case ItemKindType::DRAG_ARMOR:
76 static bool check_store_weapon(const ObjectType *o_ptr)
78 switch (o_ptr->tval) {
79 case ItemKindType::SHOT:
80 case ItemKindType::BOLT:
81 case ItemKindType::ARROW:
82 case ItemKindType::BOW:
83 case ItemKindType::DIGGING:
84 case ItemKindType::POLEARM:
85 case ItemKindType::SWORD:
86 case ItemKindType::HISSATSU_BOOK:
88 case ItemKindType::HAFTED:
89 return o_ptr->sval != SV_WIZSTAFF;
95 static bool check_store_temple(const ObjectType *o_ptr)
97 switch (o_ptr->tval) {
98 case ItemKindType::LIFE_BOOK:
99 case ItemKindType::CRUSADE_BOOK:
100 case ItemKindType::SCROLL:
101 case ItemKindType::POTION:
102 case ItemKindType::HAFTED:
104 case ItemKindType::FIGURINE:
105 case ItemKindType::STATUE: {
106 auto *r_ptr = &r_info[i2enum<MonsterRaceId>(o_ptr->pval)];
107 if (r_ptr->kind_flags.has_not(MonsterKindType::EVIL)) {
108 if ((r_ptr->kind_flags.has(MonsterKindType::GOOD)) || (r_ptr->kind_flags.has(MonsterKindType::ANIMAL)) || (angband_strchr("?!", r_ptr->d_char) != nullptr)) {
114 case ItemKindType::POLEARM:
115 case ItemKindType::SWORD:
116 if (is_blessed_item(o_ptr)) {
126 static bool check_store_alchemist(const ObjectType *o_ptr)
128 switch (o_ptr->tval) {
129 case ItemKindType::SCROLL:
130 case ItemKindType::POTION:
137 static bool check_store_magic(const ObjectType *o_ptr)
139 switch (o_ptr->tval) {
140 case ItemKindType::SORCERY_BOOK:
141 case ItemKindType::NATURE_BOOK:
142 case ItemKindType::CHAOS_BOOK:
143 case ItemKindType::DEATH_BOOK:
144 case ItemKindType::TRUMP_BOOK:
145 case ItemKindType::ARCANE_BOOK:
146 case ItemKindType::CRAFT_BOOK:
147 case ItemKindType::DEMON_BOOK:
148 case ItemKindType::MUSIC_BOOK:
149 case ItemKindType::HEX_BOOK:
150 case ItemKindType::AMULET:
151 case ItemKindType::RING:
152 case ItemKindType::STAFF:
153 case ItemKindType::WAND:
154 case ItemKindType::ROD:
155 case ItemKindType::SCROLL:
156 case ItemKindType::POTION:
157 case ItemKindType::FIGURINE:
159 case ItemKindType::HAFTED:
160 return o_ptr->sval == SV_WIZSTAFF;
166 static bool check_store_book(const ObjectType *o_ptr)
168 switch (o_ptr->tval) {
169 case ItemKindType::SORCERY_BOOK:
170 case ItemKindType::NATURE_BOOK:
171 case ItemKindType::CHAOS_BOOK:
172 case ItemKindType::DEATH_BOOK:
173 case ItemKindType::LIFE_BOOK:
174 case ItemKindType::TRUMP_BOOK:
175 case ItemKindType::ARCANE_BOOK:
176 case ItemKindType::CRAFT_BOOK:
177 case ItemKindType::DEMON_BOOK:
178 case ItemKindType::CRUSADE_BOOK:
179 case ItemKindType::MUSIC_BOOK:
180 case ItemKindType::HEX_BOOK:
187 static bool switch_store_check(const ObjectType *o_ptr, StoreSaleType store_num)
190 case StoreSaleType::GENERAL:
191 return check_store_general(o_ptr);
192 case StoreSaleType::ARMOURY:
193 return check_store_armoury(o_ptr);
194 case StoreSaleType::WEAPON:
195 return check_store_weapon(o_ptr);
196 case StoreSaleType::TEMPLE:
197 return check_store_temple(o_ptr);
198 case StoreSaleType::ALCHEMIST:
199 return check_store_alchemist(o_ptr);
200 case StoreSaleType::MAGIC:
201 return check_store_magic(o_ptr);
202 case StoreSaleType::BOOK:
203 return check_store_book(o_ptr);
210 * @brief オブジェクトが所定の店舗で引き取れるかどうかを返す /
211 * Determine if the current store will purchase the given item
212 * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
213 * @return アイテムが買い取れるならばTRUEを返す
215 * Note that a shop-keeper must refuse to buy "worthless" items
218 bool store_will_buy(PlayerType *, const ObjectType *o_ptr, StoreSaleType store_num)
220 if ((store_num == StoreSaleType::HOME) || (store_num == StoreSaleType::MUSEUM)) {
224 if (!switch_store_check(o_ptr, store_num)) {
228 return object_value(o_ptr) > 0;
231 static int mass_lite_produce(const PRICE cost)
235 size += damroll(3, 5);
239 size += damroll(3, 5);
243 size += damroll(2, 2);
249 static int mass_scroll_produce(ObjectType *o_ptr, const PRICE cost)
253 size += damroll(3, 5);
257 size += damroll(1, 5);
260 if (o_ptr->sval == SV_SCROLL_STAR_IDENTIFY) {
261 size += damroll(3, 5);
264 if (o_ptr->sval == SV_SCROLL_STAR_REMOVE_CURSE) {
265 size += damroll(1, 4);
271 static int mass_book_produce(const PRICE cost)
275 size += damroll(2, 3);
279 size += damroll(1, 3);
285 static int mass_equipment_produce(ObjectType *o_ptr, const PRICE cost)
288 if (o_ptr->is_artifact() || o_ptr->is_ego()) {
293 size += damroll(3, 5);
297 size += damroll(3, 5);
303 static int mass_arrow_produce(const PRICE cost)
307 size += damroll(5, 5);
311 size += damroll(5, 5);
315 size += damroll(5, 5);
321 static int mass_figurine_produce(const PRICE cost)
325 size += damroll(2, 2);
329 size += damroll(2, 2);
335 static int mass_magic_produce(const PRICE cost, StoreSaleType store_num)
338 if ((store_num != StoreSaleType::BLACK) || !one_in_(3)) {
343 size += damroll(1, 5);
344 } else if (cost < 3201L) {
345 size += damroll(1, 3);
351 static int switch_mass_production(ObjectType *o_ptr, const PRICE cost, StoreSaleType store_num)
353 switch (o_ptr->tval) {
354 case ItemKindType::FOOD:
355 case ItemKindType::FLASK:
356 case ItemKindType::LITE:
357 return mass_lite_produce(cost);
358 case ItemKindType::POTION:
359 case ItemKindType::SCROLL:
360 return mass_scroll_produce(o_ptr, cost);
361 case ItemKindType::LIFE_BOOK:
362 case ItemKindType::SORCERY_BOOK:
363 case ItemKindType::NATURE_BOOK:
364 case ItemKindType::CHAOS_BOOK:
365 case ItemKindType::DEATH_BOOK:
366 case ItemKindType::TRUMP_BOOK:
367 case ItemKindType::ARCANE_BOOK:
368 case ItemKindType::CRAFT_BOOK:
369 case ItemKindType::DEMON_BOOK:
370 case ItemKindType::CRUSADE_BOOK:
371 case ItemKindType::MUSIC_BOOK:
372 case ItemKindType::HISSATSU_BOOK:
373 case ItemKindType::HEX_BOOK:
374 return mass_book_produce(cost);
375 case ItemKindType::SOFT_ARMOR:
376 case ItemKindType::HARD_ARMOR:
377 case ItemKindType::SHIELD:
378 case ItemKindType::GLOVES:
379 case ItemKindType::BOOTS:
380 case ItemKindType::CLOAK:
381 case ItemKindType::HELM:
382 case ItemKindType::CROWN:
383 case ItemKindType::SWORD:
384 case ItemKindType::POLEARM:
385 case ItemKindType::HAFTED:
386 case ItemKindType::DIGGING:
387 case ItemKindType::BOW:
388 return mass_equipment_produce(o_ptr, cost);
389 case ItemKindType::SPIKE:
390 case ItemKindType::SHOT:
391 case ItemKindType::ARROW:
392 case ItemKindType::BOLT:
393 return mass_arrow_produce(cost);
394 case ItemKindType::FIGURINE:
395 return mass_figurine_produce(cost);
396 case ItemKindType::CAPTURE:
397 case ItemKindType::STATUE:
398 case ItemKindType::CARD:
400 case ItemKindType::ROD:
401 case ItemKindType::WAND:
402 case ItemKindType::STAFF:
403 return mass_magic_produce(cost, store_num);
409 static byte decide_discount_rate(const PRICE cost)
435 * @brief 安価な消耗品の販売数を増やし、低確率で割引にする /
436 * Certain "cheap" objects should be created in "piles"
437 * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
440 * Some objects can be sold at a "discount" (in small piles)
443 void mass_produce(PlayerType *, ObjectType *o_ptr, StoreSaleType store_num)
445 const PRICE cost = object_value(o_ptr);
446 int size = switch_mass_production(o_ptr, cost, store_num);
447 auto discount = decide_discount_rate(cost);
448 if (o_ptr->art_name) {
452 o_ptr->discount = discount;
453 o_ptr->number = size - (size * discount / 100);
454 if ((o_ptr->tval == ItemKindType::ROD) || (o_ptr->tval == ItemKindType::WAND)) {
455 o_ptr->pval *= (PARAMETER_VALUE)o_ptr->number;