OSDN Git Service

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