OSDN Git Service

Merge branch 'macos-develop' into macos-3-0-0
[hengbandforosx/hengbandosx.git] / src / main / scene-table-floor.cpp
1 /*!
2  * @file scene-table-floor.cpp
3  * @brief フロアの状況に応じたBGM設定処理実装
4  */
5
6 #include "main/scene-table-floor.h"
7 #include "dungeon/quest.h"
8 #include "main/music-definitions-table.h"
9 #include "system/dungeon-info.h"
10 #include "system/floor-type-definition.h"
11 #include "system/player-type-definition.h"
12
13 using scene_feel_func = bool (*)(PlayerType *player_ptr, scene_type *value);
14
15 static bool scene_basic(PlayerType *player_ptr, scene_type *value)
16 {
17     if (player_ptr->ambush_flag) {
18         value->type = TERM_XTRA_MUSIC_BASIC;
19         value->val = MUSIC_BASIC_AMBUSH;
20         return true;
21     }
22
23     if (player_ptr->wild_mode) {
24         value->type = TERM_XTRA_MUSIC_BASIC;
25         value->val = MUSIC_BASIC_WILD;
26         return true;
27     }
28
29     if (player_ptr->current_floor_ptr->inside_arena) {
30         value->type = TERM_XTRA_MUSIC_BASIC;
31         value->val = MUSIC_BASIC_ARENA;
32         return true;
33     }
34
35     if (player_ptr->phase_out) {
36         value->type = TERM_XTRA_MUSIC_BASIC;
37         value->val = MUSIC_BASIC_BATTLE;
38         return true;
39     }
40
41     return false;
42 }
43
44 static bool scene_quest(PlayerType *player_ptr, scene_type *value)
45 {
46     const QuestId quest_id = quest_number(player_ptr, player_ptr->current_floor_ptr->dun_level);
47     const bool enable = (inside_quest(quest_id));
48     if (enable) {
49         value->type = TERM_XTRA_MUSIC_QUEST;
50         value->val = enum2i(quest_id);
51     }
52
53     return enable;
54 }
55
56 static bool scene_quest_basic(PlayerType *player_ptr, scene_type *value)
57 {
58     const QuestId quest_id = quest_number(player_ptr, player_ptr->current_floor_ptr->dun_level);
59     const bool enable = (inside_quest(quest_id));
60     if (enable) {
61         value->type = TERM_XTRA_MUSIC_BASIC;
62         value->val = MUSIC_BASIC_QUEST;
63     }
64
65     return enable;
66 }
67
68 static bool scene_town(PlayerType *player_ptr, scene_type *value)
69 {
70     const auto enable = !player_ptr->current_floor_ptr->is_in_dungeon() && (player_ptr->town_num > 0);
71     if (enable) {
72         value->type = TERM_XTRA_MUSIC_TOWN;
73         value->val = player_ptr->town_num;
74     }
75     return enable;
76 }
77
78 static bool scene_town_basic(PlayerType *player_ptr, scene_type *value)
79 {
80     const auto enable = !player_ptr->current_floor_ptr->is_in_dungeon() && (player_ptr->town_num > 0);
81     if (enable) {
82         value->type = TERM_XTRA_MUSIC_BASIC;
83         value->val = MUSIC_BASIC_TOWN;
84     }
85     return enable;
86 }
87
88 static bool scene_field(PlayerType *player_ptr, scene_type *value)
89 {
90     const auto enable = !player_ptr->current_floor_ptr->is_in_dungeon();
91     if (enable) {
92         value->type = TERM_XTRA_MUSIC_BASIC;
93
94         if (player_ptr->lev >= 45) {
95             value->val = MUSIC_BASIC_FIELD3;
96         } else if (player_ptr->lev >= 25) {
97             value->val = MUSIC_BASIC_FIELD2;
98         } else {
99             value->val = MUSIC_BASIC_FIELD1;
100         }
101     }
102     return enable;
103 }
104
105 static bool scene_dungeon_feeling(PlayerType *player_ptr, scene_type *value)
106 {
107     const bool enable = (player_ptr->feeling >= 2) && (player_ptr->feeling <= 5);
108     if (enable) {
109         value->type = TERM_XTRA_MUSIC_BASIC;
110
111         if (player_ptr->feeling == 2) {
112             value->val = MUSIC_BASIC_DUN_FEEL2;
113         } else {
114             value->val = MUSIC_BASIC_DUN_FEEL1;
115         }
116     }
117     return enable;
118 }
119
120 static bool scene_dungeon(PlayerType *player_ptr, scene_type *value)
121 {
122     const bool enable = (player_ptr->dungeon_idx > 0);
123     if (enable) {
124         value->type = TERM_XTRA_MUSIC_DUNGEON;
125         value->val = player_ptr->dungeon_idx;
126     }
127     return enable;
128 }
129
130 static bool scene_dungeon_basic(PlayerType *player_ptr, scene_type *value)
131 {
132     const auto enable = player_ptr->current_floor_ptr->is_in_dungeon();
133     if (enable) {
134         value->type = TERM_XTRA_MUSIC_BASIC;
135
136         const auto dun_level = player_ptr->current_floor_ptr->dun_level;
137         if (dun_level >= 80) {
138             value->val = MUSIC_BASIC_DUN_HIGH;
139         } else if (dun_level >= 40) {
140             value->val = MUSIC_BASIC_DUN_MED;
141         } else {
142             value->val = MUSIC_BASIC_DUN_LOW;
143         }
144     }
145     return enable;
146 }
147
148 static bool scene_mute(PlayerType *player_ptr, scene_type *value)
149 {
150     (void)player_ptr;
151     value->type = TERM_XTRA_MUSIC_MUTE;
152     value->val = 0;
153     return true;
154 }
155
156 /*! シチュエーション選択のフォールバック設定。
157  * 先頭から適用する(先にある方を優先する)。
158  */
159 std::vector<scene_feel_func> scene_floor_def_list = {
160     // scene_basic : ambush, wild, arena, battleの判定
161     scene_basic,
162     // scene_quest : questの判定(クエストの個別BGMを指定)
163     scene_quest,
164     // scene_quest_basic : questの判定 (Basicのquest指定)
165     scene_quest_basic,
166     // scene_town : townの判定(町の個別BGMを指定)
167     scene_town,
168     // scene_town_basic : townの判定 (Basicのtown指定)
169     scene_town_basic,
170     // scene_field : field1/2/3の判定(プレイヤーレベル25未満、25以上45未満、45以上時の荒野)
171     scene_field,
172     // scene_dungeon_feeling : feed1/2の判定(ダンジョンの雰囲気が「悪い予感」~「とても危険」、「死の幻」)
173     scene_dungeon_feeling,
174     // scene_dungeon : dungeonの判定(ダンジョンの個別BGMを指定)
175     scene_dungeon,
176     // scene_dungeon_basic : dun_low/med/highの判定(ダンジョンレベルが40未満、40以上80未満、80以上)
177     scene_dungeon_basic,
178     // scene_mute : 最後にミュートを配置する
179     scene_mute
180 };
181
182 int get_scene_floor_count()
183 {
184     return scene_floor_def_list.size();
185 }
186
187 /*!
188  * @brief 現在の条件でフロアのBGM選曲をリストに設定する。
189  * @details リストのfrom_indexの位置から、get_scene_floor_count()で得られる個数分設定する。
190  * @param player_ptr プレイヤーへの参照ポインタ
191  * @param list BGM選曲リスト
192  * @param from_index リストの更新開始位置
193  */
194 void refresh_scene_floor(PlayerType *player_ptr, scene_type_list &list, int from_index)
195 {
196     for (auto func : scene_floor_def_list) {
197         scene_type &item = list[from_index];
198         if (!func(player_ptr, &item)) {
199             // Note -- 特に定義を設けていないが、type = 0は無効な値とする。
200             item.type = 0;
201             item.val = 0;
202         }
203         ++from_index;
204     }
205 }