OSDN Git Service

Merge pull request #2948 from backwardsEric/sprintf-refactor-item_activation_aux
[hengbandforosx/hengbandosx.git] / src / artifact / fixed-art-generator.cpp
index a470184..17179bb 100644 (file)
 #include "object-enchant/trc-types.h"
 #include "object-enchant/trg-types.h"
 #include "object/object-kind-hook.h"
-#include "object/object-kind.h"
+#include "player-base/player-class.h"
 #include "player/player-sex.h"
 #include "specific-object/bloody-moon.h"
 #include "system/artifact-type-definition.h"
+#include "system/baseitem-info.h"
 #include "system/floor-type-definition.h"
-#include "system/object-type-definition.h"
+#include "system/item-entity.h"
 #include "system/player-type-definition.h"
 #include "util/bit-flags-calculator.h"
 
  * 純戦士系職業は追加能力/耐性がもらえる。
  * それ以外では、反感、太古の怨念、呪いが付き追加能力/耐性はもらえない。
  */
-static bool invest_terror_mask(player_type *player_ptr, object_type *o_ptr)
+static bool invest_terror_mask(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    if (o_ptr->name1 != ART_TERROR)
+    if (!o_ptr->is_specific_artifact(FixedArtifactId::TERROR)) {
         return false;
+    }
 
     switch (player_ptr->pclass) {
     case PlayerClassType::WARRIOR:
@@ -53,7 +55,7 @@ static bool invest_terror_mask(player_type *player_ptr, object_type *o_ptr)
     default:
         o_ptr->art_flags.set(TR_AGGRAVATE);
         o_ptr->art_flags.set(TR_TY_CURSE);
-        o_ptr->curse_flags.set({ TRC::CURSED, TRC::HEAVY_CURSE });
+        o_ptr->curse_flags.set({ CurseTraitType::CURSED, CurseTraitType::HEAVY_CURSE });
         o_ptr->curse_flags.set(get_curse(2, o_ptr));
         return false;
     }
@@ -64,10 +66,11 @@ static bool invest_terror_mask(player_type *player_ptr, object_type *o_ptr)
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param o_ptr 対象のオブジェクト構造体への参照ポインタ
  */
-static void milim_swimsuit(player_type *player_ptr, object_type *o_ptr)
+static void milim_swimsuit(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    if ((o_ptr->name1 != ART_MILIM) || (player_ptr->ppersonality != PERSONALITY_SEXY))
+    if (!o_ptr->is_specific_artifact(FixedArtifactId::MILIM) || (player_ptr->ppersonality != PERSONALITY_SEXY)) {
         return;
+    }
 
     o_ptr->pval = 3;
     o_ptr->art_flags.set(TR_STR);
@@ -88,31 +91,35 @@ static void milim_swimsuit(player_type *player_ptr, object_type *o_ptr)
  * @details
  * 対象は村正、ロビントンのハープ、龍争虎鬪、ブラッディムーン、羽衣、天女の羽衣、ミリム
  */
-static void invest_special_artifact_abilities(player_type *player_ptr, object_type *o_ptr)
+static void invest_special_artifact_abilities(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    switch (o_ptr->name1) {
-    case ART_MURAMASA:
-        if (player_ptr->pclass != PlayerClassType::SAMURAI) {
+    const auto pc = PlayerClass(player_ptr);
+    switch (o_ptr->fixed_artifact_idx) {
+    case FixedArtifactId::MURAMASA:
+        if (!pc.equals(PlayerClassType::SAMURAI)) {
             o_ptr->art_flags.set(TR_NO_MAGIC);
-            o_ptr->curse_flags.set(TRC::HEAVY_CURSE);
+            o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
         }
         return;
-    case ART_ROBINTON:
-        if (player_ptr->pclass == PlayerClassType::BARD)
+    case FixedArtifactId::ROBINTON:
+        if (pc.equals(PlayerClassType::BARD)) {
             o_ptr->art_flags.set(TR_DEC_MANA);
+        }
         return;
-    case ART_XIAOLONG:
-        if (player_ptr->pclass == PlayerClassType::MONK)
+    case FixedArtifactId::XIAOLONG:
+        if (pc.equals(PlayerClassType::MONK)) {
             o_ptr->art_flags.set(TR_BLOWS);
+        }
         return;
-    case ART_BLOOD:
+    case FixedArtifactId::BLOOD:
         get_bloody_moon_flags(o_ptr);
         return;
-    case ART_HEAVENLY_MAIDEN:
-        if (player_ptr->psex != SEX_FEMALE)
+    case FixedArtifactId::HEAVENLY_MAIDEN:
+        if (player_ptr->psex != SEX_FEMALE) {
             o_ptr->art_flags.set(TR_AGGRAVATE);
+        }
         return;
-    case ART_MILIM:
+    case FixedArtifactId::MILIM:
         milim_swimsuit(player_ptr, o_ptr);
         return;
     default:
@@ -126,7 +133,7 @@ static void invest_special_artifact_abilities(player_type *player_ptr, object_ty
  * @param a_ptr 固定アーティファクト情報への参照ポインタ
  * @param q_ptr オブジェクト情報への参照ポインタ
  */
-static void fixed_artifact_random_abilities(player_type *player_ptr, artifact_type *a_ptr, object_type *o_ptr)
+static void fixed_artifact_random_abilities(PlayerType *player_ptr, const ArtifactType &a_ref, ItemEntity *o_ptr)
 {
     auto give_power = false;
     auto give_resistance = false;
@@ -138,32 +145,38 @@ static void fixed_artifact_random_abilities(player_type *player_ptr, artifact_ty
 
     invest_special_artifact_abilities(player_ptr, o_ptr);
 
-    if (a_ptr->gen_flags.has(TRG::XTRA_POWER))
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_POWER)) {
         give_power = true;
+    }
 
-    if (a_ptr->gen_flags.has(TRG::XTRA_H_RES))
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_H_RES)) {
         give_resistance = true;
+    }
 
-    if (a_ptr->gen_flags.has(TRG::XTRA_RES_OR_POWER)) {
-        if (one_in_(2))
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_RES_OR_POWER)) {
+        if (one_in_(2)) {
             give_resistance = true;
-        else
+        } else {
             give_power = true;
+        }
     }
 
-    if (give_power)
+    if (give_power) {
         one_ability(o_ptr);
+    }
 
-    if (give_resistance)
+    if (give_resistance) {
         one_high_resistance(o_ptr);
+    }
 
-    if (a_ptr->gen_flags.has(TRG::XTRA_DICE)) {
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::XTRA_DICE)) {
         do {
             o_ptr->dd++;
         } while (one_in_(o_ptr->dd));
 
-        if (o_ptr->dd > 9)
+        if (o_ptr->dd > 9) {
             o_ptr->dd = 9;
+        }
     }
 }
 
@@ -173,28 +186,35 @@ static void fixed_artifact_random_abilities(player_type *player_ptr, artifact_ty
  * @param a_ptr 固定アーティファクト情報への参照ポインタ
  * @param q_ptr オブジェクト情報への参照ポインタ
  */
-static void invest_curse_to_fixed_artifact(artifact_type *a_ptr, object_type *o_ptr)
+static void invest_curse_to_fixed_artifact(const ArtifactType &a_ref, ItemEntity *o_ptr)
 {
-    if (!a_ptr->cost)
+    if (!a_ref.cost) {
         set_bits(o_ptr->ident, IDENT_BROKEN);
+    }
 
-    if (a_ptr->gen_flags.has(TRG::CURSED))
-        o_ptr->curse_flags.set(TRC::CURSED);
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::CURSED)) {
+        o_ptr->curse_flags.set(CurseTraitType::CURSED);
+    }
 
-    if (a_ptr->gen_flags.has(TRG::HEAVY_CURSE))
-        o_ptr->curse_flags.set(TRC::HEAVY_CURSE);
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE)) {
+        o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
+    }
 
