1 #include "spell-realm/spells-song.h"
2 #include "core/disturbance.h"
3 #include "core/player-redraw-types.h"
4 #include "core/player-update-types.h"
5 #include "core/stuff-handler.h"
6 #include "core/window-redrawer.h"
7 #include "game-option/disturbance-options.h"
8 #include "player/attack-defense-types.h"
9 #include "player/player-skill.h"
10 #include "player/player-status.h"
11 #include "realm/realm-song-numbers.h"
12 #include "spell/spell-info.h"
13 #include "spell/spells-execution.h"
14 #include "spell/technic-info-table.h"
15 #include "status/action-setter.h"
16 #include "system/floor-type-definition.h"
17 #include "system/player-type-definition.h"
18 #include "util/bit-flags-calculator.h"
19 #include "view/display-messages.h"
22 * @brief プレイヤーの歌に関する継続処理
24 void check_music(player_type *caster_ptr)
26 if (caster_ptr->pclass != CLASS_BARD)
29 auto interupting_song_effect = get_interrupting_song_effect(caster_ptr);
30 if ((get_singing_song_effect(caster_ptr) == 0) && (interupting_song_effect == 0))
33 if (caster_ptr->anti_magic) {
34 stop_singing(caster_ptr);
38 int spell = get_singing_song_id(caster_ptr);
39 const magic_type *s_ptr;
40 s_ptr = &technic_info[REALM_MUSIC - MIN_TECHNIC][spell];
42 MANA_POINT need_mana = mod_need_mana(caster_ptr, s_ptr->smana, spell, REALM_MUSIC);
43 u32b need_mana_frac = 0;
45 s64b_rshift(&need_mana, &need_mana_frac, 1);
46 if (s64b_cmp(caster_ptr->csp, caster_ptr->csp_frac, need_mana, need_mana_frac) < 0) {
47 stop_singing(caster_ptr);
50 s64b_sub(&(caster_ptr->csp), &(caster_ptr->csp_frac), need_mana, need_mana_frac);
52 caster_ptr->redraw |= PR_MANA;
53 if (interupting_song_effect != 0) {
54 set_singing_song_effect(caster_ptr, interupting_song_effect);
55 set_interrupting_song_effect(caster_ptr, MUSIC_NONE);
56 msg_print(_("歌を再開した。", "You resume singing."));
57 caster_ptr->action = ACTION_SING;
58 caster_ptr->update |= (PU_BONUS | PU_HP | PU_MONSTERS);
59 caster_ptr->redraw |= (PR_MAP | PR_STATUS | PR_STATE);
60 caster_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
64 if (caster_ptr->spell_exp[spell] < SPELL_EXP_BEGINNER)
65 caster_ptr->spell_exp[spell] += 5;
66 else if (caster_ptr->spell_exp[spell] < SPELL_EXP_SKILLED) {
67 if (one_in_(2) && (caster_ptr->current_floor_ptr->dun_level > 4) && ((caster_ptr->current_floor_ptr->dun_level + 10) > caster_ptr->lev))
68 caster_ptr->spell_exp[spell] += 1;
69 } else if (caster_ptr->spell_exp[spell] < SPELL_EXP_EXPERT) {
70 if (one_in_(5) && ((caster_ptr->current_floor_ptr->dun_level + 5) > caster_ptr->lev)
71 && ((caster_ptr->current_floor_ptr->dun_level + 5) > s_ptr->slevel))
72 caster_ptr->spell_exp[spell] += 1;
73 } else if (caster_ptr->spell_exp[spell] < SPELL_EXP_MASTER) {
74 if (one_in_(5) && ((caster_ptr->current_floor_ptr->dun_level + 5) > caster_ptr->lev) && (caster_ptr->current_floor_ptr->dun_level > s_ptr->slevel))
75 caster_ptr->spell_exp[spell] += 1;
78 exe_spell(caster_ptr, REALM_MUSIC, spell, SPELL_CONT);
82 * @brief 隠遁の歌の継続時間をセットする / Set "tim_stealth", notice observable changes
84 * @param do_dec 現在の継続時間より長い値のみ上書きする
85 * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
87 bool set_tim_stealth(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
90 v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
92 if (creature_ptr->is_dead)
96 if (creature_ptr->tim_stealth && !do_dec) {
97 if (creature_ptr->tim_stealth > v)
99 } else if (!is_time_limit_stealth(creature_ptr)) {
100 msg_print(_("足音が小さくなった!", "You begin to walk silently!"));
104 if (creature_ptr->tim_stealth && !music_singing(creature_ptr, MUSIC_STEALTH)) {
105 msg_print(_("足音が大きくなった。", "You no longer walk silently."));
110 creature_ptr->tim_stealth = v;
111 creature_ptr->redraw |= (PR_STATUS);
117 disturb(creature_ptr, FALSE, FALSE);
118 creature_ptr->update |= (PU_BONUS);
119 handle_stuff(creature_ptr);
124 * @brief 歌の停止を処理する / Stop singing if the player is a Bard
126 void stop_singing(player_type *creature_ptr)
128 if (creature_ptr->pclass != CLASS_BARD)
131 if (get_interrupting_song_effect(creature_ptr) != 0) {
132 set_interrupting_song_effect(creature_ptr, MUSIC_NONE);
136 if (get_singing_song_effect(creature_ptr) == 0)
139 if (creature_ptr->action == ACTION_SING)
140 set_action(creature_ptr, ACTION_NONE);
142 (void)exe_spell(creature_ptr, REALM_MUSIC, get_singing_song_id(creature_ptr), SPELL_STOP);
143 set_singing_song_effect(creature_ptr, MUSIC_NONE);
144 set_singing_song_id(creature_ptr, 0);
145 set_bits(creature_ptr->update, PU_BONUS);
146 set_bits(creature_ptr->redraw, PR_STATUS);
149 bool music_singing(player_type *caster_ptr, int music_songs)
151 return (caster_ptr->pclass == CLASS_BARD) && (caster_ptr->magic_num1[0] == music_songs);
154 bool music_singing_any(player_type *creature_ptr)
156 return (creature_ptr->pclass == CLASS_BARD) && (creature_ptr->magic_num1[0] != 0);
159 MAGIC_NUM1 get_singing_song_effect(const player_type *creature_ptr)
161 return creature_ptr->magic_num1[0];
164 void set_singing_song_effect(player_type *creature_ptr, const MAGIC_NUM1 magic_num)
166 creature_ptr->magic_num1[0] = magic_num;
169 MAGIC_NUM1 get_interrupting_song_effect(const player_type *creature_ptr)
171 return creature_ptr->magic_num1[1];
174 void set_interrupting_song_effect(player_type *creature_ptr, const MAGIC_NUM1 magic_num)
176 creature_ptr->magic_num1[1] = magic_num;
179 MAGIC_NUM1 get_singing_count(const player_type *creature_ptr)
181 return creature_ptr->magic_num1[2];
184 void set_singing_count(player_type *creature_ptr, const MAGIC_NUM1 magic_num)
186 creature_ptr->magic_num1[2] = magic_num;
189 MAGIC_NUM2 get_singing_song_id(const player_type *creature_ptr)
191 return creature_ptr->magic_num2[0];
194 void set_singing_song_id(player_type *creature_ptr, const MAGIC_NUM2 magic_num)
196 creature_ptr->magic_num2[0] = magic_num;