OSDN Git Service

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