-    if (a_ptr->gen_flags.has(TRG::PERMA_CURSE))
-        o_ptr->curse_flags.set(TRC::PERMA_CURSE);
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::PERMA_CURSE)) {
+        o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
+    }
 
-    if (a_ptr->gen_flags.has(TRG::RANDOM_CURSE0))
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0)) {
         o_ptr->curse_flags.set(get_curse(0, o_ptr));
+    }
 
-    if (a_ptr->gen_flags.has(TRG::RANDOM_CURSE1))
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1)) {
         o_ptr->curse_flags.set(get_curse(1, o_ptr));
+    }
 
-    if (a_ptr->gen_flags.has(TRG::RANDOM_CURSE2))
+    if (a_ref.gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2)) {
         o_ptr->curse_flags.set(get_curse(2, o_ptr));
+    }
 }
 
 /*!
@@ -203,23 +223,21 @@ static void invest_curse_to_fixed_artifact(artifact_type *a_ptr, object_type *o_
  * @param o_ptr 生成に割り当てたいオブジェクトの構造体参照ポインタ
  * @return 適用したアーティファクト情報への参照ポインタ
  */
-artifact_type *apply_artifact(player_type *player_ptr, object_type *o_ptr)
+void apply_artifact(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    auto a_ptr = &a_info[o_ptr->name1];
-    o_ptr->pval = a_ptr->pval;
-    o_ptr->ac = a_ptr->ac;
-    o_ptr->dd = a_ptr->dd;
-    o_ptr->ds = a_ptr->ds;
-    o_ptr->to_a = a_ptr->to_a;
-    o_ptr->to_h = a_ptr->to_h;
-    o_ptr->to_d = a_ptr->to_d;
-    o_ptr->weight = a_ptr->weight;
-    o_ptr->activation_id = a_ptr->act_idx;
-
-    invest_curse_to_fixed_artifact(a_ptr, o_ptr);
-    fixed_artifact_random_abilities(player_ptr, a_ptr, o_ptr);
-
-    return a_ptr;
+    auto &a_ref = artifacts_info.at(o_ptr->fixed_artifact_idx);
+    o_ptr->pval = a_ref.pval;
+    o_ptr->ac = a_ref.ac;
+    o_ptr->dd = a_ref.dd;
+    o_ptr->ds = a_ref.ds;
+    o_ptr->to_a = a_ref.to_a;
+    o_ptr->to_h = a_ref.to_h;
+    o_ptr->to_d = a_ref.to_d;
+    o_ptr->weight = a_ref.weight;
+    o_ptr->activation_id = a_ref.act_idx;
+
+    invest_curse_to_fixed_artifact(a_ref, o_ptr);
+    fixed_artifact_random_abilities(player_ptr, a_ref, o_ptr);
 }
 
 /*!
@@ -234,24 +252,29 @@ artifact_type *apply_artifact(player_type *player_ptr, object_type *o_ptr)
  * 仮に2個以上存在可能かつ装備品以外の固定アーティファクトが作成されれば
  * drop_near()関数の返り値は信用できなくなる.
  */
