#include "monster/monster-status.h"
#include "mspell/mspell-attack/mspell-ball.h"
#include "mspell/mspell-attack/mspell-bolt.h"
-#include "mspell/mspell-breath.h"
+#include "mspell/mspell-attack/mspell-breath.h"
#include "mspell/mspell-curse.h"
#include "mspell/mspell-dispel.h"
#include "mspell/mspell-floor.h"
case MonsterAbilityType::XXX2: break; /* RF4_XXX2 */
case MonsterAbilityType::XXX3: break; /* RF4_XXX3 */
case MonsterAbilityType::XXX4: break; /* RF4_XXX4 */
- case MonsterAbilityType::BR_ACID: return spell_RF4_BREATH(player_ptr, AttributeType::ACID, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_ACID */
- case MonsterAbilityType::BR_ELEC: return spell_RF4_BREATH(player_ptr, AttributeType::ELEC, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_ELEC */
- case MonsterAbilityType::BR_FIRE: return spell_RF4_BREATH(player_ptr, AttributeType::FIRE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_FIRE */
- case MonsterAbilityType::BR_COLD: return spell_RF4_BREATH(player_ptr, AttributeType::COLD, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_COLD */
- case MonsterAbilityType::BR_POIS: return spell_RF4_BREATH(player_ptr, AttributeType::POIS, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_POIS */
- case MonsterAbilityType::BR_NETH: return spell_RF4_BREATH(player_ptr, AttributeType::NETHER, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_NETH */
- case MonsterAbilityType::BR_LITE: return spell_RF4_BREATH(player_ptr, AttributeType::LITE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_LITE */
- case MonsterAbilityType::BR_DARK: return spell_RF4_BREATH(player_ptr, AttributeType::DARK, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_DARK */
- case MonsterAbilityType::BR_CONF: return spell_RF4_BREATH(player_ptr, AttributeType::CONFUSION, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_CONF */
- case MonsterAbilityType::BR_SOUN: return spell_RF4_BREATH(player_ptr, AttributeType::SOUND, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_SOUN */
- case MonsterAbilityType::BR_CHAO: return spell_RF4_BREATH(player_ptr, AttributeType::CHAOS, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_CHAO */
- case MonsterAbilityType::BR_DISE: return spell_RF4_BREATH(player_ptr, AttributeType::DISENCHANT, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_DISE */
- case MonsterAbilityType::BR_NEXU: return spell_RF4_BREATH(player_ptr, AttributeType::NEXUS, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_NEXU */
- case MonsterAbilityType::BR_TIME: return spell_RF4_BREATH(player_ptr, AttributeType::TIME, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_TIME */
- case MonsterAbilityType::BR_INER: return spell_RF4_BREATH(player_ptr, AttributeType::INERTIAL, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_INER */
- case MonsterAbilityType::BR_GRAV: return spell_RF4_BREATH(player_ptr, AttributeType::GRAVITY, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_GRAV */
- case MonsterAbilityType::BR_SHAR: return spell_RF4_BREATH(player_ptr, AttributeType::SHARDS, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_SHAR */
- case MonsterAbilityType::BR_PLAS: return spell_RF4_BREATH(player_ptr, AttributeType::PLASMA, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_PLAS */
- case MonsterAbilityType::BR_FORC: return spell_RF4_BREATH(player_ptr, AttributeType::FORCE, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_WALL */
- case MonsterAbilityType::BR_MANA: return spell_RF4_BREATH(player_ptr, AttributeType::MANA, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_MANA */
- 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::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::BR_ACID:
+ case MonsterAbilityType::BR_ELEC:
+ case MonsterAbilityType::BR_FIRE:
+ case MonsterAbilityType::BR_COLD:
+ case MonsterAbilityType::BR_POIS:
+ case MonsterAbilityType::BR_NETH:
+ case MonsterAbilityType::BR_LITE:
+ case MonsterAbilityType::BR_DARK:
+ case MonsterAbilityType::BR_CONF:
+ case MonsterAbilityType::BR_SOUN:
+ case MonsterAbilityType::BR_CHAO:
+ case MonsterAbilityType::BR_DISE:
+ case MonsterAbilityType::BR_NEXU:
+ case MonsterAbilityType::BR_TIME:
+ case MonsterAbilityType::BR_INER:
+ case MonsterAbilityType::BR_GRAV:
+ case MonsterAbilityType::BR_SHAR:
+ case MonsterAbilityType::BR_PLAS:
+ case MonsterAbilityType::BR_FORC:
+ case MonsterAbilityType::BR_MANA:
+ case MonsterAbilityType::BR_NUKE:
+ case MonsterAbilityType::BR_DISI:
+ case MonsterAbilityType::BR_VOID:
+ case MonsterAbilityType::BR_ABYSS:
+ return spell_RF4_BREATH(player_ptr, ms_type, y, x, m_idx, 0, MONSTER_TO_PLAYER); /* RF4_BR_ABYSS */
case MonsterAbilityType::BA_ACID:
case MonsterAbilityType::BA_ELEC:
case MonsterAbilityType::XXX2: break; /* RF4_XXX2 */
case MonsterAbilityType::XXX3: break; /* RF4_XXX3 */
case MonsterAbilityType::XXX4: break; /* RF4_XXX4 */
- case MonsterAbilityType::BR_ACID: return spell_RF4_BREATH(player_ptr, AttributeType::ACID, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_ACID */
- case MonsterAbilityType::BR_ELEC: return spell_RF4_BREATH(player_ptr, AttributeType::ELEC, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_ELEC */
- case MonsterAbilityType::BR_FIRE: return spell_RF4_BREATH(player_ptr, AttributeType::FIRE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_FIRE */
- case MonsterAbilityType::BR_COLD: return spell_RF4_BREATH(player_ptr, AttributeType::COLD, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_COLD */
- case MonsterAbilityType::BR_POIS: return spell_RF4_BREATH(player_ptr, AttributeType::POIS, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_POIS */
- case MonsterAbilityType::BR_NETH: return spell_RF4_BREATH(player_ptr, AttributeType::NETHER, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_NETH */
- case MonsterAbilityType::BR_LITE: return spell_RF4_BREATH(player_ptr, AttributeType::LITE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_LITE */
- case MonsterAbilityType::BR_DARK: return spell_RF4_BREATH(player_ptr, AttributeType::DARK, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_DARK */
- case MonsterAbilityType::BR_CONF: return spell_RF4_BREATH(player_ptr, AttributeType::CONFUSION, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_CONF */
- case MonsterAbilityType::BR_SOUN: return spell_RF4_BREATH(player_ptr, AttributeType::SOUND, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_SOUN */
- case MonsterAbilityType::BR_CHAO: return spell_RF4_BREATH(player_ptr, AttributeType::CHAOS, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_CHAO */
- case MonsterAbilityType::BR_DISE: return spell_RF4_BREATH(player_ptr, AttributeType::DISENCHANT, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_DISE */
- case MonsterAbilityType::BR_NEXU: return spell_RF4_BREATH(player_ptr, AttributeType::NEXUS, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_NEXU */
- case MonsterAbilityType::BR_TIME: return spell_RF4_BREATH(player_ptr, AttributeType::TIME, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_TIME */
- case MonsterAbilityType::BR_INER: return spell_RF4_BREATH(player_ptr, AttributeType::INERTIAL, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_INER */
- case MonsterAbilityType::BR_GRAV: return spell_RF4_BREATH(player_ptr, AttributeType::GRAVITY, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_GRAV */
- case MonsterAbilityType::BR_SHAR: return spell_RF4_BREATH(player_ptr, AttributeType::SHARDS, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_SHAR */
- case MonsterAbilityType::BR_PLAS: return spell_RF4_BREATH(player_ptr, AttributeType::PLASMA, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_PLAS */
- case MonsterAbilityType::BR_FORC: return spell_RF4_BREATH(player_ptr, AttributeType::FORCE, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_WALL */
- case MonsterAbilityType::BR_MANA: return spell_RF4_BREATH(player_ptr, AttributeType::MANA, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_MANA */
- 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::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::BR_ACID:
+ case MonsterAbilityType::BR_ELEC:
+ case MonsterAbilityType::BR_FIRE:
+ case MonsterAbilityType::BR_COLD:
+ case MonsterAbilityType::BR_POIS:
+ case MonsterAbilityType::BR_NETH:
+ case MonsterAbilityType::BR_LITE:
+ case MonsterAbilityType::BR_DARK:
+ case MonsterAbilityType::BR_CONF:
+ case MonsterAbilityType::BR_SOUN:
+ case MonsterAbilityType::BR_CHAO:
+ case MonsterAbilityType::BR_DISE:
+ case MonsterAbilityType::BR_NEXU:
+ case MonsterAbilityType::BR_TIME:
+ case MonsterAbilityType::BR_INER:
+ case MonsterAbilityType::BR_GRAV:
+ case MonsterAbilityType::BR_SHAR:
+ case MonsterAbilityType::BR_PLAS:
+ case MonsterAbilityType::BR_FORC:
+ case MonsterAbilityType::BR_MANA:
+ case MonsterAbilityType::BR_NUKE:
+ case MonsterAbilityType::BR_DISI:
+ case MonsterAbilityType::BR_VOID:
+ case MonsterAbilityType::BR_ABYSS:
+ return spell_RF4_BREATH(player_ptr, ms_type, y, x, m_idx, t_idx, MONSTER_TO_MONSTER); /* RF4_BR_ABYSS */
case MonsterAbilityType::BA_ACID:
case MonsterAbilityType::BA_ELEC:
-#include "mspell/mspell-breath.h"
+#include "mspell/mspell-attack/mspell-breath.h"
#include "core/disturbance.h"
#include "effect/attribute-types.h"
#include "effect/effect-processor.h"
#include "monster/monster-update.h"
#include "mspell/mspell-checker.h"
#include "mspell/mspell-damage-calculator.h"
+#include "mspell/mspell-data.h"
#include "mspell/mspell-result.h"
#include "mspell/mspell-util.h"
#include "system/floor-type-definition.h"
return false;
}
-/*!
- * @brief RF4_BR_*の処理。各種ブレス。 /
- * @param player_ptr プレイヤーへの参照ポインタ
- * @param GF_TYPE ブレスの属性
- * @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_RF4_BREATH(PlayerType *player_ptr, AttributeType GF_TYPE, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
+static void message_breath(PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type, std::string_view type_s, AttributeType GF_TYPE)
{
- int dam, drs_type = 0;
- concptr type_s;
- bool smart_learn_aux = true;
auto *floor_ptr = player_ptr->current_floor_ptr;
auto *m_ptr = &floor_ptr->m_list[m_idx];
- bool known = monster_near_player(floor_ptr, m_idx, t_idx);
- bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
- bool mon_to_mon = (target_type == MONSTER_TO_MONSTER);
- bool mon_to_player = (target_type == MONSTER_TO_PLAYER);
+ auto see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
+ auto known = monster_near_player(floor_ptr, m_idx, t_idx);
+ auto mon_to_mon = (target_type == MONSTER_TO_MONSTER);
+ auto mon_to_player = (target_type == MONSTER_TO_PLAYER);
GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
monster_name(player_ptr, m_idx, m_name);
monster_name(player_ptr, t_idx, t_name);
- switch (GF_TYPE) {
- case AttributeType::ACID:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_ACID, m_idx, DAM_ROLL);
- type_s = _("酸", "acid");
- drs_type = DRS_ACID;
- break;
- case AttributeType::ELEC:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_ELEC, m_idx, DAM_ROLL);
- type_s = _("稲妻", "lightning");
- drs_type = DRS_ELEC;
- break;
- case AttributeType::FIRE:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_FIRE, m_idx, DAM_ROLL);
- type_s = _("火炎", "fire");
- drs_type = DRS_FIRE;
- break;
- case AttributeType::COLD:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_COLD, m_idx, DAM_ROLL);
- type_s = _("冷気", "frost");
- drs_type = DRS_COLD;
- break;
- case AttributeType::POIS:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_POIS, m_idx, DAM_ROLL);
- type_s = _("ガス", "gas");
- drs_type = DRS_POIS;
- break;
- case AttributeType::NETHER:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_NETH, m_idx, DAM_ROLL);
- type_s = _("地獄", "nether");
- drs_type = DRS_NETH;
- break;
- case AttributeType::LITE:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_LITE, m_idx, DAM_ROLL);
- type_s = _("閃光", "light");
- drs_type = DRS_LITE;
- break;
- case AttributeType::DARK:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_DARK, m_idx, DAM_ROLL);
- type_s = _("暗黒", "darkness");
- drs_type = DRS_DARK;
- break;
- case AttributeType::CONFUSION:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_CONF, m_idx, DAM_ROLL);
- type_s = _("混乱", "confusion");
- drs_type = DRS_CONF;
- break;
- case AttributeType::SOUND:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_SOUN, m_idx, DAM_ROLL);
- type_s = _("轟音", "sound");
- drs_type = DRS_SOUND;
- break;
- case AttributeType::CHAOS:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_CHAO, m_idx, DAM_ROLL);
- type_s = _("カオス", "chaos");
- drs_type = DRS_CHAOS;
- break;
- case AttributeType::DISENCHANT:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_DISE, m_idx, DAM_ROLL);
- type_s = _("劣化", "disenchantment");
- drs_type = DRS_DISEN;
- break;
- case AttributeType::NEXUS:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_NEXU, m_idx, DAM_ROLL);
- type_s = _("因果混乱", "nexus");
- drs_type = DRS_NEXUS;
- break;
- case AttributeType::TIME:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_TIME, m_idx, DAM_ROLL);
- type_s = _("時間逆転", "time");
- smart_learn_aux = false;
- break;
- case AttributeType::INERTIAL:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_INER, m_idx, DAM_ROLL);
- type_s = _("遅鈍", "inertia");
- smart_learn_aux = false;
- break;
- case AttributeType::GRAVITY:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_GRAV, m_idx, DAM_ROLL);
- type_s = _("重力", "gravity");
- smart_learn_aux = false;
- break;
- case AttributeType::SHARDS:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_SHAR, m_idx, DAM_ROLL);
- type_s = _("破片", "shards");
- drs_type = DRS_SHARD;
- break;
- case AttributeType::PLASMA:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_PLAS, m_idx, DAM_ROLL);
- type_s = _("プラズマ", "plasma");
- smart_learn_aux = false;
- break;
- case AttributeType::FORCE:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_FORC, m_idx, DAM_ROLL);
- type_s = _("フォース", "force");
- smart_learn_aux = false;
- break;
- case AttributeType::MANA:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_MANA, m_idx, DAM_ROLL);
- type_s = _("魔力", "mana");
- smart_learn_aux = false;
- break;
- case AttributeType::NUKE:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_NUKE, m_idx, DAM_ROLL);
- type_s = _("放射性廃棄物", "toxic waste");
- drs_type = DRS_POIS;
- break;
- case AttributeType::DISINTEGRATE:
- dam = monspell_damage(player_ptr, MonsterAbilityType::BR_DISI, m_idx, DAM_ROLL);
- 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;
- type_s = _("不明", "Unknown");
- smart_learn_aux = false;
- break;
- }
-
- if (mon_to_player || (mon_to_mon && known && see_either)) {
- disturb(player_ptr, true, true);
- }
-
if (!spell_RF4_BREATH_special_message(m_ptr->r_idx, GF_TYPE, m_name)) {
if (player_ptr->blind) {
if (mon_to_player || (mon_to_mon && known && see_either)) {
}
} else {
if (mon_to_player) {
- msg_format(_("%^sが%^sのブレスを吐いた。", "%^s breathes %^s."), m_name, type_s);
+ msg_format(_("%^sが%^sのブレスを吐いた。", "%^s breathes %^s."), m_name, type_s.data());
} else if (mon_to_mon && known && see_either) {
- _(msg_format("%^sが%^sに%^sのブレスを吐いた。", m_name, t_name, type_s), msg_format("%^s breathes %^s at %^s.", m_name, type_s, t_name));
+ _(msg_format("%^sが%^sに%^sのブレスを吐いた。", m_name, t_name, type_s.data()), msg_format("%^s breathes %^s at %^s.", m_name, type_s.data(), t_name));
}
}
}
if (known || see_either) {
sound(SOUND_BREATH);
}
+}
+
+static std::pair<MonsterAbilityType, MSpellData> make_breath_elemental(MonsterAbilityType ms_type, AttributeType GF_TYPE, std::string_view type_s)
+{
+ return { ms_type, { [type_s, GF_TYPE](auto *player_ptr, auto m_idx, auto t_idx, int target_type) {
+ message_breath(player_ptr, m_idx, t_idx, target_type, type_s, GF_TYPE);
+ return false;
+ },
+ GF_TYPE } };
+};
+
+static std::pair<MonsterAbilityType, MSpellData> make_breath_elemental(MonsterAbilityType ms_type, AttributeType GF_TYPE, std::string_view type_s, MSpellDrsData drs)
+{
+ return { ms_type, { [type_s, GF_TYPE](auto *player_ptr, auto m_idx, auto t_idx, int target_type) {
+ message_breath(player_ptr, m_idx, t_idx, target_type, type_s, GF_TYPE);
+ return false;
+ },
+ GF_TYPE, drs } };
+};
+
+const std::unordered_map<MonsterAbilityType, MSpellData> breath_list = {
+ make_breath_elemental(MonsterAbilityType::BR_ACID, AttributeType::ACID, _("酸", "acid"), DRS_ACID),
+ make_breath_elemental(MonsterAbilityType::BR_ELEC, AttributeType::ELEC, _("稲妻", "lightning"), DRS_ELEC),
+ make_breath_elemental(MonsterAbilityType::BR_FIRE, AttributeType::FIRE, _("火炎", "fire"), DRS_FIRE),
+ make_breath_elemental(MonsterAbilityType::BR_COLD, AttributeType::COLD, _("冷気", "frost"), DRS_COLD),
+ make_breath_elemental(MonsterAbilityType::BR_POIS, AttributeType::POIS, _("ガス", "gas"), DRS_POIS),
+ make_breath_elemental(MonsterAbilityType::BR_NETH, AttributeType::NETHER, _("地獄", "nether"), DRS_NETH),
+ make_breath_elemental(MonsterAbilityType::BR_LITE, AttributeType::LITE, _("閃光", "light"), DRS_LITE),
+ make_breath_elemental(MonsterAbilityType::BR_DARK, AttributeType::DARK, _("暗黒", "darkness"), DRS_DARK),
+ make_breath_elemental(MonsterAbilityType::BR_CONF, AttributeType::CONFUSION, _("混乱", "confusion"), DRS_CONF),
+ make_breath_elemental(MonsterAbilityType::BR_SOUN, AttributeType::SOUND, _("轟音", "sound"), DRS_SOUND),
+ make_breath_elemental(MonsterAbilityType::BR_CHAO, AttributeType::CHAOS, _("カオス", "chaos"), DRS_CHAOS),
+ make_breath_elemental(MonsterAbilityType::BR_DISE, AttributeType::DISENCHANT, _("劣化", "disenchantment"), DRS_DISEN),
+ make_breath_elemental(MonsterAbilityType::BR_NEXU, AttributeType::NEXUS, _("因果混乱", "nexus"), DRS_NEXUS),
+ make_breath_elemental(MonsterAbilityType::BR_TIME, AttributeType::TIME, _("時間逆転", "time")),
+ make_breath_elemental(MonsterAbilityType::BR_INER, AttributeType::INERTIAL, _("遅鈍", "inertia")),
+ make_breath_elemental(MonsterAbilityType::BR_SHAR, AttributeType::SHARDS, _("破片", "shards"), DRS_SHARD),
+ make_breath_elemental(MonsterAbilityType::BR_PLAS, AttributeType::PLASMA, _("プラズマ", "plasma")),
+ make_breath_elemental(MonsterAbilityType::BR_FORC, AttributeType::FORCE, _("フォース", "force")),
+ make_breath_elemental(MonsterAbilityType::BR_MANA, AttributeType::MANA, _("魔力", "mana")),
+ make_breath_elemental(MonsterAbilityType::BR_NUKE, AttributeType::NUKE, _("放射性廃棄物", "toxic waste"), DRS_POIS),
+ make_breath_elemental(MonsterAbilityType::BR_DISE, AttributeType::DISINTEGRATE, _("分解", "disintegration")),
+ make_breath_elemental(MonsterAbilityType::BR_VOID, AttributeType::VOID_MAGIC, _("虚無", "void")),
+ make_breath_elemental(MonsterAbilityType::BR_ABYSS, AttributeType::ABYSS, _("深淵", "abyss")),
+};
+
+/*!
+ * @brief RF4_BR_*の処理。各種ブレス。 /
+ * @param player_ptr プレイヤーへの参照ポインタ
+ * @param GF_TYPE ブレスの属性
+ * @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_RF4_BREATH(PlayerType *player_ptr, MonsterAbilityType ms_type, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
+{
+ auto dam = 0;
+ auto mon_to_player = (target_type == MONSTER_TO_PLAYER);
+ std::unique_ptr<MSpellData> data;
+
+ if (breath_list.find(ms_type) != breath_list.end()) {
+ dam = monspell_damage(player_ptr, ms_type, m_idx, DAM_ROLL);
+ data = std::make_unique<MSpellData>(breath_list.at(ms_type));
+ } else {
+ dam = 0;
+ data = std::make_unique<MSpellData>([](auto *player_ptr, auto m_idx, auto t_idx, int target_type) {
+ message_breath(player_ptr, m_idx, t_idx, target_type, _("不明", "Unknown"), AttributeType::NONE);
+ return false;
+ },
+ AttributeType::NONE);
+ }
+
+ data->msg.output(player_ptr, m_idx, t_idx, target_type);
+
+ const auto proj_res = breath(player_ptr, y, x, m_idx, data->type, dam, 0, target_type);
- const auto proj_res = breath(player_ptr, y, x, m_idx, GF_TYPE, dam, 0, target_type);
- if (smart_learn_aux && mon_to_player) {
- update_smart_learn(player_ptr, m_idx, drs_type);
+ if (mon_to_player) {
+ data->drs.execute(player_ptr, m_idx);
}
auto res = MonsterSpellResult::make_valid(dam);