OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[hengband/hengband.git] / src / floor / pattern-walk.c
1 #include "floor/pattern-walk.h"
2 #include "cmd-io/cmd-save.h"
3 #include "core/asking-player.h"
4 #include "dungeon/dungeon.h"
5 #include "dungeon/quest.h"
6 #include "floor/cave.h"
7 #include "floor/floor-mode-changer.h"
8 #include "game-option/birth-options.h"
9 #include "game-option/play-record-options.h"
10 #include "game-option/special-options.h"
11 #include "grid/grid.h"
12 #include "io/input-key-requester.h"
13 #include "io/write-diary.h"
14 #include "player/player-damage.h"
15 #include "player/player-move.h"
16 #include "player/player-race-types.h"
17 #include "player/player-race.h"
18 #include "spell/spells-status.h"
19 #include "spell-kind/spells-teleport.h"
20 #include "status/bad-status-setter.h"
21 #include "status/experience.h"
22 #include "system/floor-type-definition.h"
23 #include "util/bit-flags-calculator.h"
24 #include "view/display-messages.h"
25 #include "world/world.h"
26
27 /*!
28  * @brief パターン終点到達時のテレポート処理を行う
29  * @param creature_ptr プレーヤーへの参照ポインタ
30  * @return なし
31  */
32 static void pattern_teleport(player_type *creature_ptr)
33 {
34     DEPTH min_level = 0;
35     DEPTH max_level = 99;
36
37     if (get_check(_("他の階にテレポートしますか?", "Teleport level? "))) {
38         char ppp[80];
39         char tmp_val[160];
40
41         if (ironman_downward)
42             min_level = creature_ptr->current_floor_ptr->dun_level;
43
44         if (creature_ptr->dungeon_idx == DUNGEON_ANGBAND) {
45             if (creature_ptr->current_floor_ptr->dun_level > 100)
46                 max_level = MAX_DEPTH - 1;
47             else if (creature_ptr->current_floor_ptr->dun_level == 100)
48                 max_level = 100;
49         } else {
50             max_level = d_info[creature_ptr->dungeon_idx].maxdepth;
51             min_level = d_info[creature_ptr->dungeon_idx].mindepth;
52         }
53
54         sprintf(ppp, _("テレポート先:(%d-%d)", "Teleport to level (%d-%d): "), (int)min_level, (int)max_level);
55         sprintf(tmp_val, "%d", (int)creature_ptr->current_floor_ptr->dun_level);
56         if (!get_string(ppp, tmp_val, 10))
57             return;
58
59         command_arg = (COMMAND_ARG)atoi(tmp_val);
60     } else if (get_check(_("通常テレポート?", "Normal teleport? "))) {
61         teleport_player(creature_ptr, 200, TELEPORT_SPONTANEOUS);
62         return;
63     } else {
64         return;
65     }
66
67     if (command_arg < min_level)
68         command_arg = (COMMAND_ARG)min_level;
69     if (command_arg > max_level)
70         command_arg = (COMMAND_ARG)max_level;
71
72     msg_format(_("%d 階にテレポートしました。", "You teleport to dungeon level %d."), command_arg);
73     if (autosave_l)
74         do_cmd_save_game(creature_ptr, TRUE);
75
76     creature_ptr->current_floor_ptr->dun_level = command_arg;
77     leave_quest_check(creature_ptr);
78     if (record_stair)
79         exe_write_diary(creature_ptr, DIARY_PAT_TELE, 0, NULL);
80
81     creature_ptr->current_floor_ptr->inside_quest = 0;
82     free_turn(creature_ptr);
83
84     /*
85      * Clear all saved floors
86      * and create a first saved floor
87      */
88     prepare_change_floor_mode(creature_ptr, CFM_FIRST_FLOOR);
89     creature_ptr->leaving = TRUE;
90 }
91
92 /*!
93  * @brief 各種パターン地形上の特別な処理 / Returns TRUE if we are on the Pattern...
94  * @return 実際にパターン地形上にプレイヤーが居た場合はTRUEを返す。
95  */
96 bool pattern_effect(player_type *creature_ptr)
97 {
98     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
99     if (!pattern_tile(floor_ptr, creature_ptr->y, creature_ptr->x))
100         return FALSE;
101
102     if ((is_specific_player_race(creature_ptr, RACE_AMBERITE)) && (creature_ptr->cut > 0) && one_in_(10)) {
103         wreck_the_pattern(creature_ptr);
104     }
105
106     int pattern_type = f_info[floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].feat].subtype;
107     switch (pattern_type) {
108     case PATTERN_TILE_END:
109         (void)set_image(creature_ptr, 0);
110         (void)restore_all_status(creature_ptr);
111         (void)restore_level(creature_ptr);
112         (void)cure_critical_wounds(creature_ptr, 1000);
113
114         cave_set_feat(creature_ptr, creature_ptr->y, creature_ptr->x, feat_pattern_old);
115         msg_print(_("「パターン」のこの部分は他の部分より強力でないようだ。", "This section of the Pattern looks less powerful."));
116
117         /*
118          * We could make the healing effect of the
119          * Pattern center one-time only to avoid various kinds
120          * of abuse, like luring the win monster into fighting you
121          * in the middle of the pattern...
122          */
123         break;
124
125     case PATTERN_TILE_OLD:
126         /* No effect */
127         break;
128
129     case PATTERN_TILE_TELEPORT:
130         pattern_teleport(creature_ptr);
131         break;
132
133     case PATTERN_TILE_WRECKED:
134         if (!is_invuln(creature_ptr))
135             take_hit(creature_ptr, DAMAGE_NOESCAPE, 200, _("壊れた「パターン」を歩いたダメージ", "walking the corrupted Pattern"), -1);
136         break;
137
138     default:
139         if (is_specific_player_race(creature_ptr, RACE_AMBERITE) && !one_in_(2))
140             return TRUE;
141         else if (!is_invuln(creature_ptr))
142             take_hit(creature_ptr, DAMAGE_NOESCAPE, damroll(1, 3), _("「パターン」を歩いたダメージ", "walking the Pattern"), -1);
143         break;
144     }
145
146     return TRUE;
147 }
148
149 /*!
150  * @brief パターンによる移動制限処理
151  * @param creature_ptr プレーヤーへの参照ポインタ
152  * @param c_y プレイヤーの移動元Y座標
153  * @param c_x プレイヤーの移動元X座標
154  * @param n_y プレイヤーの移動先Y座標
155  * @param n_x プレイヤーの移動先X座標
156  * @return 移動処理が可能である場合(可能な場合に選択した場合)TRUEを返す。
157  */
158 bool pattern_seq(player_type *creature_ptr, POSITION c_y, POSITION c_x, POSITION n_y, POSITION n_x)
159 {
160     feature_type *cur_f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[c_y][c_x].feat];
161     feature_type *new_f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[n_y][n_x].feat];
162     bool is_pattern_tile_cur = have_flag(cur_f_ptr->flags, FF_PATTERN);
163     bool is_pattern_tile_new = have_flag(new_f_ptr->flags, FF_PATTERN);
164     if (!is_pattern_tile_cur && !is_pattern_tile_new)
165         return TRUE;
166
167     int pattern_type_cur = is_pattern_tile_cur ? cur_f_ptr->subtype : NOT_PATTERN_TILE;
168     int pattern_type_new = is_pattern_tile_new ? new_f_ptr->subtype : NOT_PATTERN_TILE;
169     if (pattern_type_new == PATTERN_TILE_START) {
170         if (!is_pattern_tile_cur && !creature_ptr->confused && !creature_ptr->stun && !creature_ptr->image) {
171             if (get_check(_("パターンの上を歩き始めると、全てを歩かなければなりません。いいですか?",
172                     "If you start walking the Pattern, you must walk the whole way. Ok? ")))
173                 return TRUE;
174             else
175                 return FALSE;
176         } else
177             return TRUE;
178     }
179
180     if ((pattern_type_new == PATTERN_TILE_OLD) || (pattern_type_new == PATTERN_TILE_END) || (pattern_type_new == PATTERN_TILE_WRECKED)) {
181         if (is_pattern_tile_cur) {
182             return TRUE;
183         } else {
184             msg_print(_("パターンの上を歩くにはスタート地点から歩き始めなくてはなりません。", "You must start walking the Pattern from the startpoint."));
185             return FALSE;
186         }
187     }
188
189     if ((pattern_type_new == PATTERN_TILE_TELEPORT) || (pattern_type_cur == PATTERN_TILE_TELEPORT))
190         return TRUE;
191
192     if (pattern_type_cur == PATTERN_TILE_START) {
193         if (is_pattern_tile_new)
194             return TRUE;
195         else {
196             msg_print(_("パターンの上は正しい順序で歩かねばなりません。", "You must walk the Pattern in correct order."));
197             return FALSE;
198         }
199     }
200
201     if ((pattern_type_cur == PATTERN_TILE_OLD) || (pattern_type_cur == PATTERN_TILE_END) || (pattern_type_cur == PATTERN_TILE_WRECKED)) {
202         if (!is_pattern_tile_new) {
203             msg_print(_("パターンを踏み外してはいけません。", "You may not step off from the Pattern."));
204             return FALSE;
205         } else {
206             return TRUE;
207         }
208     }
209
210     if (!is_pattern_tile_cur) {
211         msg_print(_("パターンの上を歩くにはスタート地点から歩き始めなくてはなりません。", "You must start walking the Pattern from the startpoint."));
212
213         return FALSE;
214     }
215
216     byte ok_move = PATTERN_TILE_START;
217     switch (pattern_type_cur) {
218     case PATTERN_TILE_1:
219         ok_move = PATTERN_TILE_2;
220         break;
221     case PATTERN_TILE_2:
222         ok_move = PATTERN_TILE_3;
223         break;
224     case PATTERN_TILE_3:
225         ok_move = PATTERN_TILE_4;
226         break;
227     case PATTERN_TILE_4:
228         ok_move = PATTERN_TILE_1;
229         break;
230     default:
231         if (current_world_ptr->wizard)
232             msg_format(_("おかしなパターン歩行、%d。", "Funny Pattern walking, %d."), pattern_type_cur);
233         return TRUE;
234     }
235
236     if ((pattern_type_new == ok_move) || (pattern_type_new == pattern_type_cur))
237         return TRUE;
238
239     if (!is_pattern_tile_new)
240         msg_print(_("パターンを踏み外してはいけません。", "You may not step off from the Pattern."));
241     else
242         msg_print(_("パターンの上は正しい順序で歩かねばなりません。", "You must walk the Pattern in correct order."));
243
244     return FALSE;
245 }