OSDN Git Service

Merge remote-tracking branch 'remotes/hengband-osx/For2.2.2-Refactoring-English-New...
[hengbandforosx/hengbandosx.git] / src / cmd-building / cmd-building.c
1 /*!
2  * @brief 町の施設処理 / Building commands
3  * @date 2013/12/23
4  * @author
5  * Created by Ken Wigle for Kangband - a variant of Angband 2.8.3
6  * -KMW-
7  *
8  * Rewritten for Kangband 2.8.3i using Kamband's version of
9  * building.c as written by Ivan Tkatchev
10  *
11  * Changed for ZAngband by Robert Ruehlmann
12  */
13
14 #include "cmd-building/cmd-building.h"
15 #include "cmd-action/cmd-spell.h"
16 #include "cmd-building/cmd-inn.h"
17 #include "cmd-io/cmd-dump.h"
18 #include "core/asking-player.h"
19 #include "core/player-redraw-types.h"
20 #include "core/player-update-types.h"
21 #include "core/scores.h"
22 #include "core/show-file.h"
23 #include "core/special-internal-keys.h"
24 #include "core/stuff-handler.h"
25 #include "core/window-redrawer.h"
26 #include "floor/cave.h"
27 #include "floor/floor-mode-changer.h"
28 #include "floor/floor-events.h"
29 #include "floor/wild.h"
30 #include "grid/feature.h"
31 #include "grid/grid.h"
32 #include "io/input-key-acceptor.h"
33 #include "io/input-key-requester.h"
34 #include "main/music-definitions-table.h"
35 #include "main/sound-of-music.h"
36 #include "market/arena.h"
37 #include "market/bounty.h"
38 #include "market/building-actions-table.h"
39 #include "market/building-craft-armor.h"
40 #include "market/building-craft-fix.h"
41 #include "market/building-craft-weapon.h"
42 #include "market/building-enchanter.h"
43 #include "market/building-monster.h"
44 #include "market/building-quest.h"
45 #include "market/building-recharger.h"
46 #include "market/building-service.h"
47 #include "market/building-util.h"
48 #include "market/play-gamble.h"
49 #include "market/poker.h"
50 #include "monster-race/monster-race.h"
51 #include "mutation/mutation-flag-types.h"
52 #include "mutation/mutation-investor-remover.h"
53 #include "object-hook/hook-armor.h"
54 #include "object-hook/hook-bow.h"
55 #include "object-hook/hook-weapon.h"
56 #include "object/item-tester-hooker.h"
57 #include "player/avatar.h"
58 #include "player/player-personalities-types.h"
59 #include "player/player-status.h"
60 #include "spell-kind/spells-perception.h"
61 #include "spell-kind/spells-world.h"
62 #include "spell/spells-status.h"
63 #include "system/building-type-definition.h"
64 #include "system/floor-type-definition.h"
65 #include "term/screen-processor.h"
66 #include "util/bit-flags-calculator.h"
67 #include "util/int-char-converter.h"
68 #include "view/display-messages.h"
69 #include "world/world.h"
70
71 MONRACE_IDX battle_mon[4];
72 u32b mon_odds[4];
73 int battle_odds;
74 PRICE kakekin;
75 int sel_monster;
76
77 bool reinit_wilderness = FALSE;
78 MONSTER_IDX today_mon;
79
80 /*!
81  * @brief 町に関するヘルプを表示する / Display town history
82  * @param player_ptr プレーヤーへの参照ポインタ
83  * @return なし
84  */
85 static void town_history(player_type *player_ptr)
86 {
87         screen_save();
88         (void)show_file(player_ptr, TRUE, _("jbldg.txt", "bldg.txt"), NULL, 0, 0);
89         screen_load();
90 }
91
92 /*!
93  * @brief 施設の処理実行メインルーチン / Execute a building command
94  * @param player_ptr プレーヤーへの参照ポインタ
95  * @param bldg 施設構造体の参照ポインタ
96  * @param i 実行したい施設のサービステーブルの添字
97  * @return なし
98  */
99 static void bldg_process_command(player_type *player_ptr, building_type *bldg, int i)
100 {
101         msg_flag = FALSE;
102         msg_erase();
103
104         PRICE bcost;
105         if (is_owner(player_ptr, bldg))
106                 bcost = bldg->member_costs[i];
107         else
108                 bcost = bldg->other_costs[i];
109
110         /* action restrictions */
111         if (((bldg->action_restr[i] == 1) && !is_member(player_ptr, bldg)) ||
112                 ((bldg->action_restr[i] == 2) && !is_owner(player_ptr, bldg)))
113         {
114                 msg_print(_("それを選択する権利はありません!", "You have no right to choose that!"));
115                 return;
116         }
117
118         BACT_IDX bact = bldg->actions[i];
119         if ((bact != BACT_RECHARGE) &&
120                 (((bldg->member_costs[i] > player_ptr->au) && is_owner(player_ptr, bldg)) ||
121                 ((bldg->other_costs[i] > player_ptr->au) && !is_owner(player_ptr, bldg))))
122         {
123                 msg_print(_("お金が足りません!", "You do not have the gold!"));
124                 return;
125         }
126
127         bool paid = FALSE;
128         switch (bact)
129         {
130         case BACT_NOTHING:
131                 /* Do nothing */
132                 break;
133         case BACT_RESEARCH_ITEM:
134                 paid = identify_fully(player_ptr, FALSE, 0);
135                 break;
136         case BACT_TOWN_HISTORY:
137                 town_history(player_ptr);
138                 break;
139         case BACT_RACE_LEGENDS:
140                 race_legends(player_ptr);
141                 break;
142         case BACT_QUEST:
143                 castle_quest(player_ptr);
144                 break;
145         case BACT_KING_LEGENDS:
146         case BACT_ARENA_LEGENDS:
147         case BACT_LEGENDS:
148                 show_highclass(player_ptr);
149                 break;
150         case BACT_POSTER:
151         case BACT_ARENA_RULES:
152         case BACT_ARENA:
153                 arena_comm(player_ptr, bact);
154                 break;
155         case BACT_IN_BETWEEN:
156         case BACT_CRAPS:
157         case BACT_SPIN_WHEEL:
158         case BACT_DICE_SLOTS:
159         case BACT_GAMBLE_RULES:
160         case BACT_POKER:
161                 gamble_comm(player_ptr, bact);
162                 break;
163         case BACT_REST:
164         case BACT_RUMORS:
165         case BACT_FOOD:
166                 paid = inn_comm(player_ptr, bact);
167                 break;
168         case BACT_RESEARCH_MONSTER:
169                 paid = research_mon(player_ptr);
170                 break;
171         case BACT_COMPARE_WEAPONS:
172                 paid = TRUE;
173                 bcost = compare_weapons(player_ptr, bcost);
174                 break;
175         case BACT_ENCHANT_WEAPON:
176                 item_tester_hook = object_allow_enchant_melee_weapon;
177                 enchant_item(player_ptr, bcost, 1, 1, 0, 0);
178                 break;
179         case BACT_ENCHANT_ARMOR:
180                 item_tester_hook = object_is_armour;
181                 enchant_item(player_ptr, bcost, 0, 0, 1, 0);
182                 break;
183         case BACT_RECHARGE:
184                 building_recharge(player_ptr);
185                 break;
186         case BACT_RECHARGE_ALL:
187                 building_recharge_all(player_ptr);
188                 break;
189         case BACT_IDENTS:
190                 if (!get_check(_("持ち物を全て鑑定してよろしいですか?", "Do you pay for identify all your possession? "))) break;
191                 identify_pack(player_ptr);
192                 msg_print(_(" 持ち物全てが鑑定されました。", "Your possessions have been identified."));
193                 paid = TRUE;
194                 break;
195         case BACT_IDENT_ONE:
196                 paid = ident_spell(player_ptr, FALSE, 0);
197                 break;
198         case BACT_LEARN:
199                 do_cmd_study(player_ptr);
200                 break;
201         case BACT_HEALING:
202                 paid = cure_critical_wounds(player_ptr, 200);
203                 break;
204         case BACT_RESTORE:
205                 paid = restore_all_status(player_ptr);
206                 break;
207         case BACT_ENCHANT_ARROWS:
208                 item_tester_hook = item_tester_hook_ammo;
209                 enchant_item(player_ptr, bcost, 1, 1, 0, 0);
210                 break;
211         case BACT_ENCHANT_BOW:
212                 enchant_item(player_ptr, bcost, 1, 1, 0, TV_BOW);
213                 break;
214
215         case BACT_RECALL:
216                 if (recall_player(player_ptr, 1)) paid = TRUE;
217                 break;
218
219         case BACT_TELEPORT_LEVEL:
220                 clear_bldg(4, 20);
221                 paid = free_level_recall(player_ptr);
222                 break;
223
224         case BACT_LOSE_MUTATION:
225                 if (player_ptr->muta1 || player_ptr->muta2 || (player_ptr->muta3 & ~MUT3_GOOD_LUCK) ||
226                         (player_ptr->pseikaku != PERSONALITY_LUCKY && (player_ptr->muta3 & MUT3_GOOD_LUCK)))
227                 {
228                         while (!lose_mutation(player_ptr, 0));
229                         paid = TRUE;
230                         break;
231                 }
232
233                 msg_print(_("治すべき突然変異が無い。", "You have no mutations."));
234                 msg_print(NULL);
235                 break;
236
237         case BACT_BATTLE:
238                 monster_arena_comm(player_ptr);
239                 break;
240
241         case BACT_TSUCHINOKO:
242                 tsuchinoko();
243                 break;
244
245         case BACT_BOUNTY:
246                 show_bounty();
247                 break;
248
249         case BACT_TARGET:
250                 today_target(player_ptr);
251                 break;
252
253         case BACT_KANKIN:
254                 exchange_cash(player_ptr);
255                 break;
256
257         case BACT_HEIKOUKA:
258                 msg_print(_("平衡化の儀式を行なった。", "You received an equalization ritual."));
259                 set_virtue(player_ptr, V_COMPASSION, 0);
260                 set_virtue(player_ptr, V_HONOUR, 0);
261                 set_virtue(player_ptr, V_JUSTICE, 0);
262                 set_virtue(player_ptr, V_SACRIFICE, 0);
263                 set_virtue(player_ptr, V_KNOWLEDGE, 0);
264                 set_virtue(player_ptr, V_FAITH, 0);
265                 set_virtue(player_ptr, V_ENLIGHTEN, 0);
266                 set_virtue(player_ptr, V_ENCHANT, 0);
267                 set_virtue(player_ptr, V_CHANCE, 0);
268                 set_virtue(player_ptr, V_NATURE, 0);
269                 set_virtue(player_ptr, V_HARMONY, 0);
270                 set_virtue(player_ptr, V_VITALITY, 0);
271                 set_virtue(player_ptr, V_UNLIFE, 0);
272                 set_virtue(player_ptr, V_PATIENCE, 0);
273                 set_virtue(player_ptr, V_TEMPERANCE, 0);
274                 set_virtue(player_ptr, V_DILIGENCE, 0);
275                 set_virtue(player_ptr, V_VALOUR, 0);
276                 set_virtue(player_ptr, V_INDIVIDUALISM, 0);
277                 get_virtues(player_ptr);
278                 paid = TRUE;
279                 break;
280
281         case BACT_TELE_TOWN:
282                 paid = tele_town(player_ptr);
283                 break;
284
285         case BACT_EVAL_AC:
286                 paid = eval_ac(player_ptr->dis_ac + player_ptr->dis_to_a);
287                 break;
288
289         case BACT_BROKEN_WEAPON:
290                 paid = TRUE;
291                 bcost = repair_broken_weapon(player_ptr, bcost);
292                 break;
293         }
294
295         if (paid) player_ptr->au -= bcost;
296 }
297
298
299 /*!
300  * @brief 施設入り口にプレイヤーが乗った際の処理 / Do building commands
301  * @param プレーヤーへの参照ポインタ
302  * @return なし
303  */
304 void do_cmd_building(player_type *player_ptr)
305 {
306         if (player_ptr->wild_mode) return;
307
308         take_turn(player_ptr, 100);
309
310         if (!cave_have_flag_bold(player_ptr->current_floor_ptr, player_ptr->y, player_ptr->x, FF_BLDG))
311         {
312                 msg_print(_("ここには建物はない。", "You see no building here."));
313                 return;
314         }
315
316         int which = f_info[player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x].feat].subtype;
317
318         building_type *bldg;
319         bldg = &building[which];
320
321         reinit_wilderness = FALSE;
322
323         if ((which == 2) && (player_ptr->arena_number < 0))
324         {
325                 msg_print(_("「敗者に用はない。」", "'There's no place here for a LOSER like you!'"));
326                 return;
327         }
328         else if ((which == 2) && player_ptr->current_floor_ptr->inside_arena)
329         {
330                 if (!player_ptr->exit_bldg && player_ptr->current_floor_ptr->m_cnt > 0)
331                 {
332                         prt(_("ゲートは閉まっている。モンスターがあなたを待っている!", "The gates are closed.  The monster awaits!"), 0, 0);
333                 }
334                 else
335                 {
336                         prepare_change_floor_mode(player_ptr, CFM_SAVE_FLOORS | CFM_NO_RETURN);
337                         player_ptr->current_floor_ptr->inside_arena = FALSE;
338                         player_ptr->leaving = TRUE;
339                         command_new = SPECIAL_KEY_BUILDING;
340                         free_turn(player_ptr);
341                 }
342
343                 return;
344         }
345         else if (player_ptr->phase_out)
346         {
347                 prepare_change_floor_mode(player_ptr, CFM_SAVE_FLOORS | CFM_NO_RETURN);
348                 player_ptr->leaving = TRUE;
349                 player_ptr->phase_out = FALSE;
350                 command_new = SPECIAL_KEY_BUILDING;
351                 free_turn(player_ptr);
352                 return;
353         }
354         else
355         {
356                 player_ptr->oldpy = player_ptr->y;
357                 player_ptr->oldpx = player_ptr->x;
358         }
359
360         forget_lite(player_ptr->current_floor_ptr);
361         forget_view(player_ptr->current_floor_ptr);
362         current_world_ptr->character_icky++;
363
364         command_arg = 0;
365         command_rep = 0;
366         command_new = 0;
367
368         display_buikding_service(player_ptr, bldg);
369         player_ptr->leave_bldg = FALSE;
370         play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_BUILD);
371
372         bool validcmd;
373         while (!player_ptr->leave_bldg)
374         {
375                 validcmd = FALSE;
376                 prt("", 1, 0);
377
378                 building_prt_gold(player_ptr);
379
380                 char command = inkey();
381
382                 if (command == ESCAPE)
383                 {
384                         player_ptr->leave_bldg = TRUE;
385                         player_ptr->current_floor_ptr->inside_arena = FALSE;
386                         player_ptr->phase_out = FALSE;
387                         break;
388                 }
389
390                 int i;
391                 for (i = 0; i < 8; i++)
392                 {
393                         if (bldg->letters[i] && (bldg->letters[i] == command))
394                         {
395                                 validcmd = TRUE;
396                                 break;
397                         }
398                 }
399
400                 if (validcmd) bldg_process_command(player_ptr, bldg, i);
401
402                 handle_stuff(player_ptr);
403         }
404
405         select_floor_music(player_ptr);
406
407         msg_flag = FALSE;
408         msg_erase();
409
410         if (reinit_wilderness) player_ptr->leaving = TRUE;
411
412         current_world_ptr->character_icky--;
413         term_clear();
414
415         player_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_BONUS | PU_LITE | PU_MON_LITE);
416         player_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_EQUIPPY | PR_MAP);
417         player_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
418 }