OSDN Git Service

Since its used as an adverb, replace "much slower" with "much more slowly" in the...
[hengband/hengband.git] / src / store / service-checker.c
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-hook/hook-enchant.h"
6 #include "object/object-flags.h"
7 #include "object/object-value.h"
8 #include "store/store-util.h"
9 #include "sv-definition/sv-potion-types.h"
10 #include "sv-definition/sv-scroll-types.h"
11 #include "sv-definition/sv-weapon-types.h"
12 #include "system/object-type-definition.h"
13 #include "util/bit-flags-calculator.h"
14 #include "util/string-processor.h"
15
16 /*!
17  * @brief オブジェクトが祝福されているかの判定を返す /
18  * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
19  * @return アイテムが祝福されたアイテムならばTRUEを返す
20  */
21 static bool is_blessed_item(player_type *player_ptr, object_type *o_ptr)
22 {
23     BIT_FLAGS flgs[TR_FLAG_SIZE];
24     object_flags(player_ptr, o_ptr, flgs);
25     return has_flag(flgs, TR_BLESSED);
26 }
27
28 static bool check_store_general(object_type *o_ptr)
29 {
30     switch (o_ptr->tval) {
31     case TV_POTION:
32         if (o_ptr->sval != SV_POTION_WATER)
33             return FALSE;
34         /* Fall through */
35     case TV_WHISTLE:
36     case TV_FOOD:
37     case TV_LITE:
38     case TV_FLASK:
39     case TV_SPIKE:
40     case TV_SHOT:
41     case TV_ARROW:
42     case TV_BOLT:
43     case TV_DIGGING:
44     case TV_CLOAK:
45     case TV_BOTTLE:
46     case TV_FIGURINE:
47     case TV_STATUE:
48     case TV_CAPTURE:
49     case TV_CARD:
50         return TRUE;
51     default:
52         return FALSE;
53     }
54 }
55
56 static bool check_store_armoury(object_type *o_ptr)
57 {
58     switch (o_ptr->tval) {
59     case TV_BOOTS:
60     case TV_GLOVES:
61     case TV_CROWN:
62     case TV_HELM:
63     case TV_SHIELD:
64     case TV_CLOAK:
65     case TV_SOFT_ARMOR:
66     case TV_HARD_ARMOR:
67     case TV_DRAG_ARMOR:
68         return TRUE;
69     default:
70         return FALSE;
71     }
72 }
73
74 static bool check_store_weapon(object_type *o_ptr)
75 {
76     switch (o_ptr->tval) {
77     case TV_SHOT:
78     case TV_BOLT:
79     case TV_ARROW:
80     case TV_BOW:
81     case TV_DIGGING:
82     case TV_POLEARM:
83     case TV_SWORD:
84     case TV_HISSATSU_BOOK:
85         return TRUE;
86     case TV_HAFTED:
87         return o_ptr->sval != SV_WIZSTAFF;
88     default:
89         return FALSE;
90     }
91 }
92
93 static bool check_store_temple(player_type *player_ptr, object_type *o_ptr)
94 {
95     switch (o_ptr->tval) {
96     case TV_LIFE_BOOK:
97     case TV_CRUSADE_BOOK:
98     case TV_SCROLL:
99     case TV_POTION:
100     case TV_HAFTED:
101         return TRUE;
102     case TV_FIGURINE:
103     case TV_STATUE: {
104         monster_race *r_ptr = &r_info[o_ptr->pval];
105         if (!(r_ptr->flags3 & RF3_EVIL))
106             if (((r_ptr->flags3 & RF3_GOOD) != 0) || ((r_ptr->flags3 & RF3_ANIMAL) != 0) || (angband_strchr("?!", r_ptr->d_char) != NULL))
107                 return TRUE;
108     }
109         /* Fall through */
110     case TV_POLEARM:
111     case TV_SWORD:
112         if (is_blessed_item(player_ptr, o_ptr))
113             return TRUE;
114
115         /* Fall through */
116     default:
117         return FALSE;
118     }
119 }
120
121 static bool check_store_alchemist(object_type *o_ptr)
122 {
123     switch (o_ptr->tval) {
124     case TV_SCROLL:
125     case TV_POTION:
126         return TRUE;
127     default:
128         return FALSE;
129     }
130 }
131
132 static bool check_store_magic(object_type *o_ptr)
133 {
134     switch (o_ptr->tval) {
135     case TV_SORCERY_BOOK:
136     case TV_NATURE_BOOK:
137     case TV_CHAOS_BOOK:
138     case TV_DEATH_BOOK:
139     case TV_TRUMP_BOOK:
140     case TV_ARCANE_BOOK:
141     case TV_CRAFT_BOOK:
142     case TV_DEMON_BOOK:
143     case TV_MUSIC_BOOK:
144     case TV_HEX_BOOK:
145     case TV_AMULET:
146     case TV_RING:
147     case TV_STAFF:
148     case TV_WAND:
149     case TV_ROD:
150     case TV_SCROLL:
151     case TV_POTION:
152     case TV_FIGURINE:
153         return TRUE;
154     case TV_HAFTED:
155         return o_ptr->sval == SV_WIZSTAFF;
156     default:
157         return FALSE;
158     }
159 }
160
161 static bool check_store_book(object_type *o_ptr)
162 {
163     switch (o_ptr->tval) {
164     case TV_SORCERY_BOOK:
165     case TV_NATURE_BOOK:
166     case TV_CHAOS_BOOK:
167     case TV_DEATH_BOOK:
168     case TV_LIFE_BOOK:
169     case TV_TRUMP_BOOK:
170     case TV_ARCANE_BOOK:
171     case TV_CRAFT_BOOK:
172     case TV_DEMON_BOOK:
173     case TV_CRUSADE_BOOK:
174     case TV_MUSIC_BOOK:
175     case TV_HEX_BOOK:
176         return TRUE;
177     default:
178         return FALSE;
179     }
180 }
181
182 static bool switch_store_check(player_type *player_ptr, object_type *o_ptr)
183 {
184     switch (cur_store_num) {
185     case STORE_GENERAL:
186         return check_store_general(o_ptr);
187     case STORE_ARMOURY:
188         return check_store_armoury(o_ptr);
189     case STORE_WEAPON:
190         return check_store_weapon(o_ptr);
191     case STORE_TEMPLE:
192         return check_store_temple(player_ptr, o_ptr);
193     case STORE_ALCHEMIST:
194         return check_store_alchemist(o_ptr);
195     case STORE_MAGIC:
196         return check_store_magic(o_ptr);
197     case STORE_BOOK:
198         return check_store_book(o_ptr);
199     default:
200         return TRUE;
201     }
202 }
203
204 /*!
205  * @brief オブジェクトが所定の店舗で引き取れるかどうかを返す /
206  * Determine if the current store will purchase the given item
207  * @param o_ptr 判定したいオブジェクト構造体の参照ポインタ
208  * @return アイテムが買い取れるならばTRUEを返す
209  * @note
210  * Note that a shop-keeper must refuse to buy "worthless" items
211  */
212 bool store_will_buy(player_type *player_ptr, object_type *o_ptr)
213 {
214     if ((cur_store_num == STORE_HOME) || (cur_store_num == STORE_MUSEUM))
215         return TRUE;
216
217     if (!switch_store_check(player_ptr, o_ptr))
218         return FALSE;
219
220     return object_value(player_ptr, o_ptr) > 0;
221 }
222
223 static int mass_lite_produce(const PRICE cost)
224 {
225     int size = 1;
226     if (cost <= 5L)
227         size += damroll(3, 5);
228
229     if (cost <= 20L)
230         size += damroll(3, 5);
231
232     if (cost <= 50L)
233         size += damroll(2, 2);
234
235     return size;
236 }
237
238 static int mass_scroll_produce(object_type *o_ptr, const PRICE cost)
239 {
240     int size = 1;
241     if (cost <= 60L)
242         size += damroll(3, 5);
243
244     if (cost <= 240L)
245         size += damroll(1, 5);
246
247     if (o_ptr->sval == SV_SCROLL_STAR_IDENTIFY)
248         size += damroll(3, 5);
249
250     if (o_ptr->sval == SV_SCROLL_STAR_REMOVE_CURSE)
251         size += damroll(1, 4);
252
253     return size;
254 }
255
256 static int mass_book_produce(const PRICE cost)
257 {
258     int size = 1;
259     if (cost <= 50L)
260         size += damroll(2, 3);
261
262     if (cost <= 500L)
263         size += damroll(1, 3);
264
265     return size;
266 }
267
268 static int mass_equipment_produce(object_type *o_ptr, const PRICE cost)
269 {
270     int size = 1;
271     if (object_is_artifact(o_ptr) || object_is_ego(o_ptr))
272         return size;
273
274     if (cost <= 10L)
275         size += damroll(3, 5);
276
277     if (cost <= 100L)
278         size += damroll(3, 5);
279
280     return size;
281 }
282
283 static int mass_arrow_produce(const PRICE cost)
284 {
285     int size = 1;
286     if (cost <= 5L)
287         size += damroll(5, 5);
288
289     if (cost <= 50L)
290         size += damroll(5, 5);
291
292     if (cost <= 500L)
293         size += damroll(5, 5);
294
295     return size;
296 }
297
298 static int mass_figurine_produce(const PRICE cost)
299 {
300     int size = 1;
301     if (cost <= 100L)
302         size += damroll(2, 2);
303
304     if (cost <= 1000L)
305         size += damroll(2, 2);
306
307     return size;
308 }
309
310 static int mass_magic_produce(const PRICE cost)
311 {
312     int size = 1;
313     if ((cur_store_num != STORE_BLACK) || !one_in_(3))
314         return size;
315
316     if (cost < 1601L)
317         size += damroll(1, 5);
318     else if (cost < 3201L)
319         size += damroll(1, 3);
320
321     return size;
322 }
323
324 static int switch_mass_production(object_type *o_ptr, const PRICE cost)
325 {
326     switch (o_ptr->tval) {
327     case TV_FOOD:
328     case TV_FLASK:
329     case TV_LITE:
330         return mass_lite_produce(cost);
331     case TV_POTION:
332     case TV_SCROLL:
333         return mass_scroll_produce(o_ptr, cost);
334     case TV_LIFE_BOOK:
335     case TV_SORCERY_BOOK:
336     case TV_NATURE_BOOK:
337     case TV_CHAOS_BOOK:
338     case TV_DEATH_BOOK:
339     case TV_TRUMP_BOOK:
340     case TV_ARCANE_BOOK:
341     case TV_CRAFT_BOOK:
342     case TV_DEMON_BOOK:
343     case TV_CRUSADE_BOOK:
344     case TV_MUSIC_BOOK:
345     case TV_HISSATSU_BOOK:
346     case TV_HEX_BOOK:
347         return mass_book_produce(cost);
348     case TV_SOFT_ARMOR:
349     case TV_HARD_ARMOR:
350     case TV_SHIELD:
351     case TV_GLOVES:
352     case TV_BOOTS:
353     case TV_CLOAK:
354     case TV_HELM:
355     case TV_CROWN:
356     case TV_SWORD:
357     case TV_POLEARM:
358     case TV_HAFTED:
359     case TV_DIGGING:
360     case TV_BOW:
361         return mass_equipment_produce(o_ptr, cost);
362     case TV_SPIKE:
363     case TV_SHOT:
364     case TV_ARROW:
365     case TV_BOLT:
366         return mass_arrow_produce(cost);
367     case TV_FIGURINE:
368         return mass_figurine_produce(cost);
369     case TV_CAPTURE:
370     case TV_STATUE:
371     case TV_CARD:
372         return 1;
373     case TV_ROD:
374     case TV_WAND:
375     case TV_STAFF:
376         return mass_magic_produce(cost);
377     default:
378         return 1;
379     }
380 }
381
382 static DISCOUNT_RATE decide_discount_rate(const PRICE cost)
383 {
384     if (cost < 5)
385         return 0;
386     
387     if (one_in_(25))
388         return 25;
389     
390     if (one_in_(150))
391         return 50;
392     
393     if (one_in_(300))
394         return 75;
395     
396     if (one_in_(500))
397         return 90;
398
399     return 0;
400 }
401
402 /*!
403  * @brief 安価な消耗品の販売数を増やし、低確率で割引にする /
404  * Certain "cheap" objects should be created in "piles"
405  * @param o_ptr 店舗に並べるオブジェクト構造体の参照ポインタ
406  * @return なし
407  * @details
408  * <pre>
409  * Some objects can be sold at a "discount" (in small piles)
410  * </pre>
411  */
412 void mass_produce(player_type *player_ptr, object_type *o_ptr)
413 {
414     const PRICE cost = object_value(player_ptr, o_ptr);
415     int size = switch_mass_production(o_ptr, cost);
416     DISCOUNT_RATE discount = decide_discount_rate(cost);
417     if (o_ptr->art_name)
418         discount = 0;
419
420     o_ptr->discount = discount;
421     o_ptr->number = size - (size * discount / 100);
422     if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND))
423         o_ptr->pval *= (PARAMETER_VALUE)o_ptr->number;
424 }