OSDN Git Service

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