OSDN Git Service

[Implement] 強力に呪われているとき、恐怖/狂戦士化の呪いを強化する
[hengbandforosx/hengbandosx.git] / src / inventory / inventory-curse.cpp
index 81816c3..2502efc 100644 (file)
 #include "object-enchant/trc-types.h"
 #include "object/object-flags.h"
 #include "perception/object-perception.h"
+#include "player-info/race-types.h"
 #include "player/player-damage.h"
-#include "player/player-race-types.h"
 #include "player/player-status-flags.h"
+#include "player/player-status.h"
 #include "spell-kind/spells-random.h"
 #include "spell-kind/spells-teleport.h"
 #include "spell/summon-types.h"
 #include "status/bad-status-setter.h"
+#include "status/buff-setter.h"
 #include "system/floor-type-definition.h"
+#include "system/object-type-definition.h"
+#include "system/player-type-definition.h"
 #include "util/bit-flags-calculator.h"
 #include "util/quarks.h"
 #include "util/string-processor.h"
 #include "view/display-messages.h"
 
-#define TRC_P_FLAG_MASK                                                                                                                                        \
-    (TRC_TELEPORT_SELF | TRC_CHAINSWORD | TRC_TY_CURSE | TRC_DRAIN_EXP | TRC_ADD_L_CURSE | TRC_ADD_H_CURSE | TRC_CALL_ANIMAL | TRC_CALL_DEMON                  \
-        | TRC_CALL_DRAGON | TRC_COWARDICE | TRC_TELEPORT | TRC_DRAIN_HP | TRC_DRAIN_MANA | TRC_CALL_UNDEAD)
+namespace {
+const EnumClassFlagGroup<CurseTraitType> TRC_P_FLAG_MASK({ CurseTraitType::TY_CURSE, CurseTraitType::DRAIN_EXP, CurseTraitType::ADD_L_CURSE, CurseTraitType::ADD_H_CURSE, CurseTraitType::CALL_ANIMAL, CurseTraitType::CALL_DEMON,
+    CurseTraitType::CALL_DRAGON, CurseTraitType::COWARDICE, CurseTraitType::TELEPORT, CurseTraitType::DRAIN_HP, CurseTraitType::DRAIN_MANA, CurseTraitType::CALL_UNDEAD, CurseTraitType::BERS_RAGE });
+const EnumClassFlagGroup<CurseSpecialTraitType> TRCS_P_FLAG_MASK({ CurseSpecialTraitType::TELEPORT_SELF, CurseSpecialTraitType::CHAINSWORD });
+}
 
-static bool is_specific_curse(BIT_FLAGS flag)
+static bool is_specific_curse(CurseTraitType flag)
 {
-    return (flag == TRC_ADD_L_CURSE) || (flag == TRC_ADD_H_CURSE) || (flag == TRC_DRAIN_HP) || (flag == TRC_DRAIN_MANA) || (flag == TRC_CALL_ANIMAL)
-        || (flag == TRC_CALL_DEMON) || (flag == TRC_CALL_DRAGON) || (flag == TRC_CALL_UNDEAD) || (flag == TRC_COWARDICE) || (flag == TRC_LOW_MELEE)
-        || (flag == TRC_LOW_AC) || (flag == TRC_HARD_SPELL) || (flag == TRC_FAST_DIGEST) || (flag == TRC_SLOW_REGEN);
+    switch (flag) {
+    case CurseTraitType::ADD_L_CURSE:
+    case CurseTraitType::ADD_H_CURSE:
+    case CurseTraitType::DRAIN_HP:
+    case CurseTraitType::DRAIN_MANA:
+    case CurseTraitType::CALL_ANIMAL:
+    case CurseTraitType::CALL_DEMON:
+    case CurseTraitType::CALL_DRAGON:
+    case CurseTraitType::CALL_UNDEAD:
+    case CurseTraitType::COWARDICE:
+    case CurseTraitType::LOW_MELEE:
+    case CurseTraitType::LOW_AC:
+    case CurseTraitType::HARD_SPELL:
+    case CurseTraitType::FAST_DIGEST:
+    case CurseTraitType::SLOW_REGEN:
+    case CurseTraitType::BERS_RAGE:
+        return true;
+    default:
+        return false;
+    }
 }
 
