5 #include "io/write-diary.h"
6 #include "cmd/cmd-dump.h"
11 #include "player-move.h"
12 #include "player-status.h"
13 #include "player-effects.h"
14 #include "player-skill.h"
15 #include "player-class.h"
16 #include "player-damage.h"
17 #include "object-hook.h"
19 #include "monster-status.h"
21 #include "cmd-basic.h"
22 #include "view-mainwindow.h"
23 #include "targeting.h"
26 int total_friends = 0;
29 * @brief プレイヤーの騎乗/下馬処理判定
30 * @param g_ptr プレイヤーの移動先マスの構造体参照ポインタ
31 * @param now_riding TRUEなら下馬処理、FALSEならば騎乗処理
32 * @return 可能ならばTRUEを返す
34 bool player_can_ride_aux(player_type *creature_ptr, grid_type *g_ptr, bool now_riding)
37 bool old_character_xtra = current_world_ptr->character_xtra;
38 MONSTER_IDX old_riding = creature_ptr->riding;
39 bool old_riding_ryoute = creature_ptr->riding_ryoute;
40 bool old_old_riding_ryoute = creature_ptr->old_riding_ryoute;
41 bool old_pf_ryoute = (creature_ptr->pet_extra_flags & PF_TWO_HANDS) ? TRUE : FALSE;
43 /* Hack -- prevent "icky" message */
44 current_world_ptr->character_xtra = TRUE;
46 if (now_riding) creature_ptr->riding = g_ptr->m_idx;
49 creature_ptr->riding = 0;
50 creature_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
51 creature_ptr->riding_ryoute = creature_ptr->old_riding_ryoute = FALSE;
54 creature_ptr->update |= PU_BONUS;
55 handle_stuff(creature_ptr);
57 p_can_enter = player_can_enter(creature_ptr, g_ptr->feat, CEM_P_CAN_ENTER_PATTERN);
59 creature_ptr->riding = old_riding;
60 if (old_pf_ryoute) creature_ptr->pet_extra_flags |= (PF_TWO_HANDS);
61 else creature_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
62 creature_ptr->riding_ryoute = old_riding_ryoute;
63 creature_ptr->old_riding_ryoute = old_old_riding_ryoute;
65 creature_ptr->update |= PU_BONUS;
66 handle_stuff(creature_ptr);
68 current_world_ptr->character_xtra = old_character_xtra;
74 * @brief ペットを開放するコマンドのメインルーチン
77 void do_cmd_pet_dismiss(player_type *creature_ptr)
80 bool all_pets = FALSE;
95 /* Allocate the "who" array */
96 C_MAKE(who, current_world_ptr->max_m_idx, MONSTER_IDX);
98 /* Process the monsters (backwards) */
99 for (pet_ctr = creature_ptr->current_floor_ptr->m_max - 1; pet_ctr >= 1; pet_ctr--)
101 if (is_pet(&creature_ptr->current_floor_ptr->m_list[pet_ctr]))
102 who[max_pet++] = pet_ctr;
105 ang_sort(who, &dummy_why, max_pet, ang_sort_comp_pet_dismiss, ang_sort_swap_hook);
107 /* Process the monsters (backwards) */
108 for (i = 0; i < max_pet; i++)
111 GAME_TEXT friend_name[MAX_NLEN];
115 m_ptr = &creature_ptr->current_floor_ptr->m_list[pet_ctr];
118 kakunin = ((pet_ctr == creature_ptr->riding) || (m_ptr->nickname));
119 monster_desc(creature_ptr, friend_name, m_ptr, MD_ASSUME_VISIBLE);
123 /* Hack -- health bar for this monster */
124 health_track(creature_ptr, pet_ctr);
125 handle_stuff(creature_ptr);
127 msg_format(_("%sを放しますか? [Yes/No/Unnamed (%d体)]", "Dismiss %s? [Yes/No/Unnamed (%d remain)]"), friend_name, max_pet - i);
130 move_cursor_relative(m_ptr->fy, m_ptr->fx);
136 if (ch == 'Y' || ch == 'y')
142 msg_format(_("本当によろしいですか? (%s) ", "Are you sure? (%s) "), friend_name);
144 if (ch != 'Y' && ch != 'y')
150 if (ch == 'U' || ch == 'u')
156 if (ch == ESCAPE || ch == 'N' || ch == 'n')
163 if ((all_pets && !kakunin) || (!all_pets && delete_this))
165 if (record_named_pet && m_ptr->nickname)
167 GAME_TEXT m_name[MAX_NLEN];
169 monster_desc(creature_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
170 exe_write_diary(creature_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_DISMISS, m_name);
173 if (pet_ctr == creature_ptr->riding)
175 msg_format(_("%sから降りた。", "You have got off %s. "), friend_name);
177 creature_ptr->riding = 0;
179 creature_ptr->update |= (PU_MONSTERS);
180 creature_ptr->redraw |= (PR_EXTRA | PR_UHEALTH);
183 /* HACK : Add the line to message buffer */
184 msg_format(_("%s を放した。", "Dismissed %s."), friend_name);
185 creature_ptr->update |= (PU_BONUS);
186 creature_ptr->window |= (PW_MESSAGE);
188 delete_monster_idx(creature_ptr, pet_ctr);
197 C_KILL(who, current_world_ptr->max_m_idx, MONSTER_IDX);
200 msg_format("%d 体のペットを放しました。", Dismissed);
202 msg_format("You have dismissed %d pet%s.", Dismissed,
203 (Dismissed == 1 ? "" : "s"));
205 if (Dismissed == 0 && all_pets)
206 msg_print(_("'U'nnamed は、乗馬以外の名前のないペットだけを全て解放します。", "'U'nnamed means all your pets except named pets and your mount."));
208 handle_stuff(creature_ptr);
214 * @brief ペットから騎乗/下馬するコマンドのメインルーチン /
215 * @param force 強制的に騎乗/下馬するならばTRUE
216 * @return 騎乗/下馬できたらTRUE
218 bool do_cmd_riding(player_type *creature_ptr, bool force)
225 if (!get_direction(creature_ptr, &dir, FALSE, FALSE)) return FALSE;
226 y = creature_ptr->y + ddy[dir];
227 x = creature_ptr->x + ddx[dir];
228 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
230 if (creature_ptr->special_defense & KATA_MUSOU) set_action(creature_ptr, ACTION_NONE);
232 if (creature_ptr->riding)
234 /* Skip non-empty grids */
235 if (!player_can_ride_aux(creature_ptr, g_ptr, FALSE))
237 msg_print(_("そちらには降りられません。", "You cannot go that direction."));
241 if (!pattern_seq(creature_ptr, creature_ptr->y, creature_ptr->x, y, x)) return FALSE;
245 take_turn(creature_ptr, 100);
247 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
249 py_attack(creature_ptr, y, x, 0);
253 creature_ptr->riding = 0;
254 creature_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
255 creature_ptr->riding_ryoute = creature_ptr->old_riding_ryoute = FALSE;
259 if (cmd_limit_confused(creature_ptr)) return FALSE;
261 m_ptr = &creature_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
263 if (!g_ptr->m_idx || !m_ptr->ml)
265 msg_print(_("その場所にはモンスターはいません。", "There is no monster here."));
268 if (!is_pet(m_ptr) && !force)
270 msg_print(_("そのモンスターはペットではありません。", "That monster is not a pet."));
273 if (!(r_info[m_ptr->r_idx].flags7 & RF7_RIDING))
275 msg_print(_("そのモンスターには乗れなさそうだ。", "This monster doesn't seem suitable for riding."));
279 if (!pattern_seq(creature_ptr, creature_ptr->y, creature_ptr->x, y, x)) return FALSE;
281 if (!player_can_ride_aux(creature_ptr, g_ptr, TRUE))
283 /* Feature code (applying "mimic" field) */
284 feature_type *f_ptr = &f_info[get_feat_mimic(g_ptr)];
286 msg_format("そのモンスターは%sの%sにいる。", f_name + f_ptr->name,
287 ((!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) ||
288 (!have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_TREE))) ?
291 msg_format("This monster is %s the %s.",
292 ((!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) ||
293 (!have_flag(f_ptr->flags, FF_LOS) && !have_flag(f_ptr->flags, FF_TREE))) ?
294 "in" : "on", f_name + f_ptr->name);
299 if (r_info[m_ptr->r_idx].level > randint1((creature_ptr->skill_exp[GINOU_RIDING] / 50 + creature_ptr->lev / 2 + 20)))
301 msg_print(_("うまく乗れなかった。", "You failed to ride."));
302 take_turn(creature_ptr, 100);
306 if (MON_CSLEEP(m_ptr))
308 GAME_TEXT m_name[MAX_NLEN];
309 monster_desc(creature_ptr, m_name, m_ptr, 0);
310 (void)set_monster_csleep(creature_ptr, g_ptr->m_idx, 0);
311 msg_format(_("%sを起こした。", "You have woken %s up."), m_name);
314 if (creature_ptr->action == ACTION_KAMAE) set_action(creature_ptr, ACTION_NONE);
316 creature_ptr->riding = g_ptr->m_idx;
318 /* Hack -- remove tracked monster */
319 if (creature_ptr->riding == creature_ptr->health_who) health_track(creature_ptr, 0);
322 take_turn(creature_ptr, 100);
324 /* Mega-Hack -- Forget the view and lite */
325 creature_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
326 creature_ptr->update |= (PU_BONUS);
327 creature_ptr->redraw |= (PR_MAP | PR_EXTRA);
328 creature_ptr->redraw |= (PR_UHEALTH);
330 (void)move_player_effect(creature_ptr, y, x, MPE_HANDLE_STUFF | MPE_ENERGY_USE | MPE_DONT_PICKUP | MPE_DONT_SWAP_MON);
336 * @brief ペットに名前をつけるコマンドのメインルーチン
339 static void do_name_pet(player_type *creature_ptr)
343 GAME_TEXT m_name[MAX_NLEN];
344 bool old_name = FALSE;
345 bool old_target_pet = target_pet;
348 if (!target_set(creature_ptr, TARGET_KILL))
350 target_pet = old_target_pet;
354 target_pet = old_target_pet;
356 if (creature_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx)
358 m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx];
362 msg_print(_("そのモンスターはペットではない。", "This monster is not a pet."));
365 if (r_info[m_ptr->r_idx].flags1 & RF1_UNIQUE)
367 msg_print(_("そのモンスターの名前は変えられない!", "You cannot change name of this monster!"));
370 monster_desc(creature_ptr, m_name, m_ptr, 0);
372 msg_format(_("%sに名前をつける。", "Name %s."), m_name);
375 /* Start with nothing */
378 /* Use old inscription */
381 /* Start with the old inscription */
382 strcpy(out_val, quark_str(m_ptr->nickname));
386 /* Get a new inscription (possibly empty) */
387 if (get_string(_("名前: ", "Name: "), out_val, 15))
391 /* Save the inscription */
392 m_ptr->nickname = quark_add(out_val);
393 if (record_named_pet)
395 monster_desc(creature_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
396 exe_write_diary(creature_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_NAME, m_name);
401 if (record_named_pet && old_name)
403 monster_desc(creature_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
404 exe_write_diary(creature_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_UNNAME, m_name);
414 * @brief ペットに関するコマンドリストのメインルーチン /
415 * Issue a pet command
418 void do_cmd_pet(player_type *creature_ptr)
423 concptr power_desc[36];
430 PET_COMMAND_IDX mode = 0;
433 char target_buf[160];
435 int menu_line = use_menu ? 1 : 0;
439 if (creature_ptr->wild_mode) return;
441 power_desc[num] = _("ペットを放す", "dismiss pets");
442 powers[num++] = PET_DISMISS;
445 sprintf(target_buf, "ペットのターゲットを指定 (現在:%s)",
446 (creature_ptr->pet_t_m_idx ? (creature_ptr->image ? "何か奇妙な物" : (r_name + r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->pet_t_m_idx].ap_r_idx].name)) : "指定なし"));
448 sprintf(target_buf, "specify a target of pet (now:%s)",
449 (creature_ptr->pet_t_m_idx ? (creature_ptr->image ? "something strange" : (r_name + r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->pet_t_m_idx].ap_r_idx].name)) : "nothing"));
451 power_desc[num] = target_buf;
452 powers[num++] = PET_TARGET;
453 power_desc[num] = _("近くにいろ", "stay close");
455 if (creature_ptr->pet_follow_distance == PET_CLOSE_DIST) mode = num;
456 powers[num++] = PET_STAY_CLOSE;
457 power_desc[num] = _("ついて来い", "follow me");
459 if (creature_ptr->pet_follow_distance == PET_FOLLOW_DIST) mode = num;
460 powers[num++] = PET_FOLLOW_ME;
461 power_desc[num] = _("敵を見つけて倒せ", "seek and destroy");
463 if (creature_ptr->pet_follow_distance == PET_DESTROY_DIST) mode = num;
464 powers[num++] = PET_SEEK_AND_DESTROY;
465 power_desc[num] = _("少し離れていろ", "give me space");
467 if (creature_ptr->pet_follow_distance == PET_SPACE_DIST) mode = num;
468 powers[num++] = PET_ALLOW_SPACE;
469 power_desc[num] = _("離れていろ", "stay away");
471 if (creature_ptr->pet_follow_distance == PET_AWAY_DIST) mode = num;
472 powers[num++] = PET_STAY_AWAY;
474 if (creature_ptr->pet_extra_flags & PF_OPEN_DOORS)
476 power_desc[num] = _("ドアを開ける (現在:ON)", "pets open doors (now On)");
480 power_desc[num] = _("ドアを開ける (現在:OFF)", "pets open doors (now Off)");
482 powers[num++] = PET_OPEN_DOORS;
484 if (creature_ptr->pet_extra_flags & PF_PICKUP_ITEMS)
486 power_desc[num] = _("アイテムを拾う (現在:ON)", "pets pick up items (now On)");
490 power_desc[num] = _("アイテムを拾う (現在:OFF)", "pets pick up items (now Off)");
492 powers[num++] = PET_TAKE_ITEMS;
494 if (creature_ptr->pet_extra_flags & PF_TELEPORT)
496 power_desc[num] = _("テレポート系魔法を使う (現在:ON)", "allow teleport (now On)");
500 power_desc[num] = _("テレポート系魔法を使う (現在:OFF)", "allow teleport (now Off)");
502 powers[num++] = PET_TELEPORT;
504 if (creature_ptr->pet_extra_flags & PF_ATTACK_SPELL)
506 power_desc[num] = _("攻撃魔法を使う (現在:ON)", "allow cast attack spell (now On)");
510 power_desc[num] = _("攻撃魔法を使う (現在:OFF)", "allow cast attack spell (now Off)");
512 powers[num++] = PET_ATTACK_SPELL;
514 if (creature_ptr->pet_extra_flags & PF_SUMMON_SPELL)
516 power_desc[num] = _("召喚魔法を使う (現在:ON)", "allow cast summon spell (now On)");
520 power_desc[num] = _("召喚魔法を使う (現在:OFF)", "allow cast summon spell (now Off)");
522 powers[num++] = PET_SUMMON_SPELL;
524 if (creature_ptr->pet_extra_flags & PF_BALL_SPELL)
526 power_desc[num] = _("プレイヤーを巻き込む範囲魔法を使う (現在:ON)", "allow involve player in area spell (now On)");
530 power_desc[num] = _("プレイヤーを巻き込む範囲魔法を使う (現在:OFF)", "allow involve player in area spell (now Off)");
532 powers[num++] = PET_BALL_SPELL;
534 if (creature_ptr->riding)
536 power_desc[num] = _("ペットから降りる", "get off a pet");
540 power_desc[num] = _("ペットに乗る", "ride a pet");
542 powers[num++] = PET_RIDING;
543 power_desc[num] = _("ペットに名前をつける", "name pets");
544 powers[num++] = PET_NAME;
546 if (creature_ptr->riding)
548 if ((creature_ptr->migite && (empty_hands(creature_ptr, FALSE) == EMPTY_HAND_LARM) &&
549 object_allow_two_hands_wielding(&creature_ptr->inventory_list[INVEN_RARM])) ||
550 (creature_ptr->hidarite && (empty_hands(creature_ptr, FALSE) == EMPTY_HAND_RARM) &&
551 object_allow_two_hands_wielding(&creature_ptr->inventory_list[INVEN_LARM])))
553 if (creature_ptr->pet_extra_flags & PF_TWO_HANDS)
555 power_desc[num] = _("武器を片手で持つ", "use one hand to control the pet you are riding");
559 power_desc[num] = _("武器を両手で持つ", "use both hands for a weapon");
562 powers[num++] = PET_TWO_HANDS;
566 switch (creature_ptr->pclass)
569 case CLASS_FORCETRAINER:
570 case CLASS_BERSERKER:
571 if (empty_hands(creature_ptr, FALSE) == (EMPTY_HAND_RARM | EMPTY_HAND_LARM))
573 if (creature_ptr->pet_extra_flags & PF_TWO_HANDS)
575 power_desc[num] = _("片手で格闘する", "use one hand to control the pet you are riding");
579 power_desc[num] = _("両手で格闘する", "use both hands for melee");
582 powers[num++] = PET_TWO_HANDS;
584 else if ((empty_hands(creature_ptr, FALSE) != EMPTY_HAND_NONE) && !has_melee_weapon(creature_ptr, INVEN_RARM) && !has_melee_weapon(creature_ptr, INVEN_LARM))
586 if (creature_ptr->pet_extra_flags & PF_TWO_HANDS)
588 power_desc[num] = _("格闘を行わない", "use one hand to control the pet you are riding");
592 power_desc[num] = _("格闘を行う", "use one hand for melee");
595 powers[num++] = PET_TWO_HANDS;
602 if (!(repeat_pull(&i) && (i >= 0) && (i < num)))
610 strnfmt(out_val, 78, _("(コマンド、ESC=終了) コマンドを選んでください:", "(Command, ESC=exit) Choose command from menu."));
615 _("(コマンド %c-%c、'*'=一覧、ESC=終了) コマンドを選んでください:", "(Command %c-%c, *=List, ESC=exit) Select a command: "),
616 I2A(0), I2A(num - 1));
619 choice = (always_show_list || use_menu) ? ESCAPE : 1;
621 /* Get a command from the user */
626 if (choice == ESCAPE) choice = ' ';
627 else if (!get_com(out_val, &choice, TRUE)) break;
629 if (use_menu && (choice != ' '))
640 menu_line += (num - 1);
669 if (menu_line > num) menu_line -= num;
673 if ((choice == ' ') || (choice == '*') || (choice == '?') || (use_menu && ask))
676 if (!redraw || use_menu)
679 PET_COMMAND_IDX ctr = 0;
681 if (!use_menu) screen_save();
686 for (ctr = 0; ctr < num; ctr++)
688 /* Letter/number for power selection */
690 sprintf(buf, "%c%s ", (ctr == mode) ? '*' : ' ', (ctr == (menu_line - 1)) ? _("》", "> ") : " ");
692 sprintf(buf, "%c%c) ", (ctr == mode) ? '*' : ' ', I2A(ctr));
694 strcat(buf, power_desc[ctr]);
696 prt(buf, y + ctr, x);
699 prt("", y + MIN(ctr, 17), x);
717 ask = (isupper(choice));
720 if (ask) choice = (char)tolower(choice);
722 /* Extract request */
723 i = (islower(choice) ? A2I(choice) : -1);
726 /* Totally Illegal */
727 if ((i < 0) || (i >= num))
737 strnfmt(buf, 78, _("%sを使いますか? ", "Use %s? "), power_desc[i]);
739 /* Belay that order */
740 if (!get_check(buf)) continue;
746 if (redraw) screen_load();
748 /* Abort if needed */
751 free_turn(creature_ptr);
759 case PET_DISMISS: /* Dismiss pets */
761 /* Check pets (backwards) */
762 for (pet_ctr = creature_ptr->current_floor_ptr->m_max - 1; pet_ctr >= 1; pet_ctr--)
765 if (is_pet(&creature_ptr->current_floor_ptr->m_list[pet_ctr])) break;
770 msg_print(_("ペットがいない!", "You have no pets!"));
773 do_cmd_pet_dismiss(creature_ptr);
774 (void)calculate_upkeep(creature_ptr);
780 if (!target_set(creature_ptr, TARGET_KILL)) creature_ptr->pet_t_m_idx = 0;
783 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[target_row][target_col];
784 if (g_ptr->m_idx && (creature_ptr->current_floor_ptr->m_list[g_ptr->m_idx].ml))
786 creature_ptr->pet_t_m_idx = creature_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx;
787 creature_ptr->pet_follow_distance = PET_DESTROY_DIST;
789 else creature_ptr->pet_t_m_idx = 0;
798 creature_ptr->pet_follow_distance = PET_CLOSE_DIST;
799 creature_ptr->pet_t_m_idx = 0;
805 creature_ptr->pet_follow_distance = PET_FOLLOW_DIST;
806 creature_ptr->pet_t_m_idx = 0;
809 /* "Seek and destoy" */
810 case PET_SEEK_AND_DESTROY:
812 creature_ptr->pet_follow_distance = PET_DESTROY_DIST;
815 /* "Give me space" */
816 case PET_ALLOW_SPACE:
818 creature_ptr->pet_follow_distance = PET_SPACE_DIST;
824 creature_ptr->pet_follow_distance = PET_AWAY_DIST;
827 /* flag - allow pets to open doors */
830 if (creature_ptr->pet_extra_flags & PF_OPEN_DOORS) creature_ptr->pet_extra_flags &= ~(PF_OPEN_DOORS);
831 else creature_ptr->pet_extra_flags |= (PF_OPEN_DOORS);
834 /* flag - allow pets to pickup items */
837 if (creature_ptr->pet_extra_flags & PF_PICKUP_ITEMS)
839 creature_ptr->pet_extra_flags &= ~(PF_PICKUP_ITEMS);
840 for (pet_ctr = creature_ptr->current_floor_ptr->m_max - 1; pet_ctr >= 1; pet_ctr--)
842 m_ptr = &creature_ptr->current_floor_ptr->m_list[pet_ctr];
846 monster_drop_carried_objects(creature_ptr, m_ptr);
850 else creature_ptr->pet_extra_flags |= (PF_PICKUP_ITEMS);
854 /* flag - allow pets to teleport */
857 if (creature_ptr->pet_extra_flags & PF_TELEPORT) creature_ptr->pet_extra_flags &= ~(PF_TELEPORT);
858 else creature_ptr->pet_extra_flags |= (PF_TELEPORT);
861 /* flag - allow pets to cast attack spell */
862 case PET_ATTACK_SPELL:
864 if (creature_ptr->pet_extra_flags & PF_ATTACK_SPELL) creature_ptr->pet_extra_flags &= ~(PF_ATTACK_SPELL);
865 else creature_ptr->pet_extra_flags |= (PF_ATTACK_SPELL);
868 /* flag - allow pets to cast attack spell */
869 case PET_SUMMON_SPELL:
871 if (creature_ptr->pet_extra_flags & PF_SUMMON_SPELL) creature_ptr->pet_extra_flags &= ~(PF_SUMMON_SPELL);
872 else creature_ptr->pet_extra_flags |= (PF_SUMMON_SPELL);
875 /* flag - allow pets to cast attack spell */
878 if (creature_ptr->pet_extra_flags & PF_BALL_SPELL) creature_ptr->pet_extra_flags &= ~(PF_BALL_SPELL);
879 else creature_ptr->pet_extra_flags |= (PF_BALL_SPELL);
885 (void)do_cmd_riding(creature_ptr, FALSE);
891 do_name_pet(creature_ptr);
897 if (creature_ptr->pet_extra_flags & PF_TWO_HANDS) creature_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
898 else creature_ptr->pet_extra_flags |= (PF_TWO_HANDS);
899 creature_ptr->update |= (PU_BONUS);
900 handle_stuff(creature_ptr);
908 * @brief プレイヤーの落馬判定処理
909 * @param dam 落馬判定を発した際に受けたダメージ量
910 * @param force TRUEならば強制的に落馬する
911 * @return 実際に落馬したらTRUEを返す
913 bool rakuba(player_type *creature_ptr, HIT_POINT dam, bool force)
916 POSITION y, x, oy, ox, sy = 0, sx = 0;
918 GAME_TEXT m_name[MAX_NLEN];
919 monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[creature_ptr->riding];
920 monster_race *r_ptr = &r_info[m_ptr->r_idx];
921 bool fall_dam = FALSE;
923 if (!creature_ptr->riding) return FALSE;
924 if (creature_ptr->wild_mode) return FALSE;
926 if (dam >= 0 || force)
930 int cur = creature_ptr->skill_exp[GINOU_RIDING];
931 int max = s_info[creature_ptr->pclass].s_max[GINOU_RIDING];
932 int ridinglevel = r_ptr->level;
935 int rakubalevel = r_ptr->level;
936 if (creature_ptr->riding_ryoute) rakubalevel += 20;
938 if ((cur < max) && (max > 1000) &&
939 (dam / 2 + ridinglevel) > (cur / 30 + 10))
943 if (ridinglevel > (cur / 100 + 15))
944 inc += 1 + (ridinglevel - cur / 100 - 15);
948 creature_ptr->skill_exp[GINOU_RIDING] = MIN(max, cur + inc);
951 /* レベルの低い乗馬からは落馬しにくい */
952 if (randint0(dam / 2 + rakubalevel * 2) < cur / 30 + 10)
954 if ((((creature_ptr->pclass == CLASS_BEASTMASTER) || (creature_ptr->pclass == CLASS_CAVALRY)) && !creature_ptr->riding_ryoute) || !one_in_(creature_ptr->lev*(creature_ptr->riding_ryoute ? 2 : 3) + 30))
961 /* Check around the player */
962 for (i = 0; i < 8; i++)
966 y = creature_ptr->y + ddy_ddd[i];
967 x = creature_ptr->x + ddx_ddd[i];
969 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
971 if (g_ptr->m_idx) continue;
973 /* Skip non-empty grids */
974 if (!cave_have_flag_grid(g_ptr, FF_MOVE) && !cave_have_flag_grid(g_ptr, FF_CAN_FLY))
976 if (!player_can_ride_aux(creature_ptr, g_ptr, FALSE)) continue;
979 if (cave_have_flag_grid(g_ptr, FF_PATTERN)) continue;
981 /* Count "safe" grids */
984 /* Randomize choice */
985 if (randint0(sn) > 0) continue;
987 /* Save the safe location */
992 monster_desc(creature_ptr, m_name, m_ptr, 0);
993 msg_format(_("%sから振り落とされそうになって、壁にぶつかった。", "You have nearly fallen from %s, but bumped into wall."), m_name);
994 take_hit(creature_ptr, DAMAGE_NOESCAPE, r_ptr->level + 3, _("壁への衝突", "bumping into wall"), -1);
998 oy = creature_ptr->y;
999 ox = creature_ptr->x;
1001 creature_ptr->y = sy;
1002 creature_ptr->x = sx;
1004 /* Redraw the old spot */
1005 lite_spot(creature_ptr, oy, ox);
1007 /* Redraw the new spot */
1008 lite_spot(creature_ptr, creature_ptr->y, creature_ptr->x);
1010 /* Check for new panel */
1011 verify_panel(creature_ptr);
1014 creature_ptr->riding = 0;
1015 creature_ptr->pet_extra_flags &= ~(PF_TWO_HANDS);
1016 creature_ptr->riding_ryoute = creature_ptr->old_riding_ryoute = FALSE;
1018 creature_ptr->update |= (PU_BONUS | PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE | PU_MONSTERS);
1019 handle_stuff(creature_ptr);
1022 creature_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1023 creature_ptr->redraw |= (PR_EXTRA);
1025 /* Update health track of mount */
1026 creature_ptr->redraw |= (PR_UHEALTH);
1028 if (creature_ptr->levitation && !force)
1030 monster_desc(creature_ptr, m_name, m_ptr, 0);
1031 msg_format(_("%sから落ちたが、空中でうまく体勢を立て直して着地した。", "You are thrown from %s, but make a good landing."), m_name);
1035 take_hit(creature_ptr, DAMAGE_NOESCAPE, r_ptr->level + 3, _("落馬", "Falling from riding"), -1);
1039 if (sy && !creature_ptr->is_dead)
1040 (void)move_player_effect(creature_ptr, creature_ptr->y, creature_ptr->x, MPE_DONT_PICKUP | MPE_DONT_SWAP_MON);