OSDN Git Service

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