-static void choise_cursed_item(player_type *creature_ptr, BIT_FLAGS flag, object_type *o_ptr, int *choices, int *number, int item_num)
+static void choise_cursed_item(CurseTraitType flag, object_type *o_ptr, int *choices, int *number, int item_num)
 {
     if (!is_specific_curse(flag))
         return;
 
     tr_type cf = TR_STR;
-    BIT_FLAGS flgs[TR_FLAG_SIZE];
-    object_flags(creature_ptr, o_ptr, flgs);
+    auto flgs = object_flags(o_ptr);
     switch (flag) {
-    case TRC_ADD_L_CURSE:
+    case CurseTraitType::ADD_L_CURSE:
         cf = TR_ADD_L_CURSE;
         break;
-    case TRC_ADD_H_CURSE:
+    case CurseTraitType::ADD_H_CURSE:
         cf = TR_ADD_H_CURSE;
         break;
-    case TRC_DRAIN_HP:
+    case CurseTraitType::DRAIN_HP:
         cf = TR_DRAIN_HP;
         break;
-    case TRC_DRAIN_MANA:
+    case CurseTraitType::DRAIN_MANA:
         cf = TR_DRAIN_MANA;
         break;
-    case TRC_CALL_ANIMAL:
+    case CurseTraitType::CALL_ANIMAL:
         cf = TR_CALL_ANIMAL;
         break;
-    case TRC_CALL_DEMON:
+    case CurseTraitType::CALL_DEMON:
         cf = TR_CALL_DEMON;
         break;
-    case TRC_CALL_DRAGON:
+    case CurseTraitType::CALL_DRAGON:
         cf = TR_CALL_DRAGON;
         break;
-    case TRC_CALL_UNDEAD:
+    case CurseTraitType::CALL_UNDEAD:
         cf = TR_CALL_UNDEAD;
         break;
-    case TRC_COWARDICE:
+    case CurseTraitType::COWARDICE:
         cf = TR_COWARDICE;
         break;
-    case TRC_LOW_MELEE:
+    case CurseTraitType::LOW_MELEE:
         cf = TR_LOW_MELEE;
         break;
-    case TRC_LOW_AC:
+    case CurseTraitType::LOW_AC:
         cf = TR_LOW_AC;
         break;
-    case TRC_HARD_SPELL:
+    case CurseTraitType::HARD_SPELL:
         cf = TR_HARD_SPELL;
         break;
-    case TRC_FAST_DIGEST:
+    case CurseTraitType::FAST_DIGEST:
         cf = TR_FAST_DIGEST;
         break;
-    case TRC_SLOW_REGEN:
+    case CurseTraitType::SLOW_REGEN:
         cf = TR_SLOW_REGEN;
         break;
+    case CurseTraitType::BERS_RAGE:
+        cf = TR_BERS_RAGE;
+        break;
     default:
         break;
     }
 
-    if (!has_flag(flgs, (long)cf))
+    if (flgs.has_not(cf))
         return;
 
     choices[*number] = item_num;
@@ -107,51 +132,49 @@ static void choise_cursed_item(player_type *creature_ptr, BIT_FLAGS flag, object
  * @brief 現在呪いを保持している装備品を一つランダムに探し出す / Choose one of items that have cursed flag
  * @param flag 探し出したい呪いフラグ配列
  * @return 該当の呪いが一つでもあった場合にランダムに選ばれた装備品のオブジェクト構造体参照ポインタを返す。\n
- * 呪いがない場合NULLを返す。
+ * 呪いがない場合nullptrを返す。
  */
-object_type *choose_cursed_obj_name(player_type *creature_ptr, BIT_FLAGS flag)
+object_type *choose_cursed_obj_name(PlayerType *player_ptr, CurseTraitType flag)
 {
     int choices[INVEN_TOTAL - INVEN_MAIN_HAND];
     int number = 0;
-    if (!(creature_ptr->cursed & flag))
-        return NULL;
+    if (player_ptr->cursed.has_not(flag))
+        return nullptr;
 
     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
-        object_type *o_ptr = &creature_ptr->inventory_list[i];
-        if (o_ptr->curse_flags & flag) {
+        object_type *o_ptr = &player_ptr->inventory_list[i];
+        if (o_ptr->curse_flags.has(flag)) {
             choices[number] = i;
             number++;
             continue;
         }
 
-        choise_cursed_item(creature_ptr, flag, o_ptr, choices, &number, i);
+        choise_cursed_item(flag, o_ptr, choices, &number, i);
     }
 
-    return &creature_ptr->inventory_list[choices[randint0(number)]];
+    return &player_ptr->inventory_list[choices[randint0(number)]];
 }
 
 /*!
  * @brief 呪われている、トランプエゴ等による装備品由来のテレポートを実行する
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @return なし
+ * @param player_ptr プレイヤーへの参照ポインタ
  */
-static void curse_teleport(player_type *creature_ptr)
+static void curse_teleport(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_TELEPORT_SELF) == 0) || !one_in_(200))
+    if ((player_ptr->cursed_special.has_not(CurseSpecialTraitType::TELEPORT_SELF)) || !one_in_(200))
         return;
 
     GAME_TEXT o_name[MAX_NLEN];
     object_type *o_ptr;
     int i_keep = 0, count = 0;
     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
