OSDN Git Service

[Add] @return を不要に書き込んだことによる警告をひとまず置換で修正.
[hengbandforosx/hengbandosx.git] / src / mind / mind-mindcrafter.cpp
1 #include "mind/mind-mindcrafter.h"
2 #include "autopick/autopick.h"
3 #include "core/player-update-types.h"
4 #include "core/window-redrawer.h"
5 #include "effect/effect-characteristics.h"
6 #include "effect/effect-processor.h"
7 #include "flavor/flag-inscriptions-table.h"
8 #include "flavor/flavor-describer.h"
9 #include "flavor/object-flavor-types.h"
10 #include "floor/floor-object.h"
11 #include "game-option/auto-destruction-options.h"
12 #include "hpmp/hp-mp-processor.h"
13 #include "mind/mind-mindcrafter.h"
14 #include "mind/mind-numbers.h"
15 #include "object-enchant/item-feeling.h"
16 #include "object-enchant/special-object-flags.h"
17 #include "object/item-use-flags.h"
18 #include "object/object-mark-types.h"
19 #include "perception/object-perception.h"
20 #include "perception/simple-perception.h"
21 #include "player-info/avatar.h"
22 #include "player/player-status.h"
23 #include "spell-kind/spells-detection.h"
24 #include "spell-kind/spells-fetcher.h"
25 #include "spell-kind/spells-floor.h"
26 #include "spell-kind/spells-launcher.h"
27 #include "spell-kind/spells-perception.h"
28 #include "spell-kind/spells-sight.h"
29 #include "spell-kind/spells-teleport.h"
30 #include "spell/spell-types.h"
31 #include "spell/spells-status.h"
32 #include "status/bad-status-setter.h"
33 #include "status/buff-setter.h"
34 #include "status/element-resistance.h"
35 #include "status/sight-setter.h"
36 #include "system/object-type-definition.h"
37 #include "system/player-type-definition.h"
38 #include "target/target-getter.h"
39 #include "util/bit-flags-calculator.h"
40 #include "view/display-messages.h"
41
42 /*!
43  * @brief 超能力者のサイコメトリー処理/ Forcibly pseudo-identify an object in the inventory (or on the floor)
44  * @param caster_ptr プレーヤーへの参照ポインタ
45  * @note
46  * currently this function allows pseudo-id of any object,
47  * including silly ones like potions & scrolls, which always
48  * get '{average}'. This should be changed, either to stop such
49  * items from being pseudo-id'd, or to allow psychometry to
50  * detect whether the unidentified potion/scroll/etc is
51  * good (Cure Light Wounds, Restore Strength, etc) or
52  * bad (Poison, Weakness etc) or 'useless' (Slime Mold Juice, etc).
53  */
54 bool psychometry(player_type *caster_ptr)
55 {
56     concptr q = _("どのアイテムを調べますか?", "Meditate on which item? ");
57     concptr s = _("調べるアイテムがありません。", "You have nothing appropriate.");
58     object_type *o_ptr;
59     OBJECT_IDX item;
60     o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), TV_NONE);
61     if (!o_ptr)
62         return FALSE;
63
64     if (object_is_known(o_ptr)) {
65         msg_print(_("何も新しいことは判らなかった。", "You cannot find out anything more about that."));
66         return TRUE;
67     }
68
69     item_feel_type feel = pseudo_value_check_heavy(o_ptr);
70     GAME_TEXT o_name[MAX_NLEN];
71     describe_flavor(caster_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
72
73     if (!feel) {
74         msg_format(_("%sからは特に変わった事は感じとれなかった。", "You do not perceive anything unusual about the %s."), o_name);
75         return TRUE;
76     }
77
78 #ifdef JP
79     msg_format("%sは%sという感じがする...", o_name, game_inscriptions[feel]);
80 #else
81     msg_format("You feel that the %s %s %s...", o_name, ((o_ptr->number == 1) ? "is" : "are"), game_inscriptions[feel]);
82 #endif
83
84     set_bits(o_ptr->ident, IDENT_SENSE);
85     o_ptr->feeling = feel;
86     set_bits(o_ptr->marked, OM_TOUCHED);
87
88     set_bits(caster_ptr->update, PU_COMBINE | PU_REORDER);
89     set_bits(caster_ptr->window_flags, PW_INVEN | PW_EQUIP | PW_PLAYER | PW_FLOOR_ITEM_LIST);
90
91     bool okay = FALSE;
92     switch (o_ptr->tval) {
93     case TV_SHOT:
94     case TV_ARROW:
95     case TV_BOLT:
96     case TV_BOW:
97     case TV_DIGGING:
98     case TV_HAFTED:
99     case TV_POLEARM:
100     case TV_SWORD:
101     case TV_BOOTS:
102     case TV_GLOVES:
103     case TV_HELM:
104     case TV_CROWN:
105     case TV_SHIELD:
106     case TV_CLOAK:
107     case TV_SOFT_ARMOR:
108     case TV_HARD_ARMOR:
109     case TV_DRAG_ARMOR:
110     case TV_CARD:
111     case TV_RING:
112     case TV_AMULET:
113     case TV_LITE:
114     case TV_FIGURINE:
115         okay = TRUE;
116         break;
117
118     default:
119         break;
120     }
121
122     autopick_alter_item(caster_ptr, item, (bool)(okay && destroy_feeling));
123     return TRUE;
124 }
125
126 /*!
127  * @brief 超能力の発動 /
128  * do_cmd_cast calls this function if the player's class is 'mindcrafter'.
129  * @param spell 発動する特殊技能のID
130  * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
131  */
132 bool cast_mindcrafter_spell(player_type *caster_ptr, mind_mindcrafter_type spell)
133 {
134     bool b = FALSE;
135     int dam = 0;
136     DIRECTION dir;
137     TIME_EFFECT t;
138     PLAYER_LEVEL plev = caster_ptr->lev;
139     switch (spell) {
140     case PRECOGNITION:
141         if (plev > 44) {
142             chg_virtue(caster_ptr, V_KNOWLEDGE, 1);
143             chg_virtue(caster_ptr, V_ENLIGHTEN, 1);
144             wiz_lite(caster_ptr, FALSE);
145         } else if (plev > 19)
146             map_area(caster_ptr, DETECT_RAD_MAP);
147
148         if (plev < 30) {
149             b = detect_monsters_normal(caster_ptr, DETECT_RAD_DEFAULT);
150             if (plev > 14)
151                 b |= detect_monsters_invis(caster_ptr, DETECT_RAD_DEFAULT);
152             if (plev > 4) {
153                 b |= detect_traps(caster_ptr, DETECT_RAD_DEFAULT, TRUE);
154                 b |= detect_doors(caster_ptr, DETECT_RAD_DEFAULT);
155             }
156         } else {
157             b = detect_all(caster_ptr, DETECT_RAD_DEFAULT);
158         }
159
160         if ((plev > 24) && (plev < 40))
161             set_tim_esp(caster_ptr, (TIME_EFFECT)plev, FALSE);
162
163         if (!b)
164             msg_print(_("安全な気がする。", "You feel safe."));
165
166         break;
167     case NEURAL_BLAST:
168         if (!get_aim_dir(caster_ptr, &dir))
169             return FALSE;
170
171         if (randint1(100) < plev * 2)
172             fire_beam(caster_ptr, GF_PSI, dir, damroll(3 + ((plev - 1) / 4), (3 + plev / 15)));
173         else
174             fire_ball(caster_ptr, GF_PSI, dir, damroll(3 + ((plev - 1) / 4), (3 + plev / 15)), 0);
175         break;
176     case MINOR_DISPLACEMENT:
177         teleport_player(caster_ptr, 10, TELEPORT_SPONTANEOUS);
178         break;
179     case MAJOR_DISPLACEMENT:
180         teleport_player(caster_ptr, plev * 5, TELEPORT_SPONTANEOUS);
181         break;
182     case DOMINATION:
183         if (plev < 30) {
184             if (!get_aim_dir(caster_ptr, &dir))
185                 return FALSE;
186
187             fire_ball(caster_ptr, GF_DOMINATION, dir, plev, 0);
188         } else {
189             charm_monsters(caster_ptr, plev * 2);
190         }
191
192         break;
193     case PLUVERISE:
194         if (!get_aim_dir(caster_ptr, &dir))
195             return FALSE;
196
197         fire_ball(caster_ptr, GF_TELEKINESIS, dir, damroll(8 + ((plev - 5) / 4), 8), (plev > 20 ? (plev - 20) / 8 + 1 : 0));
198         break;
199     case CHARACTER_ARMOR:
200         set_shield(caster_ptr, (TIME_EFFECT)plev, FALSE);
201         if (plev > 14)
202             set_oppose_acid(caster_ptr, (TIME_EFFECT)plev, FALSE);
203         if (plev > 19)
204             set_oppose_fire(caster_ptr, (TIME_EFFECT)plev, FALSE);
205         if (plev > 24)
206             set_oppose_cold(caster_ptr, (TIME_EFFECT)plev, FALSE);
207         if (plev > 29)
208             set_oppose_elec(caster_ptr, (TIME_EFFECT)plev, FALSE);
209         if (plev > 34)
210             set_oppose_pois(caster_ptr, (TIME_EFFECT)plev, FALSE);
211
212         break;
213     case PSYCHOMETRY:
214         if (plev < 25)
215             return psychometry(caster_ptr);
216         else
217             return ident_spell(caster_ptr, FALSE, TV_NONE);
218     case MIND_WAVE:
219         msg_print(_("精神を捻じ曲げる波動を発生させた!", "Mind-warping forces emanate from your brain!"));
220         if (plev < 25)
221             project(caster_ptr, 0, 2 + plev / 10, caster_ptr->y, caster_ptr->x, (plev * 3), GF_PSI, PROJECT_KILL);
222         else
223             (void)mindblast_monsters(caster_ptr, randint1(plev * ((plev - 5) / 10 + 1)));
224
225         break;
226     case ADRENALINE_CHANNELING:
227         set_afraid(caster_ptr, 0);
228         set_stun(caster_ptr, 0);
229         if (!is_fast(caster_ptr) || !is_hero(caster_ptr))
230             hp_player(caster_ptr, plev);
231
232         t = 10 + randint1((plev * 3) / 2);
233         set_hero(caster_ptr, t, FALSE);
234         (void)set_fast(caster_ptr, t, FALSE);
235         break;
236     case TELEKINESIS:
237         if (!get_aim_dir(caster_ptr, &dir))
238             return FALSE;
239
240         fetch_item(caster_ptr, dir, plev * 15, FALSE);
241         break;
242     case PSYCHIC_DRAIN:
243         if (!get_aim_dir(caster_ptr, &dir))
244             return FALSE;
245
246         dam = damroll(plev / 2, 6);
247         if (fire_ball(caster_ptr, GF_PSI_DRAIN, dir, dam, 0))
248             caster_ptr->energy_need += randint1(150);
249
250         break;
251     case PSYCHO_SPEAR:
252         if (!get_aim_dir(caster_ptr, &dir))
253             return FALSE;
254
255         fire_beam(caster_ptr, GF_PSY_SPEAR, dir, randint1(plev * 3) + plev * 3);
256         break;
257     case THE_WORLD:
258         time_walk(caster_ptr);
259         break;
260     default:
261         msg_print(_("なに?", "Zap?"));
262     }
263
264     return TRUE;
265 }