OSDN Git Service

[Implement]虚空・深淵属性のボルト・ボール・ブレスを実装
authordaradarach <daradarach@gmail.com>
Sat, 5 Feb 2022 06:50:52 +0000 (15:50 +0900)
committerdaradarach <daradarach@gmail.com>
Sat, 5 Feb 2022 07:13:43 +0000 (16:13 +0900)
24 files changed:
lib/edit/r_info.txt
src/blue-magic/blue-magic-ball-bolt.cpp
src/blue-magic/blue-magic-ball-bolt.h
src/blue-magic/blue-magic-breath.cpp
src/blue-magic/blue-magic-breath.h
src/blue-magic/blue-magic-caster.cpp
src/blue-magic/learnt-info.cpp
src/cmd-action/cmd-mane.cpp
src/info-reader/race-info-tokens-table.cpp
src/lore/magic-types-setter.cpp
src/monster-race/race-ability-flags.h
src/monster-race/race-ability-mask.cpp
src/mspell/assign-monster-spell.cpp
src/mspell/high-resistance-checker.cpp
src/mspell/monster-power-table.cpp
src/mspell/mspell-attack.cpp
src/mspell/mspell-ball.cpp
src/mspell/mspell-ball.h
src/mspell/mspell-bolt.cpp
src/mspell/mspell-bolt.h
src/mspell/mspell-breath.cpp
src/mspell/mspell-damage-calculator.cpp
src/mspell/mspell-selector.cpp
src/object/warning.cpp

index 40a8f2b..859e26f 100644 (file)
@@ -15747,7 +15747,7 @@ F:ELDRITCH_HORROR | IM_COLD | RES_NETH | RES_DARK
 F:NO_CONF | NO_SLEEP | NO_STUN | QUANTUM | RAND_25
 F:REGENERATE | SELF_DARK_1 | SELF_DARK_2
 S:1_IN_5 | BR_NETH | BRAIN_SMASH | SCARE | S_UNDEAD | S_HI_UNDEAD
-S:DRAIN_MANA | HEAL | ANIM_DEAD
+S:DRAIN_MANA | HEAL | ANIM_DEAD | BO_ABYSS | BO_VOID | BR_ABYSS | BR_VOID | BA_VOID | BA_ABYSS
 D:$A black hole in the fabric of reality.
 D:$  It simply is not there.
 D:現実という生地に空いた黒い穴。これは「無」だ。
@@ -26690,3 +26690,36 @@ S:1_IN_1
 S:BO_PLAS
 D:$It is a brain-like monster on a machine with four spider-like legs.
 D:それは脳みそのような生き物で、蜘蛛のような脚を4つ持つ機械に乗っている。
+
+N:1351:ヴォイド・ボルテックス
+E:Void vortex
+G:v:v
+I:140:32d20:100:80:0
+W:55:1:0:4000:0:0
+F:ATTR_MULTI | ATTR_ANY |
+F:PREVENT_SUDDEN_MAGIC | NEVER_BLOW | 
+F:RAND_50 | RAND_25 | CAN_FLY |
+F:EMPTY_MIND | BASH_DOOR | POWERFUL | 
+F:RES_GRAV | RES_TELE | NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | NONLIVING
+S:1_IN_6 | 
+S:BR_VOID
+V:150
+D:$It's a void whirlpool.
+D:空虚な渦巻きだ。
+
+N:1352:アビス・ボルテックス
+E:Abyss vortex
+G:v:v
+I:140:32d20:100:80:0
+W:55:1:0:4000:0:0
+F:ATTR_MULTI | ATTR_ANY |
+F:PREVENT_SUDDEN_MAGIC | NEVER_BLOW | 
+F:RAND_50 | RAND_25 | CAN_FLY |
+F:EMPTY_MIND | BASH_DOOR | POWERFUL | 
+F:HAS_DARK_1 | HAS_DARK_2 | RES_DARK | NO_CONF | NO_SLEEP | NO_FEAR | NO_STUN | NONLIVING
+S:1_IN_6 | 
+S:BR_ABYSS
+V:150
+D:$It's a abyssal whirlpool.
+D:深淵の渦巻きだ。
+
index 02f914a..98d8ef0 100644 (file)
@@ -152,6 +152,28 @@ bool cast_blue_ball_mana_storm(PlayerType *player_ptr, bmc_type *bmc_ptr)
     return true;
 }
 
+bool cast_blue_ball_void(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+    if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+        return false;
+
+    msg_print(_("虚空の嵐の呪文を念じた。", "You invoke a void storm."));
+    bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_VOID, bmc_ptr->plev, DAM_ROLL);
+    fire_ball(player_ptr, AttributeType::VOID_MAGIC, bmc_ptr->dir, bmc_ptr->damage, 4);
+    return true;
+}
+
+bool cast_blue_ball_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+    if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+        return false;
+
+    msg_print(_("深淵の嵐の呪文を念じた。", "You invoke a abyss storm."));
+    bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BA_ABYSS, bmc_ptr->plev, DAM_ROLL);
+    fire_ball(player_ptr, AttributeType::ABYSS, bmc_ptr->dir, bmc_ptr->damage, 4);
+    return true;
+}
+
 bool cast_blue_bolt_acid(PlayerType *player_ptr, bmc_type *bmc_ptr)
 {
     if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
@@ -261,3 +283,25 @@ bool cast_blue_bolt_missile(PlayerType *player_ptr, bmc_type *bmc_ptr)
     fire_bolt(player_ptr, AttributeType::MISSILE, bmc_ptr->dir, bmc_ptr->damage);
     return true;
 }