-        BIT_FLAGS flgs[TR_FLAG_SIZE];
-        o_ptr = &creature_ptr->inventory_list[i];
+        o_ptr = &player_ptr->inventory_list[i];
         if (!o_ptr->k_idx)
             continue;
 
-        object_flags(creature_ptr, o_ptr, flgs);
+        auto flgs = object_flags(o_ptr);
 
-        if (!has_flag(flgs, TR_TELEPORT))
+        if (flgs.has_not(TR_TELEPORT))
             continue;
 
         if (o_ptr->inscription && angband_strchr(quark_str(o_ptr->inscription), '.'))
@@ -162,215 +185,258 @@ static void curse_teleport(player_type *creature_ptr)
             i_keep = i;
     }
 
-    o_ptr = &creature_ptr->inventory_list[i_keep];
-    describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+    o_ptr = &player_ptr->inventory_list[i_keep];
+    describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
     msg_format(_("%sがテレポートの能力を発動させようとしている。", "Your %s tries to teleport you."), o_name);
-    if (get_check_strict(creature_ptr, _("テレポートしますか?", "Teleport? "), CHECK_OKAY_CANCEL)) {
-        disturb(creature_ptr, FALSE, TRUE);
-        teleport_player(creature_ptr, 50, TELEPORT_SPONTANEOUS);
+    if (get_check_strict(player_ptr, _("テレポートしますか?", "Teleport? "), CHECK_OKAY_CANCEL)) {
+        disturb(player_ptr, false, true);
+        teleport_player(player_ptr, 50, TELEPORT_SPONTANEOUS);
     } else {
         msg_format(_("%sに{.}(ピリオド)と銘を刻むと発動を抑制できます。", "You can inscribe {.} on your %s to disable random teleportation. "), o_name);
-        disturb(creature_ptr, TRUE, TRUE);
+        disturb(player_ptr, true, true);
     }
 }
 
 /*!
  * @details 元々呪い効果の発揮ルーチン中にいたので、整合性保持のためここに置いておく
  */
-static void occur_chainsword_effect(player_type *creature_ptr)
+static void occur_chainsword_effect(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_CHAINSWORD) == 0) || !one_in_(CHAINSWORD_NOISE))
+    if ((player_ptr->cursed_special.has_not(CurseSpecialTraitType::CHAINSWORD)) || !one_in_(CHAINSWORD_NOISE))
         return;
 
     char noise[1024];
     if (!get_rnd_line(_("chainswd_j.txt", "chainswd.txt"), 0, noise))
         msg_print(noise);
-    disturb(creature_ptr, FALSE, FALSE);
+    disturb(player_ptr, false, false);
 }
 
