1 #include "system/floor-type-definition.h"
2 #include "dungeon/quest.h"
3 #include "game-option/birth-options.h"
4 #include "system/angband-system.h"
5 #include "system/dungeon-info.h"
6 #include "system/grid-type-definition.h"
7 #include "system/item-entity.h"
8 #include "system/monster-entity.h"
9 #include "util/bit-flags-calculator.h"
10 #include "util/enum-range.h"
12 FloorType::FloorType()
13 : quest_number(QuestId::NONE)
17 Grid &FloorType::get_grid(const Pos2D pos)
19 return this->grid_array[pos.y][pos.x];
22 const Grid &FloorType::get_grid(const Pos2D pos) const
24 return this->grid_array[pos.y][pos.x];
27 bool FloorType::is_in_dungeon() const
29 return this->dun_level > 0;
32 bool FloorType::is_in_quest() const
34 return this->quest_number != QuestId::NONE;
37 void FloorType::set_dungeon_index(short dungeon_idx_)
39 this->dungeon_idx = dungeon_idx_;
42 void FloorType::reset_dungeon_index()
44 this->set_dungeon_index(0);
47 dungeon_type &FloorType::get_dungeon_definition() const
49 return dungeons_info[this->dungeon_idx];
53 * @brief 新しく入ったダンジョンの階層に固定されているランダムクエストを探し出しIDを返す。
54 * @param player_ptr プレイヤーへの参照ポインタ
55 * @param level 検索対象になる階
56 * @return クエストIDを返す。該当がない場合0を返す。
58 QuestId FloorType::get_random_quest_id(std::optional<int> level_opt) const
60 if (this->dungeon_idx != DUNGEON_ANGBAND) {
64 const auto level = level_opt.value_or(this->dun_level);
65 const auto &quest_list = QuestList::get_instance();
66 for (auto q_idx : EnumRange(QuestId::RANDOM_QUEST1, QuestId::RANDOM_QUEST10)) {
67 const auto &quest = quest_list[q_idx];
68 auto is_random_quest = (quest.type == QuestKindType::RANDOM);
69 is_random_quest &= (quest.status == QuestStatusType::TAKEN);
70 is_random_quest &= (quest.level == level);
71 is_random_quest &= (quest.dungeon == DUNGEON_ANGBAND);
72 if (is_random_quest) {
81 * @brief 新しく入ったダンジョンの階層に固定されている一般のクエストを探し出しIDを返す.
82 * @param player_ptr プレイヤーへの参照ポインタ
83 * @param bonus 検索対象になる階へのボーナス。通常0
84 * @return クエストIDを返す。該当がない場合0を返す。
86 QuestId FloorType::get_quest_id(const int bonus) const
88 const auto &quest_list = QuestList::get_instance();
89 if (this->is_in_quest()) {
90 return this->quest_number;
93 const auto level = this->dun_level + bonus;
94 for (const auto &[q_idx, quest] : quest_list) {
95 if (quest.status != QuestStatusType::TAKEN) {
99 auto depth_quest = (quest.type == QuestKindType::KILL_LEVEL);
100 depth_quest &= !(quest.flags & QUEST_FLAG_PRESET);
101 depth_quest &= (quest.level == level);
102 depth_quest &= (quest.dungeon == this->dungeon_idx);
108 return this->get_random_quest_id(level);
112 * @brief 与えられた座標のグリッドがLOSフラグを持つかを調べる
114 * @return LOSフラグを持つか否か
116 bool FloorType::has_los(const Pos2D pos) const
118 return this->get_grid(pos).has_los();
122 * @brief 特別なフロアにいるかを判定する
123 * @return 固定クエスト、アリーナ、モンスター闘技場のいずれかならばtrue
125 bool FloorType::is_special() const
127 auto is_in_fixed_quest = this->is_in_quest();
128 is_in_fixed_quest &= !inside_quest(this->get_random_quest_id());
129 return is_in_fixed_quest || this->inside_arena || AngbandSystem::get_instance().is_phase_out();
133 * @brief テレポート・レベル無効フロアの判定
134 * @param to_player プレイヤーを対象としているか否か
135 * @return テレポート・レベルが不可能ならばtrue
137 bool FloorType::can_teleport_level(bool to_player) const
139 auto is_invalid_floor = to_player;
140 is_invalid_floor &= inside_quest(this->get_quest_id()) || (this->dun_level >= this->get_dungeon_definition().maxdepth);
141 is_invalid_floor &= this->dun_level >= 1;
142 is_invalid_floor &= ironman_downward;
143 return this->is_special() || is_invalid_floor;