OSDN Git Service

[Implement] カオス効果(混沌を呼び起こす)の打撃を追加した
authorSlimebreath6078 <slimebreath6078@yahoo.co.jp>
Fri, 29 Dec 2023 11:51:40 +0000 (20:51 +0900)
committerSlimebreath6078 <slimebreath6078@yahoo.co.jp>
Fri, 29 Dec 2023 11:51:40 +0000 (20:51 +0900)
src/info-reader/race-info-tokens-table.cpp
src/lore/combat-types-setter.cpp
src/melee/melee-switcher.cpp
src/monster-attack/monster-attack-effect.h
src/monster-attack/monster-attack-switcher.cpp

index 513932f..c79a961 100644 (file)
@@ -84,6 +84,7 @@ const std::unordered_map<std::string_view, RaceBlowEffectType> r_info_blow_effec
     { "INERTIA", RaceBlowEffectType::INERTIA },
     { "STUN", RaceBlowEffectType::STUN },
     { "HUNGRY", RaceBlowEffectType::HUNGRY },
+    { "CHAOS", RaceBlowEffectType::CHAOS },
     { "FLAVOR", RaceBlowEffectType::FLAVOR },
 };
 
index d2f7d64..f310bec 100644 (file)
@@ -257,6 +257,10 @@ void set_monster_blow_effect(lore_type *lore_ptr, int m)
         lore_ptr->q = _("空腹を進行させる", "increase hunger");
         lore_ptr->qc = TERM_L_BLUE;
         break;
+    case RaceBlowEffectType::CHAOS:
+        lore_ptr->q = _("カオスを呼び起こす", "call chaotic.");
+        lore_ptr->qc = TERM_VIOLET;
+        break;
     case RaceBlowEffectType::FLAVOR:
         // フレーバー打撃には何の効果もないので付加説明もない。
         break;
index 31edd53..3515ae6 100644 (file)
@@ -6,14 +6,44 @@
 
 #include "melee/melee-switcher.h"
 #include "core/disturbance.h"
+#include "dungeon/quest.h"
 #include "melee/melee-util.h"
 #include "monster-attack/monster-attack-effect.h"
+#include "monster-race/monster-race.h"
+#include "monster-race/race-flags-resistance.h"
+#include "monster-race/race-kind-flags.h"
+#include "monster/monster-info.h"
 #include "monster/monster-status-setter.h"
 #include "spell-kind/earthquake.h"
+#include "spell-kind/spells-polymorph.h"
+#include "spell-kind/spells-teleport.h"
+#include "spell/spells-util.h"
+#include "system/floor-type-definition.h"
 #include "system/monster-entity.h"
+#include "system/monster-race-info.h"
 #include "system/player-type-definition.h"
 #include "view/display-messages.h"
 