-static void curse_drain_exp(player_type *creature_ptr)
+static void curse_drain_exp(PlayerType *player_ptr)
 {
-    if ((creature_ptr->prace == RACE_ANDROID) || ((creature_ptr->cursed & TRC_DRAIN_EXP) == 0) || !one_in_(4))
+    if ((player_ptr->prace == PlayerRaceType::ANDROID) || (player_ptr->cursed.has_not(CurseTraitType::DRAIN_EXP)) || !one_in_(4))
         return;
 
-    creature_ptr->exp -= (creature_ptr->lev + 1) / 2;
-    if (creature_ptr->exp < 0)
-        creature_ptr->exp = 0;
+    player_ptr->exp -= (player_ptr->lev + 1) / 2;
+    if (player_ptr->exp < 0)
+        player_ptr->exp = 0;
 
-    creature_ptr->max_exp -= (creature_ptr->lev + 1) / 2;
-    if (creature_ptr->max_exp < 0)
-        creature_ptr->max_exp = 0;
+    player_ptr->max_exp -= (player_ptr->lev + 1) / 2;
+    if (player_ptr->max_exp < 0)
+        player_ptr->max_exp = 0;
 
-    check_experience(creature_ptr);
+    check_experience(player_ptr);
 }
 
-static void multiply_low_curse(player_type *creature_ptr)
+static void multiply_low_curse(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_ADD_L_CURSE) == 0) || !one_in_(2000))
+    if ((player_ptr->cursed.has_not(CurseTraitType::ADD_L_CURSE)) || !one_in_(2000))
         return;
 
     object_type *o_ptr;
-    o_ptr = choose_cursed_obj_name(creature_ptr, TRC_ADD_L_CURSE);
-    BIT_FLAGS new_curse = get_curse(creature_ptr, 0, o_ptr);
-    if ((o_ptr->curse_flags & new_curse))
+    o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::ADD_L_CURSE);
+    auto new_curse = get_curse(0, o_ptr);
+    if (o_ptr->curse_flags.has(new_curse))
         return;
 
     GAME_TEXT o_name[MAX_NLEN];
-    describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
-    o_ptr->curse_flags |= new_curse;
+    describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+    o_ptr->curse_flags.set(new_curse);
     msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding your %s..."), o_name);
     o_ptr->feeling = FEEL_NONE;
-    creature_ptr->update |= (PU_BONUS);
+    player_ptr->update |= (PU_BONUS);
 }
 
-static void multiply_high_curse(player_type *creature_ptr)
+static void multiply_high_curse(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_ADD_H_CURSE) == 0) || !one_in_(2000))
+    if ((player_ptr->cursed.has_not(CurseTraitType::ADD_H_CURSE)) || !one_in_(2000))
         return;
 
     object_type *o_ptr;
-    o_ptr = choose_cursed_obj_name(creature_ptr, TRC_ADD_H_CURSE);
-    BIT_FLAGS new_curse = get_curse(creature_ptr, 1, o_ptr);
-    if ((o_ptr->curse_flags & new_curse))
+    o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::ADD_H_CURSE);
+    auto new_curse = get_curse(1, o_ptr);
+    if (o_ptr->curse_flags.has(new_curse))
         return;
 
     GAME_TEXT o_name[MAX_NLEN];
-    describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
-    o_ptr->curse_flags |= new_curse;
+    describe_flavor(player_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
+    o_ptr->curse_flags.set(new_curse);
     msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding your %s..."), o_name);
     o_ptr->feeling = FEEL_NONE;
-    creature_ptr->update |= (PU_BONUS);
+    player_ptr->update |= (PU_BONUS);
 }
 
-static void curse_call_monster(player_type *creature_ptr)
+static void curse_call_monster(PlayerType *player_ptr)
 {
     const int call_type = PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET;
     const int obj_desc_type = OD_OMIT_PREFIX | OD_NAME_ONLY;
-    floor_type *floor_ptr = creature_ptr->current_floor_ptr;
-    if ((creature_ptr->cursed & TRC_CALL_ANIMAL) && one_in_(2500)) {
-        if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, floor_ptr->dun_level, SUMMON_ANIMAL, call_type)) {
+    floor_type *floor_ptr = player_ptr->current_floor_ptr;
+    if (player_ptr->cursed.has(CurseTraitType::CALL_ANIMAL) && one_in_(2500)) {
+        if (summon_specific(player_ptr, 0, player_ptr->y, player_ptr->x, floor_ptr->dun_level, SUMMON_ANIMAL, call_type)) {
             GAME_TEXT o_name[MAX_NLEN];
-            describe_flavor(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_ANIMAL), obj_desc_type);
+            describe_flavor(player_ptr, o_name, choose_cursed_obj_name(player_ptr, CurseTraitType::CALL_ANIMAL), obj_desc_type);
             msg_format(_("%sが動物を引き寄せた!", "Your %s has attracted an animal!"), o_name);
-            disturb(creature_ptr, FALSE, TRUE);
+            disturb(player_ptr, false, true);
         }
     }
 