-bool create_named_art(player_type *player_ptr, ARTIFACT_IDX a_idx, POSITION y, POSITION x)
+bool create_named_art(PlayerType *player_ptr, FixedArtifactId a_idx, POSITION y, POSITION x)
 {
-    auto a_ptr = &a_info[a_idx];
-    if (a_ptr->name.empty())
+    auto &a_ref = artifacts_info.at(a_idx);
+    if (a_ref.name.empty()) {
         return false;
+    }
 
-    auto i = lookup_kind(a_ptr->tval, a_ptr->sval);
-    if (i == 0)
+    auto bi_id = lookup_baseitem_id(a_ref.bi_key);
+    if (bi_id == 0) {
         return true;
+    }
 
-    object_type forge;
+    ItemEntity forge;
     auto q_ptr = &forge;
-    q_ptr->prep(i);
-    q_ptr->name1 = a_idx;
-
-    (void)apply_artifact(player_ptr, q_ptr);
+    q_ptr->prep(bi_id);
+    q_ptr->fixed_artifact_idx = a_idx;
+    apply_artifact(player_ptr, q_ptr);
+    if (drop_near(player_ptr, q_ptr, -1, y, x) == 0) {
+        return false;
+    }
 
-    return drop_near(player_ptr, q_ptr, -1, y, x) > 0;
+    a_ref.is_generated = true;
+    return true;
 }
 
 /*!
@@ -265,44 +288,50 @@ bool create_named_art(player_type *player_ptr, ARTIFACT_IDX a_idx, POSITION y, P
  * This routine should only be called by "apply_magic()"\n
  * Note -- see "make_artifact_special()" and "apply_magic()"\n
  */
