OSDN Git Service

Merge pull request #3505 from habu1010/feature/fix-omission-pr3479
[hengbandforosx/hengbandosx.git] / src / blue-magic / blue-magic-checker.cpp
1 /*!
2  * @file blue-magic-checker.cpp
3  * @brief 青魔法の処理実装 / Blue magic
4  * @date 2014/01/15
5  * @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7  * This software may be copied and distributed for educational, research,
8  * and not for profit purposes provided that this copyright and statement
9  * are included in all such copies.  Other copyrights may also apply.
10  * 2014 Deskull rearranged comment for Doxygen.
11  */
12
13 #include "blue-magic/blue-magic-checker.h"
14 #include "main/sound-definitions-table.h"
15 #include "main/sound-of-music.h"
16 #include "monster-race/race-ability-mask.h"
17 #include "mspell/monster-power-table.h"
18 #include "player-base/player-class.h"
19 #include "player-info/bluemage-data-type.h"
20 #include "player/attack-defense-types.h"
21 #include "status/experience.h"
22 #include "system/angband.h"
23 #include "system/player-type-definition.h"
24 #include "system/redrawing-flags-updater.h"
25 #include "timed-effect/player-blindness.h"
26 #include "timed-effect/player-confusion.h"
27 #include "timed-effect/player-hallucination.h"
28 #include "timed-effect/player-paralysis.h"
29 #include "timed-effect/player-stun.h"
30 #include "timed-effect/timed-effects.h"
31 #include "view/display-messages.h"
32
33 /*!
34  * @brief 青魔法のラーニング判定と成功した場合のラーニング処理
35  * @param monspell ラーニングを試みるモンスター攻撃のID
36  */
37 void learn_spell(PlayerType *player_ptr, MonsterAbilityType monspell)
38 {
39     if (player_ptr->action != ACTION_LEARN) {
40         return;
41     }
42
43     auto bluemage_data = PlayerClass(player_ptr).get_specific_data<bluemage_data_type>();
44     if (!bluemage_data || bluemage_data->learnt_blue_magics.has(monspell)) {
45         return;
46     }
47
48     const auto effects = player_ptr->effects();
49     const auto is_confused = effects->confusion()->is_confused();
50     const auto is_blind = effects->blindness()->is_blind();
51     const auto is_stunned = effects->stun()->is_stunned();
52     const auto is_hallucinated = effects->hallucination()->is_hallucinated();
53     const auto is_paralyzed = effects->paralysis()->is_paralyzed();
54     if (is_confused || is_blind || is_hallucinated || is_stunned || is_paralyzed) {
55         return;
56     }
57
58     const auto &monster_power = monster_powers.at(monspell);
59     if (randint1(player_ptr->lev + 70) > monster_power.level + 40) {
60         bluemage_data->learnt_blue_magics.set(monspell);
61         msg_format(_("%sを学習した!", "You have learned %s!"), monster_power.name);
62         gain_exp(player_ptr, monster_power.level * monster_power.smana);
63         sound(SOUND_STUDY);
64         bluemage_data->new_magic_learned = true;
65         RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::ACTION);
66     }
67 }
68
69 /*!
70  * @brief モンスター特殊能力のフラグ配列から特定のタイプの能力だけを抜き出す処理
71  * Extract monster spells mask for the given mode
72  * @param ability_flags モンスター特殊能力のフラグ集合
73  * @param type 抜き出したいタイプ
74  */
75 void set_rf_masks(EnumClassFlagGroup<MonsterAbilityType> &ability_flags, BlueMagicType type)
76 {
77     ability_flags.clear();
78
79     switch (type) {
80     case BlueMagicType::BOLT:
81         ability_flags.set(RF_ABILITY_BOLT_MASK | RF_ABILITY_BEAM_MASK).reset(MonsterAbilityType::ROCKET);
82         break;
83
84     case BlueMagicType::BALL:
85         ability_flags.set(RF_ABILITY_BALL_MASK).reset(RF_ABILITY_BREATH_MASK);
86         break;
87
88     case BlueMagicType::BREATH:
89         ability_flags.set(RF_ABILITY_BREATH_MASK);
90         break;
91
92     case BlueMagicType::SUMMON:
93         ability_flags.set(RF_ABILITY_SUMMON_MASK);
94         break;
95
96     case BlueMagicType::OTHER:
97         ability_flags.set(RF_ABILITY_ATTACK_MASK);
98         ability_flags.reset(RF_ABILITY_BOLT_MASK | RF_ABILITY_BEAM_MASK | RF_ABILITY_BALL_MASK | RF_ABILITY_INDIRECT_MASK);
99         break;
100     }
101 }