-    if ((creature_ptr->cursed & TRC_CALL_DEMON) && one_in_(1111)) {
-        if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, floor_ptr->dun_level, SUMMON_DEMON, call_type)) {
+    if (player_ptr->cursed.has(CurseTraitType::CALL_DEMON) && one_in_(1111)) {
+        if (summon_specific(player_ptr, 0, player_ptr->y, player_ptr->x, floor_ptr->dun_level, SUMMON_DEMON, call_type)) {
             GAME_TEXT o_name[MAX_NLEN];
-            describe_flavor(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_DEMON), obj_desc_type);
+            describe_flavor(player_ptr, o_name, choose_cursed_obj_name(player_ptr, CurseTraitType::CALL_DEMON), obj_desc_type);
             msg_format(_("%sが悪魔を引き寄せた!", "Your %s has attracted a demon!"), o_name);
-            disturb(creature_ptr, FALSE, TRUE);
+            disturb(player_ptr, false, true);
         }
     }
 
-    if ((creature_ptr->cursed & TRC_CALL_DRAGON) && one_in_(800)) {
-        if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, floor_ptr->dun_level, SUMMON_DRAGON, call_type)) {
+    if (player_ptr->cursed.has(CurseTraitType::CALL_DRAGON) && one_in_(800)) {
+        if (summon_specific(player_ptr, 0, player_ptr->y, player_ptr->x, floor_ptr->dun_level, SUMMON_DRAGON, call_type)) {
             GAME_TEXT o_name[MAX_NLEN];
-            describe_flavor(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_DRAGON), obj_desc_type);
+            describe_flavor(player_ptr, o_name, choose_cursed_obj_name(player_ptr, CurseTraitType::CALL_DRAGON), obj_desc_type);
             msg_format(_("%sがドラゴンを引き寄せた!", "Your %s has attracted a dragon!"), o_name);
-            disturb(creature_ptr, FALSE, TRUE);
+            disturb(player_ptr, false, true);
         }
     }
 
-    if ((creature_ptr->cursed & TRC_CALL_UNDEAD) && one_in_(1111)) {
-        if (summon_specific(creature_ptr, 0, creature_ptr->y, creature_ptr->x, floor_ptr->dun_level, SUMMON_UNDEAD, call_type)) {
+    if (player_ptr->cursed.has(CurseTraitType::CALL_UNDEAD) && one_in_(1111)) {
+        if (summon_specific(player_ptr, 0, player_ptr->y, player_ptr->x, floor_ptr->dun_level, SUMMON_UNDEAD, call_type)) {
             GAME_TEXT o_name[MAX_NLEN];
-            describe_flavor(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_CALL_UNDEAD), obj_desc_type);
+            describe_flavor(player_ptr, o_name, choose_cursed_obj_name(player_ptr, CurseTraitType::CALL_UNDEAD), obj_desc_type);
             msg_format(_("%sが死霊を引き寄せた!", "Your %s has attracted an undead!"), o_name);
-            disturb(creature_ptr, FALSE, TRUE);
+            disturb(player_ptr, false, true);
         }
     }
 }
 
-static void curse_cowardice(player_type *creature_ptr)
+static void curse_cowardice(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_COWARDICE) == 0) || !one_in_(1500))
+    if (player_ptr->cursed.has_not(CurseTraitType::COWARDICE))
         return;
 
-    if (has_resist_fear(creature_ptr))
+    object_type *o_ptr;
+    o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::COWARDICE);
+    int chance = 1500;
+    int duration = 13 + randint1(26);
+
+    if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
+        chance = 150;
+        duration *= 2;
+    }
+    
+    if (!one_in_(chance))
         return;
 
