OSDN Git Service

65432085eefb782144be7a2ed67c775ddc087e78
[hengband/hengband.git] / src / inventory / simple-appraiser.c
1 #include "system/angband.h"
2 #include "inventory/simple-appraiser.h"
3 #include "object/object-flavor.h"
4 #include "player/avatar.h"
5 #include "object/object-hook.h"
6 #include "object/object-kind.h"
7 #include "player/player-move.h"
8 #include "player-inventory.h"
9 #include "autopick/autopick.h"
10
11 /*!
12  * @brief 擬似鑑定を実際に行い判定を反映する
13  * @param slot 擬似鑑定を行うプレイヤーの所持リストID
14  * @param creature_ptr プレーヤーへの参照ポインタ
15  * @param heavy 重度の擬似鑑定を行うならばTRUE
16  * @return なし
17  */
18 static void sense_inventory_aux(player_type* creature_ptr, INVENTORY_IDX slot, bool heavy)
19 {
20     byte feel;
21     object_type* o_ptr = &creature_ptr->inventory_list[slot];
22     GAME_TEXT o_name[MAX_NLEN];
23     if (o_ptr->ident & (IDENT_SENSE))
24         return;
25     if (object_is_known(o_ptr))
26         return;
27
28     feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
29     if (!feel)
30         return;
31
32     if ((creature_ptr->muta3 & MUT3_BAD_LUCK) && !randint0(13)) {
33         switch (feel) {
34         case FEEL_TERRIBLE: {
35             feel = FEEL_SPECIAL;
36             break;
37         }
38         case FEEL_WORTHLESS: {
39             feel = FEEL_EXCELLENT;
40             break;
41         }
42         case FEEL_CURSED: {
43             if (heavy)
44                 feel = randint0(3) ? FEEL_GOOD : FEEL_AVERAGE;
45             else
46                 feel = FEEL_UNCURSED;
47             break;
48         }
49         case FEEL_AVERAGE: {
50             feel = randint0(2) ? FEEL_CURSED : FEEL_GOOD;
51             break;
52         }
53         case FEEL_GOOD: {
54             if (heavy)
55                 feel = randint0(3) ? FEEL_CURSED : FEEL_AVERAGE;
56             else
57                 feel = FEEL_CURSED;
58             break;
59         }
60         case FEEL_EXCELLENT: {
61             feel = FEEL_WORTHLESS;
62             break;
63         }
64         case FEEL_SPECIAL: {
65             feel = FEEL_TERRIBLE;
66             break;
67         }
68         }
69     }
70
71     if (disturb_minor)
72         disturb(creature_ptr, FALSE, FALSE);
73
74     object_desc(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
75     if (slot >= INVEN_RARM) {
76 #ifdef JP
77         msg_format("%s%s(%c)は%sという感じがする...",
78             describe_use(creature_ptr, slot), o_name, index_to_label(slot), game_inscriptions[feel]);
79 #else
80         msg_format("You feel the %s (%c) you are %s %s %s...",
81             o_name, index_to_label(slot), describe_use(creature_ptr, slot),
82             ((o_ptr->number == 1) ? "is" : "are"),
83             game_inscriptions[feel]);
84 #endif
85
86     } else {
87 #ifdef JP
88         msg_format("ザックの中の%s(%c)は%sという感じがする...",
89             o_name, index_to_label(slot), game_inscriptions[feel]);
90 #else
91         msg_format("You feel the %s (%c) in your pack %s %s...",
92             o_name, index_to_label(slot),
93             ((o_ptr->number == 1) ? "is" : "are"),
94             game_inscriptions[feel]);
95 #endif
96     }
97
98     o_ptr->ident |= (IDENT_SENSE);
99     o_ptr->feeling = feel;
100
101     autopick_alter_item(creature_ptr, slot, destroy_feeling);
102     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
103     creature_ptr->window |= (PW_INVEN | PW_EQUIP);
104 }
105
106 /*!
107  * @brief 1プレイヤーターン毎に武器、防具の擬似鑑定が行われるかを判定する。
108  * @return なし
109  * @details
110  * Sense the inventory\n
111  *\n
112  *   Class 0 = Warrior --> fast and heavy\n
113  *   Class 1 = Mage    --> slow and light\n
114  *   Class 2 = Priest  --> fast but light\n
115  *   Class 3 = Rogue   --> okay and heavy\n
116  *   Class 4 = Ranger  --> slow but heavy  (changed!)\n
117  *   Class 5 = Paladin --> slow but heavy\n
118  */
119 void sense_inventory1(player_type* creature_ptr)
120 {
121     PLAYER_LEVEL plev = creature_ptr->lev;
122     bool heavy = FALSE;
123     object_type* o_ptr;
124     if (creature_ptr->confused)
125         return;
126
127     switch (creature_ptr->pclass) {
128     case CLASS_WARRIOR:
129     case CLASS_ARCHER:
130     case CLASS_SAMURAI:
131     case CLASS_CAVALRY: {
132         if (0 != randint0(9000L / (plev * plev + 40)))
133             return;
134
135         heavy = TRUE;
136         break;
137     }
138     case CLASS_SMITH: {
139         if (0 != randint0(6000L / (plev * plev + 50)))
140             return;
141
142         heavy = TRUE;
143         break;
144     }
145     case CLASS_MAGE:
146     case CLASS_HIGH_MAGE:
147     case CLASS_SORCERER:
148     case CLASS_MAGIC_EATER: {
149         if (0 != randint0(240000L / (plev + 5)))
150             return;
151
152         break;
153     }
154     case CLASS_PRIEST:
155     case CLASS_BARD: {
156         if (0 != randint0(10000L / (plev * plev + 40)))
157             return;
158
159         break;
160     }
161     case CLASS_ROGUE:
162     case CLASS_NINJA: {
163         if (0 != randint0(20000L / (plev * plev + 40)))
164             return;
165
166         heavy = TRUE;
167         break;
168     }
169     case CLASS_RANGER: {
170         if (0 != randint0(95000L / (plev * plev + 40)))
171             return;
172
173         heavy = TRUE;
174         break;
175     }
176     case CLASS_PALADIN:
177     case CLASS_SNIPER: {
178         if (0 != randint0(77777L / (plev * plev + 40)))
179             return;
180
181         heavy = TRUE;
182         break;
183     }
184     case CLASS_WARRIOR_MAGE:
185     case CLASS_RED_MAGE: {
186         if (0 != randint0(75000L / (plev * plev + 40)))
187             return;
188
189         break;
190     }
191     case CLASS_MINDCRAFTER:
192     case CLASS_IMITATOR:
193     case CLASS_BLUE_MAGE:
194     case CLASS_MIRROR_MASTER: {
195         if (0 != randint0(55000L / (plev * plev + 40)))
196             return;
197
198         break;
199     }
200     case CLASS_CHAOS_WARRIOR: {
201         if (0 != randint0(80000L / (plev * plev + 40)))
202             return;
203
204         heavy = TRUE;
205         break;
206     }
207     case CLASS_MONK:
208     case CLASS_FORCETRAINER: {
209         if (0 != randint0(20000L / (plev * plev + 40)))
210             return;
211
212         break;
213     }
214     case CLASS_TOURIST: {
215         if (0 != randint0(20000L / ((plev + 50) * (plev + 50))))
216             return;
217
218         heavy = TRUE;
219         break;
220     }
221     case CLASS_BEASTMASTER: {
222         if (0 != randint0(65000L / (plev * plev + 40)))
223             return;
224
225         break;
226     }
227     case CLASS_BERSERKER: {
228         heavy = TRUE;
229         break;
230     }
231     }
232
233     if (compare_virtue(creature_ptr, V_KNOWLEDGE, 100, VIRTUE_LARGE))
234         heavy = TRUE;
235
236     for (INVENTORY_IDX i = 0; i < INVEN_TOTAL; i++) {
237         bool okay = FALSE;
238
239         o_ptr = &creature_ptr->inventory_list[i];
240
241         if (!o_ptr->k_idx)
242             continue;
243
244         switch (o_ptr->tval) {
245         case TV_SHOT:
246         case TV_ARROW:
247         case TV_BOLT:
248         case TV_BOW:
249         case TV_DIGGING:
250         case TV_HAFTED:
251         case TV_POLEARM:
252         case TV_SWORD:
253         case TV_BOOTS:
254         case TV_GLOVES:
255         case TV_HELM:
256         case TV_CROWN:
257         case TV_SHIELD:
258         case TV_CLOAK:
259         case TV_SOFT_ARMOR:
260         case TV_HARD_ARMOR:
261         case TV_DRAG_ARMOR:
262         case TV_CARD: {
263             okay = TRUE;
264             break;
265         }
266         }
267
268         if (!okay)
269             continue;
270         if ((i < INVEN_RARM) && (0 != randint0(5)))
271             continue;
272
273         if ((creature_ptr->muta3 & MUT3_GOOD_LUCK) && !randint0(13)) {
274             heavy = TRUE;
275         }
276
277         sense_inventory_aux(creature_ptr, i, heavy);
278     }
279 }
280
281 /*!
282  * @brief 1プレイヤーターン毎に武器、防具以外の擬似鑑定が行われるかを判定する。
283  * @return なし
284  */
285 void sense_inventory2(player_type* creature_ptr)
286 {
287     PLAYER_LEVEL plev = creature_ptr->lev;
288     object_type* o_ptr;
289
290     if (creature_ptr->confused)
291         return;
292
293     switch (creature_ptr->pclass) {
294     case CLASS_WARRIOR:
295     case CLASS_ARCHER:
296     case CLASS_SAMURAI:
297     case CLASS_CAVALRY:
298     case CLASS_BERSERKER:
299     case CLASS_SNIPER: {
300         return;
301     }
302     case CLASS_SMITH:
303     case CLASS_PALADIN:
304     case CLASS_CHAOS_WARRIOR:
305     case CLASS_IMITATOR:
306     case CLASS_BEASTMASTER:
307     case CLASS_NINJA: {
308         if (0 != randint0(240000L / (plev + 5)))
309             return;
310
311         break;
312     }
313     case CLASS_RANGER:
314     case CLASS_WARRIOR_MAGE:
315     case CLASS_RED_MAGE:
316     case CLASS_MONK: {
317         if (0 != randint0(95000L / (plev * plev + 40)))
318             return;
319
320         break;
321     }
322     case CLASS_PRIEST:
323     case CLASS_BARD:
324     case CLASS_ROGUE:
325     case CLASS_FORCETRAINER:
326     case CLASS_MINDCRAFTER: {
327         if (0 != randint0(20000L / (plev * plev + 40)))
328             return;
329
330         break;
331     }
332     case CLASS_MAGE:
333     case CLASS_HIGH_MAGE:
334     case CLASS_SORCERER:
335     case CLASS_MAGIC_EATER:
336     case CLASS_MIRROR_MASTER:
337     case CLASS_BLUE_MAGE: {
338         if (0 != randint0(9000L / (plev * plev + 40)))
339             return;
340
341         break;
342     }
343     case CLASS_TOURIST: {
344         if (0 != randint0(20000L / ((plev + 50) * (plev + 50))))
345             return;
346
347         break;
348     }
349     }
350
351     for (INVENTORY_IDX i = 0; i < INVEN_TOTAL; i++) {
352         bool okay = FALSE;
353         o_ptr = &creature_ptr->inventory_list[i];
354         if (!o_ptr->k_idx)
355             continue;
356
357         switch (o_ptr->tval) {
358         case TV_RING:
359         case TV_AMULET:
360         case TV_LITE:
361         case TV_FIGURINE: {
362             okay = TRUE;
363             break;
364         }
365         }
366
367         if (!okay)
368             continue;
369         if ((i < INVEN_RARM) && (0 != randint0(5)))
370             continue;
371
372         sense_inventory_aux(creature_ptr, i, TRUE);
373     }
374 }