OSDN Git Service

[Fix] スペルマスターが全ての武器を得意武器として自動拾いする #736
[hengbandforosx/hengbandosx.git] / src / object-hook / hook-weapon.cpp
1 #include "object-hook/hook-weapon.h"
2 #include "object-enchant/tr-types.h"
3 #include "object-hook/hook-armor.h"
4 #include "object/object-flags.h"
5 #include "player/player-skill.h"
6 #include "sv-definition/sv-weapon-types.h"
7 #include "system/object-type-definition.h"
8 #include "util/bit-flags-calculator.h"
9
10 /*!
11  * @brief 武器匠の「武器」鑑定対象になるかを判定する。/ Hook to specify "weapon"
12  * @param o_ptr オブジェクトの構造体の参照ポインタ。
13  * @return 対象になるならTRUEを返す。
14  */
15 bool item_tester_hook_orthodox_melee_weapons(player_type *player_ptr, object_type *o_ptr)
16 {
17     /* Unused */
18     (void)player_ptr;
19
20     switch (o_ptr->tval) {
21     case TV_HAFTED:
22     case TV_POLEARM:
23     case TV_DIGGING: {
24         return TRUE;
25     }
26     case TV_SWORD: {
27         if (o_ptr->sval != SV_POISON_NEEDLE)
28             return TRUE;
29     }
30
31     default:
32         break;
33     }
34
35     return FALSE;
36 }
37
38 /*!
39  * @brief オブジェクトが右手か左手に装備できる武器かどうかの判定
40  * @param o_ptr 判定するオブジェクトの構造体参照ポインタ
41  * @return 右手か左手の武器として装備できるならばTRUEを返す。
42  */
43 bool item_tester_hook_melee_weapon(player_type *player_ptr, object_type *o_ptr)
44 {
45     /* Unused */
46     (void)player_ptr;
47
48     /* Check for a usable slot */
49     if ((o_ptr->tval >= TV_DIGGING) && (o_ptr->tval <= TV_SWORD))
50         return TRUE;
51
52     return FALSE;
53 }
54
55 /*!
56  * @brief 修復対象となる壊れた武器かを判定する。 / Hook to specify "broken weapon"
57  * @param o_ptr オブジェクトの構造体の参照ポインタ。
58  * @return 修復対象になるならTRUEを返す。
59  */
60 bool item_tester_hook_broken_weapon(player_type *player_ptr, object_type *o_ptr)
61 {
62     /* Unused */
63     (void)player_ptr;
64
65     if (o_ptr->tval != TV_SWORD)
66         return FALSE;
67
68     switch (o_ptr->sval) {
69     case SV_BROKEN_DAGGER:
70     case SV_BROKEN_SWORD:
71         return TRUE;
72     }
73
74     return FALSE;
75 }
76
77 /*!
78  * @brief オブジェクトが投射可能な武器かどうかを返す。
79  * @param o_ptr 判定するオブジェクトの構造体参照ポインタ
80  * @return 投射可能な武器ならばTRUE
81  */
82 bool item_tester_hook_boomerang(player_type *player_ptr, object_type *o_ptr)
83 {
84     /* Unused */
85     (void)player_ptr;
86
87     if ((o_ptr->tval == TV_DIGGING) || (o_ptr->tval == TV_SWORD) || (o_ptr->tval == TV_POLEARM) || (o_ptr->tval == TV_HAFTED))
88         return TRUE;
89
90     return FALSE;
91 }
92
93 /*!
94  * @brief オブジェクトがどちらの手にも装備できる武器かどうかの判定
95  * @param o_ptr 判定するオブジェクトの構造体参照ポインタ
96  * @return 左右両方の手で装備できるならばTRUEを返す。
97  */
98 bool item_tester_hook_mochikae(player_type *player_ptr, object_type *o_ptr)
99 {
100     /* Unused */
101     (void)player_ptr;
102
103     /* Check for a usable slot */
104     if (((o_ptr->tval >= TV_DIGGING) && (o_ptr->tval <= TV_SWORD)) || (o_ptr->tval == TV_SHIELD) || (o_ptr->tval == TV_CAPTURE) || (o_ptr->tval == TV_CARD))
105         return TRUE;
106
107     return FALSE;
108 }
109
110 /*!
111  * @brief オブジェクトがプレイヤーの職業に応じた適正武器か否かを返す / Favorite weapons
112  * @param o_ptr 対象のオブジェクト構造体ポインタ
113  * @return オブジェクトが適正武器ならばTRUEを返す
114  */
115 bool object_is_favorite(player_type *player_ptr, object_type *o_ptr)
116 {
117     /* Only melee weapons match */
118     if (!(o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD || o_ptr->tval == TV_DIGGING || o_ptr->tval == TV_HAFTED)) {
119         return FALSE;
120     }
121
122     /* Favorite weapons are varied depend on the class */
123     switch (player_ptr->pclass) {
124     case CLASS_PRIEST: {
125         BIT_FLAGS flgs[TR_FLAG_SIZE];
126         object_flags_known(player_ptr, o_ptr, flgs);
127
128         if (!has_flag(flgs, TR_BLESSED) && !(o_ptr->tval == TV_HAFTED))
129             return FALSE;
130         break;
131     }
132
133     case CLASS_MONK:
134     case CLASS_FORCETRAINER:
135         /* Icky to wield? */
136         if (!(s_info[player_ptr->pclass].w_max[o_ptr->tval - TV_WEAPON_BEGIN][o_ptr->sval]))
137             return FALSE;
138         break;
139
140     case CLASS_BEASTMASTER:
141     case CLASS_CAVALRY: {
142         BIT_FLAGS flgs[TR_FLAG_SIZE];
143         object_flags_known(player_ptr, o_ptr, flgs);
144
145         /* Is it known to be suitable to using while riding? */
146         if (!(has_flag(flgs, TR_RIDING)))
147             return FALSE;
148
149         break;
150     }
151
152     case CLASS_SORCERER:
153         if (s_info[player_ptr->pclass].w_max[o_ptr->tval - TV_WEAPON_BEGIN][o_ptr->sval] < WEAPON_EXP_MASTER)
154             return FALSE;
155         break;
156
157     case CLASS_NINJA:
158         /* Icky to wield? */
159         if (s_info[player_ptr->pclass].w_max[o_ptr->tval - TV_WEAPON_BEGIN][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
160             return FALSE;
161         break;
162
163     default:
164         /* All weapons are okay for non-special classes */
165         return TRUE;
166     }
167
168     return TRUE;
169 }
170
171 /*!
172  * @brief オブジェクトが武器として装備できるかどうかを返す / Check if an object is weapon (including bows and ammo)
173  * @param o_ptr 対象のオブジェクト構造体ポインタ
174  * @return 武器として使えるならばTRUEを返す
175  */
176 bool object_is_weapon(player_type *player_ptr, object_type *o_ptr)
177 {
178     /* Unused */
179     (void)player_ptr;
180
181     if (TV_WEAPON_BEGIN <= o_ptr->tval && o_ptr->tval <= TV_WEAPON_END)
182         return TRUE;
183
184     return FALSE;
185 }
186
187 /*!
188  * @brief オブジェクトが武器や矢弾として使用できるかを返す / Check if an object is weapon (including bows and ammo)
189  * Rare weapons/aromors including Blade of Chaos, Dragon armors, etc.
190  * @param o_ptr 対象のオブジェクト構造体ポインタ
191  * @return 武器や矢弾として使えるならばTRUEを返す
192  */
193 bool object_is_weapon_ammo(object_type *o_ptr)
194 {
195     if (TV_MISSILE_BEGIN <= o_ptr->tval && o_ptr->tval <= TV_WEAPON_END)
196         return TRUE;
197
198     return FALSE;
199 }
200
201 /*!
202  * @brief オブジェクトが武器、防具、矢弾として使用できるかを返す / Check if an object is weapon, armour or ammo
203  * @param o_ptr 対象のオブジェクト構造体ポインタ
204  * @return 武器、防具、矢弾として使えるならばTRUEを返す
205  */
206 bool object_is_weapon_armour_ammo(player_type *player_ptr, object_type *o_ptr)
207 {
208     /* Unused */
209     (void)player_ptr;
210
211     if (object_is_weapon_ammo(o_ptr) || object_is_armour(player_ptr, o_ptr))
212         return TRUE;
213
214     return FALSE;
215 }
216
217 /*!
218  * @brief オブジェクトが近接武器として装備できるかを返す / Melee weapons
219  * @param o_ptr 対象のオブジェクト構造体ポインタ
220  * @return 近接武器として使えるならばTRUEを返す
221  */
222 bool object_is_melee_weapon(object_type *o_ptr)
223 {
224     if (TV_DIGGING <= o_ptr->tval && o_ptr->tval <= TV_SWORD)
225         return TRUE;
226
227     return FALSE;
228 }
229
230 /*!
231  * @brief オブジェクトが装備可能であるかを返す / Wearable including all weapon, all armour, bow, light source, amulet, and ring
232  * @param o_ptr 対象のオブジェクト構造体ポインタ
233  * @return 装備可能ならばTRUEを返す
234  */
235 bool object_is_wearable(object_type *o_ptr)
236 {
237     if (TV_WEARABLE_BEGIN <= o_ptr->tval && o_ptr->tval <= TV_WEARABLE_END)
238         return TRUE;
239
240     return FALSE;
241 }
242
243 /*!
244  * @brief オブジェクトが装備品であるかを返す(object_is_wearableに矢弾を含む) / Equipment including all wearable objects and ammo
245  * @param o_ptr 対象のオブジェクト構造体ポインタ
246  * @return 装備品ならばTRUEを返す
247  */
248 bool object_is_equipment(object_type *o_ptr)
249 {
250     if (TV_EQUIP_BEGIN <= o_ptr->tval && o_ptr->tval <= TV_EQUIP_END)
251         return TRUE;
252
253     return FALSE;
254 }
255
256 /*!
257  * @brief オブジェクトが強化不能武器であるかを返す / Poison needle can not be enchanted
258  * @param o_ptr 対象のオブジェクト構造体ポインタ
259  * @return 強化不能ならばTRUEを返す
260  */
261 bool object_refuse_enchant_weapon(object_type *o_ptr)
262 {
263     if (o_ptr->tval == TV_SWORD && o_ptr->sval == SV_POISON_NEEDLE)
264         return TRUE;
265
266     return FALSE;
267 }
268
269 /*!
270  * @brief オブジェクトが強化可能武器であるかを返す /
271  * Check if an object is weapon (including bows and ammo) and allows enchantment
272  * @param o_ptr 対象のオブジェクト構造体ポインタ
273  * @return 強化可能ならばTRUEを返す
274  */
275 bool object_allow_enchant_weapon(player_type *player_ptr, object_type *o_ptr)
276 {
277     /* Unused */
278     (void)player_ptr;
279
280     if (object_is_weapon_ammo(o_ptr) && !object_refuse_enchant_weapon(o_ptr))
281         return TRUE;
282
283     return FALSE;
284 }
285
286 /*!
287  * @brief オブジェクトが強化可能な近接武器であるかを返す /
288  * Check if an object is melee weapon and allows enchantment
289  * @param o_ptr 対象のオブジェクト構造体ポインタ
290  * @return 強化可能な近接武器ならばTRUEを返す
291  */
292 bool object_allow_enchant_melee_weapon(player_type *player_ptr, object_type *o_ptr)
293 {
294     /* Unused */
295     (void)player_ptr;
296
297     if (object_is_melee_weapon(o_ptr) && !object_refuse_enchant_weapon(o_ptr))
298         return TRUE;
299
300     return FALSE;
301 }
302
303 /*!
304  * @brief オブジェクトが両手持ち可能な武器かを返す /
305  * Check if an object is melee weapon and allows wielding with two-hands
306  * @param o_ptr 対象のオブジェクト構造体ポインタ
307  * @return 両手持ち可能ならばTRUEを返す
308  */
309 bool object_allow_two_hands_wielding(object_type *o_ptr)
310 {
311     if (object_is_melee_weapon(o_ptr) && ((o_ptr->weight > 99) || (o_ptr->tval == TV_POLEARM)))
312         return TRUE;
313
314     return FALSE;
315 }