-    disturb(creature_ptr, FALSE, TRUE);
+    if (has_resist_fear(player_ptr))
+        return;
+
+    disturb(player_ptr, false, true);
     msg_print(_("とても暗い... とても恐い!", "It's so dark... so scary!"));
-    set_afraid(creature_ptr, creature_ptr->afraid + 13 + randint1(26));
+    (void)BadStatusSetter(player_ptr).mod_afraidness(duration);
+}
+
+/*!
+ * @brief 装備による狂戦士化の発作を引き起こす
+ * @param player_ptr プレイヤー情報への参照ポインタ
+ */
+static void curse_berserk_rage(PlayerType *player_ptr)
+{
+    if (player_ptr->cursed.has_not(CurseTraitType::BERS_RAGE))
+        return;
+
+    object_type *o_ptr;
+    o_ptr = choose_cursed_obj_name(player_ptr, CurseTraitType::BERS_RAGE);
+    int chance = 1500;
+    int duration = 10 + randint1(player_ptr->lev);
+
+    if (o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE)) {
+        chance = 150;
+        duration *= 2;
+    }
+    
+    if (!one_in_(chance))
+        return;
+
+    disturb(player_ptr, false, true);
+    msg_print(_("ウガァァア!", "RAAAAGHH!"));
+    msg_print(_("激怒の発作に襲われた!", "You feel a fit of rage coming over you!"));
+    (void)set_shero(player_ptr, duration, false);
+    (void)BadStatusSetter(player_ptr).afraidness(0);
 }
 
-static void curse_drain_hp(player_type *creature_ptr)
+static void curse_drain_hp(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_DRAIN_HP) == 0) || !one_in_(666))
+    if ((player_ptr->cursed.has_not(CurseTraitType::DRAIN_HP)) || !one_in_(666))
         return;
 
     GAME_TEXT o_name[MAX_NLEN];
-    describe_flavor(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_DRAIN_HP), (OD_OMIT_PREFIX | OD_NAME_ONLY));
+    describe_flavor(player_ptr, o_name, choose_cursed_obj_name(player_ptr, CurseTraitType::DRAIN_HP), (OD_OMIT_PREFIX | OD_NAME_ONLY));
     msg_format(_("%sはあなたの体力を吸収した!", "Your %s drains HP from you!"), o_name);
-    take_hit(creature_ptr, DAMAGE_LOSELIFE, MIN(creature_ptr->lev * 2, 100), o_name, -1);
+    take_hit(player_ptr, DAMAGE_LOSELIFE, std::min(player_ptr->lev * 2, 100), o_name);
 }
 
-static void curse_drain_mp(player_type *creature_ptr)
+static void curse_drain_mp(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_DRAIN_MANA) == 0) || (creature_ptr->csp == 0) || !one_in_(666))
+    if ((player_ptr->cursed.has_not(CurseTraitType::DRAIN_MANA)) || (player_ptr->csp == 0) || !one_in_(666))
         return;
 
     GAME_TEXT o_name[MAX_NLEN];
-    describe_flavor(creature_ptr, o_name, choose_cursed_obj_name(creature_ptr, TRC_DRAIN_MANA), (OD_OMIT_PREFIX | OD_NAME_ONLY));
+    describe_flavor(player_ptr, o_name, choose_cursed_obj_name(player_ptr, CurseTraitType::DRAIN_MANA), (OD_OMIT_PREFIX | OD_NAME_ONLY));
     msg_format(_("%sはあなたの魔力を吸収した!", "Your %s drains mana from you!"), o_name);
-    creature_ptr->csp -= MIN(creature_ptr->lev, 50);
-    if (creature_ptr->csp < 0) {
-        creature_ptr->csp = 0;
-        creature_ptr->csp_frac = 0;
+    player_ptr->csp -= std::min<short>(player_ptr->lev, 50);
+    if (player_ptr->csp < 0) {
+        player_ptr->csp = 0;
+        player_ptr->csp_frac = 0;
     }
 
-    creature_ptr->redraw |= PR_MANA;
+    player_ptr->redraw |= PR_MANA;
 }
 