+/*!
+ * @brief モンスターがカオス属性へ耐性を示すかどうか
+ */
+static bool monster_has_chaos_resist(PlayerType *player_ptr, MonsterEntity *m_ptr)
+{
+    auto r_info = m_ptr->get_monrace();
+    if (r_info.resistance_flags.has(MonsterResistanceType::RESIST_CHAOS)) {
+        if (is_original_ap_and_seen(player_ptr, m_ptr)) {
+            r_info.r_resistance_flags.set(MonsterResistanceType::RESIST_CHAOS);
+        }
+        return true;
+    } else if (r_info.kind_flags.has(MonsterKindType::DEMON) && one_in_(3)) {
+        if (is_original_ap_and_seen(player_ptr, m_ptr)) {
+            r_info.r_kind_flags.set(MonsterKindType::DEMON);
+        }
+        return true;
+    }
+    return false;
+}
+
 void describe_melee_method(PlayerType *player_ptr, mam_type *mam_ptr)
 {
     switch (mam_ptr->method) {
@@ -244,6 +274,45 @@ void decide_monster_attack_effect(PlayerType *player_ptr, mam_type *mam_ptr)
     case RaceBlowEffectType::HUNGRY:
         mam_ptr->pt = AttributeType::HUNGRY;
         break;
+    case RaceBlowEffectType::CHAOS: {
+        const auto has_resist = monster_has_chaos_resist(player_ptr, mam_ptr->t_ptr);
+        if (has_resist) {
+            mam_ptr->damage *= 3;
+            mam_ptr->damage /= randint1(6) + 6;
+        }
+
+        if (randint1(5) < 3) {
+            mam_ptr->pt = AttributeType::HYPODYNAMIA;
+            mam_ptr->attribute = BlowEffectType::HEAL;
+            break;
+        }
+        if (one_in_(250)) {
+            const auto *floor_ptr = player_ptr->current_floor_ptr;
+            if (floor_ptr->is_in_dungeon() && (!floor_ptr->is_in_quest() || !QuestType::is_fixed(floor_ptr->quest_number))) {
+                msg_print(_("カオスの力でダンジョンが崩れ始める!", "The dungeon tumbles by the chaotic power!"));
+                if (mam_ptr->damage > 23) {
+                    earthquake(player_ptr, mam_ptr->m_ptr->fy, mam_ptr->m_ptr->fx, 8, mam_ptr->m_idx);
+                }
+            }
+        }
+        if (!one_in_(10)) {
+            if (!has_resist) {
+                mam_ptr->pt = AttributeType::CONFUSION;
+            }
+            break;
+        }
+
+        if (!has_resist) {
+            if (one_in_(2)) {
+                msg_format(_(("%s^はどこかへ消えていった!"), ("%s^ disappears!")), mam_ptr->t_name);
+                teleport_away(player_ptr, mam_ptr->t_idx, 50, TELEPORT_PASSIVE);
+            } else {
+                if (polymorph_monster(player_ptr, mam_ptr->t_ptr->fy, mam_ptr->t_ptr->fx)) {
+                    msg_format(_("%s^は変化した!", "%s^ changes!"), mam_ptr->t_name);
+                }
+            }
+        }
+    } break;
     case RaceBlowEffectType::FLAVOR:
         // フレーバー打撃には何の効果もない。
         mam_ptr->pt = AttributeType::NONE;
index 28a410c..ce1ff7b 100644 (file)
@@ -45,6 +45,7 @@ enum class RaceBlowEffectType : int {
     STUN = 35, /*!< モンスターの攻撃効果: 朦朧とさせる*/
     FLAVOR = 36, /*!< モンスターの攻撃効果: フレーバー(メッセージ表示のみ) */
     HUNGRY = 37, /*!< モンスターの攻撃効果: 空腹を進行させる*/
+    CHAOS = 38, /*!< モンスターの攻撃効果: カオスを呼び起こす*/
 
     MAX, /*!< 最大値 */
 };
index b190049..d92569d 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "monster-attack/monster-attack-switcher.h"
+#include "dungeon/quest.h"
 #include "inventory/inventory-slot-types.h"
 #include "mind/drs-types.h"
 #include "mind/mind-mirror-master.h"
 #include "monster-attack/monster-eating.h"
 #include "monster/monster-status.h"
 #include "monster/monster-update.h"
+#include "mutation/mutation-investor-remover.h"
 #include "player/player-damage.h"
 #include "player/player-status-flags.h"
 #include "player/player-status-resist.h"
 #include "player/player-status.h"
 #include "spell-kind/earthquake.h"
 #include "spell-kind/spells-equipment.h"
+#include "spell-kind/spells-teleport.h"
 #include "status/bad-status-setter.h"
 #include "status/base-status.h"
 #include "status/element-resistance.h"
 #include "status/experience.h"
+#include "system/floor-type-definition.h"
 #include "system/item-entity.h"
 #include "system/monster-entity.h"
 #include "system/player-type-definition.h"
@@ -533,6 +537,73 @@ void switch_monster_blow_to_player(PlayerType *player_ptr, MonsterAttackPlayer *
     case RaceBlowEffectType::HUNGRY:
         calc_blow_hungry(player_ptr, monap_ptr);
         break;
+    case RaceBlowEffectType::CHAOS: {
+        update_smart_learn(player_ptr, monap_ptr->m_idx, DRS_CHAOS);
+        monap_ptr->damage = monap_ptr->damage * calc_chaos_damage_rate(player_ptr, CALC_RAND) / 100;
+        monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
+
+        const auto has_chaos_resist = has_resist_chaos(player_ptr);
+
+        if (!has_chaos_resist) {
+            monap_ptr->obvious = true;
+        }
+        if (randint1(5) < 3) {
+            monap_ptr->obvious = true;
+            if (!has_chaos_resist) {
+                if (player_ptr->is_dead || check_multishadow(player_ptr)) {
+                    return;
+                }
+
+                int32_t d = damroll(60, 6) + (player_ptr->exp / 100) * MON_DRAIN_LIFE;
+
+                bool resist_drain = check_drain_hp(player_ptr, d);
+                process_drain_life(player_ptr, monap_ptr, resist_drain);
+            }
+            break;
+        }
+        if (one_in_(250)) {
+            monap_ptr->obvious = true;
+            const auto *floor_ptr = player_ptr->current_floor_ptr;
+            if (floor_ptr->is_in_dungeon() && (!floor_ptr->is_in_quest() || !QuestType::is_fixed(floor_ptr->quest_number))) {
+                msg_print(_("カオスの力でダンジョンが崩れ始める!", "The dungeon tumbles by the chaotic power!"));
+                if (monap_ptr->damage > 23 || monap_ptr->explode) {
+                    earthquake(player_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, 8, monap_ptr->m_idx);
+                    break;
+                }
+            }
+        }
+        if (!one_in_(10)) {
+            if (player_ptr->is_dead) {
+                return;
+            }
+            monap_ptr->obvious = true;
+
+            if (!has_chaos_resist && !has_resist_conf(player_ptr) && !check_multishadow(player_ptr) && BadStatusSetter(player_ptr).mod_confusion(3 + randint1(monap_ptr->rlev))) {
+                monap_ptr->obvious = true;
+            }
+            break;
+        }
+
+        if (one_in_(2)) {
+            if (player_ptr->is_dead) {
+                return;
+            }
+            monap_ptr->obvious = true;
+
+            if (!has_chaos_resist && player_ptr->anti_tele == 0) {
+                msg_print(_("突然体が浮きだした!", "Your body floats suddenly!"));
+                teleport_player(player_ptr, 50, TELEPORT_PASSIVE);
+            }
+        } else if (!has_chaos_resist) {
+            if (player_ptr->is_dead) {
+                return;
+            }
+            monap_ptr->obvious = true;
+
+            msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
+            (void)gain_mutation(player_ptr, 0);
+        }
+    } break;
 
     case RaceBlowEffectType::MAX:
         break;