-bool make_artifact(player_type *player_ptr, object_type *o_ptr)
+bool make_artifact(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
     auto floor_ptr = player_ptr->current_floor_ptr;
-    if (floor_ptr->dun_level == 0)
+    if (floor_ptr->dun_level == 0) {
         return false;
+    }
 
-    if (o_ptr->number != 1)
+    if (o_ptr->number != 1) {
         return false;
+    }
 
-    for (const auto &a_ref : a_info) {
-        if (a_ref.name.empty())
-            continue;
-
-        if (a_ref.cur_num)
+    for (const auto &[a_idx, a_ref] : artifacts_info) {
+        if (a_ref.name.empty()) {
             continue;
+        }
 
-        if (a_ref.gen_flags.has(TRG::QUESTITEM))
+        if (a_ref.is_generated) {
             continue;
+        }
 
-        if (a_ref.gen_flags.has(TRG::INSTA_ART))
+        if (a_ref.gen_flags.has(ItemGenerationTraitType::QUESTITEM)) {
             continue;
+        }
 
-        if (a_ref.tval != o_ptr->tval)
+        if (a_ref.gen_flags.has(ItemGenerationTraitType::INSTA_ART)) {
             continue;
+        }
 
-        if (a_ref.sval != o_ptr->sval)
+        if (a_ref.bi_key != o_ptr->bi_key) {
             continue;
+        }
 
         if (a_ref.level > floor_ptr->dun_level) {
             int d = (a_ref.level - floor_ptr->dun_level) * 2;
-            if (!one_in_(d))
+            if (!one_in_(d)) {
                 continue;
+            }
         }
 
-        if (!one_in_(a_ref.rarity))
+        if (!one_in_(a_ref.rarity)) {
             continue;
+        }
 
-        o_ptr->name1 = a_ref.idx;
+        o_ptr->fixed_artifact_idx = a_idx;
         return true;
     }
 
@@ -321,61 +350,68 @@ bool make_artifact(player_type *player_ptr, object_type *o_ptr)
  *\n
  * Note -- see "make_artifact()" and "apply_magic()"\n
  */
-bool make_artifact_special(player_type *player_ptr, object_type *o_ptr)
+bool make_artifact_special(PlayerType *player_ptr, ItemEntity *o_ptr)
 {
-    KIND_OBJECT_IDX k_idx = 0;
-
     /*! @note 地上ではキャンセルする / No artifacts in the town */
     auto floor_ptr = player_ptr->current_floor_ptr;
-    if (floor_ptr->dun_level == 0)
+    if (floor_ptr->dun_level == 0) {
         return false;
+    }
 
-    /*! @note get_obj_num_hookによる指定がある場合は生成をキャンセルする / Themed object */
-    if (get_obj_num_hook)
+    /*! @note get_obj_index_hookによる指定がある場合は生成をキャンセルする / Themed object */
+    if (get_obj_index_hook) {
         return false;
+    }
 
     /*! @note 全固定アーティファクト中からIDの若い順に生成対象とその確率を走査する / Check the artifact list (just the "specials") */
-    for (const auto &a_ref : a_info) {
+    for (const auto &[a_idx, a_ref] : artifacts_info) {
         /*! @note アーティファクト名が空の不正なデータは除外する / Skip "empty" artifacts */
-        if (a_ref.name.empty())
+        if (a_ref.name.empty()) {
             continue;
+        }
 
         /*! @note 既に生成回数がカウントされたアーティファクト、QUESTITEMと非INSTA_ARTは除外 / Cannot make an artifact twice */
-        if (a_ref.cur_num)
+        if (a_ref.is_generated) {
             continue;
-        if (a_ref.gen_flags.has(TRG::QUESTITEM))
+        }
+        if (a_ref.gen_flags.has(ItemGenerationTraitType::QUESTITEM)) {
             continue;
-        if (!(a_ref.gen_flags.has(TRG::INSTA_ART)))
+        }
+        if (!(a_ref.gen_flags.has(ItemGenerationTraitType::INSTA_ART))) {
             continue;
+        }
 
-        /*! @note アーティファクト生成階が現在に対して足りない場合は高確率で1/(不足階層*2)を満たさないと生成リストに加えられない /
-         *  XXX XXX Enforce minimum "depth" (loosely) */
+        /*! @note アーティファクト生成階が現在に対して足りない場合は高確率で1/(不足階層*2)を満たさないと生成リストに加えられない */
         if (a_ref.level > floor_ptr->object_level) {
             /* @note  / Acquire the "out-of-depth factor". Roll for out-of-depth creation. */
             int d = (a_ref.level - floor_ptr->object_level) * 2;
-            if (!one_in_(d))
+            if (!one_in_(d)) {
                 continue;
+            }
         }
 
         /*! @note 1/(レア度)の確率を満たさないと除外される / Artifact "rarity roll" */
-        if (!one_in_(a_ref.rarity))
+        if (!one_in_(a_ref.rarity)) {
             continue;
+        }
 
-        /*! @note INSTA_ART型固定アーティファクトのベースアイテムもチェック対象とする。ベースアイテムの生成階層が足りない場合1/(不足階層*5)
-         * を満たさないと除外される。 / Find the base object. XXX XXX Enforce minimum "object" level (loosely). Acquire the "out-of-depth factor". Roll for
-         * out-of-depth creation. */
-        k_idx = lookup_kind(a_ref.tval, a_ref.sval);
-        if (k_info[k_idx].level > floor_ptr->object_level) {
-            int d = (k_info[k_idx].level - floor_ptr->object_level) * 5;
-            if (!one_in_(d))
+        /*!
+         * @note INSTA_ART型固定アーティファクトのベースアイテムもチェック対象とする。
+         * ベースアイテムの生成階層が足りない場合1/(不足階層*5)を満たさないと除外される。
+         */
+        const auto bi_id = lookup_baseitem_id(a_ref.bi_key);
+        if (baseitems_info[bi_id].level > floor_ptr->object_level) {
+            int d = (baseitems_info[bi_id].level - floor_ptr->object_level) * 5;
+            if (!one_in_(d)) {
                 continue;
+            }
         }
 
         /*! @note 前述の条件を満たしたら、後のIDのアーティファクトはチェックせずすぐ確定し生成処理に移す /
          * Assign the template. Mega-Hack -- mark the item as an artifact. Hack: Some artifacts get random extra powers. Success. */
-        o_ptr->prep(k_idx);
+        o_ptr->prep(bi_id);
 
-        o_ptr->name1 = a_ref.idx;
+        o_ptr->fixed_artifact_idx = a_idx;
         return true;
     }