-static void occur_curse_effects(player_type *creature_ptr)
+static void occur_curse_effects(PlayerType *player_ptr)
 {
-    if (((creature_ptr->cursed & TRC_P_FLAG_MASK) == 0) || creature_ptr->phase_out || creature_ptr->wild_mode)
+    if ((player_ptr->cursed.has_none_of(TRC_P_FLAG_MASK) && player_ptr->cursed_special.has_none_of(TRCS_P_FLAG_MASK)) || player_ptr->phase_out
+        || player_ptr->wild_mode)
         return;
 
-    curse_teleport(creature_ptr);
-    occur_chainsword_effect(creature_ptr);
-    if ((creature_ptr->cursed & TRC_TY_CURSE) && one_in_(TY_CURSE_CHANCE)) {
+    curse_teleport(player_ptr);
+    occur_chainsword_effect(player_ptr);
+    if (player_ptr->cursed.has(CurseTraitType::TY_CURSE) && one_in_(TY_CURSE_CHANCE)) {
         int count = 0;
-        (void)activate_ty_curse(creature_ptr, FALSE, &count);
+        (void)activate_ty_curse(player_ptr, false, &count);
     }
 
-    curse_drain_exp(creature_ptr);
-    multiply_low_curse(creature_ptr);
-    multiply_high_curse(creature_ptr);
-    curse_call_monster(creature_ptr);
-    curse_cowardice(creature_ptr);
-    if ((creature_ptr->cursed & TRC_TELEPORT) && one_in_(200) && !creature_ptr->anti_tele) {
-        disturb(creature_ptr, FALSE, TRUE);
-        teleport_player(creature_ptr, 40, TELEPORT_PASSIVE);
+    curse_drain_exp(player_ptr);
+    multiply_low_curse(player_ptr);
+    multiply_high_curse(player_ptr);
+    curse_call_monster(player_ptr);
+    curse_cowardice(player_ptr);
+    curse_berserk_rage(player_ptr);
+    if (player_ptr->cursed.has(CurseTraitType::TELEPORT) && one_in_(200) && !player_ptr->anti_tele) {
+        disturb(player_ptr, false, true);
+        teleport_player(player_ptr, 40, TELEPORT_PASSIVE);
     }
 
-    curse_drain_hp(creature_ptr);
-    curse_drain_mp(creature_ptr);
+    curse_drain_hp(player_ptr);
+    curse_drain_mp(player_ptr);
 }
 
 /*!
  * @brief 10ゲームターンが進行するごとに装備効果の発動判定を行う処理
  * / Handle curse effects once every 10 game turns
- * @param creature_ptr プレーヤーへの参照ポインタ
- * @return なし
+ * @param player_ptr プレイヤーへの参照ポインタ
  */
-void execute_cursed_items_effect(player_type *creature_ptr)
+void execute_cursed_items_effect(PlayerType *player_ptr)
 {
-    occur_curse_effects(creature_ptr);
-    if (!one_in_(999) || creature_ptr->anti_magic)
+    occur_curse_effects(player_ptr);
+    if (!one_in_(999) || player_ptr->anti_magic || (one_in_(2) && has_resist_curse(player_ptr)))
         return;
 
-    object_type *o_ptr = &creature_ptr->inventory_list[INVEN_LITE];
+    object_type *o_ptr = &player_ptr->inventory_list[INVEN_LITE];
     if (o_ptr->name1 != ART_JUDGE)
         return;
 
-    if (object_is_known(o_ptr))
+    if (o_ptr->is_known())
         msg_print(_("『審判の宝石』はあなたの体力を吸収した!", "The Jewel of Judgement drains life from you!"));
     else
         msg_print(_("なにかがあなたの体力を吸収した!", "Something drains life from you!"));
 
-    take_hit(creature_ptr, DAMAGE_LOSELIFE, MIN(creature_ptr->lev, 50), _("審判の宝石", "the Jewel of Judgement"), -1);
+    take_hit(player_ptr, DAMAGE_LOSELIFE, std::min<short>(player_ptr->lev, 50), _("審判の宝石", "the Jewel of Judgement"));
 }