+
+bool cast_blue_bolt_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+    if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+        return false;
+
+    msg_print(_("アビス・ボルトの呪文を唱えた。", "You cast a abyss bolt."));
+    bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_ABYSS, bmc_ptr->plev, DAM_ROLL);
+    fire_bolt(player_ptr, AttributeType::ABYSS, bmc_ptr->dir, bmc_ptr->damage);
+    return true;
+}
+
+bool cast_blue_bolt_void(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+    if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+        return false;
+
+    msg_print(_("ヴォイド・ボルトの呪文を唱えた。", "You cast a void bolt."));
+    bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BO_VOID, bmc_ptr->plev, DAM_ROLL);
+    fire_bolt(player_ptr, AttributeType::VOID_MAGIC, bmc_ptr->dir, bmc_ptr->damage);
+    return true;
+}
index 145187d..03e75a3 100644 (file)
@@ -18,6 +18,8 @@ bool cast_blue_ball_water(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_ball_star_burst(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_ball_dark_storm(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_ball_mana_storm(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_ball_void(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_ball_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr);
 
 bool cast_blue_bolt_acid(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_bolt_elec(PlayerType *player_ptr, bmc_type *bmc_ptr);
@@ -28,4 +30,6 @@ bool cast_blue_bolt_water(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_bolt_mana(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_bolt_plasma(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_bolt_icee(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_bolt_void(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_bolt_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_bolt_missile(PlayerType *player_ptr, bmc_type *bmc_ptr);
index 36d9e25..0d96e7f 100644 (file)
@@ -261,3 +261,35 @@ bool cast_blue_breath_disintegration(PlayerType *player_ptr, bmc_type *bmc_ptr)
     fire_breath(player_ptr, AttributeType::DISINTEGRATE, bmc_ptr->dir, bmc_ptr->damage, (bmc_ptr->plev > 40 ? 3 : 2));
     return true;
 }
+
+/*!
+ * @brief 虚無のブレスの青魔法
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param bmc_ptr 青魔法詠唱への参照ポインタ
+ */
+bool cast_blue_breath_void(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+    if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+        return false;
+
+    msg_print(_("虚無のブレスを吐いた。", "You breathe void."));
+    bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_VOID, bmc_ptr->plev, DAM_ROLL);
+    fire_breath(player_ptr, AttributeType::VOID_MAGIC, bmc_ptr->dir, bmc_ptr->damage, (bmc_ptr->plev > 40 ? 3 : 2));
+    return true;
+}
+
+/*!
+ * @brief 深淵のブレスの青魔法
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param bmc_ptr 青魔法詠唱への参照ポインタ
+ */
+bool cast_blue_breath_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr)
+{
+    if (!get_aim_dir(player_ptr, &bmc_ptr->dir))
+        return false;
+
+    msg_print(_("分解のブレスを吐いた。", "You breathe abyss."));
+    bmc_ptr->damage = monspell_bluemage_damage(player_ptr, MonsterAbilityType::BR_ABYSS, bmc_ptr->plev, DAM_ROLL);
+    fire_breath(player_ptr, AttributeType::ABYSS, bmc_ptr->dir, bmc_ptr->damage, (bmc_ptr->plev > 40 ? 3 : 2));
+    return true;
+}
index 2eb9180..ed3271c 100644 (file)
@@ -28,3 +28,5 @@ bool cast_blue_breath_force(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_breath_mana(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_breath_nuke(PlayerType *player_ptr, bmc_type *bmc_ptr);
 bool cast_blue_breath_disintegration(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_breath_void(PlayerType *player_ptr, bmc_type *bmc_ptr);
+bool cast_blue_breath_abyss(PlayerType *player_ptr, bmc_type *bmc_ptr);
index dfdf164..5170528 100644 (file)
@@ -229,6 +229,10 @@ static bool switch_cast_blue_magic(PlayerType *player_ptr, bmc_type *bmc_ptr, Mo
         return cast_blue_breath_nuke(player_ptr, bmc_ptr);
     case MonsterAbilityType::BR_DISI:
         return cast_blue_breath_disintegration(player_ptr, bmc_ptr);
+    case MonsterAbilityType::BR_VOID:
+        return cast_blue_breath_void(player_ptr, bmc_ptr);
+    case MonsterAbilityType::BR_ABYSS:
+        return cast_blue_breath_abyss(player_ptr, bmc_ptr);
     case MonsterAbilityType::BA_ACID:
         return cast_blue_ball_acid(player_ptr, bmc_ptr);
     case MonsterAbilityType::BA_ELEC:
@@ -253,6 +257,10 @@ static bool switch_cast_blue_magic(PlayerType *player_ptr, bmc_type *bmc_ptr, Mo
         return cast_blue_ball_dark_storm(player_ptr, bmc_ptr);
     case MonsterAbilityType::BA_MANA:
         return cast_blue_ball_mana_storm(player_ptr, bmc_ptr);
+    case MonsterAbilityType::BA_VOID:
+        return cast_blue_ball_void(player_ptr, bmc_ptr);
+    case MonsterAbilityType::BA_ABYSS:
+        return cast_blue_ball_abyss(player_ptr, bmc_ptr);
     case MonsterAbilityType::DRAIN_MANA:
         return cast_blue_drain_mana(player_ptr, bmc_ptr);
     case MonsterAbilityType::MIND_BLAST:
@@ -285,6 +293,10 @@ static bool switch_cast_blue_magic(PlayerType *player_ptr, bmc_type *bmc_ptr, Mo
         return cast_blue_bolt_plasma(player_ptr, bmc_ptr);
     case MonsterAbilityType::BO_ICEE:
         return cast_blue_bolt_icee(player_ptr, bmc_ptr);
+    case MonsterAbilityType::BO_ABYSS:
+        return cast_blue_bolt_abyss(player_ptr, bmc_ptr);
+    case MonsterAbilityType::BO_VOID:
+        return cast_blue_bolt_void(player_ptr, bmc_ptr);
     case MonsterAbilityType::MISSILE:
         return cast_blue_bolt_missile(player_ptr, bmc_ptr);
     case MonsterAbilityType::SCARE:
index 0ff3342..41e40ef 100644 (file)
@@ -120,6 +120,8 @@ void learnt_info(PlayerType *player_ptr, char *p, MonsterAbilityType power)
     case MonsterAbilityType::BR_INER:
     case MonsterAbilityType::BR_FORC:
     case MonsterAbilityType::BR_DISI:
+    case MonsterAbilityType::BR_VOID:
+    case MonsterAbilityType::BR_ABYSS:
     case MonsterAbilityType::BA_NUKE:
     case MonsterAbilityType::BA_CHAO:
     case MonsterAbilityType::BA_ACID:
@@ -129,6 +131,8 @@ void learnt_info(PlayerType *player_ptr, char *p, MonsterAbilityType power)
     case MonsterAbilityType::BA_POIS:
     case MonsterAbilityType::BA_NETH:
     case MonsterAbilityType::BA_WATE:
+    case MonsterAbilityType::BA_VOID:
+    case MonsterAbilityType::BA_ABYSS:
         set_bluemage_damage(player_ptr, power, plev, KWD_DAM, p);
         break;
     case MonsterAbilityType::DRAIN_MANA:
@@ -148,6 +152,8 @@ void learnt_info(PlayerType *player_ptr, char *p, MonsterAbilityType power)
     case MonsterAbilityType::BO_WATE:
     case MonsterAbilityType::BO_MANA:
     case MonsterAbilityType::BO_PLAS:
+    case MonsterAbilityType::BO_ABYSS:
+    case MonsterAbilityType::BO_VOID:
     case MonsterAbilityType::BO_ICEE:
     case MonsterAbilityType::MISSILE:
         set_bluemage_damage(player_ptr, power, plev, KWD_DAM, p);
index b403f1f..786d720 100644 (file)
@@ -89,7 +89,9 @@ static void mane_info(PlayerType *player_ptr, char *p, MonsterAbilityType power,
 
     const auto power_int = enum2i(power);
 
-    if ((power_int > 2 && power_int < 41) || (power_int > 41 && power_int < 59) || (power == MonsterAbilityType::PSY_SPEAR))
+    if ((power_int > 2 && power_int < 41) || (power_int > 41 && power_int < 59) || (power == MonsterAbilityType::PSY_SPEAR)
+        || (power == MonsterAbilityType::BO_VOID) || (power == MonsterAbilityType::BO_ABYSS)
+        || (power == MonsterAbilityType::BR_VOID) || (power == MonsterAbilityType::BR_ABYSS))
         sprintf(p, " %s%d", KWD_DAM, (int)dam);
     else {
         switch (power) {
@@ -567,6 +569,24 @@ static bool use_mane(PlayerType *player_ptr, MonsterAbilityType spell)
 
         fire_breath(player_ptr, AttributeType::DISINTEGRATE, dir, damage, (plev > 35 ? 3 : 2));
         break;
+    case MonsterAbilityType::BR_VOID:
+        if (!get_aim_dir(player_ptr, &dir))
+            return false;
+        else
+            msg_print(_("虚空のブレスを吐いた。", "You breathe void."));
+
+        fire_breath(player_ptr, AttributeType::VOID_MAGIC, dir, damage, (plev > 35 ? 3 : 2));
+        break;
+
+    case MonsterAbilityType::BR_ABYSS:
+        if (!get_aim_dir(player_ptr, &dir))
+            return false;
+        else
+            msg_print(_("深淵のブレスを吐いた。", "You breathe abyss."));
+
+        fire_breath(player_ptr, AttributeType::ABYSS, dir, damage, (plev > 35 ? 3 : 2));
+        break;
+
     case MonsterAbilityType::BA_ACID:
         if (!get_aim_dir(player_ptr, &dir))
             return false;
@@ -639,6 +659,22 @@ static bool use_mane(PlayerType *player_ptr, MonsterAbilityType spell)
 
         fire_ball(player_ptr, AttributeType::DARK, dir, damage, 4);
         break;
+    case MonsterAbilityType::BA_VOID:
+        if (!get_aim_dir(player_ptr, &dir))
+            return false;
+        else
+            msg_print(_("虚空の嵐の呪文を念じた。", "You cast a void ball."));
+
+        fire_ball(player_ptr, AttributeType::VOID_MAGIC, dir, damage, 4);
+        break;
+    case MonsterAbilityType::BA_ABYSS:
+        if (!get_aim_dir(player_ptr, &dir))
+            return false;
+        else
+            msg_print(_("深淵の嵐の呪文を念じた。", "You cast a abyss ball."));
+
+        fire_ball(player_ptr, AttributeType::ABYSS, dir, damage, 4);
+        break;
     case MonsterAbilityType::DRAIN_MANA:
         if (!get_aim_dir(player_ptr, &dir))
             return false;
@@ -754,6 +790,22 @@ static bool use_mane(PlayerType *player_ptr, MonsterAbilityType spell)
 
         fire_bolt(player_ptr, AttributeType::ICE, dir, damage);
         break;
+    case MonsterAbilityType::BO_VOID:
+        if (!get_aim_dir(player_ptr, &dir))
+            return false;
+        else
+            msg_print(_("虚空の矢の呪文を唱えた。", "You cast a void bolt."));
+
+        fire_bolt(player_ptr, AttributeType::VOID_MAGIC, dir, damage);
+        break;
+    case MonsterAbilityType::BO_ABYSS:
+        if (!get_aim_dir(player_ptr, &dir))
+            return false;
+        else
+            msg_print(_("深淵の矢の呪文を唱えた。", "You cast a abyss bolt."));
+
+        fire_bolt(player_ptr, AttributeType::ABYSS, dir, damage);
+        break;
     case MonsterAbilityType::MISSILE:
         if (!get_aim_dir(player_ptr, &dir))
             return false;
index 5371ea8..f018eca 100644 (file)
@@ -215,6 +215,8 @@ const std::unordered_map<std::string_view, MonsterAbilityType> r_info_ability_fl
        {"BR_NUKE", MonsterAbilityType::BR_NUKE },
        {"BA_CHAO", MonsterAbilityType::BA_CHAO },
        {"BR_DISI", MonsterAbilityType::BR_DISI },
+       {"BR_VOID", MonsterAbilityType::BR_VOID },
+       {"BR_ABYSS", MonsterAbilityType::BR_ABYSS },
 
        {"BA_ACID", MonsterAbilityType::BA_ACID },
        {"BA_ELEC", MonsterAbilityType::BA_ELEC },
@@ -225,6 +227,8 @@ const std::unordered_map<std::string_view, MonsterAbilityType> r_info_ability_fl
        {"BA_WATE", MonsterAbilityType::BA_WATE },
        {"BA_MANA", MonsterAbilityType::BA_MANA },
        {"BA_DARK", MonsterAbilityType::BA_DARK },
+       {"BA_VOID", MonsterAbilityType::BA_VOID },
+       {"BA_ABYSS", MonsterAbilityType::BA_ABYSS },
        {"DRAIN_MANA", MonsterAbilityType::DRAIN_MANA },
        {"MIND_BLAST", MonsterAbilityType::MIND_BLAST },
        {"BRAIN_SMASH", MonsterAbilityType::BRAIN_SMASH },
@@ -242,6 +246,8 @@ const std::unordered_map<std::string_view, MonsterAbilityType> r_info_ability_fl
        {"BO_MANA", MonsterAbilityType::BO_MANA },
        {"BO_PLAS", MonsterAbilityType::BO_PLAS },
        {"BO_ICEE", MonsterAbilityType::BO_ICEE },
+       {"BO_VOID", MonsterAbilityType::BO_VOID },
+       {"BO_ABYSS", MonsterAbilityType::BO_ABYSS },
        {"MISSILE", MonsterAbilityType::MISSILE },
        {"SCARE", MonsterAbilityType::SCARE },
        {"BLIND", MonsterAbilityType::BLIND },
index f11f0ed..5ee8129 100644 (file)
@@ -141,6 +141,18 @@ void set_breath_types(PlayerType *player_ptr, lore_type *lore_ptr)
         lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
         lore_ptr->color[lore_ptr->vn++] = TERM_SLATE;
     }
+
+    if (lore_ptr->ability_flags.has(MonsterAbilityType::BR_VOID)) {
+        set_damage(player_ptr, lore_ptr, MonsterAbilityType::BR_VOID, _("虚空%s", "void%s"));
+        lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+        lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+    }
+
+    if (lore_ptr->ability_flags.has(MonsterAbilityType::BR_ABYSS)) {
+        set_damage(player_ptr, lore_ptr, MonsterAbilityType::BR_ABYSS, _("深淵%s", "abyss%s"));
+        lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+        lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+    }
 }
 
 void set_ball_types(PlayerType *player_ptr, lore_type *lore_ptr)
@@ -216,6 +228,18 @@ void set_ball_types(PlayerType *player_ptr, lore_type *lore_ptr)
         lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
         lore_ptr->color[lore_ptr->vn++] = TERM_VIOLET;
     }
+
+    if (lore_ptr->ability_flags.has(MonsterAbilityType::BA_VOID)) {
+        set_damage(player_ptr, lore_ptr, MonsterAbilityType::BA_VOID, _("虚空の嵐%s", "invoke void storms%s"));
+        lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+        lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+    }
+
+    if (lore_ptr->ability_flags.has(MonsterAbilityType::BA_ABYSS)) {
+        set_damage(player_ptr, lore_ptr, MonsterAbilityType::BA_ABYSS, _("深淵の嵐%s", "invoke abyss storms%s"));
+        lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+        lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+    }
 }
 
 void set_particular_types(PlayerType *player_ptr, lore_type *lore_ptr)
@@ -330,6 +354,18 @@ void set_bolt_types(PlayerType *player_ptr, lore_type *lore_ptr)
         lore_ptr->color[lore_ptr->vn++] = TERM_WHITE;
     }
 
+    if (lore_ptr->ability_flags.has(MonsterAbilityType::BO_VOID)) {
+        set_damage(player_ptr, lore_ptr, MonsterAbilityType::BO_VOID, _("ヴォイド・ボルト%s", "produce void bolts%s"));
+        lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+        lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+    }
+
+     if (lore_ptr->ability_flags.has(MonsterAbilityType::BO_ABYSS)) {
+        set_damage(player_ptr, lore_ptr, MonsterAbilityType::BO_ABYSS, _("アビス・ボルト%s", "produce abyss bolts%s"));
+        lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
+        lore_ptr->color[lore_ptr->vn++] = TERM_L_DARK;
+    }
+
     if (lore_ptr->ability_flags.has(MonsterAbilityType::MISSILE)) {
         set_damage(player_ptr, lore_ptr, MonsterAbilityType::MISSILE, _("マジックミサイル%s", "produce magic missiles%s"));
         lore_ptr->vp[lore_ptr->vn] = lore_ptr->tmp_msg[lore_ptr->vn];
index 10a8834..9f0028b 100644 (file)
@@ -99,5 +99,11 @@ enum class MonsterAbilityType {
     S_HI_DRAGON = 93, /* Summon Ancient Dragon */
     S_AMBERITES = 94, /* Summon Amberites */
     S_UNIQUE = 95, /* Summon Unique Monster */
+    BO_VOID = 97, /*!< モンスター能力: ヴォイド・ボルト / Void Bolt */
+    BO_ABYSS = 98, /*!< モンスター能力: アビス・ボルト / Abyss Bolt */
+    BR_VOID = 99, /*!< モンスター能力: 虚無のブレス / Breathe Void */
+    BR_ABYSS = 100, /*!< モンスター能力: 深淵のブレス / Breathe Abyss */
+    BA_VOID = 101, /*!< モンスター能力: 虚無のボール / Void Ball */
+    BA_ABYSS = 102, /*!< モンスター能力: 深淵のボール / Abyss Ball */
     MAX,
 };
index 8324a5a..9e5df37 100644 (file)
@@ -31,7 +31,8 @@ const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_RIDING_MASK = {
 const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_BOLT_MASK = {
     MonsterAbilityType::ROCKET, MonsterAbilityType::SHOOT, MonsterAbilityType::BO_ACID, MonsterAbilityType::BO_ELEC,
     MonsterAbilityType::BO_FIRE, MonsterAbilityType::BO_COLD, MonsterAbilityType::BO_NETH, MonsterAbilityType::BO_WATE,
-    MonsterAbilityType::BO_MANA, MonsterAbilityType::BO_PLAS, MonsterAbilityType::BO_ICEE, MonsterAbilityType::MISSILE,
+    MonsterAbilityType::BO_MANA, MonsterAbilityType::BO_PLAS, MonsterAbilityType::BO_ICEE, MonsterAbilityType::BO_VOID,
+    MonsterAbilityType::BO_ABYSS, MonsterAbilityType::MISSILE,
 };
 
 /*
@@ -48,7 +49,7 @@ const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_BEAM_MASK = {
  */
 const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_BIG_BALL_MASK = {
     MonsterAbilityType::BA_CHAO, MonsterAbilityType::BA_LITE, MonsterAbilityType::BA_DARK, MonsterAbilityType::BA_WATE,
-    MonsterAbilityType::BA_MANA,
+    MonsterAbilityType::BA_MANA, MonsterAbilityType::BA_VOID, MonsterAbilityType::BA_ABYSS,
 };
 
 /*
@@ -61,7 +62,7 @@ const EnumClassFlagGroup<MonsterAbilityType> RF_ABILITY_BREATH_MASK = {
     MonsterAbilityType::BR_CONF, MonsterAbilityType::BR_SOUN, MonsterAbilityType::BR_CHAO, MonsterAbilityType::BR_DISE,
     MonsterAbilityType::BR_NEXU, MonsterAbilityType::BR_SHAR, MonsterAbilityType::BR_TIME, MonsterAbilityType::BR_INER,
     MonsterAbilityType::BR_GRAV, MonsterAbilityType::BR_PLAS, MonsterAbilityType::BR_FORC, MonsterAbilityType::BR_MANA,
-    MonsterAbilityType::BR_NUKE, MonsterAbilityType::BR_DISI,
+    MonsterAbilityType::BR_NUKE, MonsterAbilityType::BR_DISI, MonsterAbilityType::BR_VOID, MonsterAbilityType::BR_ABYSS,
 };
 
 /*
index 09761bd..52e3445 100644 (file)
@@ -60,6 +60,8 @@ static MonsterSpellResult monspell_to_player_impl(PlayerType *player_ptr, Monste
     case MonsterAbilityType::BR_NUKE: return spell_RF4_BREATH(player_ptr, AttributeType::NUKE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_NUKE */
     case MonsterAbilityType::BA_CHAO: return spell_RF4_BA_CHAO(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BA_CHAO */
     case MonsterAbilityType::BR_DISI: return spell_RF4_BREATH(player_ptr, AttributeType::DISINTEGRATE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_DISI */
+    case MonsterAbilityType::BR_VOID: return spell_RF4_BREATH(player_ptr, AttributeType::VOID_MAGIC, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_VOID */
+    case MonsterAbilityType::BR_ABYSS: return spell_RF4_BREATH(player_ptr, AttributeType::ABYSS, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_ABYSS */
     case MonsterAbilityType::BA_ACID: return spell_RF5_BA_ACID(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_ACID */
     case MonsterAbilityType::BA_ELEC: return spell_RF5_BA_ELEC(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_ELEC */
     case MonsterAbilityType::BA_FIRE: return spell_RF5_BA_FIRE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_FIRE */
@@ -69,6 +71,8 @@ static MonsterSpellResult monspell_to_player_impl(PlayerType *player_ptr, Monste
     case MonsterAbilityType::BA_WATE: return spell_RF5_BA_WATE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_WATE */
     case MonsterAbilityType::BA_MANA: return spell_RF5_BA_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_MANA */
     case MonsterAbilityType::BA_DARK: return spell_RF5_BA_DARK(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_DARK */
+    case MonsterAbilityType::BA_VOID: return spell_RF5_BA_VOID(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_VOID */
+    case MonsterAbilityType::BA_ABYSS: return spell_RF5_BA_ABYSS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BA_ABYSS */
     case MonsterAbilityType::DRAIN_MANA: return spell_RF5_DRAIN_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER);  /* RF5_DRAIN_MANA */
     case MonsterAbilityType::MIND_BLAST: return spell_RF5_MIND_BLAST(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER);  /* RF5_MIND_BLAST */
     case MonsterAbilityType::BRAIN_SMASH: return spell_RF5_BRAIN_SMASH(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_MIND_BLAST */
@@ -86,6 +90,8 @@ static MonsterSpellResult monspell_to_player_impl(PlayerType *player_ptr, Monste
     case MonsterAbilityType::BO_MANA: return spell_RF5_BO_MANA(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_MANA */
     case MonsterAbilityType::BO_PLAS: return spell_RF5_BO_PLAS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_PLAS */
     case MonsterAbilityType::BO_ICEE: return spell_RF5_BO_ICEE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_ICEE */
+    case MonsterAbilityType::BO_VOID: return spell_RF5_BO_VOID(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_VOID */
+    case MonsterAbilityType::BO_ABYSS: return spell_RF5_BO_ABYSS(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_BO_ABYSS */
     case MonsterAbilityType::MISSILE: return spell_RF5_MISSILE(player_ptr, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF5_MISSILE */
     case MonsterAbilityType::SCARE: return spell_RF5_SCARE(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_SCARE */
     case MonsterAbilityType::BLIND: return spell_RF5_BLIND(m_idx, player_ptr, 0, MONSTER_TO_PLAYER); /* RF5_BLIND */
@@ -168,6 +174,8 @@ static MonsterSpellResult monspell_to_monster_impl(
     case MonsterAbilityType::BR_NUKE: return spell_RF4_BREATH(player_ptr, AttributeType::NUKE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_NUKE */
     case MonsterAbilityType::BA_CHAO: return spell_RF4_BA_CHAO(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BA_CHAO */
     case MonsterAbilityType::BR_DISI: return spell_RF4_BREATH(player_ptr, AttributeType::DISINTEGRATE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_DISI */
+    case MonsterAbilityType::BR_VOID: return spell_RF4_BREATH(player_ptr, AttributeType::VOID_MAGIC, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_VOID */
+    case MonsterAbilityType::BR_ABYSS: return spell_RF4_BREATH(player_ptr, AttributeType::ABYSS, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_ABYSS */
     case MonsterAbilityType::BA_ACID: return spell_RF5_BA_ACID(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_ACID */
     case MonsterAbilityType::BA_ELEC: return spell_RF5_BA_ELEC(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_ELEC */
     case MonsterAbilityType::BA_FIRE: return spell_RF5_BA_FIRE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_FIRE */
@@ -177,6 +185,8 @@ static MonsterSpellResult monspell_to_monster_impl(
     case MonsterAbilityType::BA_WATE: return spell_RF5_BA_WATE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_WATE */
     case MonsterAbilityType::BA_MANA: return spell_RF5_BA_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_MANA */
     case MonsterAbilityType::BA_DARK: return spell_RF5_BA_DARK(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_DARK */
+    case MonsterAbilityType::BA_VOID: return spell_RF5_BA_VOID(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_VOID */
+    case MonsterAbilityType::BA_ABYSS: return spell_RF5_BA_ABYSS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BA_ABYSS */
     case MonsterAbilityType::DRAIN_MANA: return spell_RF5_DRAIN_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_DRAIN_MANA */
     case MonsterAbilityType::MIND_BLAST: return spell_RF5_MIND_BLAST(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_MIND_BLAST */
     case MonsterAbilityType::BRAIN_SMASH: return spell_RF5_BRAIN_SMASH(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BRAIN_SMASH */
@@ -194,6 +204,8 @@ static MonsterSpellResult monspell_to_monster_impl(
     case MonsterAbilityType::BO_MANA: return spell_RF5_BO_MANA(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_MANA */
     case MonsterAbilityType::BO_PLAS: return spell_RF5_BO_PLAS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_PLAS */
     case MonsterAbilityType::BO_ICEE: return spell_RF5_BO_ICEE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_ICEE */
+    case MonsterAbilityType::BO_VOID: return spell_RF5_BO_VOID(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_VOID */
+    case MonsterAbilityType::BO_ABYSS: return spell_RF5_BO_ABYSS(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_BO_ABYSS */
     case MonsterAbilityType::MISSILE: return spell_RF5_MISSILE(player_ptr, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF5_MISSILE */
     case MonsterAbilityType::SCARE: return spell_RF5_SCARE(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_SCARE */
     case MonsterAbilityType::BLIND: return spell_RF5_BLIND(m_idx, player_ptr, t_idx, MONSTER_TO_MONSTER); /* RF5_BLIND */
index 022f940..8347a21 100644 (file)
@@ -170,6 +170,12 @@ static void check_reflection(msr_type *msr_ptr)
         msr_ptr->ability_flags.reset(MonsterAbilityType::BO_ICEE);
 
     if (int_outof(msr_ptr->r_ptr, 150))
+        msr_ptr->ability_flags.reset(MonsterAbilityType::BO_VOID);
+
+    if (int_outof(msr_ptr->r_ptr, 150))
+        msr_ptr->ability_flags.reset(MonsterAbilityType::BO_ABYSS);
+
+    if (int_outof(msr_ptr->r_ptr, 150))
         msr_ptr->ability_flags.reset(MonsterAbilityType::MISSILE);
 }
 
index f4e3d4d..b89824c 100644 (file)
@@ -40,6 +40,8 @@ const std::map<MonsterAbilityType, const monster_power> monster_powers = {
     { MonsterAbilityType::BR_NUKE, { 25, 15, 70, 800, 95, A_CON, _("放射性廃棄物のブレス", "breathe nuke") } },
     { MonsterAbilityType::BA_CHAO, { 30, 32, 85, 400, 80, A_INT, _("純ログルス", "raw Logrus") } },
     { MonsterAbilityType::BR_DISI, { 35, 40, 95, 150, 95, A_CON, _("分解のブレス", "breathe disintegration") } },
+    { MonsterAbilityType::BR_VOID, { 40, 44, 95, 250, 95, A_CON, _("虚空のブレス", "breathe void") } },
+    { MonsterAbilityType::BR_ABYSS, { 40, 44, 95, 250, 95, A_CON, _("深淵のブレス", "breathe abyss") } },
 
     { MonsterAbilityType::BA_ACID, { 18, 13, 55, 630, 80, A_INT, _("アシッド・ボール", "acid ball") } },
     { MonsterAbilityType::BA_ELEC, { 14, 10, 45, 316, 60, A_INT, _("サンダー・ボール", "lightning ball") } },
@@ -50,6 +52,8 @@ const std::map<MonsterAbilityType, const monster_power> monster_powers = {
     { MonsterAbilityType::BA_WATE, { 30, 22, 75, 350, 80, A_INT, _("ウォーター・ボール", "water ball") } },
     { MonsterAbilityType::BA_MANA, { 44, 45, 85, 550, 95, A_INT, _("魔力の嵐", "mana storm") } },
     { MonsterAbilityType::BA_DARK, { 40, 42, 90, 550, 95, A_INT, _("暗黒の嵐", "darkness storm") } },
+    { MonsterAbilityType::BA_VOID, { 38, 41, 85, 400, 90, A_INT, _("虚空の嵐", "void ball") } },
+    { MonsterAbilityType::BA_ABYSS, { 39, 42, 85, 400, 90, A_INT, _("深淵の嵐", "abyss ball") } },
     { MonsterAbilityType::DRAIN_MANA, { 10, 5, 50, 0, 25, A_INT, _("魔力吸収", "drain mana") } },
     { MonsterAbilityType::MIND_BLAST, { 25, 10, 60, 0, 30, A_INT, _("精神攻撃", "mind blast") } },
     { MonsterAbilityType::BRAIN_SMASH, { 30, 14, 65, 0, 30, A_INT, _("脳攻撃", "brain smash") } },
@@ -67,6 +71,8 @@ const std::map<MonsterAbilityType, const monster_power> monster_powers = {
     { MonsterAbilityType::BO_MANA, { 25, 24, 90, 400, 80, A_INT, _("魔力の矢", "mana bolt") } },
     { MonsterAbilityType::BO_PLAS, { 25, 20, 80, 216, 60, A_INT, _("プラズマ・ボルト", "plasma bolt") } },
     { MonsterAbilityType::BO_ICEE, { 25, 16, 60, 186, 60, A_INT, _("極寒の矢", "ice bolt") } },
+    { MonsterAbilityType::BO_VOID, { 35, 31, 80, 342, 70, A_INT, _("ヴォイド・ボルト", "void bolt") } },
+    { MonsterAbilityType::BO_ABYSS, { 35, 33, 80, 342, 70, A_INT, _("アビス・ボルト", "abyss bolt") } },
     { MonsterAbilityType::MISSILE, { 3, 1, 25, 12, 20, A_INT, _("マジック・ミサイル", "magic missile") } },
     { MonsterAbilityType::SCARE, { 5, 3, 35, 0, 20, A_INT, _("恐慌", "scare") } },
     { MonsterAbilityType::BLIND, { 10, 5, 40, 0, 20, A_INT, _("盲目", "blind") } },
@@ -144,6 +150,8 @@ const std::map<MonsterAbilityType, concptr> monster_powers_short = {
     { MonsterAbilityType::BR_NUKE, _("放射性廃棄物", "Nuke") },
     { MonsterAbilityType::BA_CHAO, _("純ログルス", "Logrus") },
     { MonsterAbilityType::BR_DISI, _("分解", "Disintegration") },
+    { MonsterAbilityType::BR_VOID, _("虚空", "Void") },
+    { MonsterAbilityType::BR_ABYSS, _("深淵", "Abyss") },
 
     { MonsterAbilityType::BA_ACID, _("酸", "Acid") },
     { MonsterAbilityType::BA_ELEC, _("電撃", "Lightning") },
@@ -154,6 +162,8 @@ const std::map<MonsterAbilityType, concptr> monster_powers_short = {
     { MonsterAbilityType::BA_WATE, _("ウォーター", "Water") },
     { MonsterAbilityType::BA_MANA, _("魔力の嵐", "Mana storm") },
     { MonsterAbilityType::BA_DARK, _("暗黒の嵐", "Darkness storm") },
+    { MonsterAbilityType::BA_VOID, _("虚空", "Void") },
+    { MonsterAbilityType::BA_ABYSS, _("深淵", "Abyss") },
     { MonsterAbilityType::DRAIN_MANA, _("魔力吸収", "Drain mana") },
     { MonsterAbilityType::MIND_BLAST, _("精神攻撃", "Mind blast") },
     { MonsterAbilityType::BRAIN_SMASH, _("脳攻撃", "Brain smash") },
@@ -171,6 +181,8 @@ const std::map<MonsterAbilityType, concptr> monster_powers_short = {
     { MonsterAbilityType::BO_MANA, _("魔力の矢", "Mana") },
     { MonsterAbilityType::BO_PLAS, _("プラズマ", "Plasma") },
     { MonsterAbilityType::BO_ICEE, _("極寒", "Ice") },
+    { MonsterAbilityType::BO_VOID, _("ヴォイド", "Void") },
+    { MonsterAbilityType::BO_ABYSS, _("アビス", "Abyss") },
     { MonsterAbilityType::MISSILE, _("マジックミサイル", "Magic missile") },
     { MonsterAbilityType::SCARE, _("恐慌", "Scare") },
     { MonsterAbilityType::BLIND, _("盲目", "Blind") },
index 06366e5..5e41a00 100644 (file)
@@ -233,6 +233,8 @@ static bool check_thrown_mspell(PlayerType *player_ptr, msa_type *msa_ptr)
     case MonsterAbilityType::BO_MANA:
     case MonsterAbilityType::BO_PLAS:
     case MonsterAbilityType::BO_ICEE:
+    case MonsterAbilityType::BO_VOID:
+    case MonsterAbilityType::BO_ABYSS:
     case MonsterAbilityType::MISSILE:
     case MonsterAbilityType::SCARE:
     case MonsterAbilityType::BLIND:
index 8c04987..139cf8d 100644 (file)
@@ -393,3 +393,61 @@ MonsterSpellResult spell_RF5_BA_LITE(PlayerType *player_ptr, POSITION y, POSITIO
 
     return res;
 }
+
+/*!
+ * @brief RF5_BA_VOIDの処理。虚空の嵐。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BA_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+    mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
+        _("%^sが虚空の嵐の呪文を念じた。", "%^s invokes a void storm."),
+        _("%^sが%sに対して虚空の嵐の呪文を念じた。", "%^s invokes a void storm upon %s."));
+
+    monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+    const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_VOID, m_idx, DAM_ROLL);
+    const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::VOID_MAGIC, dam, 4, false, TARGET_TYPE);
+
+    auto res = MonsterSpellResult::make_valid(dam);
+    res.learnable = proj_res.affected_player;
+
+    return res;
+}
+
+/*!
+ * @brief RF5_BA_ABYSSの処理。アビス・ボール。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BA_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+    mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
+        _("%^sが深淵の嵐の呪文を念じた。", "%^s invokes a abyss storm."),
+        _("%^sが%sに対して深淵の嵐の呪文を念じた。", "%^s invokes a void abyss upon %s."));
+
+    monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+    const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ABYSS, m_idx, DAM_ROLL);
+    const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ABYSS, dam, 4, false, TARGET_TYPE);
+    if (TARGET_TYPE == MONSTER_TO_PLAYER)
+        update_smart_learn(player_ptr, m_idx, DRS_DARK);
+
+    auto res = MonsterSpellResult::make_valid(dam);
+    res.learnable = proj_res.affected_player;
+
+    return res;
+}
index 8ab2026..01edaf0 100644 (file)
@@ -17,3 +17,5 @@ MonsterSpellResult spell_RF5_BA_WATE(PlayerType *player_ptr, POSITION y, POSITIO
 MonsterSpellResult spell_RF5_BA_MANA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
 MonsterSpellResult spell_RF5_BA_DARK(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
 MonsterSpellResult spell_RF5_BA_LITE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BA_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BA_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
index 64b15b9..c9f4c20 100644 (file)
@@ -330,6 +330,68 @@ MonsterSpellResult spell_RF5_BO_ICEE(PlayerType *player_ptr, POSITION y, POSITIO
 }
 
 /*!
+ * @brief RF5_BO_VOIDの処理。ヴォイド・ボルト。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BO_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+    mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
+        _("%^sがヴォイド・ボルトの呪文を唱えた。", "%^s casts a void bolt."),
+        _("%^sが%sに向かってヴォイド・ボルトの呪文を唱えた。", "%^s casts a void bolt at %s."));
+
+    monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+    const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BO_VOID, m_idx, DAM_ROLL);
+    const auto proj_res = bolt(player_ptr, m_idx, y, x, AttributeType::VOID_MAGIC, dam, TARGET_TYPE);
+    if (TARGET_TYPE == MONSTER_TO_PLAYER) {
+        update_smart_learn(player_ptr, m_idx, DRS_REFLECT);
+    }
+
+    auto res = MonsterSpellResult::make_valid(dam);
+    res.learnable = proj_res.affected_player;
+
+    return res;
+}
+
+/*!
+ * @brief RF5_BO_ABYSSの処理。アビス・ボルト。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param y 対象の地点のy座標
+ * @param x 対象の地点のx座標
+ * @param m_idx 呪文を唱えるモンスターID
+ * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
+ * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
+ *
+ * プレイヤーに当たったらラーニング可。
+ */
+MonsterSpellResult spell_RF5_BO_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
+{
+    mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
+        _("%^sがアビス・ボルトの呪文を唱えた。", "%^s casts a abyss bolt."),
+        _("%^sが%sに向かってアビス・ボルトの呪文を唱えた。", "%^s casts a abyss bolt at %s."));
+
+    monspell_message(player_ptr, m_idx, t_idx, msg, TARGET_TYPE);
+
+    const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BO_ABYSS, m_idx, DAM_ROLL);
+    const auto proj_res = bolt(player_ptr, m_idx, y, x, AttributeType::ABYSS, dam, TARGET_TYPE);
+    if (TARGET_TYPE == MONSTER_TO_PLAYER) {
+        update_smart_learn(player_ptr, m_idx, DRS_REFLECT);
+    }
+
+    auto res = MonsterSpellResult::make_valid(dam);
+    res.learnable = proj_res.affected_player;
+
+    return res;
+}
+
+/*!
  * @brief RF5_MISSILEの処理。マジック・ミサイル。 /
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param y 対象の地点のy座標
index 36af844..eb13d8e 100644 (file)
@@ -15,4 +15,6 @@ MonsterSpellResult spell_RF5_BO_WATE(PlayerType *player_ptr, POSITION y, POSITIO
 MonsterSpellResult spell_RF5_BO_MANA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
 MonsterSpellResult spell_RF5_BO_PLAS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
 MonsterSpellResult spell_RF5_BO_ICEE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BO_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
+MonsterSpellResult spell_RF5_BO_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
 MonsterSpellResult spell_RF5_MISSILE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE);
index 72e1435..73d3d43 100644 (file)
@@ -183,6 +183,16 @@ MonsterSpellResult spell_RF4_BREATH(PlayerType *player_ptr, AttributeType GF_TYP
         type_s = _("分解", "disintegration");
         smart_learn_aux = false;
         break;
+    case AttributeType::VOID_MAGIC:
+        dam = monspell_damage(player_ptr, MonsterAbilityType::BR_VOID, m_idx, DAM_ROLL);
+        type_s = _("虚空", "void");
+        smart_learn_aux = false;
+        break;
+    case AttributeType::ABYSS:
+        dam = monspell_damage(player_ptr, MonsterAbilityType::BR_ABYSS, m_idx, DAM_ROLL);
+        type_s = _("深淵", "disintegration");
+        smart_learn_aux = false;
+        break;
     default:
         /* Do not reach here */
         dam = 0;
index e2d5558..2ab3256 100644 (file)
@@ -157,6 +157,12 @@ static HIT_POINT monspell_damage_base(
     case MonsterAbilityType::BR_DISI:
         dam = ((hp / 6) > 150 ? 150 : (hp / 6));
         break;
+    case MonsterAbilityType::BR_VOID:
+        dam = ((hp / 3) > 250 ? 250 : (hp / 6));
+        break;
+    case MonsterAbilityType::BR_ABYSS:
+        dam = ((hp / 3) > 250 ? 250 : (hp / 6));
+        break;
     case MonsterAbilityType::BA_ACID:
         if (powerful) {
             dam = (rlev * 4) + 50;
@@ -226,6 +232,16 @@ static HIT_POINT monspell_damage_base(
         dice_num = 10;
         dice_side = 10;
         break;
+    case MonsterAbilityType::BA_VOID:
+        dam = (powerful ? (rlev * 3) : (rlev * 2));
+        dice_num = 10;
+        dice_side = 10;
+        break;
+    case MonsterAbilityType::BA_ABYSS:
+        dam = (powerful ? (rlev * 3) : (rlev * 2));
+        dice_num = 10;
+        dice_side = 10;
+        break;
     case MonsterAbilityType::DRAIN_MANA:
         dam = rlev;
         div = 1;
@@ -310,6 +326,16 @@ static HIT_POINT monspell_damage_base(
         dice_num = 6;
         dice_side = 6;
         break;
+    case MonsterAbilityType::BO_VOID:
+        dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
+        dice_num = 13;
+        dice_side = 14;
+        break;
+    case MonsterAbilityType::BO_ABYSS:
+        dam = 10 + (rlev * 3 / (powerful ? 2 : 3));
+        dice_num = 13;
+        dice_side = 14;
+        break;
     case MonsterAbilityType::MISSILE:
         dam = (rlev / 3);
         dice_num = 2;
index 63970a0..4ca0d4d 100644 (file)
@@ -48,6 +48,8 @@ static bool spell_attack(MonsterAbilityType spell)
     /* All RF4 spells hurt (except for shriek and dispel) */
     if (spell_in_between(spell, MonsterAbilityType::ROCKET, MonsterAbilityType::BR_DISI))
         return true;
+    if (spell_in_between(spell, MonsterAbilityType::BR_VOID, MonsterAbilityType::BR_ABYSS))
+        return true;
 
     /* Various "ball" spells */
     if (spell_in_between(spell, MonsterAbilityType::BA_ACID, MonsterAbilityType::BA_DARK))
@@ -56,6 +58,8 @@ static bool spell_attack(MonsterAbilityType spell)
     /* "Cause wounds" and "bolt" spells */
     if (spell_in_between(spell, MonsterAbilityType::CAUSE_1, MonsterAbilityType::MISSILE))
         return true;
+    if (spell_in_between(spell, MonsterAbilityType::BO_VOID, MonsterAbilityType::BO_ABYSS))
+        return true;
 
     /* Hand of Doom */
     if (spell == MonsterAbilityType::HAND_DOOM)
index 82604ce..14c8e2e 100644 (file)
@@ -396,6 +396,10 @@ bool process_warning(PlayerType *player_ptr, POSITION xx, POSITION yy)
                         spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::HAND_DOOM, AttributeType::HAND_DOOM, g_ptr->m_idx, &dam_max0);
                     if (flags.has(MonsterAbilityType::PSY_SPEAR))
                         spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::PSY_SPEAR, AttributeType::PSY_SPEAR, g_ptr->m_idx, &dam_max0);
+                    if (flags.has(MonsterAbilityType::BA_VOID))
+                        spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_VOID, AttributeType::VOID_MAGIC, g_ptr->m_idx, &dam_max0);
+                    if (flags.has(MonsterAbilityType::BA_ABYSS))
+                        spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BA_ABYSS, AttributeType::ABYSS, g_ptr->m_idx, &dam_max0);
                 }
 
                 if (flags.has(MonsterAbilityType::ROCKET))
@@ -444,6 +448,10 @@ bool process_warning(PlayerType *player_ptr, POSITION xx, POSITION yy)
                     spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_NUKE, AttributeType::NUKE, g_ptr->m_idx, &dam_max0);
                 if (flags.has(MonsterAbilityType::BR_DISI))
                     spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_DISI, AttributeType::DISINTEGRATE, g_ptr->m_idx, &dam_max0);
+                if (flags.has(MonsterAbilityType::BR_VOID))
+                    spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_VOID, AttributeType::VOID_MAGIC, g_ptr->m_idx, &dam_max0);
+                if (flags.has(MonsterAbilityType::BR_ABYSS))
+                    spell_damcalc_by_spellnum(player_ptr, MonsterAbilityType::BR_ABYSS, AttributeType::ABYSS, g_ptr->m_idx, &dam_max0);
             }
 
             /* Monster melee attacks */